feat(vessel-registration): add vessel registration page with incident reporting and certificate download functionality

feat(waiver): implement waiver page with application tracking and letter download feature

feat(ui): introduce AdvancedTable component for enhanced table functionality across the application

chore: update package-lock.json to remove unnecessary dependencies
This commit is contained in:
Nati
2026-08-13 09:11:50 +00:00
parent a7e74cb7bd
commit 2af9e60800
67 changed files with 4209 additions and 3446 deletions

View File

@@ -0,0 +1,29 @@
import { IconEdit, IconTrash } from '@tabler/icons-react';
import type { TFunction } from 'i18next';
import type { AdvancedTableAction } from '@ema-platform/ui';
import type { LocationType } from '../../types/location';
export function locationTypeColumnActions(
t: TFunction,
handlers: {
onEdit: (type: LocationType) => void;
onDelete: (type: LocationType) => void;
},
): AdvancedTableAction<LocationType>[] {
return [
{
key: 'edit',
label: t('location.edit'),
color: 'blue',
icon: <IconEdit size={14} />,
onClick: handlers.onEdit,
},
{
key: 'delete',
label: t('location.delete'),
color: 'red',
icon: <IconTrash size={14} />,
onClick: handlers.onDelete,
},
];
}

View File

@@ -0,0 +1,35 @@
import { Badge } from '@mantine/core';
import type { TFunction } from 'i18next';
import type { AdvancedTableColumn } from '@ema-platform/ui';
import type { LocationType } from '../../types/location';
export function locationTypeColumns(
t: TFunction,
locale: 'en' | 'am',
): AdvancedTableColumn<LocationType>[] {
return [
{
key: 'level',
header: t('location.level'),
render: (type) => (
<Badge size="sm" variant="light" color="gray">
{type.level}
</Badge>
),
},
{
key: 'code',
header: t('location.code'),
render: (type) => (
<Badge size="sm" variant="light" color="blue">
{type.code}
</Badge>
),
},
{
key: 'name',
header: t('location.name'),
render: (type) => type.names[locale],
},
];
}

View File

@@ -6,23 +6,20 @@ import {
Group,
Stack,
NumberInput,
Table,
ActionIcon,
Badge,
Text,
Tooltip,
Divider,
} from '@mantine/core';
import { useForm } from '@mantine/form';
import { IconEdit, IconTrash, IconPlus } from '@tabler/icons-react';
import { IconPlus } from '@tabler/icons-react';
import { useTranslation } from 'react-i18next';
import {
useGetLocationTypesQuery,
useCreateLocationTypeMutation,
useUpdateLocationTypeMutation,
useDeleteLocationTypeMutation,
} from '../api/location-api';
import { notify } from '@ema-platform/ui';
} from '../../api/location-api';
import { AdvancedTable, notify } from '@ema-platform/ui';
import { locationTypeColumns } from './columns';
import { locationTypeColumnActions } from './actions';
interface LocationTypeFormValues {
code: string;
@@ -34,7 +31,7 @@ interface LocationTypeFormValues {
export function LocationTypeModal({ opened, onClose }: { opened: boolean; onClose: () => void }) {
const { t, i18n } = useTranslation();
const locale = i18n.language as 'en' | 'am';
const { data: locationTypes, isLoading } = useGetLocationTypesQuery();
const { data: locationTypes, isLoading, refetch } = useGetLocationTypesQuery();
const [createType] = useCreateLocationTypeMutation();
const [updateType] = useUpdateLocationTypeMutation();
const [deleteType] = useDeleteLocationTypeMutation();
@@ -171,61 +168,18 @@ export function LocationTypeModal({ opened, onClose }: { opened: boolean; onClos
<Divider mb="md" />
{isLoading && <Text c="dimmed">Loading...</Text>}
{!isLoading && sortedTypes.length === 0 && (
<Text c="dimmed" ta="center" py="xl">
{t('location.noTypes')}
</Text>
)}
{sortedTypes.length > 0 && (
<Table striped highlightOnHover>
<Table.Thead>
<Table.Tr>
<Table.Th>{t('location.level')}</Table.Th>
<Table.Th>{t('location.code')}</Table.Th>
<Table.Th>{t('location.name')}</Table.Th>
<Table.Th />
</Table.Tr>
</Table.Thead>
<Table.Tbody>
{sortedTypes.map((type) => (
<Table.Tr key={type.id}>
<Table.Td>
<Badge size="sm" variant="light" color="gray">
{type.level}
</Badge>
</Table.Td>
<Table.Td>
<Badge size="sm" variant="light" color="blue">
{type.code}
</Badge>
</Table.Td>
<Table.Td>{type.names[locale]}</Table.Td>
<Table.Td>
<Group gap="xs">
<ActionIcon
variant="subtle"
color="blue"
size="sm"
onClick={() => handleEdit(type)}
>
<IconEdit size={14} />
</ActionIcon>
<ActionIcon
variant="subtle"
color="red"
size="sm"
onClick={() => handleDelete(type.id)}
>
<IconTrash size={14} />
</ActionIcon>
</Group>
</Table.Td>
</Table.Tr>
))}
</Table.Tbody>
</Table>
)}
<AdvancedTable
columns={locationTypeColumns(t, locale)}
data={sortedTypes}
rowKey={(type) => type.id}
actions={locationTypeColumnActions(t, {
onEdit: handleEdit,
onDelete: (type) => handleDelete(type.id),
})}
loading={isLoading}
onRefresh={refetch}
emptyTitle={t('location.noTypes')}
/>
</Modal>
);
}