mirror of
https://github.com/Tria-plc/emaui.git
synced 2026-08-26 19:12:50 +00:00
- Implemented ExamStageActions component to manage actions related to exam booking and payment based on application status. - Added mock-base-query for development, providing a partial mock backend for various API endpoints. - Introduced mock-data for simulating responses in the mock-base-query, covering profiles, vessels, applications, licenses, exams, and notifications.
160 lines
5.4 KiB
TypeScript
160 lines
5.4 KiB
TypeScript
import { Badge, Group, Paper, Stack, Table, Text } from '@mantine/core';
|
|
import { useTranslation } from 'react-i18next';
|
|
import { useLocalized, type LicenseType } from '@ema-platform/api';
|
|
|
|
interface Props {
|
|
licenseType: LicenseType;
|
|
}
|
|
|
|
/**
|
|
* The STCW identity of a certificate type — regulation, level, and the
|
|
* function and capacity rows a Certificate of Competency prints.
|
|
*
|
|
* Read-only for now: these are seeded configuration, and editing them safely
|
|
* needs the approval workflow the designer guide describes. Showing them
|
|
* matters regardless — an officer configuring fees or documents has no other
|
|
* way to see what the certificate will actually claim.
|
|
*/
|
|
export function StcwMappingPanel({ licenseType }: Props) {
|
|
const { t } = useTranslation();
|
|
const localized = useLocalized();
|
|
|
|
if (!licenseType.stcwControlled && !licenseType.certificateCategory) {
|
|
return null;
|
|
}
|
|
|
|
const functions = licenseType.stcwFunctions ?? [];
|
|
const capacities = licenseType.stcwCapacities ?? [];
|
|
|
|
return (
|
|
<Paper withBorder p="md" radius="md">
|
|
<Stack gap="sm">
|
|
<Group gap="xs">
|
|
<Text fw={600} size="sm">
|
|
{t('configuration.stcw.title', 'STCW mapping')}
|
|
</Text>
|
|
{licenseType.certificateCategory && (
|
|
<Badge size="sm" variant="light">
|
|
{licenseType.certificateCategory}
|
|
</Badge>
|
|
)}
|
|
{licenseType.stcwControlled && (
|
|
<Badge size="sm" variant="light" color="teal">
|
|
{t('configuration.stcw.controlled', 'STCW controlled')}
|
|
</Badge>
|
|
)}
|
|
</Group>
|
|
|
|
<Group gap="xl">
|
|
<Field
|
|
label={t('configuration.stcw.regulation', 'Regulation')}
|
|
value={licenseType.stcwRegulation}
|
|
/>
|
|
<Field
|
|
label={t('configuration.stcw.codeSection', 'Code section')}
|
|
value={licenseType.stcwCodeSection}
|
|
/>
|
|
<Field
|
|
label={t('configuration.stcw.department', 'Department')}
|
|
value={licenseType.stcwDepartment}
|
|
/>
|
|
<Field
|
|
label={t('configuration.stcw.level', 'Level')}
|
|
value={licenseType.competencyLevel}
|
|
/>
|
|
</Group>
|
|
|
|
{functions.length > 0 && (
|
|
<Stack gap={4}>
|
|
<Text size="xs" c="dimmed" tt="uppercase" fw={700}>
|
|
{t('configuration.stcw.functions', 'Functions')}
|
|
</Text>
|
|
<Table withTableBorder withColumnBorders fz="xs">
|
|
<Table.Thead>
|
|
<Table.Tr>
|
|
<Table.Th>{t('configuration.stcw.function', 'Function')}</Table.Th>
|
|
<Table.Th>{t('configuration.stcw.level', 'Level')}</Table.Th>
|
|
<Table.Th>
|
|
{t('configuration.stcw.limitation', 'Limitation')}
|
|
</Table.Th>
|
|
</Table.Tr>
|
|
</Table.Thead>
|
|
<Table.Tbody>
|
|
{functions.map((row, i) => (
|
|
<Table.Tr key={`${localized(row.function)}-${i}`}>
|
|
<Table.Td>{localized(row.function)}</Table.Td>
|
|
<Table.Td>{row.level}</Table.Td>
|
|
<Table.Td>
|
|
{row.limitation
|
|
? localized(row.limitation)
|
|
: t('configuration.stcw.none', 'None')}
|
|
</Table.Td>
|
|
</Table.Tr>
|
|
))}
|
|
</Table.Tbody>
|
|
</Table>
|
|
</Stack>
|
|
)}
|
|
|
|
{capacities.length > 0 && (
|
|
<Stack gap={4}>
|
|
<Text size="xs" c="dimmed" tt="uppercase" fw={700}>
|
|
{t('configuration.stcw.capacities', 'Capacities')}
|
|
</Text>
|
|
<Table withTableBorder withColumnBorders fz="xs">
|
|
<Table.Thead>
|
|
<Table.Tr>
|
|
<Table.Th>{t('configuration.stcw.capacity', 'Capacity')}</Table.Th>
|
|
<Table.Th>
|
|
{t('configuration.stcw.limitation', 'Limitation')}
|
|
</Table.Th>
|
|
</Table.Tr>
|
|
</Table.Thead>
|
|
<Table.Tbody>
|
|
{capacities.map((row, i) => (
|
|
<Table.Tr key={`${localized(row.capacity)}-${i}`}>
|
|
<Table.Td>{localized(row.capacity)}</Table.Td>
|
|
<Table.Td>
|
|
{row.limitation
|
|
? localized(row.limitation)
|
|
: t('configuration.stcw.none', 'None')}
|
|
</Table.Td>
|
|
</Table.Tr>
|
|
))}
|
|
</Table.Tbody>
|
|
</Table>
|
|
</Stack>
|
|
)}
|
|
|
|
{licenseType.prerequisiteLicenseKeys?.length ? (
|
|
<Stack gap={4}>
|
|
<Text size="xs" c="dimmed" tt="uppercase" fw={700}>
|
|
{t('configuration.stcw.prerequisites', 'Must already hold')}
|
|
</Text>
|
|
<Group gap="xs">
|
|
{licenseType.prerequisiteLicenseKeys.map((key) => (
|
|
<Badge key={key} size="sm" variant="outline">
|
|
{key}
|
|
</Badge>
|
|
))}
|
|
</Group>
|
|
</Stack>
|
|
) : null}
|
|
</Stack>
|
|
</Paper>
|
|
);
|
|
}
|
|
|
|
function Field({ label, value }: { label: string; value?: string | null }) {
|
|
return (
|
|
<div>
|
|
<Text size="xs" c="dimmed">
|
|
{label}
|
|
</Text>
|
|
<Text size="sm" fw={600}>
|
|
{value || '—'}
|
|
</Text>
|
|
</div>
|
|
);
|
|
}
|