mirror of
https://github.com/Tria-plc/emaui.git
synced 2026-08-29 19:58:13 +00:00
feat: add ExamStageActions component for exam fee handling
- 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.
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user