188 lines
5.8 KiB
TypeScript
188 lines
5.8 KiB
TypeScript
import {
|
|
Container,
|
|
Stack,
|
|
Group,
|
|
Paper,
|
|
ThemeIcon,
|
|
Box,
|
|
Grid,
|
|
Flex,
|
|
Text,
|
|
rem,
|
|
useMantineTheme,
|
|
} from '@pikku/mantine/core'
|
|
import {
|
|
IconIdBadge2,
|
|
IconWorld,
|
|
IconBriefcase,
|
|
IconSchool,
|
|
} from '@tabler/icons-react'
|
|
import { Qualification } from './Qualification'
|
|
import { QualificationSectionStatusCard } from './QualificationSectionStatusCard'
|
|
import { CandidateResults } from '@heygermany/sdk'
|
|
import { useI18n } from '@/context/i18n-provider'
|
|
import { asI18n } from '@pikku/react'
|
|
|
|
interface QualificationData {
|
|
title: string
|
|
description: string
|
|
status: string
|
|
requirements: string[]
|
|
steps?: string[]
|
|
progress?: number
|
|
}
|
|
|
|
type SectionOut = {
|
|
key: "education" | "license" | "language" | "additional"
|
|
title: string
|
|
color: "education" | "license" | "language" | "additional"
|
|
icon: string
|
|
qualifications: QualificationData[]
|
|
}
|
|
|
|
const ICONS: Record<string, React.ReactElement> = {
|
|
school: <IconSchool size={38} />,
|
|
"id-badge": <IconIdBadge2 size={38} />,
|
|
world: <IconWorld size={38} />,
|
|
briefcase: <IconBriefcase size={38} />,
|
|
};
|
|
|
|
const getQualificationSectionStatus = (
|
|
title: string,
|
|
qualifications: QualificationData[]
|
|
) => {
|
|
const statuses = qualifications.map((q) => q.status)
|
|
|
|
if (statuses.includes('in-progress')) return 'in-progress'
|
|
if (statuses.every((s) => s === 'completed')) return 'completed'
|
|
if (statuses.every((s) => s === 'required')) return 'required'
|
|
if (statuses.includes('optional')) return 'optional'
|
|
|
|
return 'required'
|
|
}
|
|
|
|
function buildSections(candidateResults: CandidateResults, t: any): SectionOut[] {
|
|
return [
|
|
{
|
|
key: "education",
|
|
title: t('enums.qualificationsections.education'),
|
|
color: "education",
|
|
icon: "school",
|
|
qualifications: [candidateResults.education],
|
|
},
|
|
{
|
|
key: "license",
|
|
title: t('enums.qualificationsections.license'),
|
|
color: "license",
|
|
icon: "id-badge",
|
|
qualifications: [candidateResults.license],
|
|
},
|
|
{
|
|
key: "language",
|
|
title: t('enums.qualificationsections.language'),
|
|
color: "language",
|
|
icon: "world",
|
|
qualifications: [candidateResults.language],
|
|
},
|
|
{
|
|
key: "additional",
|
|
title: t('enums.qualificationsections.additional'),
|
|
color: "additional",
|
|
icon: "briefcase",
|
|
qualifications: [candidateResults.experience, candidateResults.copies, candidateResults.originals],
|
|
},
|
|
]
|
|
}
|
|
|
|
export const QualificationsSection: React.FunctionComponent<{ candidateResults: CandidateResults }> = ({ candidateResults }) => {
|
|
const t = useI18n()
|
|
const sections = buildSections(candidateResults, t)
|
|
const theme = useMantineTheme()
|
|
const mainSections = sections.slice(0, 3) // Education, License, Language
|
|
const additionalSection = sections[3] // Additional Requirements
|
|
|
|
return (
|
|
<>
|
|
<Container size="xl" py="xl" maw="full">
|
|
<Stack gap="xl">
|
|
<Flex wrap="wrap" gap="md" justify="center">
|
|
{sections.map((section, i) => (
|
|
<QualificationSectionStatusCard
|
|
key={i}
|
|
label={section.title}
|
|
status={section.color === 'additional' ? 'required' : getQualificationSectionStatus(section.title, section.qualifications)}
|
|
color={`var(--mantine-color-${section.color}-6)`}
|
|
icon={ICONS[section.icon]}
|
|
/>
|
|
))}
|
|
</Flex>
|
|
</Stack>
|
|
</Container>
|
|
|
|
<Box bg={theme.colors.gray[0]}>
|
|
<Container bg={theme.colors.gray[0]} size="xl" py="xl" maw="full">
|
|
<Grid mt="xl" grow>
|
|
{mainSections.map((section, sectionIndex) => (
|
|
<Grid.Col key={sectionIndex} span={{ base: 12, md: 4 }} mt="xl">
|
|
<Group align="center" mb="lg">
|
|
<ThemeIcon variant="transparent" color={section.color} size="xl" radius="md">{ICONS[section.icon]}</ThemeIcon>
|
|
<Text c={`${theme.colors.gray[7]}`} size="xl" fw={700}>
|
|
{asI18n(section.title)}
|
|
</Text>
|
|
</Group>
|
|
|
|
<Flex
|
|
gap="md"
|
|
flex={1}
|
|
align="stretch"
|
|
h='full'
|
|
>
|
|
{section.qualifications.map((qualification, qualIndex) => (
|
|
<Qualification
|
|
key={qualIndex}
|
|
title={qualification.title}
|
|
description={qualification.description}
|
|
status={qualification.status}
|
|
requirements={qualification.requirements}
|
|
steps={qualification.steps}
|
|
progress={qualification.progress}
|
|
/>
|
|
))}
|
|
</Flex>
|
|
</Grid.Col>
|
|
))}
|
|
</Grid>
|
|
|
|
<Box mb="md" mt={rem(80)}>
|
|
<Group align="center" mb="lg" gap="sm">
|
|
{ICONS[additionalSection.icon]}
|
|
<Text fw={700} size="xl">
|
|
{asI18n(additionalSection.title)}
|
|
</Text>
|
|
</Group>
|
|
|
|
<Grid>
|
|
{additionalSection.qualifications.map(
|
|
(qualification, qualIndex) => (
|
|
<Grid.Col key={qualIndex} span={{ base: 12, md: 4 }}>
|
|
<Paper shadow="xs" radius="lg" h="100%">
|
|
<Qualification
|
|
title={qualification.title}
|
|
description={qualification.description}
|
|
status={qualification.status}
|
|
requirements={qualification.requirements}
|
|
steps={qualification.steps}
|
|
progress={qualification.progress}
|
|
/>
|
|
</Paper>
|
|
</Grid.Col>
|
|
)
|
|
)}
|
|
</Grid>
|
|
</Box>
|
|
</Container>
|
|
</Box>
|
|
</>
|
|
)
|
|
}
|