Refactored UI endpoint usage
This commit is contained in:
@@ -18,6 +18,7 @@ import {
|
||||
} from 'lucide-react';
|
||||
import { useAuth } from '../../auth/AuthProvider';
|
||||
import { BrandLogo } from '../ui/BrandLogo';
|
||||
import { HelpTooltip } from '../ui/HelpTooltip';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { getUsers } from '../../services/api';
|
||||
import { getUserEmail, registerUserEmail } from '../../lib/formatters';
|
||||
@@ -27,31 +28,37 @@ const navItems = [
|
||||
name: 'Executive Dashboard',
|
||||
path: '/dashboard',
|
||||
icon: LayoutDashboard,
|
||||
help: 'Strategic macro metrics, portfolio value, disbursed funding, ISO 31000 risk heatmap, and projects requiring immediate intervention.',
|
||||
},
|
||||
{
|
||||
name: 'Governance & Structure',
|
||||
path: '/governance',
|
||||
icon: Building2,
|
||||
help: 'Master records for legal entities, holding structures, investment portfolios, and thematic programmes funded under statutory mandates.',
|
||||
},
|
||||
{
|
||||
name: 'Projects & Milestones',
|
||||
path: '/projects',
|
||||
icon: FolderKanban,
|
||||
help: 'Project Work Breakdown Structure (WBS), contractual deliverables, scheduled milestones, evidence verification, and execution tracking.',
|
||||
},
|
||||
{
|
||||
name: 'Grant & Financials',
|
||||
path: '/grants',
|
||||
icon: Coins,
|
||||
help: 'Financial management including statutory awards, multi-year budget line allocations, tranches, and scheduled payment disbursements.',
|
||||
},
|
||||
{
|
||||
name: 'M&E, Evidence & Risks',
|
||||
path: '/monitoring',
|
||||
icon: ShieldAlert,
|
||||
help: 'Monitoring & Evaluation (M&E) framework, indicator tracking, ISO 31000 risk registers, mitigation plans, and compliance audits.',
|
||||
},
|
||||
{
|
||||
name: 'Settings & Communications',
|
||||
path: '/settings',
|
||||
icon: Settings,
|
||||
help: 'User account provisioning, statutory sync, tenant environment parameters, and communication invite templates.',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -109,7 +116,7 @@ export const AppLayout: React.FC = () => {
|
||||
sidebarOpen ? 'w-64' : 'w-20'
|
||||
} shrink-0 bg-[#0b101b]/95 text-slate-200 border-r border-slate-800/80 transition-all duration-300 flex flex-col z-30 shadow-2xl backdrop-blur-md`}
|
||||
>
|
||||
{/* Brand Header — Clickable link navigating to auth-aware Home page */}
|
||||
{/* Brand Header */}
|
||||
<div className="h-16 px-4 flex items-center justify-between border-b border-slate-800/80 bg-[#0d121f]/90">
|
||||
<Link
|
||||
to="/"
|
||||
@@ -141,25 +148,36 @@ export const AppLayout: React.FC = () => {
|
||||
{navItems.map((item) => {
|
||||
const Icon = item.icon;
|
||||
return (
|
||||
<NavLink
|
||||
key={item.path}
|
||||
to={item.path}
|
||||
className={({ isActive }) =>
|
||||
`flex items-center gap-3 px-3.5 py-2.5 rounded-xl text-xs font-medium transition-all ${
|
||||
isActive
|
||||
? 'bg-gradient-to-r from-blue-600 to-indigo-600 text-white shadow-md shadow-blue-600/25 font-semibold'
|
||||
: 'text-slate-400 hover:text-slate-100 hover:bg-slate-800/60'
|
||||
}`
|
||||
}
|
||||
>
|
||||
<Icon className="w-4 h-4 shrink-0" />
|
||||
{sidebarOpen && <span className="truncate">{item.name}</span>}
|
||||
</NavLink>
|
||||
<div key={item.path} className="flex items-center justify-between group">
|
||||
<NavLink
|
||||
to={item.path}
|
||||
className={({ isActive }) =>
|
||||
`flex items-center gap-3 px-3.5 py-2.5 rounded-xl text-xs font-medium transition-all flex-1 min-w-0 ${
|
||||
isActive
|
||||
? 'bg-gradient-to-r from-blue-600 to-indigo-600 text-white shadow-md shadow-blue-600/25 font-semibold'
|
||||
: 'text-slate-400 hover:text-slate-100 hover:bg-slate-800/60'
|
||||
}`
|
||||
}
|
||||
>
|
||||
<Icon className="w-4 h-4 shrink-0" />
|
||||
{sidebarOpen && <span className="truncate">{item.name}</span>}
|
||||
</NavLink>
|
||||
{sidebarOpen && (
|
||||
<div className="pl-1">
|
||||
<HelpTooltip
|
||||
title={item.name}
|
||||
content={item.help}
|
||||
size="sm"
|
||||
placement="right"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</nav>
|
||||
|
||||
{/* User Card with Token-derived info & Identity Server Logout */}
|
||||
{/* User Card */}
|
||||
<div className="p-3 border-t border-slate-800/80 bg-[#0d121f]/90">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="h-9 w-9 shrink-0 rounded-full bg-blue-600/20 border border-blue-500/40 flex items-center justify-center font-bold text-xs text-blue-400">
|
||||
@@ -192,7 +210,7 @@ export const AppLayout: React.FC = () => {
|
||||
{/* Top Header */}
|
||||
<header className="h-16 bg-[#0d121f]/90 border-b border-slate-800/80 backdrop-blur-md px-4 sm:px-6 md:px-8 flex items-center justify-between shrink-0 z-20">
|
||||
<div className="flex items-center gap-3">
|
||||
{/* Top Bar Brand Icon & Direct Portal Link */}
|
||||
{/* Brand Icon */}
|
||||
<Link
|
||||
to="/"
|
||||
id="header-brand-logo-link"
|
||||
@@ -207,7 +225,7 @@ export const AppLayout: React.FC = () => {
|
||||
|
||||
<span className="h-4 w-px bg-slate-800 hidden md:block" />
|
||||
|
||||
{/* Clickable Home Link */}
|
||||
{/* Home Navigation */}
|
||||
<Link
|
||||
to="/"
|
||||
id="header-home-link"
|
||||
@@ -229,17 +247,31 @@ export const AppLayout: React.FC = () => {
|
||||
<Database className="w-3.5 h-3.5 text-blue-400 shrink-0" />
|
||||
<span className="truncate">{tenantName}</span>
|
||||
</span>
|
||||
<HelpTooltip
|
||||
title="Tenant Context"
|
||||
content="Identifies the multi-tenant organization partition and database boundary within the national PFM environment."
|
||||
size="sm"
|
||||
placement="bottom"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<ChevronRight className="w-4 h-4 text-slate-600 hidden sm:block" />
|
||||
|
||||
<span className="text-xs font-medium text-emerald-400 bg-emerald-500/10 px-2.5 py-0.5 rounded-full border border-emerald-500/30 flex items-center gap-1.5 shadow-xs">
|
||||
<ShieldCheck className="w-3.5 h-3.5 text-emerald-400" />
|
||||
Authenticated Session
|
||||
</span>
|
||||
<div className="flex items-center gap-1.5">
|
||||
<span className="text-xs font-medium text-emerald-400 bg-emerald-500/10 px-2.5 py-0.5 rounded-full border border-emerald-500/30 flex items-center gap-1.5 shadow-xs">
|
||||
<ShieldCheck className="w-3.5 h-3.5 text-emerald-400" />
|
||||
Authenticated Session
|
||||
</span>
|
||||
<HelpTooltip
|
||||
title="Security Session Status"
|
||||
content="Current session is verified against OIDC Identity Server with active cryptographic token and claims."
|
||||
size="sm"
|
||||
placement="bottom"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* User Name & Email derived from token, plus Identity Server signout */}
|
||||
{/* User Profile and Controls */}
|
||||
<div className="relative flex items-center gap-3">
|
||||
<div className="text-right hidden sm:block">
|
||||
<p className="text-xs font-semibold text-white truncate max-w-[200px]" title={tokenUserName}>
|
||||
@@ -292,7 +324,7 @@ export const AppLayout: React.FC = () => {
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{/* Viewport with Landing Page ambient dot grid and glow */}
|
||||
{/* Main Content Area */}
|
||||
<main className="flex-1 overflow-y-auto p-6 md:p-8 bg-[#090d16] relative text-slate-100">
|
||||
<div
|
||||
className="absolute inset-0 pointer-events-none opacity-15"
|
||||
|
||||
Reference in New Issue
Block a user