| "use client"; |
| import { translations, Language } from "../lib/translations"; |
|
|
| import type { Dispatch, SetStateAction } from "react"; |
|
|
| type SidebarTab = |
| | "Dashboard" |
| | "Tender Search" |
| | "My Portfolio" |
| | "Company Profile" |
| | "Agent Analysis" |
| | "Proposal Draft" |
| | "Reports" |
| | "History" |
| | "About"; |
|
|
| type Props = { |
| tabs: readonly SidebarTab[]; |
| activeTab: SidebarTab; |
| onTabSelect: Dispatch<SetStateAction<SidebarTab>>; |
| status: string; |
| lang: Language; |
| }; |
|
|
| export default function Sidebar({ tabs, activeTab, onTabSelect, status, lang }: Props) { |
| const t = translations[lang]; |
| |
| const getTabLabel = (tab: SidebarTab) => { |
| switch(tab) { |
| case "Dashboard": return t.dashboard; |
| case "Tender Search": return t.tenderSearch; |
| case "My Portfolio": return t.myPortfolio; |
| case "Company Profile": return t.companyProfile; |
| case "Agent Analysis": return t.agentAnalysis; |
| case "Proposal Draft": return t.proposalDraft; |
| case "Reports": return t.reports; |
| case "History": return t.history; |
| case "About": return t.about; |
| default: return tab; |
| } |
| }; |
| return ( |
| <aside className="w-72 glass-card rounded-3xl h-[calc(100vh-3rem)] sticky top-6 p-6 flex flex-col gap-8"> |
| <div className="flex items-center gap-3 px-2"> |
| <div className="w-10 h-10 premium-gradient rounded-xl flex items-center justify-center shadow-lg shadow-purple-500/20"> |
| <span className="text-white font-bold text-xl">A</span> |
| </div> |
| <h1 className="text-xl font-bold tracking-tight text-white">AndesOps AI</h1> |
| </div> |
| |
| <nav className="flex-1 flex flex-col gap-2"> |
| {tabs.map((tab) => { |
| const isActive = activeTab === tab; |
| const tabSlug = tab.toLowerCase().replace(/ /g, "_"); |
| |
| return ( |
| <button |
| key={tab} |
| onClick={() => { |
| onTabSelect(tab); |
| window.history.pushState({}, '', `?tab=${tabSlug}`); |
| }} |
| className={`flex items-center gap-3 px-4 py-3 rounded-xl transition-all duration-200 group ${ |
| isActive |
| ? "bg-white/10 text-white shadow-inner" |
| : "text-slate-400 hover:bg-white/5 hover:text-white" |
| }`} |
| > |
| <div className={`w-1.5 h-1.5 rounded-full transition-all duration-300 ${ |
| isActive ? "bg-purple-500 scale-125 shadow-[0_0_8px_rgba(168,85,247,0.8)]" : "bg-transparent group-hover:bg-slate-600" |
| }`} /> |
| <span className="font-medium text-sm">{getTabLabel(tab)}</span> |
| </button> |
| ); |
| })} |
| </nav> |
| |
| <div className="mt-auto pt-6 border-t border-white/5"> |
| <div className="px-4 py-3 rounded-xl bg-gradient-to-br from-indigo-500/10 to-purple-500/10 border border-indigo-500/20"> |
| <p className="text-[10px] uppercase tracking-widest text-indigo-300 font-bold mb-1">Status</p> |
| <div className="flex items-center gap-2"> |
| <div className={`w-2 h-2 rounded-full ${status === "connected" ? "bg-green-500 animate-pulse" : "bg-yellow-500"}`} /> |
| <span className={`text-xs font-medium ${status === "connected" ? "text-green-300" : "text-yellow-300"}`}> |
| {status === "connected" ? "Systems Nominal" : "Connecting..."} |
| </span> |
| </div> |
| </div> |
| </div> |
| </aside> |
| ); |
| } |
|
|