File size: 5,199 Bytes
2c5651e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | import React from "react";
import {
Briefcase,
PlusCircle,
FileText,
Files,
Users,
Sliders,
Shield,
CheckCircle,
Calendar,
Sparkles,
Award,
GitCompare,
Download,
History,
Activity,
Cpu,
} from "lucide-react";
export type NavTabId =
| "drives"
| "create_drive"
| "announcements"
| "students"
| "rule_editor"
| "policies"
| "policy_simulator"
| "eligibility"
| "schedule"
| "what_if"
| "results"
| "dispute"
| "export"
| "audit"
| "offline_audit";
interface NavigationProps {
activeTab: NavTabId;
onSelectTab: (tab: NavTabId) => void;
userRole?: string;
}
interface NavGroup {
name: string;
tabs: Array<{
id: NavTabId;
label: string;
icon: React.ComponentType<{ className?: string }>;
badge?: string;
}>;
}
export const Navigation: React.FC<NavigationProps> = ({
activeTab,
onSelectTab,
userRole = "officer",
}) => {
const navGroups: NavGroup[] = [
{
name: "Setup & Roster",
tabs: [
{ id: "drives", label: "Drives", icon: Briefcase },
{ id: "create_drive", label: "New Drive", icon: PlusCircle, badge: "Create" },
{ id: "announcements", label: "25 Announcements", icon: Files, badge: "25 Docs" },
{ id: "students", label: "Students & Importer", icon: Users },
],
},
{
name: "Rules & Policy",
tabs: [
{ id: "rule_editor", label: "Rule Editor", icon: Sliders },
{ id: "policies", label: "Offer Policies", icon: Shield },
{ id: "policy_simulator", label: "Policy Simulator", icon: Cpu, badge: "New" },
],
},
{
name: "Execution",
tabs: [
{ id: "eligibility", label: "Eligibility Runs", icon: CheckCircle },
{ id: "schedule", label: "Schedule Grid", icon: Calendar, badge: "0 Clashes" },
{ id: "what_if", label: "What-If & Publish", icon: Sparkles },
{ id: "results", label: "Result Entry", icon: Award },
],
},
{
name: "Governance",
tabs: [
{ id: "dispute", label: "Dispute Explainer", icon: GitCompare },
{ id: "export", label: "Company Export", icon: Download },
{ id: "audit", label: "Event Replay", icon: History },
{ id: "offline_audit", label: "Offline Audit", icon: Activity },
],
},
];
return (
<nav className="bg-[#080e1c]/95 backdrop-blur-md border-b border-[#1b2b4d] sticky top-[73px] z-20 shadow-sm no-print">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-2">
<div className="flex items-center gap-4 overflow-x-auto no-scrollbar py-0.5">
{navGroups.map((group, groupIdx) => (
<React.Fragment key={group.name}>
{groupIdx > 0 && (
<div className="h-6 w-px bg-[#1b2b4d] shrink-0 mx-1" aria-hidden="true" />
)}
<div className="flex items-center gap-1 shrink-0">
<span className="text-[10px] uppercase font-black tracking-wider text-slate-500 mr-1 hidden xl:inline">
{group.name}
</span>
{group.tabs.map((tab) => {
const Icon = tab.icon;
const isActive = activeTab === tab.id;
return (
<button
key={tab.id}
type="button"
onClick={() => onSelectTab(tab.id)}
className={`flex items-center gap-1.5 px-3 py-1.5 rounded-xl text-xs font-bold whitespace-nowrap transition-all duration-150 cursor-pointer ${
isActive
? "bg-gradient-to-r from-blue-700 via-teal-600 to-emerald-600 text-white shadow-md shadow-emerald-900/40 ring-1 ring-emerald-400/40 scale-[1.02]"
: "text-slate-300 hover:text-white hover:bg-[#111d38]"
}`}
>
<Icon className={`w-3.5 h-3.5 ${isActive ? "text-white" : "text-slate-400"}`} />
<span>{tab.label}</span>
{tab.badge && (
<span
className={`text-[9px] px-1.5 py-0.2 rounded-full font-black uppercase tracking-wider ${
isActive
? "bg-white/20 text-white"
: tab.badge === "0 Clashes"
? "bg-emerald-950/80 text-emerald-300 border border-emerald-800/60"
: tab.badge === "New"
? "bg-blue-950/80 text-blue-300 border border-blue-800/60"
: "bg-[#111d38] text-slate-300 border border-[#1b2b4d]"
}`}
>
{tab.badge}
</span>
)}
</button>
);
})}
</div>
</React.Fragment>
))}
</div>
</div>
</nav>
);
};
|