mirror of
https://github.com/Tria-plc/emaui.git
synced 2026-08-26 19:12:50 +00:00
feat: add status filtering and display to medical and sea service verification queues
This commit is contained in:
@@ -33,24 +33,28 @@ export function medicalActionsColumn(
|
||||
anyOf={[LICENSE_PERMISSIONS.VERIFY_SEAFARER_RECORDS]}
|
||||
hideOnly
|
||||
>
|
||||
<Button
|
||||
size="compact-xs"
|
||||
color="teal"
|
||||
leftSection={<IconCheck size={14} />}
|
||||
loading={handlers.ruling}
|
||||
onClick={() => handlers.onVerify(row.original)}
|
||||
>
|
||||
{t('recordVerification.verify', 'Verify')}
|
||||
</Button>
|
||||
<Button
|
||||
size="compact-xs"
|
||||
color="red"
|
||||
variant="light"
|
||||
leftSection={<IconX size={14} />}
|
||||
onClick={() => handlers.onReject(row.original)}
|
||||
>
|
||||
{t('recordVerification.reject', 'Reject')}
|
||||
</Button>
|
||||
{row.original.status === 'SUBMITTED' && (
|
||||
<>
|
||||
<Button
|
||||
size="compact-xs"
|
||||
color="teal"
|
||||
leftSection={<IconCheck size={14} />}
|
||||
loading={handlers.ruling}
|
||||
onClick={() => handlers.onVerify(row.original)}
|
||||
>
|
||||
{t('recordVerification.verify', 'Verify')}
|
||||
</Button>
|
||||
<Button
|
||||
size="compact-xs"
|
||||
color="red"
|
||||
variant="light"
|
||||
leftSection={<IconX size={14} />}
|
||||
onClick={() => handlers.onReject(row.original)}
|
||||
>
|
||||
{t('recordVerification.reject', 'Reject')}
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
</RequirePermission>
|
||||
</Group>
|
||||
),
|
||||
@@ -85,24 +89,28 @@ export function seaServiceActionsColumn(
|
||||
anyOf={[LICENSE_PERMISSIONS.VERIFY_SEAFARER_RECORDS]}
|
||||
hideOnly
|
||||
>
|
||||
<Button
|
||||
size="compact-xs"
|
||||
color="teal"
|
||||
leftSection={<IconCheck size={14} />}
|
||||
loading={handlers.ruling}
|
||||
onClick={() => handlers.onVerify(row.original)}
|
||||
>
|
||||
{t('recordVerification.verify', 'Verify')}
|
||||
</Button>
|
||||
<Button
|
||||
size="compact-xs"
|
||||
color="red"
|
||||
variant="light"
|
||||
leftSection={<IconX size={14} />}
|
||||
onClick={() => handlers.onReject(row.original)}
|
||||
>
|
||||
{t('recordVerification.reject', 'Reject')}
|
||||
</Button>
|
||||
{row.original.status === 'SUBMITTED' && (
|
||||
<>
|
||||
<Button
|
||||
size="compact-xs"
|
||||
color="teal"
|
||||
leftSection={<IconCheck size={14} />}
|
||||
loading={handlers.ruling}
|
||||
onClick={() => handlers.onVerify(row.original)}
|
||||
>
|
||||
{t('recordVerification.verify', 'Verify')}
|
||||
</Button>
|
||||
<Button
|
||||
size="compact-xs"
|
||||
color="red"
|
||||
variant="light"
|
||||
leftSection={<IconX size={14} />}
|
||||
onClick={() => handlers.onReject(row.original)}
|
||||
>
|
||||
{t('recordVerification.reject', 'Reject')}
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
</RequirePermission>
|
||||
</Group>
|
||||
),
|
||||
|
||||
@@ -5,6 +5,7 @@ import type {
|
||||
MedicalCertificate,
|
||||
SeaServiceRecord,
|
||||
SeafarerProfileSummary,
|
||||
SeafarerRecordStatus,
|
||||
} from '@ema-platform/api';
|
||||
|
||||
export function ownerName(profile?: SeafarerProfileSummary): string {
|
||||
@@ -16,6 +17,28 @@ export function ownerName(profile?: SeafarerProfileSummary): string {
|
||||
);
|
||||
}
|
||||
|
||||
const STATUS_COLOR: Record<SeafarerRecordStatus, string> = {
|
||||
SUBMITTED: 'yellow',
|
||||
VERIFIED: 'teal',
|
||||
REJECTED: 'red',
|
||||
};
|
||||
|
||||
/** Only meaningful now the queue can show ruled records too. */
|
||||
function statusColumn<T extends { status: SeafarerRecordStatus }>(
|
||||
t: TFunction,
|
||||
): AdvancedColumn<T> {
|
||||
return {
|
||||
header: t('recordVerification.columns.status', 'Status'),
|
||||
label: t('recordVerification.columns.status', 'Status'),
|
||||
accessorKey: 'status',
|
||||
cell: ({ row }) => (
|
||||
<Badge size="sm" variant="light" color={STATUS_COLOR[row.original.status]}>
|
||||
{t(`recordVerification.status.${row.original.status}`, row.original.status)}
|
||||
</Badge>
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
export function medicalColumns(
|
||||
t: TFunction,
|
||||
showDate: (date: string) => string,
|
||||
@@ -72,6 +95,7 @@ export function medicalColumns(
|
||||
</Badge>
|
||||
),
|
||||
},
|
||||
statusColumn<MedicalCertificate>(t),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -127,5 +151,6 @@ export function seaServiceColumns(
|
||||
</Text>
|
||||
),
|
||||
},
|
||||
statusColumn<SeaServiceRecord>(t),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
Loader,
|
||||
Modal,
|
||||
Paper,
|
||||
SegmentedControl,
|
||||
Stack,
|
||||
Tabs,
|
||||
Text,
|
||||
@@ -32,7 +33,11 @@ import {
|
||||
useVerifyMedicalCertificateMutation,
|
||||
useVerifySeaServiceRecordMutation,
|
||||
} from '@ema-platform/api';
|
||||
import type { MedicalCertificate, SeaServiceRecord } from '@ema-platform/api';
|
||||
import type {
|
||||
MedicalCertificate,
|
||||
RecordQueueFilter,
|
||||
SeaServiceRecord,
|
||||
} from '@ema-platform/api';
|
||||
import { medicalColumns, seaServiceColumns, ownerName } from './columns';
|
||||
import { medicalActionsColumn, seaServiceActionsColumn } from './actions';
|
||||
|
||||
@@ -180,19 +185,20 @@ function AttachmentsModal({
|
||||
*/
|
||||
export function MedicalVerificationPage() {
|
||||
const { t } = useTranslation();
|
||||
const [filter, setFilter] = useState<RecordQueueFilter>('SUBMITTED');
|
||||
const {
|
||||
data: pendingMedical,
|
||||
isLoading: loadingMedical,
|
||||
isFetching: fetchingMedical,
|
||||
refetch: refetchMedical,
|
||||
} = useGetPendingMedicalQuery();
|
||||
} = useGetPendingMedicalQuery(filter);
|
||||
|
||||
const {
|
||||
data: pendingSeaService,
|
||||
isLoading: loadingSeaService,
|
||||
isFetching: fetchingSeaService,
|
||||
refetch: refetchSeaService,
|
||||
} = useGetPendingSeaServiceQuery();
|
||||
} = useGetPendingSeaServiceQuery(filter);
|
||||
|
||||
const [verifyMedical, { isLoading: rulingMedical }] =
|
||||
useVerifyMedicalCertificateMutation();
|
||||
@@ -251,6 +257,12 @@ export function MedicalVerificationPage() {
|
||||
return pendingSeaServiceList.slice(start, start + seaServicePageSize);
|
||||
}, [pendingSeaServiceList, seaServicePage, seaServicePageSize]);
|
||||
|
||||
const changeFilter = useCallback((value: string) => {
|
||||
setFilter(value as RecordQueueFilter);
|
||||
setMedicalPage(0);
|
||||
setSeaServicePage(0);
|
||||
}, []);
|
||||
|
||||
const handleMedicalPageSizeChange = useCallback((size: number) => {
|
||||
setMedicalPageSize(size);
|
||||
setMedicalPage(0);
|
||||
@@ -261,6 +273,11 @@ export function MedicalVerificationPage() {
|
||||
setSeaServicePage(0);
|
||||
}, []);
|
||||
|
||||
const emptyText =
|
||||
filter === 'SUBMITTED'
|
||||
? t('recordVerification.emptyText', 'Nothing awaiting verification.')
|
||||
: t('recordVerification.emptyTextFiltered', 'No records match this filter.');
|
||||
|
||||
const medicalTableColumns: AdvancedColumn<MedicalCertificate>[] = useMemo(
|
||||
() => [
|
||||
...medicalColumns(t, showDate),
|
||||
@@ -331,6 +348,27 @@ export function MedicalVerificationPage() {
|
||||
)}
|
||||
</Text>
|
||||
|
||||
<SegmentedControl
|
||||
mb="md"
|
||||
value={filter}
|
||||
onChange={changeFilter}
|
||||
data={[
|
||||
{
|
||||
value: 'SUBMITTED',
|
||||
label: t('recordVerification.filter.pending', 'Pending'),
|
||||
},
|
||||
{
|
||||
value: 'VERIFIED',
|
||||
label: t('recordVerification.filter.verified', 'Accepted'),
|
||||
},
|
||||
{
|
||||
value: 'REJECTED',
|
||||
label: t('recordVerification.filter.rejected', 'Rejected'),
|
||||
},
|
||||
{ value: 'ALL', label: t('recordVerification.filter.all', 'All') },
|
||||
]}
|
||||
/>
|
||||
|
||||
<Tabs defaultValue="medical" keepMounted={false}>
|
||||
<Tabs.List>
|
||||
<Tabs.Tab value="medical" leftSection={<IconStethoscope size={16} />}>
|
||||
@@ -362,7 +400,7 @@ export function MedicalVerificationPage() {
|
||||
onPageSizeChange={handleMedicalPageSizeChange}
|
||||
refresh={refetchMedical}
|
||||
isLoading={loadingMedical || fetchingMedical}
|
||||
emptyText={t('recordVerification.emptyText', 'Nothing awaiting verification.')}
|
||||
emptyText={emptyText}
|
||||
/>
|
||||
</Tabs.Panel>
|
||||
|
||||
@@ -381,7 +419,7 @@ export function MedicalVerificationPage() {
|
||||
onPageSizeChange={handleSeaServicePageSizeChange}
|
||||
refresh={refetchSeaService}
|
||||
isLoading={loadingSeaService || fetchingSeaService}
|
||||
emptyText={t('recordVerification.emptyText', 'Nothing awaiting verification.')}
|
||||
emptyText={emptyText}
|
||||
/>
|
||||
</Tabs.Panel>
|
||||
</Tabs>
|
||||
|
||||
Reference in New Issue
Block a user