This commit is contained in:
estifanos
2026-07-31 06:33:15 +00:00
parent 0db451bdec
commit 1e894ecfa7
4 changed files with 167 additions and 112 deletions

View File

@@ -48,6 +48,10 @@ export const am: Translations = {
support: 'እገዛና ድጋፍ',
collapseSidebar: 'ሰብስብ',
expandSidebar: 'ዘርጋ',
sectionSeafarerServices: 'የመርከበኞች አገልግሎቶች',
sectionVesselServices: 'የመርከብ አገልግሎቶች',
sectionLogisticsLicensing: 'ሎጂስቲክስና ፈቃድ',
sectionAccountManagement: 'የመለያ አስተዳደር',
},
common: {

View File

@@ -46,6 +46,10 @@ export const en = {
support: 'Help & Support',
collapseSidebar: 'Collapse',
expandSidebar: 'Expand sidebar',
sectionSeafarerServices: 'Seafarer Services',
sectionVesselServices: 'Vessel Services',
sectionLogisticsLicensing: 'Logistics and Licensing',
sectionAccountManagement: 'Account Management',
},
common: {

View File

@@ -28,120 +28,146 @@ import { logout } from "@ema-platform/auth";
import { SUPPORTED_LANGUAGES } from "../i18n/config";
import { useAppSelector } from "../store/hooks";
const NAV_ITEMS: (NavItem & { i18nKey: string })[] = [
type SectionId = "seafarer" | "vessel" | "logistics" | "common";
const SECTION_I18N_KEY: Record<SectionId, string> = {
seafarer: "nav.sectionSeafarerServices",
vessel: "nav.sectionVesselServices",
logistics: "nav.sectionLogisticsLicensing",
common: "nav.sectionAccountManagement",
};
const NAV_ITEMS: (NavItem & { i18nKey: string; section?: SectionId })[] = [
{
to: "/dashboard",
label: "Dashboard",
i18nKey: "nav.dashboard",
icon: IconHome2,
},
{
to: "/seafarer-registry",
label: "Seafarer Registry",
i18nKey: "nav.seafarerRegistry",
icon: IconList,
},
{
to: "/seaman-book",
label: "My Application",
i18nKey: "nav.myApplication",
icon: IconSend,
},
{
to: "/vessel-registration-dashboard",
label: "Vessel Registration Dashboard",
i18nKey: "nav.vesselRegistrationDashboard",
icon: IconGauge,
},
{
to: "/vessel-registration",
label: "Vessel Registration",
i18nKey: "nav.vesselRegistration",
icon: IconShip,
},
{
to: "/vessel-registration/transfer",
label: "Ownership Transfer",
i18nKey: "nav.ownershipTransfer",
icon: IconArrowsExchange,
},
{
to: "/logistics-dashboard",
label: "Logistics Licenses Dashboard",
i18nKey: "nav.logisticsDashboard",
icon: IconGauge,
},
{
to: "/freight-forwarder-license",
label: "Freight Forwarder License",
i18nKey: "nav.freightForwarderLicense",
icon: IconTruck,
},
{
to: "/shipping-agent-license",
label: "Shipping Agent License",
i18nKey: "nav.shippingAgentLicense",
icon: IconShip,
},
{
to: "/combined-license",
label: "Combined License",
i18nKey: "nav.combinedLicense",
icon: IconStack2,
},
{
to: "/joint-investment-license",
label: "Joint Investment License",
i18nKey: "nav.jointInvestmentLicense",
icon: IconUsers,
},
{
to: "/mto-license",
label: "MTO License",
i18nKey: "nav.mtoLicense",
icon: IconTruck,
},
{
to: "/waiver",
label: "Waiver",
i18nKey: "nav.waiver",
icon: IconShieldOff,
},
{
to: "/certificates",
label: "Certificates",
i18nKey: "nav.certificates",
icon: IconShieldCheck,
},
{
to: "/endorsements",
label: "Endorsements",
i18nKey: "nav.endorsements",
icon: IconRubberStamp,
},
{
to: "/documents",
label: "My Documents",
i18nKey: "nav.documents",
icon: IconFolderOpen,
},
{
to: "/notifications",
label: "Notifications",
i18nKey: "nav.notifications",
icon: IconBell,
},
{
to: "/seafarer-registry",
label: "Seafarer Registry",
i18nKey: "nav.seafarerRegistry",
icon: IconList,
section: "seafarer",
},
{
to: "/seaman-book",
label: "My Application",
i18nKey: "nav.myApplication",
icon: IconSend,
section: "seafarer",
},
{
to: "/certificates",
label: "Certificates",
i18nKey: "nav.certificates",
icon: IconShieldCheck,
section: "seafarer",
},
{
to: "/endorsements",
label: "Endorsements",
i18nKey: "nav.endorsements",
icon: IconRubberStamp,
section: "seafarer",
},
{
to: "/vessel-registration-dashboard",
label: "Vessel Registration Dashboard",
i18nKey: "nav.vesselRegistrationDashboard",
icon: IconGauge,
section: "vessel",
},
{
to: "/vessel-registration",
label: "Vessel Registration",
i18nKey: "nav.vesselRegistration",
icon: IconShip,
section: "vessel",
},
{
to: "/vessel-registration/transfer",
label: "Ownership Transfer",
i18nKey: "nav.ownershipTransfer",
icon: IconArrowsExchange,
section: "vessel",
},
{
to: "/logistics-dashboard",
label: "Logistics Licenses Dashboard",
i18nKey: "nav.logisticsDashboard",
icon: IconGauge,
section: "logistics",
},
{
to: "/freight-forwarder-license",
label: "Freight Forwarder License",
i18nKey: "nav.freightForwarderLicense",
icon: IconTruck,
section: "logistics",
},
{
to: "/shipping-agent-license",
label: "Shipping Agent License",
i18nKey: "nav.shippingAgentLicense",
icon: IconShip,
section: "logistics",
},
{
to: "/combined-license",
label: "Combined License",
i18nKey: "nav.combinedLicense",
icon: IconStack2,
section: "logistics",
},
{
to: "/joint-investment-license",
label: "Joint Investment License",
i18nKey: "nav.jointInvestmentLicense",
icon: IconUsers,
section: "logistics",
},
{
to: "/mto-license",
label: "MTO License",
i18nKey: "nav.mtoLicense",
icon: IconTruck,
section: "logistics",
},
{
to: "/waiver",
label: "Waiver",
i18nKey: "nav.waiver",
icon: IconShieldOff,
section: "logistics",
},
{
to: "/documents",
label: "My Documents",
i18nKey: "nav.documents",
icon: IconFolderOpen,
section: "common",
},
{
to: "/profile",
label: "Profile",
i18nKey: "nav.profile",
icon: IconUserCircle,
section: "common",
},
{
to: "/support",
label: "Help & Support",
i18nKey: "nav.support",
icon: IconHeadset,
section: "common",
},
];
@@ -152,19 +178,19 @@ const NAV_ITEMS: (NavItem & { i18nKey: string })[] = [
// matches a profession named "Deck Cadet". Values are the `to` paths from
// NAV_ITEMS above. '*' means every item.
const ALWAYS_VISIBLE = ["/notifications", "/profile", "/support"];
const ALWAYS_VISIBLE = ["/notifications", "/profile", "/support", "/documents"];
const NAV_ACCESS: Record<string, string[] | "*"> = {
null: "*",
cadet: "*",
// cadet: [
// "/dashboard",
// "/seafarer-registry",
// "/seaman-book",
// "/certificates",
// "/endorsements",
// "/documents",
// ],
// cadet: "*",
cadet: [
"/dashboard",
"/seafarer-registry",
"/seaman-book",
"/certificates",
"/endorsements",
"/documents",
],
registration: [
"/vessel-registration-dashboard",
"/vessel-registration",
@@ -314,9 +340,10 @@ export function PortalLayout() {
}}
>
<AppSidebar
navItems={visibleNavItems.map(({ i18nKey, ...rest }) => ({
navItems={visibleNavItems.map(({ i18nKey, section, ...rest }) => ({
...rest,
label: t(i18nKey),
section: section ? t(SECTION_I18N_KEY[section]) : undefined,
}))}
collapsed={sidebarCollapsed}
activePath={location.pathname}

View File

@@ -1,3 +1,4 @@
import { Fragment } from 'react';
import {
AppShell,
NavLink,
@@ -21,6 +22,7 @@ export interface NavItem {
icon: Icon;
to?: string;
soon?: boolean;
section?: string;
}
interface AppSidebarProps {
@@ -97,9 +99,25 @@ export function AppSidebar({
{/* Navigation items */}
<AppShell.Section grow component={ScrollArea} p="md">
<Stack gap={4}>
{navItems.map((item) => {
{navItems.map((item, index) => {
const ItemIcon = item.icon;
const active = activeNavItem(item);
const showHeader =
!collapsed && !!item.section && item.section !== navItems[index - 1]?.section;
const header = showHeader ? (
<Text
size="xs"
fw={700}
c="dimmed"
mt={index === 0 ? 0 : 12}
mb={2}
px={8}
style={{ textTransform: 'uppercase', letterSpacing: '0.05em' }}
>
{item.section}
</Text>
) : null;
if (collapsed) {
return (
@@ -124,15 +142,17 @@ export function AppSidebar({
}
return (
<NavLink
key={item.label}
active={active}
label={t(item.label)}
leftSection={<ItemIcon size={19} stroke={1.6} />}
onClick={() => onNavigate(item)}
variant="light"
styles={{ root: { borderRadius: rem(10) }, label: { fontWeight: 500 } }}
/>
<Fragment key={item.label}>
{header}
<NavLink
active={active}
label={t(item.label)}
leftSection={<ItemIcon size={19} stroke={1.6} />}
onClick={() => onNavigate(item)}
variant="light"
styles={{ root: { borderRadius: rem(10) }, label: { fontWeight: 500 } }}
/>
</Fragment>
);
})}
</Stack>