chore: heygermany customer project
This commit is contained in:
187
apps/website/components/jobs/results/QualificationsSection.tsx
Normal file
187
apps/website/components/jobs/results/QualificationsSection.tsx
Normal file
@@ -0,0 +1,187 @@
|
||||
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>
|
||||
</>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user