153 lines
3.9 KiB
TypeScript
153 lines
3.9 KiB
TypeScript
'use client'
|
|
|
|
import { useI18n } from '@/context/i18n-provider'
|
|
import { asI18n } from '@pikku/react'
|
|
import { LanguageLevels } from '@heygermany/sdk'
|
|
import {
|
|
Stack,
|
|
Title,
|
|
Text,
|
|
Box,
|
|
Paper,
|
|
Progress,
|
|
List,
|
|
ThemeIcon,
|
|
Flex,
|
|
rem,
|
|
useMantineTheme,
|
|
} from '@pikku/mantine/core'
|
|
import {
|
|
IconCircleCheck,
|
|
IconExclamationCircle,
|
|
IconClock,
|
|
IconInfoCircle,
|
|
IconCircle,
|
|
} from '@tabler/icons-react'
|
|
|
|
interface QualificationProps {
|
|
title: string
|
|
description: string
|
|
status: string
|
|
requirements: string[]
|
|
steps?: string[]
|
|
progress?: number
|
|
fillHeight?: boolean
|
|
}
|
|
|
|
const getStatusColor = (status: string) => {
|
|
switch (status) {
|
|
case 'completed':
|
|
return 'green'
|
|
case 'required':
|
|
return 'red'
|
|
case 'in-progress':
|
|
return 'orange'
|
|
case 'optional':
|
|
return 'blue'
|
|
default:
|
|
return 'gray'
|
|
}
|
|
}
|
|
|
|
const getStatusIcon = (status: string) => {
|
|
const iconProps = { size: 28, color: getStatusColor(status) }
|
|
switch (status) {
|
|
case 'completed':
|
|
return <IconCircleCheck {...iconProps} />
|
|
case 'required':
|
|
return <IconExclamationCircle {...iconProps} />
|
|
case 'in-progress':
|
|
return <IconClock {...iconProps} />
|
|
case 'optional':
|
|
return <IconInfoCircle {...iconProps} />
|
|
default:
|
|
return <IconCircle {...iconProps} />
|
|
}
|
|
}
|
|
|
|
export const Qualification: React.FunctionComponent<QualificationProps> = ({
|
|
title,
|
|
description,
|
|
status,
|
|
requirements,
|
|
steps,
|
|
progress,
|
|
fillHeight = true,
|
|
}) => {
|
|
const t = useI18n()
|
|
const theme = useMantineTheme()
|
|
|
|
function translateLevels(req: string): string {
|
|
for (const key of Object.keys(LanguageLevels)) {
|
|
req = req.replace(key, t(`enums.languagelevel.${key}`.toLowerCase() as any))
|
|
}
|
|
return req
|
|
}
|
|
|
|
return (
|
|
<Paper flex={1} withBorder p="lg" radius="lg" h={fillHeight ? '100%' : undefined}>
|
|
<Stack flex={1} gap={0}>
|
|
<Flex align="center" gap="xs" mb={5}>
|
|
<ThemeIcon variant="transparent" color={getStatusColor(status)}>
|
|
{getStatusIcon(status)}
|
|
</ThemeIcon>
|
|
<Text size="xl">{asI18n(title)}</Text>
|
|
</Flex>
|
|
|
|
<Flex mb="md" gap="sm" align="center">
|
|
<Text component="span" fw="600" c={getStatusColor(status)}>
|
|
{t(`enums.documentstatus.${status}` as any)}
|
|
</Text>
|
|
{!isNaN(progress!) && (
|
|
<Progress.Root flex={1} h="md" radius="xl">
|
|
<Progress.Section value={progress!}>
|
|
<Progress.Label c="dimmed" fz="sm" fw={700}>
|
|
{progress}%
|
|
</Progress.Label>
|
|
</Progress.Section>
|
|
</Progress.Root>
|
|
)}
|
|
</Flex>
|
|
|
|
<Text size="lg" c="dimmed" mb="md">
|
|
{asI18n(description)}
|
|
</Text>
|
|
|
|
{requirements && (
|
|
<Box mb="md">
|
|
<Text size="lg" fw={500} mb="xs">
|
|
{asI18n(`${t('jobs.qualification.requirements')}:`)}
|
|
</Text>
|
|
<List pl="md" size="md">
|
|
{requirements.map((req, reqIndex) => (
|
|
<List.Item key={reqIndex}>
|
|
<Text c={`${theme.colors.gray[7]}`} fz="md" fw={300}>
|
|
{asI18n(translateLevels(req))}
|
|
</Text>
|
|
</List.Item>
|
|
))}
|
|
</List>
|
|
</Box>
|
|
)}
|
|
|
|
{(steps?.length && steps.length > 0) ? (
|
|
<Box mb="md">
|
|
<Text component='h4' size="lg" fw={500} mb="xs">
|
|
{asI18n(`${t('jobs.qualification.nextsteps')}:`)}
|
|
</Text>
|
|
<List pl="md" type="ordered" size="md">
|
|
{steps.map((step, stepIndex) => (
|
|
<List.Item key={stepIndex}>
|
|
<Text c={`${theme.colors.gray[7]}`} fz="md" fw={300}>
|
|
{asI18n(translateLevels(step))}
|
|
</Text>
|
|
</List.Item>
|
|
))}
|
|
</List>
|
|
</Box>
|
|
) : null}
|
|
</Stack>
|
|
</Paper>
|
|
)
|
|
}
|