Files
emaui/apps/portal/src/app/features/payments/pages/PaymentSuccessPage.tsx
Nati 8eb4c38216 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.
2026-08-20 08:39:17 +00:00

86 lines
3.1 KiB
TypeScript

import { useNavigate, useSearchParams } from 'react-router-dom';
import {
Button,
Card,
Container,
Divider,
Group,
Stack,
Text,
ThemeIcon,
Title,
} from '@mantine/core';
import { IconCircleCheck } from '@tabler/icons-react';
import { useTranslation } from 'react-i18next';
import { useGetApplicationPaymentQuery, useGetDocumentPaymentQuery } from '@ema-platform/api';
import { useDateDisplayer } from '@ema-platform/shared';
/** Confirmation that the licence fee has been received. */
export function PaymentSuccessPage() {
const { t } = useTranslation();
const [params] = useSearchParams();
const navigate = useNavigate();
const showDate = useDateDisplayer();
const applicationId = params.get('applicationId') ?? '';
// Seaman Book / BTC fees come back with `documentId` instead.
const documentId = params.get('documentId') ?? '';
const applicationPayment = useGetApplicationPaymentQuery(applicationId, {
skip: !applicationId,
});
const documentPayment = useGetDocumentPaymentQuery(documentId, { skip: !documentId });
const { data } = documentId ? documentPayment : applicationPayment;
const backTo = documentId ? '/seaman-book' : '/licensing/applications';
return (
<Container size="sm" py="xl">
<Card withBorder padding="xl" radius="md">
<Stack align="center" gap="sm">
<ThemeIcon size={56} radius="xl" color="teal" variant="light">
<IconCircleCheck size={30} />
</ThemeIcon>
<Title order={3}>{t('payments.success.title')}</Title>
<Text size="sm" c="dimmed" ta="center">
{t('payments.success.body')}
</Text>
{data && (
<>
<Divider my="xs" w="100%" />
<Stack gap={4} w="100%">
<Group justify="space-between">
<Text size="sm" c="dimmed">{t('payments.fields.amount')}</Text>
<Text size="sm" fw={600}>
{Number(data.amount).toLocaleString()} {data.currency}
</Text>
</Group>
<Group justify="space-between">
<Text size="sm" c="dimmed">{t('payments.fields.method')}</Text>
<Text size="sm">{data.provider}</Text>
</Group>
{data.providerRef && (
<Group justify="space-between">
<Text size="sm" c="dimmed">{t('payments.fields.reference')}</Text>
<Text size="sm" ff="monospace">{data.providerRef}</Text>
</Group>
)}
{data.paidAt && (
<Group justify="space-between">
<Text size="sm" c="dimmed">{t('payments.fields.paid')}</Text>
<Text size="sm">{showDate(data.paidAt)}</Text>
</Group>
)}
</Stack>
</>
)}
<Button mt="md" onClick={() => navigate(backTo)}>
{t('payments.success.backToApplications')}
</Button>
</Stack>
</Card>
</Container>
);
}
export default PaymentSuccessPage;