import { Navigate, useLocation } from 'react-router-dom'; import { Center, Loader } from '@mantine/core'; import { useGetMyOperatorTypesQuery } from '@ema-platform/api'; /** * Sends an applicant who has not said what they operate as to the step that * asks. The logistics licence catalogue is keyed off that answer — it offers * nothing without it, and the server refuses an application for a mode the * profile does not hold — so it is asked once, up front. * * The gate is deliberately not portal-wide. Seafarer and vessel services are * seeded `requiresOperatorMode: false` precisely because a seafarer holds no * logistics mode of operation; gating them on this question locked the people * those services exist for out of registration, sea records, certificates and * examinations. Profile and support stay open for the same reason: someone who * cannot answer the question yet must still reach their account and ask for * help. */ const ALWAYS_ALLOWED = [ '/onboarding/operations', '/profile', '/support', '/notifications', // Seafarer services — no operator mode required by the licence types behind // them (SEAFARER_REGISTRATION, CERTIFICATE_OF_COMPETENCY/PROFICIENCY). '/seafarer-registration', '/seafarer/records', '/seafarer-registry', '/exams', '/certificates', '/seaman-book', '/endorsements', '/documents', // Vessel services — VESSEL_REGISTRATION is likewise mode-free. '/vessel-registration', // Waivers are filed by importers, who hold no logistics operating licence. '/waiver', ]; /** * Licence types seeded `requiresOperatorMode: false`. * * The wizard lives at one shared route (`/licensing/:typeCode/apply`), so the * gate has to know which types behind it are mode-free — otherwise a seafarer * or an importer reaches their service page and is bounced the moment they * start the application. Mirrors the seeds; the server is still the authority, * refusing a create for a mode the profile does not hold. */ const MODE_FREE_TYPE_KEYS = [ 'SEAFARER_REGISTRATION', 'VESSEL_REGISTRATION', 'CERTIFICATE_OF_COMPETENCY', 'CERTIFICATE_OF_PROFICIENCY', 'PRE_WAIVER', 'POST_WAIVER', ]; function isModeFreeLicensingRoute(pathname: string): boolean { const match = pathname.match(/^\/licensing\/([^/]+)/); return match ? MODE_FREE_TYPE_KEYS.includes(match[1]) : false; } export function RequireOperations({ children }: { children: React.ReactNode }) { const { pathname } = useLocation(); const { data, isLoading, isFetching, isError } = useGetMyOperatorTypesQuery(); if ( ALWAYS_ALLOWED.some((path) => pathname.startsWith(path)) || isModeFreeLicensingRoute(pathname) ) { return <>{children}>; } if (isLoading) { return (