import { useEffect, useState } from 'react'; import { Container, Title, Text, Paper, Stack, Loader, Alert, Grid, Group, Flex, Card, Button, Switch, ActionIcon } from '@pikku/mantine/core'; import { IconExternalLink, IconEye } from '@tabler/icons-react'; import { EnumSelect } from '@/components/common/EnumSelect'; import dayjs from 'dayjs'; import { useParams } from '@tanstack/react-router'; import { useGetBackOfficeCandidate } from '@/hooks/backoffice/useGetBackOfficeCandidate'; import { useUpdateBackOfficeCandidate } from '@/hooks/backoffice/useUpdateBackOfficeCandidate'; import { useGetBackOfficeCandidateResult } from '@/hooks/backoffice/useGetBackOfficeCandidateResult'; import { EducationVerificationCard } from '@/components/backoffice/EducationVerificationCard'; import { LicenseVerificationCard } from '@/components/backoffice/LicenseVerificationCard'; import { LanguageVerificationCard } from '@/components/backoffice/LanguageVerificationCard'; import { ExperienceVerificationCard } from '@/components/backoffice/ExperienceVerificationCard'; import type { DB } from '@heygermany/sdk'; import { NurseRecognitionGermanyValues, NurseRecognitionHomeCountryValues, RecognitionLikelihoodValues, } from '@heygermany/sdk'; import { CandidateResult } from '@/components/jobs/CandidateResult'; import { QualificationAssessment } from '@/components/backoffice/QualificationAssessment'; import { BooleanSelectComponent } from '@/components/backoffice/DocumentFieldFactory'; import { useGetCandidateResults } from '@/hooks/useGetCandidateResult'; import { ApplicantStatusSelect } from '@/components/backoffice/ApplicantStatusSelect'; import { useGetCountries } from '@/hooks/useGetCountries'; import { LifecycleNotificationsCard } from '@/components/backoffice/LifecycleNotificationsCard'; import { asI18n } from '@pikku/react'; import { useI18n } from '@/context/i18n-provider'; const CandidateResultPreview: React.FunctionComponent<{ candidateId: string }> = ({ candidateId }) => { const { data: candidateResults } = useGetCandidateResults(candidateId) if (!candidateResults) return null return } export default function BackOfficeCandidateDetailPage() { const params = useParams({ strict: false }); const candidateId = params.candidateId as string; const t = useI18n(); const { data: candidate, isLoading, error } = useGetBackOfficeCandidate(candidateId); const { data: candidateResult } = useGetBackOfficeCandidateResult(candidateId); const updateCandidateMutation = useUpdateBackOfficeCandidate(candidateId); const { getCountryNameFromAbbreviation } = useGetCountries(); const [showResultsDrawer, setShowResultsDrawer] = useState(false); const [verbose, setVerbose] = useState(false); const [analysisIssuesDraft, setAnalysisIssuesDraft] = useState(''); const notAvailable = t('common.na'); const yesNo = (value: boolean | null | undefined) => { if (value === true) return t('common.yes'); if (value === false) return t('common.no'); return notAvailable; }; const currentAnalysisIssues = Array.isArray(candidate?.lifecycleNotifications?.analysis?.issues) ? candidate.lifecycleNotifications.analysis.issues.filter((issue: any): issue is string => typeof issue === 'string') : []; const currentAnalysisIssuesDraft = currentAnalysisIssues.join('\n'); useEffect(() => { setAnalysisIssuesDraft(currentAnalysisIssuesDraft); }, [candidateId, currentAnalysisIssuesDraft]); const saveAnalysisIssues = () => { const analysisIssues = analysisIssuesDraft .split('\n') .map((issue: string) => issue.trim()) .filter((issue: string) => issue.length > 0) updateCandidateMutation.mutate({ analysisIssues }) } if (isLoading) { return ( ); } if (error || !candidate) { return ( {t('backoffice.candidate.error.notfound')} ); } return ( <> {asI18n(candidate.name)} { updateCandidateMutation.mutate({ status: status! }) }} isValid={candidateResult?.isValid ?? false} /> {t('backoffice.candidate.verbose')} setVerbose(event.currentTarget.checked)} /> {candidateResult && ( {candidateResult.isValid ? t('backoffice.candidate.result.valid') : t('backoffice.candidate.result.invalid')} )} setShowResultsDrawer(!showResultsDrawer)} title={t('backoffice.candidate.actions.showresultspanel')} > {/* Qualification Result Summary */} {/* Manual Assessment Section */} {t('backoffice.candidate.manualassessment')} updateCandidateMutation.mutate({ qualificationStatusHomeCountry: qualificationStatusHomeCountry! as DB.NurseRecognitionHomeCountry }) } /> updateCandidateMutation.mutate({ qualificationStatusGermany: qualificationStatusGermany! as DB.NurseRecognitionGermany }) } /> updateCandidateMutation.mutate({ licenseMandatory })} /> updateCandidateMutation.mutate({ durationRequirementsMet })} /> updateCandidateMutation.mutate({ recognitionLikelihood: recognitionLikelihood! as DB.RecognitionLikelihood }) } /> {t('backoffice.candidate.basicinfo')} {t('backoffice.candidate.fields.email')} {candidate.email ? asI18n(candidate.email) : notAvailable} {t('backoffice.candidate.fields.currentresidence')} {asI18n(getCountryNameFromAbbreviation(candidate.currentResidence))} {t('backoffice.candidate.fields.countryofeducation')} {asI18n(getCountryNameFromAbbreviation(candidate.countryEducation))} {t('backoffice.candidate.fields.eupassport')} {yesNo(candidate.euPassport)} {t('backoffice.candidate.fields.dateofbirthage')} {candidate.dateOfBirth ? ( <> {dayjs(candidate.dateOfBirth).format('YYYY-MM-DD')} {` (${dayjs().diff(dayjs(candidate.dateOfBirth), 'year')} ${t('backoffice.candidate.fields.years')})`} ) : notAvailable} {t('backoffice.candidate.fields.livingingermany')} {yesNo(candidate.livingInGermany)} {t('backoffice.candidate.fields.jointalentpool')} {yesNo(candidate.joinTalentPool)} {t('backoffice.candidate.fields.worklocation')} {asI18n(candidate.stateWorkPreference !== null ? candidate.stateWorkPreference.join(', ') : notAvailable)} {t('backoffice.candidate.fields.submittedat')} {candidate.submittedAt ? asI18n(new Date(candidate.submittedAt).toLocaleDateString()) : notAvailable} {/* Education Section */} {t('enums.candidatedocumenttype.education')} {/* License Section */} {t('enums.candidatedocumenttype.license')} {/* Language Section */} {t('enums.candidatedocumenttype.language')} {/* Experience Section */} {t('enums.candidatedocumenttype.work_experience')} {/* Results Drawer */} {showResultsDrawer && } ); }