mirror of
https://github.com/Tria-plc/emaui.git
synced 2026-08-28 04:20:56 +00:00
merge fix
This commit is contained in:
@@ -14,15 +14,15 @@ import {
|
||||
IconShip,
|
||||
IconTruck,
|
||||
IconUserCircle,
|
||||
} from '@tabler/icons-react';
|
||||
import { Outlet, useLocation, useNavigate } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { notify, AppHeader, AppSidebar } from '@ema-platform/ui';
|
||||
import type { NavItem } from '@ema-platform/ui';
|
||||
import { BrandMark, logout } from '@ema-platform/auth';
|
||||
import { SUPPORTED_LANGUAGES } from '../i18n/config';
|
||||
import { useAppSelector } from '../store/hooks';
|
||||
} from "@tabler/icons-react";
|
||||
import { Outlet, useLocation, useNavigate } from "react-router-dom";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { notify, AppHeader, AppSidebar } from "@ema-platform/ui";
|
||||
import type { NavItem } from "@ema-platform/ui";
|
||||
import { BrandMark, logout } from "@ema-platform/auth";
|
||||
import { SUPPORTED_LANGUAGES } from "../i18n/config";
|
||||
import { useAppSelector } from "../store/hooks";
|
||||
|
||||
type PortalNavItem = NavItem & { i18nKey: string };
|
||||
|
||||
@@ -35,59 +35,131 @@ type PortalNavItem = NavItem & { i18nKey: string };
|
||||
const NAV_SECTIONS: { label?: string; items: PortalNavItem[] }[] = [
|
||||
{
|
||||
items: [
|
||||
{ to: '/dashboard', label: 'Dashboard', i18nKey: 'nav.dashboard', icon: IconHome2 },
|
||||
{ to: '/notifications', label: 'Notifications', i18nKey: 'nav.notifications', icon: IconBell },
|
||||
{
|
||||
to: "/dashboard",
|
||||
label: "Dashboard",
|
||||
i18nKey: "nav.dashboard",
|
||||
icon: IconHome2,
|
||||
},
|
||||
{
|
||||
to: "/notifications",
|
||||
label: "Notifications",
|
||||
i18nKey: "nav.notifications",
|
||||
icon: IconBell,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'nav.groupLicensing',
|
||||
label: "nav.groupLicensing",
|
||||
items: [
|
||||
{ to: '/licensing/applications', label: 'My Applications', i18nKey: 'nav.myApplications', icon: IconTruck },
|
||||
{ to: '/waiver', label: 'Waiver', i18nKey: 'nav.waiver', icon: IconShieldOff, soon: true },
|
||||
{
|
||||
to: "/licensing/applications",
|
||||
label: "My Applications",
|
||||
i18nKey: "nav.myApplications",
|
||||
icon: IconTruck,
|
||||
},
|
||||
{
|
||||
to: "/waiver",
|
||||
label: "Waiver",
|
||||
i18nKey: "nav.waiver",
|
||||
icon: IconShieldOff,
|
||||
soon: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'nav.groupSeafarer',
|
||||
label: "nav.groupSeafarer",
|
||||
items: [
|
||||
{ to: '/seafarer-registry', label: 'Seafarer Registry', i18nKey: 'nav.seafarerRegistry', icon: IconList },
|
||||
{ to: '/seaman-book', label: 'Seaman Book', i18nKey: 'nav.myApplication', icon: IconSend, soon: true },
|
||||
{ to: '/certificates', label: 'Certificates', i18nKey: 'nav.certificates', icon: IconShieldCheck, soon: true },
|
||||
{ to: '/endorsements', label: 'Endorsements', i18nKey: 'nav.endorsements', icon: IconRubberStamp, soon: true },
|
||||
{
|
||||
to: "/seafarer-registry",
|
||||
label: "Seafarer Registry",
|
||||
i18nKey: "nav.seafarerRegistry",
|
||||
icon: IconList,
|
||||
},
|
||||
{
|
||||
to: "/seaman-book",
|
||||
label: "Seaman Book",
|
||||
i18nKey: "nav.myApplication",
|
||||
icon: IconSend,
|
||||
soon: true,
|
||||
},
|
||||
{
|
||||
to: "/certificates",
|
||||
label: "Certificates",
|
||||
i18nKey: "nav.certificates",
|
||||
icon: IconShieldCheck,
|
||||
soon: true,
|
||||
},
|
||||
{
|
||||
to: "/endorsements",
|
||||
label: "Endorsements",
|
||||
i18nKey: "nav.endorsements",
|
||||
icon: IconRubberStamp,
|
||||
soon: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'nav.groupVessels',
|
||||
label: "nav.groupVessels",
|
||||
items: [
|
||||
{ to: '/vessel-registration', label: 'Vessel Registration', i18nKey: 'nav.vesselRegistration', icon: IconShip, soon: true },
|
||||
{ to: '/vessel-registration/transfer', label: 'Ownership Transfer', i18nKey: 'nav.ownershipTransfer', icon: IconArrowsExchange, soon: true },
|
||||
{
|
||||
to: "/vessel-registration",
|
||||
label: "Vessel Registration",
|
||||
i18nKey: "nav.vesselRegistration",
|
||||
icon: IconShip,
|
||||
soon: true,
|
||||
},
|
||||
{
|
||||
to: "/vessel-registration/transfer",
|
||||
label: "Ownership Transfer",
|
||||
i18nKey: "nav.ownershipTransfer",
|
||||
icon: IconArrowsExchange,
|
||||
soon: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'nav.groupAccount',
|
||||
label: "nav.groupAccount",
|
||||
items: [
|
||||
{ to: '/documents', label: 'My Documents', i18nKey: 'nav.documents', icon: IconFolderOpen },
|
||||
{ to: '/profile', label: 'Profile', i18nKey: 'nav.profile', icon: IconUserCircle },
|
||||
{ to: '/support', label: 'Help & Support', i18nKey: 'nav.support', icon: IconHeadset },
|
||||
{
|
||||
to: "/documents",
|
||||
label: "My Documents",
|
||||
i18nKey: "nav.documents",
|
||||
icon: IconFolderOpen,
|
||||
},
|
||||
{
|
||||
to: "/profile",
|
||||
label: "Profile",
|
||||
i18nKey: "nav.profile",
|
||||
icon: IconUserCircle,
|
||||
},
|
||||
{
|
||||
to: "/support",
|
||||
label: "Help & Support",
|
||||
i18nKey: "nav.support",
|
||||
icon: IconHeadset,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
const PAGE_META: Record<string, { i18nKey: string }> = {
|
||||
'/dashboard': { i18nKey: 'nav.dashboard' },
|
||||
'/vessel-registration-dashboard': { i18nKey: 'nav.vesselRegistrationDashboard' },
|
||||
'/vessel-registration': { i18nKey: 'nav.vesselRegistration' },
|
||||
'/vessel-registration/transfer': { i18nKey: 'nav.ownershipTransfer' },
|
||||
'/licensing/applications': { i18nKey: 'nav.myApplications' },
|
||||
'/waiver': { i18nKey: 'nav.waiver' },
|
||||
'/seafarer-registry': { i18nKey: 'nav.seafarerRegistry' },
|
||||
'/seaman-book': { i18nKey: 'nav.myApplication' },
|
||||
'/certificates': { i18nKey: 'nav.certificates' },
|
||||
'/endorsements': { i18nKey: 'nav.endorsements' },
|
||||
'/documents': { i18nKey: 'nav.documents' },
|
||||
'/notifications':{ i18nKey: 'nav.notifications' },
|
||||
'/profile': { i18nKey: 'nav.profile' },
|
||||
'/support': { i18nKey: 'nav.support' },
|
||||
"/dashboard": { i18nKey: "nav.dashboard" },
|
||||
"/vessel-registration-dashboard": {
|
||||
i18nKey: "nav.vesselRegistrationDashboard",
|
||||
},
|
||||
"/vessel-registration": { i18nKey: "nav.vesselRegistration" },
|
||||
"/vessel-registration/transfer": { i18nKey: "nav.ownershipTransfer" },
|
||||
"/licensing/applications": { i18nKey: "nav.myApplications" },
|
||||
"/waiver": { i18nKey: "nav.waiver" },
|
||||
"/seafarer-registry": { i18nKey: "nav.seafarerRegistry" },
|
||||
"/seaman-book": { i18nKey: "nav.myApplication" },
|
||||
"/certificates": { i18nKey: "nav.certificates" },
|
||||
"/endorsements": { i18nKey: "nav.endorsements" },
|
||||
"/documents": { i18nKey: "nav.documents" },
|
||||
"/notifications": { i18nKey: "nav.notifications" },
|
||||
"/profile": { i18nKey: "nav.profile" },
|
||||
"/support": { i18nKey: "nav.support" },
|
||||
};
|
||||
|
||||
export function PortalLayout() {
|
||||
@@ -96,37 +168,9 @@ export function PortalLayout() {
|
||||
const location = useLocation();
|
||||
const dispatch = useDispatch();
|
||||
const user = useAppSelector((state) => state.auth.user);
|
||||
const currentProfile = useAppSelector((state) => state.auth.currentProfile);
|
||||
const professionName = (
|
||||
currentProfile?.profession?.name?.en ?? ""
|
||||
).toLowerCase();
|
||||
const matchedKey = Object.keys(NAV_ACCESS).find((key) =>
|
||||
professionName.includes(key),
|
||||
);
|
||||
const allowed =
|
||||
(matchedKey ? NAV_ACCESS[matchedKey] : undefined) ?? FALLBACK_ACCESS;
|
||||
const home = allowed === "*" ? "/dashboard" : (allowed[0] ?? "/dashboard");
|
||||
const isAllowed =
|
||||
allowed === "*" ||
|
||||
[...ALWAYS_VISIBLE, ...ALWAYS_ALLOWED, ...allowed].some((p) =>
|
||||
matchesPath(location.pathname, p),
|
||||
);
|
||||
const visibleNavItems =
|
||||
allowed === "*"
|
||||
? NAV_ITEMS
|
||||
: NAV_ITEMS.filter(
|
||||
(item) =>
|
||||
ALWAYS_VISIBLE.includes(item.to ?? "") ||
|
||||
allowed.includes(item.to ?? ""),
|
||||
);
|
||||
const [navOpened, { toggle: toggleNav, close: closeNav }] = useDisclosure();
|
||||
const [sidebarCollapsed, { toggle: toggleSidebar }] = useDisclosure(false);
|
||||
|
||||
if (!isAllowed) {
|
||||
notify.error(t("msg.permissionError"));
|
||||
return <Navigate to={home} replace />;
|
||||
}
|
||||
|
||||
// Breadcrumb trail
|
||||
const segments = location.pathname.split("/").filter(Boolean);
|
||||
const crumbs = [
|
||||
@@ -204,14 +248,17 @@ export function PortalLayout() {
|
||||
<AppSidebar
|
||||
navItems={NAV_SECTIONS.map((section) => ({
|
||||
label: section.label,
|
||||
items: section.items.map(({ i18nKey, ...rest }) => ({ ...rest, label: t(i18nKey) })),
|
||||
items: section.items.map(({ i18nKey, ...rest }) => ({
|
||||
...rest,
|
||||
label: t(i18nKey),
|
||||
})),
|
||||
}))}
|
||||
collapsed={sidebarCollapsed}
|
||||
activePath={location.pathname}
|
||||
onToggleCollapse={toggleSidebar}
|
||||
onNavigate={go}
|
||||
brandName={t('app.name')}
|
||||
brandSubtitle={t('app.authority')}
|
||||
brandName={t("app.name")}
|
||||
brandSubtitle={t("app.authority")}
|
||||
brandLogo={<BrandMark size={32} />}
|
||||
/>
|
||||
</AppShell.Navbar>
|
||||
|
||||
Reference in New Issue
Block a user