This commit is contained in:
estifanos
2026-08-08 06:36:48 +00:00
parent 70b6562045
commit 44786a2f6f

View File

@@ -24,7 +24,7 @@ import {
IconShieldCog,
IconStethoscope,
} from '@tabler/icons-react';
import { notify } from '@ema-platform/ui';
import { AdvancedTable, notify, useServerTable, type AdvancedColumn } from '@ema-platform/ui';
import {
extractErrorMessage,
useApiQuery,
@@ -355,14 +355,29 @@ export function SeafarerRegistryPage() {
{
header: 'Name',
cell: ({ row }) => (
<Text size="sm" fw={500}>
<Text
size="sm"
fw={500}
style={{ cursor: 'pointer' }}
onClick={() => setDetail(row.original)}
>
{[row.original.firstName, row.original.middleName, row.original.lastName].filter(Boolean).join(' ')}
</Text>
),
},
{
header: 'Profession',
cell: ({ row }) => <Text size="sm">{row.original.profession?.name?.en ?? '—'}</Text>,
header: 'Seafarer №',
cell: ({ row }) => <Text size="sm" ff="monospace">{row.original.seafarerNumber ?? '—'}</Text>,
},
{
header: 'Department',
cell: ({ row }) => (
<Text size="sm">
{row.original.seafarerDepartment
? DEPARTMENT_LABELS[row.original.seafarerDepartment] ?? row.original.seafarerDepartment
: '—'}
</Text>
),
},
{
header: 'ID number',
@@ -374,11 +389,33 @@ export function SeafarerRegistryPage() {
},
{
header: 'Status',
cell: ({ row }) => (
<Badge size="sm" variant="light" color={row.original.isComplete ? 'teal' : 'gray'}>
{row.original.isComplete ? 'Complete' : 'Incomplete'}
</Badge>
),
cell: ({ row }) =>
row.original.seafarerNumber ? (
<Badge size="sm" variant="light" color={SEAFARER_STATUS_COLORS[row.original.seafarerStatus ?? ''] ?? 'gray'}>
{row.original.seafarerStatus}
</Badge>
) : (
<Badge size="sm" variant="light" color={row.original.isComplete ? 'teal' : 'gray'}>
{row.original.isComplete ? 'Not registered' : 'Incomplete'}
</Badge>
),
},
{
header: '',
label: 'Actions',
cell: ({ row }) =>
row.original.seafarerNumber ? (
<Tooltip label="Suspend / reinstate / close">
<Button
size="compact-xs"
variant="subtle"
leftSection={<IconShieldCog size={14} />}
onClick={() => setStatusTarget(row.original)}
>
Status
</Button>
</Tooltip>
) : null,
},
];
@@ -401,97 +438,18 @@ export function SeafarerRegistryPage() {
</Group>
<Card withBorder padding={0}>
{isLoading ? (
<Center h={200}>
<Loader />
</Center>
) : items.length === 0 ? (
<Center h={160}>
<Text size="sm" c="dimmed">
{search ? 'No profiles match that search.' : 'No seafarers registered yet.'}
</Text>
</Center>
) : (
<Table highlightOnHover>
<Table.Thead>
<Table.Tr>
<Table.Th>Name</Table.Th>
<Table.Th>Seafarer </Table.Th>
<Table.Th>Department</Table.Th>
<Table.Th>ID number</Table.Th>
<Table.Th>Phone</Table.Th>
<Table.Th>Status</Table.Th>
<Table.Th />
</Table.Tr>
</Table.Thead>
<Table.Tbody>
{items.map((p) => (
<Table.Tr
key={p.id}
style={{ cursor: 'pointer' }}
onClick={() => setDetail(p)}
>
<Table.Td>
<Text size="sm" fw={500}>
{[p.firstName, p.middleName, p.lastName].filter(Boolean).join(' ')}
</Text>
</Table.Td>
<Table.Td>
<Text size="sm" ff="monospace">
{p.seafarerNumber ?? '—'}
</Text>
</Table.Td>
<Table.Td>
<Text size="sm">
{p.seafarerDepartment
? DEPARTMENT_LABELS[p.seafarerDepartment] ?? p.seafarerDepartment
: '—'}
</Text>
</Table.Td>
<Table.Td>
<Text size="sm" c="dimmed">
{p.address?.idNumber ?? '—'}
</Text>
</Table.Td>
<Table.Td>
<Text size="sm" c="dimmed">
{p.address?.primaryPhoneNumber ?? '—'}
</Text>
</Table.Td>
<Table.Td>
{p.seafarerNumber ? (
<Badge
size="sm"
variant="light"
color={SEAFARER_STATUS_COLORS[p.seafarerStatus ?? ''] ?? 'gray'}
>
{p.seafarerStatus}
</Badge>
) : (
<Badge size="sm" variant="light" color={p.isComplete ? 'teal' : 'gray'}>
{p.isComplete ? 'Not registered' : 'Incomplete'}
</Badge>
)}
</Table.Td>
<Table.Td onClick={(e) => e.stopPropagation()}>
{p.seafarerNumber && (
<Tooltip label="Suspend / reinstate / close">
<Button
size="compact-xs"
variant="subtle"
leftSection={<IconShieldCog size={14} />}
onClick={() => setStatusTarget(p)}
>
Status
</Button>
</Tooltip>
)}
</Table.Td>
</Table.Tr>
))}
</Table.Tbody>
</Table>
)}
<AdvancedTable
columns={columns}
data={page.rows}
tableName="Seafarer registry"
itemCount={page.itemCount}
pageIndex={page.pageIndex}
onPageChange={setPageIndex}
pageSize={pageSize}
refresh={refetch}
isLoading={isLoading}
emptyText={search ? 'No profiles match that search.' : 'No seafarers registered yet.'}
/>
</Card>
<SeafarerDetailDrawer profile={detail} onClose={() => setDetail(null)} />