Merge pull request 'Implemented markdown based notification message body formatting' (#156) from finishline into main

Reviewed-on: #156
This commit was merged in pull request #156.
This commit is contained in:
2026-10-22 18:19:36 +02:00
2 changed files with 319 additions and 173 deletions
@@ -69,7 +69,7 @@ export const UserSearchPicker: React.FC<UserSearchPickerProps> = ({
const filtered = activeUsers.filter(u => { const filtered = activeUsers.filter(u => {
if (!term) return true; if (!term) return true;
const email = (u.email || '').toLowerCase(); const email = (u.email || '').toLowerCase();
const role = (u.role || '').toLowerCase(); const role = String(u.role ?? '').toLowerCase();
return email.includes(term) || role.includes(term); return email.includes(term) || role.includes(term);
}); });
@@ -80,7 +80,7 @@ export const UserSearchPicker: React.FC<UserSearchPickerProps> = ({
const otherUsers: User[] = []; const otherUsers: User[] = [];
filtered.forEach(u => { filtered.forEach(u => {
const r = (u.role || '').toLowerCase(); const r = String(u.role ?? '').toLowerCase();
if (r.includes('admin') || r.includes('executive') || r.includes('director')) { if (r.includes('admin') || r.includes('executive') || r.includes('director')) {
adminUsers.push(u); adminUsers.push(u);
} else if (r.includes('programme') || r.includes('project') || r.includes('manager')) { } else if (r.includes('programme') || r.includes('project') || r.includes('manager')) {
@@ -178,7 +178,7 @@ export const UserSearchPicker: React.FC<UserSearchPickerProps> = ({
id: u.id, id: u.id,
email: u.email, email: u.email,
name: formattedName, name: formattedName,
role: u.role || 'User', role: String(u.role ?? 'User'),
}); });
setIsDropdownOpen(false); setIsDropdownOpen(false);
} else { } else {
@@ -186,7 +186,7 @@ export const UserSearchPicker: React.FC<UserSearchPickerProps> = ({
id: u.id, id: u.id,
email: u.email, email: u.email,
name: formattedName, name: formattedName,
role: u.role || 'User', role: String(u.role ?? 'User'),
}); });
} }
} }
@@ -214,6 +214,11 @@ export const ExecutiveDashboard: React.FC = () => {
return dashboard?.disbursed || 0; return dashboard?.disbursed || 0;
}, [dashboard, disbursements, filteredProjects, selectedProgramme, selectedSector]); }, [dashboard, disbursements, filteredProjects, selectedProgramme, selectedSector]);
const disbursedPercentage = useMemo(() => {
if (!portfolioValue || portfolioValue <= 0) return 0;
return Math.min(100, Math.round((disbursed / portfolioValue) * 1000) / 10);
}, [disbursed, portfolioValue]);
const onTrackPercentage = useMemo(() => { const onTrackPercentage = useMemo(() => {
const targetProjects = filteredProjects.length > 0 ? filteredProjects : projects; const targetProjects = filteredProjects.length > 0 ? filteredProjects : projects;
if (targetProjects.length === 0) return 0; if (targetProjects.length === 0) return 0;
@@ -341,7 +346,7 @@ export const ExecutiveDashboard: React.FC = () => {
}, [disbursements]); }, [disbursements]);
// Projects requiring management attention based on risk profile // Projects requiring management attention based on risk profile
const attentionProjects = useMemo(() => { const attentionProjects = useMemo<AttentionProject[]>(() => {
const targetProjects = filteredProjects.length > 0 ? filteredProjects : projects; const targetProjects = filteredProjects.length > 0 ? filteredProjects : projects;
if (targetProjects.length === 0) return []; if (targetProjects.length === 0) return [];
@@ -356,7 +361,7 @@ export const ExecutiveDashboard: React.FC = () => {
}); });
return targetProjects return targetProjects
.map((p) => { .map((p): AttentionProject => {
const maxScore = projectMaxRisk[String(p.id)] || 0; const maxScore = projectMaxRisk[String(p.id)] || 0;
const isRejected = p.status === ApprovalStatus.Rejected; const isRejected = p.status === ApprovalStatus.Rejected;
const isPending = p.status === ApprovalStatus.Pending || p.status === ApprovalStatus.Review; const isPending = p.status === ApprovalStatus.Pending || p.status === ApprovalStatus.Review;
@@ -393,7 +398,7 @@ export const ExecutiveDashboard: React.FC = () => {
return { return {
id: p.id, id: p.id,
name: p.name, name: p.name || 'Unnamed Project',
programme: p.programmeName || `Programme ${p.programmeId}`, programme: p.programmeName || `Programme ${p.programmeId}`,
status: statusLabel, status: statusLabel,
risk: riskLevel, risk: riskLevel,
@@ -568,187 +573,328 @@ export const ExecutiveDashboard: React.FC = () => {
</div> </div>
</div> </div>
{/* 8 Headline Portfolio KPI Cards with Compliance & Budget At Risk */} {/* Executive Portfolio KPIs: Structured 2-Tier Balanced Grid */}
<div className="grid grid-cols-2 sm:grid-cols-4 xl:grid-cols-8 gap-3.5"> <div className="space-y-6">
{/* Card 1: Portfolio Value */} {/* Tier 1: Capital Commitments & Deployment Scale */}
<div className="bg-[#0f1523]/80 p-5 rounded-2xl border border-slate-800/80 hover:border-blue-500/30 transition-all flex flex-col justify-between shadow-md group backdrop-blur-sm"> <div className="space-y-3">
<div className="flex items-center justify-between text-slate-400"> <div className="flex items-center justify-between px-1">
<div className="flex items-center gap-1.5"> <div className="flex items-center gap-2">
<span className="text-[11px] font-semibold uppercase tracking-wider text-slate-400">Portfolio Value</span> <span className="text-[11px] font-bold uppercase tracking-widest text-slate-400">
<HelpTooltip Capital Deployment & Scale
title="Total Portfolio Value" </span>
content="Aggregated statutory grant commitment amount approved across all active grant awards and contracts." <span className="h-1 w-1 rounded-full bg-slate-600" />
size="sm" <span className="text-xs text-slate-500 hidden sm:inline">Portfolio commitments, disbursements & capital exposure</span>
placement="top"
/>
</div>
<div className="p-1.5 rounded-lg bg-blue-500/10 text-blue-400 border border-blue-500/20 group-hover:scale-110 transition">
<Coins className="w-3.5 h-3.5" />
</div> </div>
<span className="text-[10px] font-semibold text-blue-400/90 bg-blue-500/10 px-2 py-0.5 rounded-full border border-blue-500/20">
Financial Governance
</span>
</div> </div>
<div className="mt-3">
<p className="text-2xl font-bold text-white tracking-tight">{formatCompactZAR(portfolioValue)}</p> <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
<p className="text-[10px] text-slate-400 font-mono mt-1">{formatZAR(portfolioValue)}</p> {/* Card 1: Portfolio Value */}
<div className="bg-[#0f1523]/80 p-5 rounded-2xl border border-slate-800/80 hover:border-blue-500/40 transition-all flex flex-col justify-between shadow-md group backdrop-blur-sm relative overflow-hidden">
<div className="flex items-start justify-between gap-3">
<div className="flex items-center gap-1.5 min-w-0 flex-1">
<span className="text-xs font-semibold uppercase tracking-wider text-slate-400 truncate">
Portfolio Value
</span>
<HelpTooltip
title="Total Portfolio Value"
content="Aggregated statutory grant commitment amount approved across all active grant awards and contracts."
size="sm"
placement="top"
/>
</div>
<div className="shrink-0 p-2 rounded-xl bg-blue-500/10 text-blue-400 border border-blue-500/20 group-hover:scale-105 transition-transform">
<Coins className="w-4 h-4" />
</div>
</div>
<div className="mt-3">
<p className="text-2xl sm:text-3xl font-bold text-white tracking-tight">
{formatCompactZAR(portfolioValue)}
</p>
<div className="flex items-center justify-between mt-3 pt-2.5 border-t border-slate-800/70 text-xs">
<span className="text-slate-400 font-mono text-[11px] truncate mr-2" title={formatZAR(portfolioValue)}>
{formatZAR(portfolioValue)}
</span>
<span className="text-[10px] font-medium text-blue-400 bg-blue-500/10 px-1.5 py-0.5 rounded border border-blue-500/20 shrink-0">
Statutory Total
</span>
</div>
</div>
</div>
{/* Card 2: Disbursed */}
<div className="bg-[#0f1523]/80 p-5 rounded-2xl border border-slate-800/80 hover:border-teal-500/40 transition-all flex flex-col justify-between shadow-md group backdrop-blur-sm relative overflow-hidden">
<div className="flex items-start justify-between gap-3">
<div className="flex items-center gap-1.5 min-w-0 flex-1">
<span className="text-xs font-semibold uppercase tracking-wider text-slate-400 truncate">
Disbursed
</span>
<HelpTooltip
title="Disbursed Funds"
content="Actual funds paid out to implementing grantees following verified milestone proof-of-performance."
size="sm"
placement="top"
/>
</div>
<div className="shrink-0 p-2 rounded-xl bg-teal-500/10 text-teal-400 border border-teal-500/20 group-hover:scale-105 transition-transform">
<TrendingUp className="w-4 h-4" />
</div>
</div>
<div className="mt-3">
<div className="flex items-baseline justify-between gap-2">
<p className="text-2xl sm:text-3xl font-bold text-teal-400 tracking-tight">
{formatCompactZAR(disbursed)}
</p>
<span className="text-xs font-semibold text-teal-400 bg-teal-500/10 px-2 py-0.5 rounded-full border border-teal-500/20 shrink-0 font-mono">
{disbursedPercentage}%
</span>
</div>
<div className="w-full h-1.5 bg-slate-800/90 rounded-full overflow-hidden mt-3">
<div
className="h-full bg-gradient-to-r from-teal-500 to-emerald-400 rounded-full transition-all duration-500"
style={{ width: `${disbursedPercentage}%` }}
/>
</div>
<div className="flex items-center justify-between mt-2.5 pt-2 border-t border-slate-800/70 text-xs text-slate-400">
<span className="text-[11px]">Tranches released</span>
<span className="font-mono text-slate-300 text-[11px]">{disbursedPercentage}% deployed</span>
</div>
</div>
</div>
{/* Card 3: Active Awards */}
<div className="bg-[#0f1523]/80 p-5 rounded-2xl border border-slate-800/80 hover:border-indigo-500/40 transition-all flex flex-col justify-between shadow-md group backdrop-blur-sm relative overflow-hidden">
<div className="flex items-start justify-between gap-3">
<div className="flex items-center gap-1.5 min-w-0 flex-1">
<span className="text-xs font-semibold uppercase tracking-wider text-slate-400 truncate">
Active Awards
</span>
<HelpTooltip
title="Active Grant Awards"
content="Total legally executed statutory agreements currently undergoing active disbursement and implementation."
size="sm"
placement="top"
/>
</div>
<div className="shrink-0 p-2 rounded-xl bg-indigo-500/10 text-indigo-400 border border-indigo-500/20 group-hover:scale-105 transition-transform">
<Layers className="w-4 h-4" />
</div>
</div>
<div className="mt-3">
<p className="text-2xl sm:text-3xl font-bold text-white tracking-tight">
{activeAwards}
</p>
<div className="flex items-center justify-between mt-3 pt-2.5 border-t border-slate-800/70 text-xs">
<span className="text-slate-400 text-[11px]">Under implementation</span>
<span className="font-medium text-indigo-400 bg-indigo-500/10 px-1.5 py-0.5 rounded border border-indigo-500/20 shrink-0 text-[10px]">
{portfolios.length} Portfolio{portfolios.length === 1 ? '' : 's'}
</span>
</div>
</div>
</div>
{/* Card 4: Budget At Risk */}
<div className="bg-[#0f1523]/80 p-5 rounded-2xl border border-slate-800/80 hover:border-rose-500/40 transition-all flex flex-col justify-between shadow-md group backdrop-blur-sm relative overflow-hidden">
<div className="flex items-start justify-between gap-3">
<div className="flex items-center gap-1.5 min-w-0 flex-1">
<span className="text-xs font-semibold uppercase tracking-wider text-slate-400 truncate">
Budget At Risk
</span>
<HelpTooltip
title="Total Budgeted Capital At Risk"
content="Aggregated approved budget across all projects currently flagged as noncompliant or carrying unmitigated high risks."
size="sm"
placement="top"
/>
</div>
<div className="shrink-0 p-2 rounded-xl bg-rose-500/10 text-rose-400 border border-rose-500/20 group-hover:scale-105 transition-transform">
<ShieldAlert className="w-4 h-4" />
</div>
</div>
<div className="mt-3">
<p className="text-2xl sm:text-3xl font-bold text-rose-400 tracking-tight">
{formatCompactZAR(totalBudgetAtRisk)}
</p>
<div className="flex items-center justify-between mt-3 pt-2.5 border-t border-slate-800/70 text-xs">
<span className="text-slate-400 font-mono text-[11px] truncate mr-2" title={formatZAR(totalBudgetAtRisk)}>
{formatZAR(totalBudgetAtRisk)}
</span>
<span className={`text-[10px] font-medium px-1.5 py-0.5 rounded border shrink-0 ${
totalBudgetAtRisk > 0
? 'text-rose-400 bg-rose-500/10 border-rose-500/20'
: 'text-emerald-400 bg-emerald-500/10 border-emerald-500/20'
}`}>
{totalBudgetAtRisk > 0 ? 'Exposed' : 'Clear'}
</span>
</div>
</div>
</div>
</div> </div>
</div> </div>
{/* Card 2: Active Awards */} {/* Tier 2: Operational Health, Risk & Beneficiary Impact */}
<div className="bg-[#0f1523]/80 p-5 rounded-2xl border border-slate-800/80 hover:border-blue-500/30 transition-all flex flex-col justify-between shadow-md group backdrop-blur-sm"> <div className="space-y-3">
<div className="flex items-center justify-between text-slate-400"> <div className="flex items-center justify-between px-1">
<div className="flex items-center gap-1.5"> <div className="flex items-center gap-2">
<span className="text-[11px] font-semibold uppercase tracking-wider text-slate-400">Active Awards</span> <span className="text-[11px] font-bold uppercase tracking-widest text-slate-400">
<HelpTooltip Operational Performance & Impact
title="Active Grant Awards" </span>
content="Total legally executed statutory agreements currently undergoing active disbursement and implementation." <span className="h-1 w-1 rounded-full bg-slate-600" />
size="sm" <span className="text-xs text-slate-500 hidden sm:inline">Milestone pace, compliance gate health & direct beneficiaries</span>
placement="top"
/>
</div>
<div className="p-1.5 rounded-lg bg-indigo-500/10 text-indigo-400 border border-indigo-500/20 group-hover:scale-110 transition">
<Layers className="w-3.5 h-3.5" />
</div> </div>
<span className="text-[10px] font-semibold text-emerald-400/90 bg-emerald-500/10 px-2 py-0.5 rounded-full border border-emerald-500/20">
Delivery Health
</span>
</div> </div>
<div className="mt-3">
<p className="text-2xl font-bold text-white tracking-tight">{activeAwards}</p>
<p className="text-[10px] text-emerald-400 font-mono mt-1">
Across {portfolios.length} portfolio{portfolios.length === 1 ? '' : 's'}
</p>
</div>
</div>
{/* Card 3: Disbursed */} <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
<div className="bg-[#0f1523]/80 p-5 rounded-2xl border border-slate-800/80 hover:border-teal-500/30 transition-all flex flex-col justify-between shadow-md group backdrop-blur-sm"> {/* Card 5: On Track */}
<div className="flex items-center justify-between text-slate-400"> <div className="bg-[#0f1523]/80 p-5 rounded-2xl border border-slate-800/80 hover:border-emerald-500/40 transition-all flex flex-col justify-between shadow-md group backdrop-blur-sm relative overflow-hidden">
<div className="flex items-center gap-1.5"> <div className="flex items-start justify-between gap-3">
<span className="text-[11px] font-semibold uppercase tracking-wider text-slate-400">Disbursed</span> <div className="flex items-center gap-1.5 min-w-0 flex-1">
<HelpTooltip <span className="text-xs font-semibold uppercase tracking-wider text-slate-400 truncate">
title="Disbursed Funds" On Track
content="Actual funds paid out to implementing grantees following verified milestone proof-of-performance." </span>
size="sm" <HelpTooltip
placement="top" title="On-Track Progress Ratio"
/> content="Percentage of active projects meeting schedule deadlines and deliverable acceptance criteria without critical deviations."
size="sm"
placement="top"
/>
</div>
<div className="shrink-0 p-2 rounded-xl bg-emerald-500/10 text-emerald-400 border border-emerald-500/20 group-hover:scale-105 transition-transform">
<CheckCircle className="w-4 h-4" />
</div>
</div>
<div className="mt-3">
<div className="flex items-baseline justify-between gap-2">
<p className="text-2xl sm:text-3xl font-bold text-emerald-400 tracking-tight">
{onTrackPercentage}%
</p>
<span className="text-xs font-semibold text-emerald-400 bg-emerald-500/10 px-2 py-0.5 rounded-full border border-emerald-500/20 shrink-0 font-mono">
{onTrackPercentage >= 80 ? 'Optimal' : onTrackPercentage >= 60 ? 'Moderate' : 'Critical'}
</span>
</div>
<div className="w-full h-1.5 bg-slate-800/90 rounded-full overflow-hidden mt-3">
<div
className="h-full bg-gradient-to-r from-emerald-500 to-teal-400 rounded-full transition-all duration-500"
style={{ width: `${Math.min(100, onTrackPercentage)}%` }}
/>
</div>
<div className="flex items-center justify-between mt-2.5 pt-2 border-t border-slate-800/70 text-xs text-slate-400">
<span className="text-[11px]">Milestones verified</span>
<span className="font-mono text-slate-300 text-[11px]">Pace index</span>
</div>
</div>
</div> </div>
<div className="p-1.5 rounded-lg bg-teal-500/10 text-teal-400 border border-teal-500/20 group-hover:scale-110 transition">
<TrendingUp className="w-3.5 h-3.5" />
</div>
</div>
<div className="mt-3">
<p className="text-2xl font-bold text-teal-400 tracking-tight">{formatCompactZAR(disbursed)}</p>
<p className="text-[10px] text-slate-400 font-mono mt-1">
{portfolioValue > 0 ? `${((disbursed / portfolioValue) * 100).toFixed(1)}% of commitments` : '0.0% of commitments'}
</p>
</div>
</div>
{/* Card 4: On Track */} {/* Card 6: Compliance Health */}
<div className="bg-[#0f1523]/80 p-5 rounded-2xl border border-slate-800/80 hover:border-emerald-500/30 transition-all flex flex-col justify-between shadow-md group backdrop-blur-sm"> <div className="bg-[#0f1523]/80 p-5 rounded-2xl border border-slate-800/80 hover:border-emerald-500/40 transition-all flex flex-col justify-between shadow-md group backdrop-blur-sm relative overflow-hidden">
<div className="flex items-center justify-between text-slate-400"> <div className="flex items-start justify-between gap-3">
<div className="flex items-center gap-1.5"> <div className="flex items-center gap-1.5 min-w-0 flex-1">
<span className="text-[11px] font-semibold uppercase tracking-wider text-slate-400">On Track</span> <span className="text-xs font-semibold uppercase tracking-wider text-slate-400 truncate">
<HelpTooltip Compliance
title="On-Track Progress Ratio" </span>
content="Percentage of active projects meeting schedule deadlines and deliverable acceptance criteria without critical deviations." <HelpTooltip
size="sm" title="Portfolio Compliance Health"
placement="top" content="Percentage of active projects meeting 100% statutory compliance and beneficiary outcome criteria."
/> size="sm"
placement="top"
/>
</div>
<div className="shrink-0 p-2 rounded-xl bg-emerald-500/10 text-emerald-400 border border-emerald-500/20 group-hover:scale-105 transition-transform">
<ShieldCheck className="w-4 h-4" />
</div>
</div>
<div className="mt-3">
<div className="flex items-baseline justify-between gap-2">
<p className="text-2xl sm:text-3xl font-bold text-emerald-400 tracking-tight">
{complianceRate}%
</p>
<span className="text-xs font-semibold text-emerald-400 bg-emerald-500/10 px-2 py-0.5 rounded-full border border-emerald-500/20 shrink-0 font-mono">
{complianceRate >= 90 ? 'Passed' : 'Gated'}
</span>
</div>
<div className="w-full h-1.5 bg-slate-800/90 rounded-full overflow-hidden mt-3">
<div
className="h-full bg-gradient-to-r from-emerald-500 to-cyan-400 rounded-full transition-all duration-500"
style={{ width: `${Math.min(100, complianceRate)}%` }}
/>
</div>
<div className="flex items-center justify-between mt-2.5 pt-2 border-t border-slate-800/70 text-xs text-slate-400">
<span className="text-[11px]">Statutory gate check</span>
<span className="font-mono text-slate-300 text-[11px]">100% requirement</span>
</div>
</div>
</div> </div>
<div className="p-1.5 rounded-lg bg-emerald-500/10 text-emerald-400 border border-emerald-500/20 group-hover:scale-110 transition">
<CheckCircle className="w-3.5 h-3.5" />
</div>
</div>
<div className="mt-3">
<p className="text-2xl font-bold text-emerald-400 tracking-tight">{onTrackPercentage}%</p>
<p className="text-[10px] text-slate-400 font-mono mt-1">Milestones verified</p>
</div>
</div>
{/* Card 5: At Risk */} {/* Card 7: At Risk */}
<div className="bg-[#0f1523]/80 p-5 rounded-2xl border border-slate-800/80 hover:border-amber-500/30 transition-all flex flex-col justify-between shadow-md group backdrop-blur-sm"> <div className="bg-[#0f1523]/80 p-5 rounded-2xl border border-slate-800/80 hover:border-amber-500/40 transition-all flex flex-col justify-between shadow-md group backdrop-blur-sm relative overflow-hidden">
<div className="flex items-center justify-between text-slate-400"> <div className="flex items-start justify-between gap-3">
<div className="flex items-center gap-1.5"> <div className="flex items-center gap-1.5 min-w-0 flex-1">
<span className="text-[11px] font-semibold uppercase tracking-wider text-slate-400">At Risk</span> <span className="text-xs font-semibold uppercase tracking-wider text-slate-400 truncate">
<HelpTooltip At Risk
title="At-Risk Projects" </span>
content="Count of projects with high residual risk scores (≥12), schedule slippage >30 days, or adverse financial variance." <HelpTooltip
size="sm" title="At-Risk Projects"
placement="top" content="Count of projects with high residual risk scores (≥12), schedule slippage >30 days, or adverse financial variance."
/> size="sm"
placement="top"
/>
</div>
<div className="shrink-0 p-2 rounded-xl bg-amber-500/10 text-amber-400 border border-amber-500/20 group-hover:scale-105 transition-transform">
<AlertTriangle className="w-4 h-4" />
</div>
</div>
<div className="mt-3">
<p className="text-2xl sm:text-3xl font-bold text-amber-400 tracking-tight">
{atRiskCount}
</p>
<div className="flex items-center justify-between mt-3 pt-2.5 border-t border-slate-800/70 text-xs">
<span className="text-slate-400 text-[11px]">{atRiskCount === 1 ? 'Project flagged' : 'Projects flagged'}</span>
<span className={`text-[10px] font-medium px-1.5 py-0.5 rounded border shrink-0 ${
atRiskCount > 0
? 'text-amber-400 bg-amber-500/10 border-amber-500/20'
: 'text-emerald-400 bg-emerald-500/10 border-emerald-500/20'
}`}>
{atRiskCount > 0 ? 'Requires PM Action' : 'Nominal'}
</span>
</div>
</div>
</div> </div>
<div className="p-1.5 rounded-lg bg-amber-500/10 text-amber-400 border border-amber-500/20 group-hover:scale-110 transition">
<AlertTriangle className="w-3.5 h-3.5" />
</div>
</div>
<div className="mt-3">
<p className="text-2xl font-bold text-amber-400 tracking-tight">{atRiskCount}</p>
<p className="text-[10px] text-rose-400 font-mono mt-1">Requires PM action</p>
</div>
</div>
{/* Card 6: Beneficiaries Reached */} {/* Card 8: Beneficiaries Reached */}
<div className="bg-[#0f1523]/80 p-5 rounded-2xl border border-slate-800/80 hover:border-indigo-500/30 transition-all flex flex-col justify-between shadow-md group backdrop-blur-sm"> <div className="bg-[#0f1523]/80 p-5 rounded-2xl border border-slate-800/80 hover:border-purple-500/40 transition-all flex flex-col justify-between shadow-md group backdrop-blur-sm relative overflow-hidden">
<div className="flex items-center justify-between text-slate-400"> <div className="flex items-start justify-between gap-3">
<div className="flex items-center gap-1.5"> <div className="flex items-center gap-1.5 min-w-0 flex-1">
<span className="text-[11px] font-semibold uppercase tracking-wider text-slate-400">Beneficiaries</span> <span className="text-xs font-semibold uppercase tracking-wider text-slate-400 truncate">
<HelpTooltip Beneficiaries
title="Beneficiaries Impacted" </span>
content="Cumulative count of direct beneficiaries reached through projects, verified against national M&E indicator targets." <HelpTooltip
size="sm" title="Beneficiaries Impacted"
placement="top" content="Cumulative count of direct beneficiaries reached through projects, verified against national M&E indicator targets."
/> size="sm"
placement="top"
/>
</div>
<div className="shrink-0 p-2 rounded-xl bg-purple-500/10 text-purple-400 border border-purple-500/20 group-hover:scale-105 transition-transform">
<Users className="w-4 h-4" />
</div>
</div>
<div className="mt-3">
<p className="text-2xl sm:text-3xl font-bold text-white tracking-tight">
{beneficiariesReached >= 1000 ? `${(beneficiariesReached / 1000).toFixed(1)}k` : beneficiariesReached}
</p>
<div className="flex items-center justify-between mt-3 pt-2.5 border-t border-slate-800/70 text-xs">
<span className="text-slate-400 text-[11px]">Directly impacted</span>
<span className="text-[10px] font-medium text-purple-400 bg-purple-500/10 px-1.5 py-0.5 rounded border border-purple-500/20 shrink-0">
M&E Verified
</span>
</div>
</div>
</div> </div>
<div className="p-1.5 rounded-lg bg-indigo-500/10 text-indigo-400 border border-indigo-500/20 group-hover:scale-110 transition">
<Users className="w-3.5 h-3.5" />
</div>
</div>
<div className="mt-3">
<p className="text-2xl font-bold text-white tracking-tight">
{beneficiariesReached >= 1000 ? `${(beneficiariesReached / 1000).toFixed(0)}k` : beneficiariesReached}
</p>
<p className="text-[10px] text-slate-400 font-mono mt-1">Directly impacted</p>
</div>
</div>
{/* Card 7: Budget At Risk */}
<div className="bg-[#0f1523]/80 p-5 rounded-2xl border border-slate-800/80 hover:border-rose-500/40 transition-all flex flex-col justify-between shadow-md group backdrop-blur-sm">
<div className="flex items-center justify-between text-slate-400">
<div className="flex items-center gap-1.5">
<span className="text-[11px] font-semibold uppercase tracking-wider text-slate-400">Budget At Risk</span>
<HelpTooltip
title="Total Budgeted Capital At Risk"
content="Aggregated approved budget across all projects currently flagged as noncompliant or carrying unmitigated high risks."
size="sm"
placement="top"
/>
</div>
<div className="p-1.5 rounded-lg bg-rose-500/10 text-rose-400 border border-rose-500/20 group-hover:scale-110 transition">
<AlertTriangle className="w-3.5 h-3.5" />
</div>
</div>
<div className="mt-3">
<p className="text-2xl font-bold text-rose-400 tracking-tight">{formatCompactZAR(totalBudgetAtRisk)}</p>
<p className="text-[10px] text-slate-400 font-mono mt-1">{formatZAR(totalBudgetAtRisk)}</p>
</div>
</div>
{/* Card 8: Compliance Health */}
<div className="bg-[#0f1523]/80 p-5 rounded-2xl border border-slate-800/80 hover:border-emerald-500/40 transition-all flex flex-col justify-between shadow-md group backdrop-blur-sm">
<div className="flex items-center justify-between text-slate-400">
<div className="flex items-center gap-1.5">
<span className="text-[11px] font-semibold uppercase tracking-wider text-slate-400">Compliance</span>
<HelpTooltip
title="Portfolio Compliance Health"
content="Percentage of active projects meeting 100% statutory compliance and beneficiary outcome criteria."
size="sm"
placement="top"
/>
</div>
<div className="p-1.5 rounded-lg bg-emerald-500/10 text-emerald-400 border border-emerald-500/20 group-hover:scale-110 transition">
<ShieldCheck className="w-3.5 h-3.5" />
</div>
</div>
<div className="mt-3">
<p className="text-2xl font-bold text-emerald-400 tracking-tight">{complianceRate}%</p>
<p className="text-[10px] text-slate-400 font-mono mt-1">100% statutory gate</p>
</div> </div>
</div> </div>
</div> </div>