chore: heygermany customer project
This commit is contained in:
142
apps/website/components/jobs/form/GermanLanguage.tsx
Normal file
142
apps/website/components/jobs/form/GermanLanguage.tsx
Normal file
@@ -0,0 +1,142 @@
|
||||
import { Controller, useFormContext } from 'react-hook-form'
|
||||
import { Checkbox, Box, Text, Group, Stack, Title } from '@pikku/mantine/core'
|
||||
import type { DB } from '@heygermany/sdk'
|
||||
import {
|
||||
ApplicationCandidateData,
|
||||
ApplicationCandidateLanguage,
|
||||
CandidateDocumentTypes,
|
||||
LanguageLevels,
|
||||
} from '@heygermany/sdk'
|
||||
import { FileUpload } from '../../ui/FileUpload'
|
||||
import { useUploadCandidateFiles } from '@/hooks/useUploadCandidateFiles'
|
||||
import { useEffect } from 'react'
|
||||
import { CandidateSection } from './CandidateSection'
|
||||
import { useI18n } from '@/context/i18n-provider'
|
||||
import { EnumSelect } from '@/components/common/EnumSelect'
|
||||
import { asI18n } from '@pikku/react'
|
||||
|
||||
export const GermanLanguage: React.FunctionComponent<{ candidate: ApplicationCandidateData }> = ({ candidate }) => {
|
||||
const t = useI18n()
|
||||
const { control, trigger, clearErrors, setValue, formState: { errors }, watch } = useFormContext<ApplicationCandidateLanguage>()
|
||||
const languageCertificateProvided = watch('languageCertificateProvided')
|
||||
const selfAssessment = watch('languageSelfAssessmentLevel')
|
||||
|
||||
useEffect(() => {
|
||||
if (languageCertificateProvided === null) {
|
||||
setValue('languageCertificateProvided', true)
|
||||
} else if (languageCertificateProvided === true) {
|
||||
setValue('languageSelfAssessmentLevel', null)
|
||||
}
|
||||
clearErrors()
|
||||
}, [languageCertificateProvided])
|
||||
|
||||
useEffect(() => {
|
||||
if (selfAssessment) {
|
||||
clearErrors()
|
||||
}
|
||||
}, [selfAssessment])
|
||||
|
||||
const { uploadFiles, deleteFile } = useUploadCandidateFiles(candidate.candidateId, CandidateDocumentTypes.LANGUAGE, trigger)
|
||||
|
||||
const validateLanguages = (files?: any[], selfAssessment?: DB.LanguageLevel | null, certificateProvided?: boolean | null): boolean | string => {
|
||||
if (certificateProvided) {
|
||||
if (!files || files.length === 0) {
|
||||
return t('jobs.germanlanguage.validation.certificaterequired')
|
||||
}
|
||||
if (files.length > 5) {
|
||||
return t('jobs.germanlanguage.validation.maxfiles')
|
||||
}
|
||||
} else {
|
||||
if (!selfAssessment) {
|
||||
return t('jobs.germanlanguage.validation.selfassessmentrequired')
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
return (
|
||||
<CandidateSection
|
||||
title={t('jobs.germanlanguage.title')}
|
||||
example={t('jobs.germanlanguage.example')}
|
||||
description={t('jobs.germanlanguage.description')}
|
||||
>
|
||||
<Stack gap="lg">
|
||||
<Controller
|
||||
name="languageCertificateProvided"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<Group gap="xs" mb="sm">
|
||||
<Checkbox
|
||||
id="language-certificate-not-provided"
|
||||
checked={field.value !== true}
|
||||
onChange={() => field.onChange(!field.value)}
|
||||
/>
|
||||
<Text
|
||||
size="sm"
|
||||
style={{ cursor: 'pointer' }}
|
||||
component="label"
|
||||
htmlFor="language-certificate-not-provided"
|
||||
>
|
||||
{t('jobs.germanlanguage.nocertificate')}
|
||||
</Text>
|
||||
</Group>
|
||||
)}
|
||||
/>
|
||||
|
||||
{languageCertificateProvided && (
|
||||
<Controller
|
||||
name="languageCertificates"
|
||||
control={control}
|
||||
rules={{
|
||||
validate: () => validateLanguages(candidate.languageCertificates, undefined, languageCertificateProvided)
|
||||
}}
|
||||
render={() => (
|
||||
<FileUpload
|
||||
files={candidate.languageCertificates.map((file: DB.CandidateDocument) => ({ id: file.documentId, fileName: file.fileName }))}
|
||||
uploadFiles={uploadFiles}
|
||||
deleteFile={deleteFile}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
|
||||
{!languageCertificateProvided && (
|
||||
<Box>
|
||||
<Title order={3} size="lg" mb="md">{t('jobs.germanlanguage.selfassessment.title')}</Title>
|
||||
<Text size="sm" c="dimmed" mb="md">
|
||||
{t('jobs.germanlanguage.selfassessment.description')}
|
||||
</Text>
|
||||
|
||||
<Controller
|
||||
name="languageSelfAssessmentLevel"
|
||||
control={control}
|
||||
rules={{
|
||||
validate: (value) => validateLanguages(undefined, value, languageCertificateProvided)
|
||||
}}
|
||||
render={({ field }) => (
|
||||
<Box w="fit-content">
|
||||
<EnumSelect
|
||||
label={t('jobs.germanlanguage.selfassessment.levellabel')}
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
enumName='LanguageLevel'
|
||||
enumObject={LanguageLevels}
|
||||
placeholder={t('jobs.germanlanguage.selfassessment.placeholder')}
|
||||
error={errors.languageSelfAssessmentLevel?.message}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{errors.languageCertificates && (
|
||||
<Text size="sm" c="error">
|
||||
{asI18n(errors.languageCertificates?.message ?? '')}
|
||||
</Text>
|
||||
)}
|
||||
</Stack>
|
||||
</CandidateSection>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user