chore: heygermany customer project
This commit is contained in:
95
apps/website/components/jobs/form/TrainingCertificates.tsx
Normal file
95
apps/website/components/jobs/form/TrainingCertificates.tsx
Normal file
@@ -0,0 +1,95 @@
|
||||
import { Controller, useFormContext } from 'react-hook-form'
|
||||
import type { DB } from '@heygermany/sdk'
|
||||
import { ApplicationCandidateData, ApplicationCandidateEducation, CandidateDocumentTypes } from '@heygermany/sdk'
|
||||
import { FileUpload } from '../../ui/FileUpload'
|
||||
import { useUploadCandidateFiles } from '@/hooks/useUploadCandidateFiles'
|
||||
import { CandidateSection } from './CandidateSection'
|
||||
import { Alert, Box, List, Text, ThemeIcon } from '@pikku/mantine/core'
|
||||
import { useI18n } from '@/context/i18n-provider'
|
||||
import { IconCheck, IconInfoCircle } from '@tabler/icons-react'
|
||||
import { asI18n } from '@pikku/react'
|
||||
|
||||
export const TrainingCertificates: React.FunctionComponent<{ candidate: ApplicationCandidateData }> = ({ candidate }) => {
|
||||
const t = useI18n()
|
||||
const { control, trigger, formState: { errors } } = useFormContext<ApplicationCandidateEducation>()
|
||||
const { uploadFiles, deleteFile } = useUploadCandidateFiles(candidate.candidateId, CandidateDocumentTypes.EDUCATION, trigger)
|
||||
const uploadedEducationDocuments = [...candidate.education]
|
||||
const i18n = (key: string) => t(key as any)
|
||||
const educationCopy = {
|
||||
title: i18n('jobs.educationdocuments.title'),
|
||||
example: i18n('jobs.educationdocuments.example'),
|
||||
description: i18n('jobs.educationdocuments.description'),
|
||||
validationRequired: i18n('jobs.educationdocuments.validation.required'),
|
||||
validationMaxFiles: i18n('jobs.educationdocuments.validation.maxfiles'),
|
||||
checklistTitle: i18n('jobs.educationdocuments.checklist.title'),
|
||||
checklist: [
|
||||
i18n('jobs.educationdocuments.checklist.item1'),
|
||||
i18n('jobs.educationdocuments.checklist.item2'),
|
||||
i18n('jobs.educationdocuments.checklist.item3')
|
||||
]
|
||||
}
|
||||
|
||||
const validateEducation = (files: DB.CandidateDocument[]): string | boolean => {
|
||||
if (!files || files.length === 0) {
|
||||
return educationCopy.validationRequired
|
||||
} else if (files.length > 10) {
|
||||
return educationCopy.validationMaxFiles
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
return (
|
||||
<CandidateSection
|
||||
title={educationCopy.title}
|
||||
example={educationCopy.example}
|
||||
description={educationCopy.description}
|
||||
>
|
||||
<Box>
|
||||
{educationCopy.checklist.length > 0 && (
|
||||
<Alert
|
||||
color="blue"
|
||||
mb="md"
|
||||
title={asI18n(educationCopy.checklistTitle)}
|
||||
icon={<IconInfoCircle size={16} />}
|
||||
>
|
||||
<List size="sm" spacing="xs">
|
||||
{educationCopy.checklist.map((item) => (
|
||||
<List.Item
|
||||
key={item}
|
||||
icon={
|
||||
<ThemeIcon size={18} radius="xl" color="blue.6">
|
||||
<IconCheck size={12} />
|
||||
</ThemeIcon>
|
||||
}
|
||||
>
|
||||
{asI18n(item)}
|
||||
</List.Item>
|
||||
))}
|
||||
</List>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
<Controller
|
||||
name="education"
|
||||
control={control}
|
||||
rules={{
|
||||
validate: () => validateEducation(uploadedEducationDocuments)
|
||||
}}
|
||||
render={() => (
|
||||
<Box mt="xs">
|
||||
<FileUpload
|
||||
files={uploadedEducationDocuments.map((file: DB.CandidateDocument) => ({ id: file.documentId, fileName: file.fileName }))}
|
||||
uploadFiles={uploadFiles}
|
||||
deleteFile={deleteFile}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
/>
|
||||
|
||||
{errors.education && (
|
||||
<Text size="sm" c="error" mt="xs">{asI18n(errors.education.message ?? '')}</Text>
|
||||
)}
|
||||
</Box>
|
||||
</CandidateSection>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user