mirror of
https://github.com/Tria-plc/emaui.git
synced 2026-08-26 19:12:50 +00:00
- Implement DocumentRequirementsTab for managing document upload requirements. - Create FieldEditorDrawer and SectionEditorDrawer for editing fields and sections in the form schema. - Develop FormSchemaTab to handle sections and fields for a license type's form schema. - Introduce CertificateRequirementsPage to serve as the main interface for configuring license type requirements. - Add hooks for requirement actions to streamline mutation handling and notifications. - Implement condition handling for fields and sections to manage visibility based on user input. - Create schema-paths configuration to facilitate condition target collection.
151 lines
10 KiB
TypeScript
151 lines
10 KiB
TypeScript
import type { ReactNode } from 'react';
|
|
import {
|
|
createBrowserRouter,
|
|
RouterProvider,
|
|
Navigate,
|
|
} from 'react-router-dom';
|
|
import {
|
|
LoginPage,
|
|
ForgotPasswordPage,
|
|
SetPasswordPage,
|
|
OTPVerificationPage,
|
|
RequirePermission,
|
|
LICENSE_PERMISSIONS as P,
|
|
} from '@ema-platform/auth';
|
|
import { AuthLayout } from '../layouts/AuthLayout';
|
|
import { BackofficeLayout } from '../layouts/BackofficeLayout';
|
|
import { ProtectedRoute } from './ProtectedRoute';
|
|
import { LandingRoute } from './LandingRoute';
|
|
import { DashboardPage } from '../features/dashboard/pages/DashboardPage';
|
|
import UserManagementPage from '../features/user-management/UserManagementPage';
|
|
import { ProfilePage } from '../features/profile/pages/ProfilePage';
|
|
import { ConfigurationPage } from '../features/configuration/pages/ConfigurationPage';
|
|
import { AnalyticsPage } from '../features/analytics/pages/AnalyticsPage';
|
|
import { ApplicationReviewPage } from '../features/applications/pages/ApplicationReviewPage';
|
|
import {
|
|
MedicalVerificationPage,
|
|
SeaServiceVerificationPage,
|
|
} from '../features/medical-verification/pages/MedicalVerificationPage';
|
|
import { PaymentConfigPage } from '../features/payment-config/pages/PaymentConfigPage';
|
|
import { SeafarerRegistryPage } from '../features/seafarer-registry/pages/SeafarerRegistryPage';
|
|
import { SeafarerRegistrationQueuePage } from '../features/seafarer-registration-review/pages/SeafarerRegistrationQueuePage';
|
|
import { SeafarerRegistrationReviewPage } from '../features/seafarer-registration-review/pages/SeafarerRegistrationReviewPage';
|
|
import { BtcQueuePage, SeamanBookQueuePage } from '../features/seafarer-document-review/pages/SeafarerDocumentQueuePage';
|
|
import { SeafarerDocumentReviewPage } from '../features/seafarer-document-review/pages/SeafarerDocumentReviewPage';
|
|
import { QuestionPage } from '../features/question/pages/QuestionPage';
|
|
import { ExamPage } from '../features/exam/pages/ExamPage';
|
|
import { ExamDetailPage } from '../features/exam/pages/ExamDetailPage';
|
|
import { ResultPage } from '../features/result/pages/ResultPage';
|
|
import { ExamAppealsPage } from '../features/result/pages/ExamAppealsPage';
|
|
import { VesselRegistrationQueuePage } from '../features/vessel-registration/pages/VesselRegistrationQueuePage';
|
|
import { VesselRegistrationReviewPage } from '../features/vessel-registration/pages/VesselRegistrationReviewPage';
|
|
import { VesselRegistrationReportPage } from '../features/vessel-registration/pages/VesselRegistrationReportPage';
|
|
import { VesselRegistrationFormBuilderPage } from '../features/vessel-registration/pages/VesselRegistrationFormBuilderPage';
|
|
import { LicenseQueuePage } from '../features/license-review/pages/LicenseQueuePage';
|
|
import { LicenseRegisterPage } from '../features/license-register/pages/LicenseRegisterPage';
|
|
import { LicenseReviewPage } from '../features/license-review/pages/LicenseReviewPage';
|
|
import { LogisticsHeadDashboardPage } from '../features/logistics-head/pages/LogisticsHeadDashboardPage';
|
|
import { CertificateDesignerPage } from '../features/certificate-designer/pages/CertificateDesignerPage';
|
|
import { CertificateRequirementsPage } from '../features/certificate-requirements/pages/CertificateRequirementsPage';
|
|
|
|
/** Any-of gate shared by every licence-type queue and its review workspace. */
|
|
const APPLICATION_QUEUE = [P.VIEW_APPLICATION_QUEUE, P.VIEW_APPLICATIONS];
|
|
|
|
/** Route gate: same keys as the route's nav item in nav-config.ts. */
|
|
const guard = (anyOf: string[], element: ReactNode) => (
|
|
<RequirePermission anyOf={anyOf}>{element}</RequirePermission>
|
|
);
|
|
|
|
const router = createBrowserRouter([
|
|
{
|
|
element: <AuthLayout />,
|
|
children: [
|
|
{ path: '/login', element: <LoginPage /> },
|
|
{ path: '/forgot-password', element: <ForgotPasswordPage /> },
|
|
{ path: '/set-password', element: <SetPasswordPage /> },
|
|
{ path: '/reset-password', element: <SetPasswordPage /> },
|
|
{ path: '/otp-verify', element: <OTPVerificationPage /> },
|
|
],
|
|
},
|
|
{ path: '/um/*', element: <UserManagementPage /> },
|
|
{ path: '/', element: <LandingRoute /> },
|
|
{ path: '/profile-setup', element: <Navigate to="/dashboard" replace /> },
|
|
{
|
|
element: <ProtectedRoute />,
|
|
children: [
|
|
{
|
|
element: <BackofficeLayout />,
|
|
children: [
|
|
{ path: 'dashboard', element: <DashboardPage /> },
|
|
{ path: 'logistics-head-dashboard', element: guard(APPLICATION_QUEUE, <LogisticsHeadDashboardPage />) },
|
|
{ path: 'profile', element: <ProfilePage /> },
|
|
{ path: 'configuration', element: guard([P.VIEW_LICENSE_TYPES, P.VIEW_TEMPLATES], <ConfigurationPage />) },
|
|
{ path: 'analytics', element: <AnalyticsPage /> },
|
|
{ path: 'applications/:id', element: guard(APPLICATION_QUEUE, <ApplicationReviewPage />) },
|
|
// CoC/CoP review happens in the config-driven licence queue.
|
|
{ path: 'coc-queue', element: <Navigate to="/licence-review/type/CERTIFICATE_OF_COMPETENCY" replace /> },
|
|
{ path: 'coc-queue/:id', element: <Navigate to="/licence-review" replace /> },
|
|
// Endorsement review happens in the config-driven licence queue.
|
|
{ path: 'endorsement-queue', element: <Navigate to="/licence-review/type/ENDORSEMENT_COC" replace /> },
|
|
{ path: 'endorsement-queue/:id', element: <Navigate to="/licence-review" replace /> },
|
|
{ path: 'medical-verification', element: guard([P.VERIFY_SEAFARER_RECORDS], <MedicalVerificationPage />) },
|
|
{ path: 'sea-service-verification', element: guard([P.VERIFY_SEAFARER_RECORDS], <SeaServiceVerificationPage />) },
|
|
{ path: 'payment-config', element: guard([P.VIEW_PAYMENTS], <PaymentConfigPage />) },
|
|
{ path: 'seafarer-registry', element: guard([P.VIEW_SEAFARER_REGISTRY], <SeafarerRegistryPage />) },
|
|
// Seafarer registration is not a licence: own queue, own review.
|
|
{ path: 'seafarer-registrations', element: guard(APPLICATION_QUEUE, <SeafarerRegistrationQueuePage />) },
|
|
{ path: 'seafarer-registrations/:id', element: guard(APPLICATION_QUEUE, <SeafarerRegistrationReviewPage />) },
|
|
{ path: 'licence-review/type/SEAFARER_REGISTRATION', element: <Navigate to="/seafarer-registrations" replace /> },
|
|
// Seaman Book and BTC are not licences: own queues, own review.
|
|
{ path: 'seaman-book-queue', element: guard(APPLICATION_QUEUE, <SeamanBookQueuePage />) },
|
|
{ path: 'btc-queue', element: guard(APPLICATION_QUEUE, <BtcQueuePage />) },
|
|
{ path: 'seafarer-documents/:id', element: guard(APPLICATION_QUEUE, <SeafarerDocumentReviewPage />) },
|
|
{ path: 'licence-review/type/SEAMAN_BOOK', element: <Navigate to="/seaman-book-queue" replace /> },
|
|
{ path: 'licence-review/type/BTC_BASIC_TRAINING', element: <Navigate to="/btc-queue" replace /> },
|
|
{ path: 'questions', element: guard([P.APPROVE_QUESTION, P.AUTHOR_QUESTION], <QuestionPage />) },
|
|
{ path: 'exams', element: guard([P.MANAGE_EXAMS, P.RECORD_EXAM_ATTENDANCE, P.MANAGE_EXAM_INCIDENTS, P.PUBLISH_EXAM_RESULT], <ExamPage />) },
|
|
{ path: 'exams/:id', element: guard([P.MANAGE_EXAMS, P.RECORD_EXAM_ATTENDANCE, P.MANAGE_EXAM_INCIDENTS, P.PUBLISH_EXAM_RESULT], <ExamDetailPage />) },
|
|
{ path: 'exam-results', element: guard([P.RECORD_EXAM_RESULT, P.MODERATE_EXAM_RESULT, P.APPROVE_EXAM_RESULT, P.PUBLISH_EXAM_RESULT], <ResultPage />) },
|
|
{ path: 'exam-appeals', element: guard([P.DECIDE_EXAM_APPEAL], <ExamAppealsPage />) },
|
|
{ path: 'vessel-registration-queue', element: guard([P.VIEW_VESSEL_REGISTRY], <VesselRegistrationQueuePage />) },
|
|
{ path: 'vessel-registration-queue/new', element: guard([P.VIEW_VESSEL_REGISTRY], <VesselRegistrationFormBuilderPage />) },
|
|
// { path: 'vessel-registration-queue/:id', element: <VesselRegistrationReviewPage /> },
|
|
{ path: 'vessel-registration-report', element: guard([P.VIEW_VESSEL_REGISTRY], <VesselRegistrationReportPage />) },
|
|
{ path: 'vessel-ownership-transfer', element: <Navigate to="/licence-review/type/VESSEL_OWNERSHIP_TRANSFER" replace /> },
|
|
{ path: 'vessel-ownership-transfer/:id', element: <Navigate to="/licence-review" replace /> },
|
|
// Config-driven review workspace, shared by every licence type.
|
|
{ path: 'certificate-designer', element: guard([P.VIEW_TEMPLATES], <CertificateDesignerPage />) },
|
|
// Form schema + document requirement authoring, shared by every licence type.
|
|
{ path: 'certificate-requirements', element: guard([P.VIEW_LICENSE_TYPES], <CertificateRequirementsPage />) },
|
|
{ path: 'licence-review', element: guard(APPLICATION_QUEUE, <LicenseQueuePage />) },
|
|
{ path: 'licence-register', element: guard([P.VIEW_LICENSES], <LicenseRegisterPage />) },
|
|
// Deep link into the grid with the type facet pinned, so "Freight
|
|
// Forwarder" in the nav is a filtered view rather than a page.
|
|
{ path: 'licence-review/type/:typeCode', element: guard(APPLICATION_QUEUE, <LicenseQueuePage />) },
|
|
{ path: 'licence-review/:id', element: guard(APPLICATION_QUEUE, <LicenseReviewPage />) },
|
|
{ path: 'freight-forwarder-license', element: <Navigate to="/licence-review" replace /> },
|
|
{ path: 'freight-forwarder-license/:id', element: <Navigate to="/licence-review" replace /> },
|
|
{ path: 'shipping-agent-license', element: <Navigate to="/licence-review" replace /> },
|
|
{ path: 'shipping-agent-license/:id', element: <Navigate to="/licence-review" replace /> },
|
|
{ path: 'combined-license', element: <Navigate to="/licence-review" replace /> },
|
|
{ path: 'combined-license/:id', element: <Navigate to="/licence-review" replace /> },
|
|
{ path: 'joint-investment-license', element: <Navigate to="/licence-review" replace /> },
|
|
{ path: 'joint-investment-license/:id', element: <Navigate to="/licence-review" replace /> },
|
|
{ path: 'mto-license', element: <Navigate to="/licence-review" replace /> },
|
|
{ path: 'mto-license/:id', element: <Navigate to="/licence-review" replace /> },
|
|
// Waivers are seeded licence types, so their queue is the licence
|
|
// queue filtered by type and their review is the licence review.
|
|
{ path: 'waiver', element: <Navigate to="/licence-review/type/PRE_WAIVER" replace /> },
|
|
{ path: 'waiver/:id', element: <Navigate to="/licence-review" replace /> },
|
|
],
|
|
},
|
|
],
|
|
},
|
|
{ path: '/404', element: <div>Page not found</div> },
|
|
{ path: '*', element: <Navigate to="/404" replace /> },
|
|
]);
|
|
|
|
export function AppRouter() {
|
|
return <RouterProvider router={router} />;
|
|
}
|