import React, { useEffect, useState } from "react";
import { NavLink } from "react-router-dom";
import { Menu, Sparkles, X } from "lucide-react";
import { AnimatePresence, motion } from "framer-motion";
import { NAV_ITEMS } from "../../constants/navigation";
export const SIDEBAR_EXPANDED = 260;
export const SIDEBAR_COLLAPSED = 72;
const TRANSITION = { duration: 0.3, ease: [0.4, 0, 0.2, 1] };
const LABEL_TRANSITION = { duration: 0.18, ease: [0.4, 0, 0.2, 1] };
// ── Tooltip ──────────────────────────────────────────────────────────────────
function Tooltip({ label, visible }) {
return (
{visible && (
{label}
)}
);
}
// ── Nav Item ─────────────────────────────────────────────────────────────────
function NavItem({ item, collapsed, onClose }) {
const [hovered, setHovered] = useState(false);
const Icon = item.icon;
return (
setHovered(true)}
onMouseLeave={() => setHovered(false)}
>
({
display: "flex",
alignItems: "center",
gap: 10,
height: 40,
padding: collapsed ? "0" : "0 12px",
justifyContent: collapsed ? "center" : "flex-start",
margin: "1px 8px",
borderRadius: "var(--radius-md)",
background: isActive
? "linear-gradient(135deg, rgba(0,201,167,0.14) 0%, rgba(0,201,167,0.06) 100%)"
: hovered
? "rgba(255,255,255,0.04)"
: "transparent",
color: isActive ? "var(--color-teal)" : hovered ? "var(--text-primary)" : "var(--text-muted)",
textDecoration: "none",
cursor: "pointer",
transition: "background 0.15s ease, color 0.15s ease",
whiteSpace: "nowrap",
overflow: "hidden",
position: "relative",
border: isActive ? "1px solid rgba(0,201,167,0.18)" : "1px solid transparent",
boxShadow: isActive ? "0 0 12px rgba(0,201,167,0.08)" : "none",
})}
>
{({ isActive }) => (
<>
{/* Left active bar */}
{isActive && (
)}
{/* Label */}
{!collapsed && (
{item.label}
)}
{/* AI badge */}
{!collapsed && item.ai && (
AI
)}
>
)}
{/* Tooltip — collapsed only */}
{collapsed &&
}
);
}
// ── Sidebar ───────────────────────────────────────────────────────────────────
export function Sidebar({ collapsed, onToggle, isMobile, mobileOpen, onMobileClose }) {
const [aiHovered, setAiHovered] = useState(false);
// Mobile: close on Escape
useEffect(() => {
if (!isMobile) return;
const handler = (e) => { if (e.key === "Escape") onMobileClose?.(); };
window.addEventListener("keydown", handler);
return () => window.removeEventListener("keydown", handler);
}, [isMobile, onMobileClose]);
const sidebarContent = (
{/* ── Header ── */}
{!collapsed && (
TradeMind
AI FINTECH · NSE INDIA
)}
{/* Toggle button */}
{isMobile ? (
) : (
)}
{/* ── Nav ── */}
{/* ── AI Status bottom ── */}
{collapsed ? (
/* Collapsed: glowing dot */
setAiHovered(true)}
onMouseLeave={() => setAiHovered(false)}
style={{ position: "relative", display: "flex", justifyContent: "center", padding: "8px 0" }}
>
) : (
TRADEMIND AI
Models: RF · LSTM · FinBERT
)}
);
// ── Mobile: overlay drawer ──
if (isMobile) {
return (
{mobileOpen && (
<>
{/* Backdrop */}
{/* Drawer */}
{sidebarContent}
>
)}
);
}
// ── Desktop: fixed rail ──
return (
{sidebarContent}
);
}
// ── Shared button style ───────────────────────────────────────────────────────
const btnStyle = {
background: "transparent",
border: "1px solid var(--border)",
borderRadius: "var(--radius-md)",
padding: "6px 7px",
color: "var(--text-muted)",
cursor: "pointer",
display: "flex",
alignItems: "center",
justifyContent: "center",
flexShrink: 0,
transition: "border-color 0.15s ease, color 0.15s ease",
};