From 8eb4c3821695264c0088647067c3dbb25407333e Mon Sep 17 00:00:00 2001 From: Nati Date: Thu, 20 Aug 2026 08:39:17 +0000 Subject: [PATCH] feat: Refactor seafarer document application flow - Remove SeamanBookApplicationPage from router and redirect to Seaman Book page. - Add new API endpoints for managing seafarer documents, including listing, reviewing, and issuing documents. - Introduce new SeafarerDocumentQueuePage and SeafarerDocumentReviewPage components for document management. - Update licensing types to accommodate optional applicationId and documentId in ApplicationPayment. - Remove unused claimSeafarerRegistration mutation and related constants. - Update seafarer registration status labels and types to remove 'UNDER_REVIEW'. - Create new constants and types for seafarer documents, including status labels and colors. - Implement document payment initiation and confirmation functionalities. - Enhance UI components for better user experience in document management. --- .../pages/SeafarerDocumentQueuePage.tsx | 161 ++++ .../pages/SeafarerDocumentReviewPage.tsx | 276 +++++++ .../pages/SeafarerRegistrationReviewPage.tsx | 22 +- .../pages/SeamanBookQueuePage.tsx | 21 - apps/backoffice/src/app/layouts/nav-config.ts | 4 +- apps/backoffice/src/app/router/index.tsx | 8 +- apps/e2e/src/seafarer-registration.spec.ts | 204 ++++-- apps/e2e/src/support/applicant.ts | 30 +- apps/e2e/src/support/db.ts | 7 +- apps/e2e/src/support/workflow.ts | 44 +- .../payments/hooks/useApplicationPayment.ts | 38 +- .../payments/pages/PaymentCheckPage.tsx | 32 +- .../payments/pages/PaymentFailurePage.tsx | 11 +- .../payments/pages/PaymentSuccessPage.tsx | 11 +- .../pages/SeafarerRegistrationPage.tsx | 11 +- .../pages/SeamanBookApplicationPage.tsx | 595 --------------- .../seaman-book/pages/SeamanBookPage.tsx | 687 ++++-------------- apps/portal/src/app/router.tsx | 13 +- libs/api/src/index.ts | 1 + .../lib/features/licensing/licensing.types.ts | 3 +- .../lib/features/seafarer-document/index.ts | 3 + .../seafarer-document-api.ts | 131 ++++ .../seafarer-document.constants.ts | 28 + .../seafarer-document.types.ts | 54 ++ .../seafarer-registration-api.ts | 6 - .../seafarer-registration.constants.ts | 2 - .../seafarer-registration.types.ts | 3 - 27 files changed, 1081 insertions(+), 1325 deletions(-) create mode 100644 apps/backoffice/src/app/features/seafarer-document-review/pages/SeafarerDocumentQueuePage.tsx create mode 100644 apps/backoffice/src/app/features/seafarer-document-review/pages/SeafarerDocumentReviewPage.tsx delete mode 100644 apps/backoffice/src/app/features/seaman-book-queue/pages/SeamanBookQueuePage.tsx delete mode 100644 apps/portal/src/app/features/seaman-book/pages/SeamanBookApplicationPage.tsx create mode 100644 libs/api/src/lib/features/seafarer-document/index.ts create mode 100644 libs/api/src/lib/features/seafarer-document/seafarer-document-api.ts create mode 100644 libs/api/src/lib/features/seafarer-document/seafarer-document.constants.ts create mode 100644 libs/api/src/lib/features/seafarer-document/seafarer-document.types.ts diff --git a/apps/backoffice/src/app/features/seafarer-document-review/pages/SeafarerDocumentQueuePage.tsx b/apps/backoffice/src/app/features/seafarer-document-review/pages/SeafarerDocumentQueuePage.tsx new file mode 100644 index 000000000..961545a97 --- /dev/null +++ b/apps/backoffice/src/app/features/seafarer-document-review/pages/SeafarerDocumentQueuePage.tsx @@ -0,0 +1,161 @@ +import { useMemo, useState } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { Badge, Container, Group, Select, Text, TextInput, Title } from '@mantine/core'; +import { IconSearch } from '@tabler/icons-react'; +import { useDebouncedValue } from '@mantine/hooks'; +import { + SEAFARER_DOCUMENT_KIND_LABELS, + SEAFARER_DOCUMENT_STATUS_COLORS, + SEAFARER_DOCUMENT_STATUS_LABELS, + useListSeafarerDocumentsQuery, + type SeafarerDocumentKind, + type SeafarerDocumentRow, + type SeafarerDocumentStatus, +} from '@ema-platform/api'; +import { AdvancedTable, type AdvancedColumn } from '@ema-platform/ui'; +import { useDateDisplayer } from '@ema-platform/shared'; + +const PAGE_SIZE = 10; + +/** Statuses an officer filters by — held and withdrawn requests are not work. */ +const STATUS_FILTERS = ( + ['PAYMENT_PENDING', 'PAID', 'PAYMENT_CONFIRMED', 'SCHEDULED', 'ISSUED', 'REJECTED'] as SeafarerDocumentStatus[] +).map((value) => ({ value, label: SEAFARER_DOCUMENT_STATUS_LABELS[value] })); + +/** + * The Seaman Book queue and the BTC queue — one page, keyed by kind. Requests + * appear here once the seafarer registration that opened them is approved. + */ +export function SeafarerDocumentQueuePage({ kind }: { kind: SeafarerDocumentKind }) { + const navigate = useNavigate(); + const showDate = useDateDisplayer(); + const [status, setStatus] = useState(null); + const [search, setSearch] = useState(''); + const [debouncedSearch] = useDebouncedValue(search, 300); + const [page, setPage] = useState(0); + const [pageSize, setPageSize] = useState(PAGE_SIZE); + + const { data, isLoading, isFetching, refetch } = useListSeafarerDocumentsQuery({ + kind, + status: status ?? undefined, + search: debouncedSearch || undefined, + take: pageSize, + skip: page * pageSize, + }); + + const columns: AdvancedColumn[] = useMemo( + () => [ + { + header: 'Request №', + accessorKey: 'requestNumber', + cell: ({ row }) => ( +
+ + {row.original.requestNumber} + + {row.original.documentNumber && ( + + {row.original.documentNumber} + + )} +
+ ), + }, + { + header: 'Seafarer', + accessorKey: 'applicant.name', + cell: ({ row }) => ( +
+ + {row.original.applicant?.name ?? '—'} + + + {row.original.applicant?.seafarerNumber ?? '—'} + +
+ ), + }, + { + header: 'Fee', + accessorKey: 'feeAmount', + cell: ({ row }) => ( + + {row.original.feeAmount !== null ? `${row.original.feeAmount} ${row.original.feeCurrency}` : '—'} + + ), + }, + { + header: 'Released', + accessorKey: 'submittedAt', + cell: ({ row }) => ( + {row.original.submittedAt ? showDate(row.original.submittedAt) : '—'} + ), + }, + { + header: 'Status', + accessorKey: 'status', + cell: ({ row }) => ( + + {SEAFARER_DOCUMENT_STATUS_LABELS[row.original.status]} + + ), + }, + ], + [showDate], + ); + + return ( + + + {SEAFARER_DOCUMENT_KIND_LABELS[kind]} Queue + + + Requests released by an approved seafarer registration: confirm payment, schedule the + collection date, then issue. + + + } + value={search} + onChange={(e) => { + setSearch(e.currentTarget.value); + setPage(0); + }} + w={280} + /> +