import { createBrowserRouter, Navigate } from "react-router-dom"; import { I18nextProvider } from "react-i18next"; import { i18n } from "./i18n/config"; import { PortalLayout } from "./layouts/PortalLayout"; import { ProtectedRoute } from "./components/ProtectedRoute"; // Auth (standalone pages, no portal chrome) import { LoginPage, SignupPage, OTPVerificationPage, ForgotPasswordPage, SetPasswordPage, } from "@ema-platform/auth"; // Portal feature pages import { DashboardPage } from "./features/dashboard/pages/DashboardPage"; import { RequireOperations } from "./features/onboarding/components/RequireOperations"; import { RequireSeafarerProfile } from "./features/profile/components/RequireSeafarerProfile"; import { OperationsOnboardingPage } from "./features/onboarding/pages/OperationsOnboardingPage"; import { ProfilePage } from "./features/profile/pages/ProfilePage"; import { SupportPage } from "./features/support/pages/SupportPage"; import { SeafarerRegistrationPage } from "./features/seafarer/pages/SeafarerRegistrationPage"; import { MySeaRecordsPage } from "./features/seafarer/pages/MySeaRecordsPage"; import { VerifyCertificatePage } from "./features/verify/pages/VerifyCertificatePage"; import { ExamsPage } from "./features/exams/pages/ExamsPage"; // Phase 1 pages import { DocumentVaultPage } from "./features/documents/pages/DocumentVaultPage"; import { SeamanBookPage } from "./features/seaman-book/pages/SeamanBookPage"; import { SeamanBookApplicationPage } from "./features/seaman-book/pages/SeamanBookApplicationPage"; import { NotificationsPage } from "./features/notifications/pages/NotificationsPage"; // Phase 2 — CoC / CoP import { CertificatesPage } from "./features/certificates/pages/CertificatesPage"; import { CoCApplicationPage } from "./features/certificates/pages/CoCApplicationPage"; // Phase 3 — Endorsement import { EndorsementPage } from "./features/endorsement/pages/EndorsementPage"; import { VesselRegistrationPage } from "./features/vessel-registration/pages/VesselRegistrationPage"; import { OwnershipTransferPage } from "./features/vessel-registration/pages/OwnershipTransferPage"; import { MyApplicationsPage } from "./features/licensing/pages/MyApplicationsPage"; import { PaymentCheckPage } from "./features/payments/pages/PaymentCheckPage"; import { PaymentSuccessPage } from "./features/payments/pages/PaymentSuccessPage"; import { PaymentFailurePage } from "./features/payments/pages/PaymentFailurePage"; import { LicenseApplicationPage } from "./features/licensing/pages/LicenseApplicationPage"; import { ApplicationRedirectPage } from "./features/licensing/pages/ApplicationRedirectPage"; import { WaiverPage } from "./features/waiver/pages/WaiverPage"; import { VesselRegistrationStatusPage } from "./features/vessel-registration/pages/VesselRegistrationStatusPage"; export const router = createBrowserRouter([ // Public auth pages { path: "/login", element: }, { path: "/signup", element: }, // Public certificate verification — the target of every printed QR code. // No auth: a verifier scanning a certificate has no portal account. { path: "/verify", element: }, { path: "/verify/:code", element: }, // Completes the forgot-password flow; the reset message links here. The // IAM package generates `/reset-password` links, `/set-password` is the // first-time-credential variant — one page serves both. { path: "/set-password", element: }, { path: "/reset-password", element: }, // Protected auth pages { element: ( ), path: "/otp-verify", }, { element: ( ), path: "/forgot-password", }, // The two-step setup wizard is gone. Signing up lands on the dashboard, and // profile details are collected where they are actually needed: on /profile, // via the dashboard nudge, or inline in an application flow. The path stays // as a redirect so existing bookmarks and emailed links do not 404. { path: "/profile-setup", element: }, // Portal — protected. { element: ( {/* Asks what the applicant operates as before the rest of the portal, which is filtered by that answer. */} ), children: [ { path: "/", element: }, { path: "/dashboard", element: }, { path: "/onboarding/operations", element: }, // Config-driven licensing: one set of pages serves every licence type. { path: "/licensing/applications", element: }, // Telebirr returns the applicant to these. { path: "/payments/check", element: }, { path: "/payments/success", element: }, { path: "/payments/failure", element: }, { path: "/licensing/:typeCode/apply", element: ( ), }, { path: "/licensing/:typeCode/applications/:applicationId", element: , }, // Notification / email deep links arrive as /applications/; resolve the // licence type and forward to the canonical route. { path: "/applications/:applicationId", element: , }, // Seafarer { path: "/seafarer-registration", element: ( ), }, { path: "/seafarer/records", element: }, { path: "/exams", element: }, // The public-facing registry was a hardcoded mock and does not belong in // the applicant portal; officers browse seafarers in the backoffice. { path: "/seafarer-registry", element: , }, { path: "/seafarer-registry/:id", element: , }, // Phase 1 { path: "/documents", element: }, { path: "/seaman-book", element: }, { path: "/seaman-book/apply", element: }, { path: "/notifications", element: }, // Phase 2 — CoC / CoP { path: "/certificates", element: }, { path: "/certificates/apply", element: }, // Phase 3 — Endorsement { path: "/endorsements", element: }, { path: "/vessel-registration", element: }, // The registration wizard is the config-driven licensing flow; the old // standalone wizard posted to endpoints that never existed. { path: "/vessel-registration/apply", element: , }, { path: "/vessel-registration-dashboard", element: , }, { path: "/vessel-registration/transfer", element: , }, // Legacy per-licence-type URLs. Each once had its own hand-written page // that posted to a `/logistics-licenses/*` endpoint the API never had, // and dropped every uploaded document on the floor. They are kept as // redirects so old bookmarks land somewhere real; the config-driven // wizard below serves every licence type from one place. { path: "/logistics-dashboard", element: , }, { path: "/freight-forwarder-license", element: , }, { path: "/freight-forwarder-license/apply", element: , }, { path: "/freight-forwarder-license/:id/renew", element: , }, { path: "/shipping-agent-license", element: , }, { path: "/shipping-agent-license/apply", element: , }, { path: "/shipping-agent-license/:id/renew", element: , }, { path: "/combined-license", element: , }, { path: "/combined-license/apply", element: , }, { path: "/combined-license/:id/renew", element: , }, { path: "/joint-investment-license", element: , }, { path: "/joint-investment-license/apply", element: , }, { path: "/joint-investment-license/:id/renew", element: , }, { path: "/mto-license", element: , }, { path: "/mto-license/apply", element: ( ), }, { path: "/mto-license/:id/renew", element: , }, // Waiver has no backend yet, so it says so rather than pretending. { path: "/waiver", element: }, { path: "/waiver/apply", element: }, // Vessel Registration { path: "/vessel-registrations", element: }, // { path: '/vessel-registrations/apply', element: }, { path: "/vessel-registrations/:id", element: , }, // General { path: "/profile", element: }, { path: "/support", element: }, ], }, // The separate vessel-owner login/portal was mock-only and called auth // endpoints that never existed; vessel owners are ordinary portal users. { path: "/vessel-owner/login", element: }, { path: "/vessel-owner/register", element: , }, { path: "/vessel-owner/dashboard", element: , }, { path: "/vessel-owner/registration", element: , }, { path: "/vessel-owner/registration/apply", element: , }, { path: "/vessel-owner/registration/transfer", element: , }, { path: "*", element: }, ]);