|
|
|
|
@@ -54,24 +54,34 @@ const navSections = [
|
|
|
|
|
{ label: 'Payments', icon: IconCash, path: '/payments' },
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'Planning',
|
|
|
|
|
items: [
|
|
|
|
|
{ label: 'Projects', icon: IconShieldCheck, path: '/projects' },
|
|
|
|
|
{ label: 'Capital Planning', icon: IconBuildingBank, path: '/capital-projects' },
|
|
|
|
|
{ label: 'Investment Planning', icon: IconSparkles, path: '/investment-planning', tourId: 'nav-investment-planning' },
|
|
|
|
|
{ label: 'Vendors', icon: IconUsers, path: '/vendors' },
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'Board Planning',
|
|
|
|
|
items: [
|
|
|
|
|
{ label: 'Budget Planning', icon: IconReportAnalytics, path: '/board-planning/budgets' },
|
|
|
|
|
{ label: 'Assessment Scenarios', icon: IconCalculator, path: '/board-planning/assessments' },
|
|
|
|
|
{ label: 'Investment Scenarios', icon: IconScale, path: '/board-planning/investments' },
|
|
|
|
|
{
|
|
|
|
|
label: 'Projects', icon: IconShieldCheck, path: '/projects',
|
|
|
|
|
children: [
|
|
|
|
|
{ label: 'Capital Planning', path: '/capital-projects' },
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'Assessment Scenarios', icon: IconCalculator, path: '/board-planning/assessments',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'Investment Planning', icon: IconSparkles, path: '/investment-planning', tourId: 'nav-investment-planning',
|
|
|
|
|
children: [
|
|
|
|
|
{ label: 'Investment Scenarios', path: '/board-planning/investments' },
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
{ label: 'Compare Scenarios', icon: IconGitCompare, path: '/board-planning/compare' },
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'Board Reference',
|
|
|
|
|
items: [
|
|
|
|
|
{ label: 'Vendors', icon: IconUsers, path: '/vendors' },
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'Reports',
|
|
|
|
|
items: [
|
|
|
|
|
@@ -153,7 +163,8 @@ export function Sidebar({ onNavigate }: SidebarProps) {
|
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
{section.items.map((item: any) =>
|
|
|
|
|
item.children ? (
|
|
|
|
|
item.children && !item.path ? (
|
|
|
|
|
// Collapsible group without a parent route (e.g. Reports)
|
|
|
|
|
<NavLink
|
|
|
|
|
key={item.label}
|
|
|
|
|
label={item.label}
|
|
|
|
|
@@ -172,6 +183,29 @@ export function Sidebar({ onNavigate }: SidebarProps) {
|
|
|
|
|
/>
|
|
|
|
|
))}
|
|
|
|
|
</NavLink>
|
|
|
|
|
) : item.children && item.path ? (
|
|
|
|
|
// Parent with its own route + nested children (e.g. Projects > Capital Planning)
|
|
|
|
|
<NavLink
|
|
|
|
|
key={item.path}
|
|
|
|
|
label={item.label}
|
|
|
|
|
leftSection={<item.icon size={18} />}
|
|
|
|
|
defaultOpened={
|
|
|
|
|
location.pathname === item.path ||
|
|
|
|
|
item.children.some((c: any) => location.pathname.startsWith(c.path))
|
|
|
|
|
}
|
|
|
|
|
data-tour={item.tourId || undefined}
|
|
|
|
|
active={location.pathname === item.path}
|
|
|
|
|
onClick={() => go(item.path!)}
|
|
|
|
|
>
|
|
|
|
|
{item.children.map((child: any) => (
|
|
|
|
|
<NavLink
|
|
|
|
|
key={child.path}
|
|
|
|
|
label={child.label}
|
|
|
|
|
active={location.pathname === child.path}
|
|
|
|
|
onClick={(e: React.MouseEvent) => { e.stopPropagation(); go(child.path); }}
|
|
|
|
|
/>
|
|
|
|
|
))}
|
|
|
|
|
</NavLink>
|
|
|
|
|
) : (
|
|
|
|
|
<NavLink
|
|
|
|
|
key={item.path}
|
|
|
|
|
|