chore: heygermany customer project
This commit is contained in:
182
apps/website/components/jobs/form/StartApplication.tsx
Normal file
182
apps/website/components/jobs/form/StartApplication.tsx
Normal file
@@ -0,0 +1,182 @@
|
||||
'use client'
|
||||
|
||||
import Link from "@/framework/link"
|
||||
import { Button, Checkbox, Stack, TextInput, Text, Anchor, Alert } from "@pikku/mantine/core"
|
||||
import { Controller, useForm } from "react-hook-form"
|
||||
import { requestMagicLink } from "@/lib/auth"
|
||||
import { pikku } from "@/pikku/http"
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query"
|
||||
import { useI18n } from "@/context/i18n-provider"
|
||||
import { useRouter, useParams } from "@/framework/navigation"
|
||||
import { useState } from "react"
|
||||
import { asI18n } from "@pikku/react"
|
||||
|
||||
export const StartApplication: React.FunctionComponent<{ initializing: boolean }> = ({ initializing }) => {
|
||||
const router = useRouter()
|
||||
const params = useParams()
|
||||
const lang = params.lang as string
|
||||
const t = useI18n()
|
||||
const [emailExists, setEmailExists] = useState(false)
|
||||
const [existingEmail, setExistingEmail] = useState('')
|
||||
const [hasError, setHasError] = useState(false)
|
||||
const {
|
||||
control,
|
||||
handleSubmit,
|
||||
formState: { errors },
|
||||
} = useForm({
|
||||
defaultValues: {
|
||||
email: '',
|
||||
fullName: '',
|
||||
termsAndPrivacyAccepted: false
|
||||
}
|
||||
})
|
||||
|
||||
const queryClient = useQueryClient()
|
||||
const mutation = useMutation({
|
||||
mutationFn: async (data: any) => {
|
||||
if (data.termsAndPrivacyAccepted && data.fullName && data.email) {
|
||||
try {
|
||||
await pikku().post('/candidate', {
|
||||
name: data.fullName,
|
||||
email: data.email
|
||||
});
|
||||
(window as any).fbq?.('trackCustom', 'StartApplication', {
|
||||
source: 'check_my_qualification_button',
|
||||
page: '/en/jobs/apply'
|
||||
});
|
||||
queryClient.invalidateQueries({ queryKey: ['candidate'] });
|
||||
router.push(`/${lang}/jobs/application`);
|
||||
} catch (error: any) {
|
||||
if (error.status === 409) {
|
||||
setEmailExists(true)
|
||||
setExistingEmail(data.email)
|
||||
setHasError(false)
|
||||
throw error
|
||||
}
|
||||
setHasError(true)
|
||||
setEmailExists(false)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const sendMagicLinkMutation = useMutation({
|
||||
mutationFn: async () => {
|
||||
await requestMagicLink(existingEmail)
|
||||
}
|
||||
})
|
||||
|
||||
return (
|
||||
<Stack component="form" gap="md" onSubmit={handleSubmit(data => mutation.mutateAsync(data))}>
|
||||
<Controller
|
||||
name="fullName"
|
||||
control={control}
|
||||
rules={{ required: t('jobs.startapplication.validation.fullnamerequired') }}
|
||||
disabled={initializing}
|
||||
render={({ field }) => (
|
||||
<TextInput
|
||||
id="fullName"
|
||||
label={t('jobs.startapplication.fullname')}
|
||||
error={errors.fullName?.message}
|
||||
{...field}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
<Controller
|
||||
name="email"
|
||||
control={control}
|
||||
rules={{
|
||||
required: t('jobs.startapplication.validation.emailrequired'),
|
||||
pattern: {
|
||||
value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
|
||||
message: t('jobs.startapplication.validation.emailinvalid')
|
||||
}
|
||||
}}
|
||||
disabled={initializing}
|
||||
render={({ field }) => (
|
||||
<TextInput
|
||||
id="email"
|
||||
type="email"
|
||||
label={t('jobs.startapplication.email')}
|
||||
autoComplete="email"
|
||||
error={errors.email?.message}
|
||||
{...field}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
<Controller
|
||||
name="termsAndPrivacyAccepted"
|
||||
control={control}
|
||||
disabled={initializing}
|
||||
rules={{ required: t('jobs.startapplication.validation.termsrequired') }}
|
||||
render={({ field }) => (
|
||||
<Checkbox
|
||||
id="terms"
|
||||
checked={field.value}
|
||||
onChange={field.onChange}
|
||||
disabled={field.disabled}
|
||||
error={errors.termsAndPrivacyAccepted?.message}
|
||||
label={
|
||||
<Text size="sm">
|
||||
{t('jobs.startapplication.termstext.prefix')}{asI18n(' ')}
|
||||
<Anchor component={Link} href={`/${lang}/legal/terms-and-conditions`} size="sm">
|
||||
{t('jobs.startapplication.termstext.terms')}
|
||||
</Anchor>{asI18n(' ')}
|
||||
{t('jobs.startapplication.termstext.and')}{asI18n(' ')}
|
||||
<Anchor component={Link} href={`/${lang}/legal/privacy`} size="sm">
|
||||
{t('jobs.startapplication.termstext.privacy')}
|
||||
</Anchor>{asI18n(' ')}
|
||||
{t('jobs.startapplication.termstext.suffix')}
|
||||
</Text>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
{hasError && (
|
||||
<Alert color="red" title={t('jobs.startapplication.error.title')}>
|
||||
<Text size="sm">
|
||||
{t('jobs.startapplication.error.message')}
|
||||
</Text>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
{emailExists && (
|
||||
<Alert color="blue" title={t('jobs.startapplication.emailexists.title')}>
|
||||
<Text size="sm" mb="md">
|
||||
{t('jobs.startapplication.emailexists.message')}
|
||||
</Text>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="light"
|
||||
onClick={() => sendMagicLinkMutation.mutate()}
|
||||
loading={sendMagicLinkMutation.isPending}
|
||||
disabled={sendMagicLinkMutation.isSuccess}
|
||||
>
|
||||
{sendMagicLinkMutation.isSuccess
|
||||
? t('jobs.startapplication.emailexists.sent')
|
||||
: t('jobs.startapplication.emailexists.button')}
|
||||
</Button>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
<Stack gap="xs">
|
||||
<Button
|
||||
size="lg"
|
||||
type="submit"
|
||||
loading={mutation.isPending}
|
||||
disabled={initializing || mutation.isPending}
|
||||
px="xl"
|
||||
>
|
||||
{t('jobs.startapplication.checkqualification')}
|
||||
</Button>
|
||||
<Text size="sm" c="dimmed" ta="center">
|
||||
{t('jobs.startapplication.freetext')}
|
||||
</Text>
|
||||
</Stack>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user