LeadPilot / frontend /src /components /Sidebar.tsx
Ashraf Al-Kassem
Fix dark mode UI elements across dashboard
c0d36bc
raw
history blame
4.48 kB
"use client";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { useEffect, useState } from "react";
import {
LayoutDashboard,
Users,
Zap,
Sparkles,
Plug,
FileText,
Settings,
ShieldCheck,
MessageSquare,
LogOut,
SendHorizontal,
Inbox,
Landmark,
LayoutTemplate,
} from "lucide-react";
import { cn } from "@/lib/utils";
import { apiClient } from "@/lib/api";
const navItems = [
{ name: "Dashboard", href: "/dashboard", icon: LayoutDashboard },
{ name: "Inbox", href: "/inbox", icon: Inbox },
{ name: "Contacts", href: "/contacts", icon: Users },
{ name: "Automations", href: "/automations", icon: Zap },
{ name: "Templates", href: "/templates", icon: LayoutTemplate },
{ name: "Outbound Queue", href: "/dispatch", icon: SendHorizontal },
{ name: "Prompt Studio", href: "/prompt-studio", icon: Sparkles },
{ name: "Test Chat", href: "/test-chat", icon: MessageSquare },
{ name: "Integrations", href: "/integrations", icon: Plug },
{ name: "Logs", href: "/logs", icon: FileText },
{ name: "Settings", href: "/settings", icon: Settings },
{ name: "Team", href: "/team", icon: ShieldCheck },
{ name: "Agency", href: "/agency", icon: Landmark },
];
function getInitials(name: string | null): string {
if (!name) return "?";
const parts = name.trim().split(/\s+/);
if (parts.length >= 2) return (parts[0][0] + parts[1][0]).toUpperCase();
return parts[0].substring(0, 2).toUpperCase();
}
export function Sidebar() {
const pathname = usePathname();
const [userName, setUserName] = useState<string | null>(null);
useEffect(() => {
apiClient.get("/auth/me").then((res) => {
if (res.success && res.data) {
setUserName(res.data.full_name || res.data.email);
}
});
}, []);
const handleLogout = () => {
const { auth } = require("@/lib/auth");
auth.logout();
};
return (
<div className="fixed inset-y-0 left-0 w-64 bg-white dark:bg-card border-r border-border flex flex-col transition-colors">
<div className="h-16 flex items-center px-6 border-bottom border-border">
<span className="text-primary dark:text-teal-400 font-bold text-xl tracking-tight transition-colors">LeadPilot</span>
</div>
<nav className="flex-1 px-4 py-4 space-y-1 overflow-y-auto">
{navItems.map((item) => {
const isActive = pathname.startsWith(item.href);
return (
<Link
key={item.href}
href={item.href}
className={cn(
"flex items-center gap-3 px-3 py-2 rounded-md transition-colors text-sm font-medium",
isActive
? "bg-primary/10 dark:bg-primary/20 text-primary dark:text-teal-400"
: "text-foreground dark:text-slate-400 hover:bg-background dark:hover:bg-slate-800/50 hover:text-primary dark:hover:text-teal-400"
)}
>
<item.icon className="w-4 h-4" />
{item.name}
</Link>
);
})}
</nav>
<div className="p-4 border-t border-border">
<div className="flex items-center gap-3 px-3 py-2">
<div className="w-8 h-8 rounded-full bg-slate-200 dark:bg-slate-800 flex items-center justify-center text-slate-600 dark:text-slate-300 text-xs font-bold transition-colors">
{getInitials(userName)}
</div>
<div className="flex-1 min-w-0">
<p className="text-xs font-semibold truncate">{userName || "Loading..."}</p>
</div>
<button
onClick={handleLogout}
className="p-1.5 rounded-md text-slate-400 hover:text-red-600 hover:bg-red-50 dark:hover:bg-red-900/30 dark:hover:text-red-400 transition-colors"
title="Log out"
>
<LogOut className="w-4 h-4" />
</button>
</div>
</div>
</div>
);
}