192 lines
6.6 KiB
TypeScript
192 lines
6.6 KiB
TypeScript
import React from 'react'
|
|
import { Controller, useFormContext, useWatch } from 'react-hook-form'
|
|
import { GermanStates } from '@heygermany/sdk'
|
|
import { MultiSelect, Radio, Stack, Title, Group, Box, Input, Alert } from '@pikku/mantine/core'
|
|
import { DateInput } from '@mantine/dates'
|
|
import { IconInfoCircle } from '@tabler/icons-react'
|
|
import { useI18n } from '@/context/i18n-provider'
|
|
import { CountrySearch } from './CountrySearch'
|
|
import { SUPPORTED_COUNTRIES } from '@/config'
|
|
|
|
export const BasicInfo: React.FunctionComponent = () => {
|
|
const t = useI18n()
|
|
const { control, formState: { errors } } = useFormContext()
|
|
|
|
const countryEducation = useWatch({ control, name: 'countryEducation' })
|
|
const isUnsupportedCountry = countryEducation && !SUPPORTED_COUNTRIES.includes(countryEducation)
|
|
|
|
const germanStates = Object.values(GermanStates)
|
|
|
|
return (
|
|
<Stack gap="lg">
|
|
<Title order={2}>{t('jobs.apply.steps.basicinfo')}</Title>
|
|
|
|
{/* German States Multi-Select */}
|
|
<Box>
|
|
<Controller
|
|
name="stateWorkPreference"
|
|
control={control}
|
|
rules={{ required: t('jobs.basicinfo.validation.staterequired') }}
|
|
render={({ field }) => (
|
|
<MultiSelect
|
|
label={t('jobs.basicinfo.worklocation.question')}
|
|
value={field.value || []}
|
|
onChange={(newValue) => {
|
|
if (newValue.includes('ALL')) {
|
|
// If ALL is selected, select all states
|
|
if (!field.value?.includes('ALL')) {
|
|
field.onChange(germanStates)
|
|
} else {
|
|
// If ALL is already selected and user clicks it again, deselect all
|
|
field.onChange([])
|
|
}
|
|
} else {
|
|
field.onChange(newValue)
|
|
}
|
|
}}
|
|
data={[
|
|
{ value: 'ALL', label: t('jobs.basicinfo.worklocation.selectall')},
|
|
...germanStates.map(state => ({ value: state, label: state }))
|
|
]}
|
|
placeholder={t('jobs.basicinfo.worklocation.placeholder')}
|
|
searchable
|
|
clearable
|
|
error={errors.stateWorkPreference?.message as string}
|
|
w="100%"
|
|
/>
|
|
)}
|
|
/>
|
|
</Box>
|
|
|
|
{/* Open to Work */}
|
|
<Box>
|
|
<Input.Wrapper label={t('jobs.basicinfo.jointalentpool.question')}>
|
|
<Controller
|
|
name="joinTalentPool"
|
|
control={control}
|
|
rules={{
|
|
validate: (value) => (value === true || value === false) || t('jobs.basicinfo.validation.optionrequired')
|
|
}}
|
|
render={({ field }) => (
|
|
<Radio.Group
|
|
value={field.value?.toString()}
|
|
onChange={(value) => field.onChange(value === 'true' ? true : false)}
|
|
error={errors.joinTalentPool?.message as string}
|
|
>
|
|
<Group gap="lg" mb="xs">
|
|
<Radio value="true" label={t('jobs.basicinfo.yes')} />
|
|
<Radio value="false" label={t('jobs.basicinfo.no')} />
|
|
</Group>
|
|
</Radio.Group>
|
|
)}
|
|
/>
|
|
</Input.Wrapper>
|
|
</Box>
|
|
|
|
{/* Living in Germany */}
|
|
<Box>
|
|
<Input.Wrapper label={t('jobs.basicinfo.livingingermany.question')}>
|
|
<Controller
|
|
name="livingInGermany"
|
|
control={control}
|
|
rules={{
|
|
validate: (value) => (value === true || value === false) || t('jobs.basicinfo.validation.optionrequired')
|
|
}}
|
|
render={({ field }) => (
|
|
<Radio.Group
|
|
value={field.value?.toString()}
|
|
onChange={(value) => field.onChange(value === 'true' ? true : false)}
|
|
error={errors.livingInGermany?.message as string}
|
|
>
|
|
<Group gap="lg" mb="xs">
|
|
<Radio value="true" label={t('jobs.basicinfo.yes')} />
|
|
<Radio value="false" label={t('jobs.basicinfo.no')} />
|
|
</Group>
|
|
</Radio.Group>
|
|
)}
|
|
/>
|
|
</Input.Wrapper>
|
|
</Box>
|
|
|
|
{/* EU Passport */}
|
|
<Box>
|
|
<Input.Wrapper label={t('jobs.basicinfo.eupassport.question')}>
|
|
<Controller
|
|
name="euPassport"
|
|
control={control}
|
|
rules={{
|
|
validate: (value) => (value === true || value === false) || t('jobs.basicinfo.validation.optionrequired')
|
|
}}
|
|
render={({ field }) => (
|
|
<Radio.Group
|
|
value={field.value?.toString()}
|
|
onChange={(value) => field.onChange(value === 'true' ? true : false)}
|
|
error={errors.euPassport?.message as string}
|
|
>
|
|
<Group gap="lg" mb="xs">
|
|
<Radio value="true" label={t('jobs.basicinfo.yes')} />
|
|
<Radio value="false" label={t('jobs.basicinfo.no')} />
|
|
</Group>
|
|
</Radio.Group>
|
|
)}
|
|
/>
|
|
</Input.Wrapper>
|
|
</Box>
|
|
|
|
{/* Date of Birth */}
|
|
<Box>
|
|
<Controller
|
|
name="dateOfBirth"
|
|
control={control}
|
|
rules={{
|
|
required: t('jobs.basicinfo.validation.dateofbirthrequired')
|
|
}}
|
|
render={({ field }) => (
|
|
<DateInput
|
|
label={t('jobs.basicinfo.dateofbirth.question')}
|
|
placeholder={t('jobs.basicinfo.dateofbirth.placeholder')}
|
|
value={field.value ? new Date(field.value) : null}
|
|
onChange={field.onChange}
|
|
error={errors.dateOfBirth?.message as string}
|
|
clearable
|
|
weekendDays={[]}
|
|
/>
|
|
)}
|
|
/>
|
|
</Box>
|
|
|
|
{/* Education Country */}
|
|
<Box>
|
|
<Controller
|
|
name="countryEducation"
|
|
control={control}
|
|
rules={{
|
|
required: t('jobs.basicinfo.validation.countryrequired'),
|
|
}}
|
|
render={({ field }) => (
|
|
<CountrySearch
|
|
value={field.value}
|
|
onChange={field.onChange}
|
|
label={t('jobs.basicinfo.education.question')}
|
|
placeholder={t('jobs.basicinfo.education.placeholder')}
|
|
error={errors.countryEducation?.message as string}
|
|
/>
|
|
)}
|
|
/>
|
|
|
|
{isUnsupportedCountry && (
|
|
<Alert
|
|
icon={<IconInfoCircle size={16} />}
|
|
title={t('jobs.basicinfo.unsupportedcountry.title')}
|
|
color="blue"
|
|
mt="sm"
|
|
>
|
|
{t('jobs.basicinfo.unsupportedcountry.message')}
|
|
</Alert>
|
|
)}
|
|
</Box>
|
|
|
|
</Stack>
|
|
)
|
|
}
|