Files
heygermany-e2e-mrg1vyey/apps/website/components/jobs/form/GermanLanguage.tsx
e2e 1e78e21c36
Some checks failed
Main / Setup and Test (push) Has been cancelled
Main / Build Website (push) Has been cancelled
chore: heygermany customer project
2026-07-11 09:36:03 +02:00

145 lines
5.0 KiB
TypeScript

'use client'
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>
)
}