import { useEffect, useState } from "react" import { NavLink, useNavigate } from "react-router-dom" import { Users, LayoutDashboard, X, PanelLeftClose, PanelLeftOpen, PanelRightClose, PanelRightOpen, Briefcase, ChartColumn, Clock3, History, Tags, User, Globe, LogOut, LogIn, } from "lucide-react" import { toast } from "sonner" import { useOptionalWorkspace } from "../context/WorkspaceContext" import { useTranslation } from "../hooks/useTranslation" import { canWorkspace, WORKSPACE_LOGS_VIEW } from "../lib/permissions" import { WorkspaceSelector } from "./WorkspaceSelector" import { SettingsMenu } from "./SettingsMenu" import { Button } from "./ui/button" import { getUserProfile, logoutUser } from "../api/users" import { clearSessionTokens, getAccessToken, getRefreshToken } from "../lib/session" type SidebarProps = { mobileOpen?: boolean onMobileClose?: () => void } export const Sidebar = ({ mobileOpen = false, onMobileClose }: SidebarProps) => { const [isCollapsed, setIsCollapsed] = useState(false) const [showLogoutModal, setShowLogoutModal] = useState(false) const [user, setUser] = useState(null) const navigate = useNavigate() const { t, lang, setLanguage } = useTranslation() const workspaceContext = useOptionalWorkspace() const activeWorkspace = workspaceContext?.activeWorkspace ?? null const isRtl = lang === "fa" const canViewLogs = canWorkspace(activeWorkspace?.my_role, WORKSPACE_LOGS_VIEW) const ToggleIcon = isRtl ? isCollapsed ? PanelRightOpen : PanelRightClose : isCollapsed ? PanelLeftOpen : PanelLeftClose useEffect(() => { const handleProfileUpdated = ((e: CustomEvent) => { if (e.detail) { setUser((prev: any) => (prev ? { ...prev, ...e.detail } : e.detail)) } }) as EventListener window.addEventListener("profile_updated", handleProfileUpdated) return () => window.removeEventListener("profile_updated", handleProfileUpdated) }, []) useEffect(() => { const fetchUser = async () => { const token = getAccessToken() if (!token) return try { const userData = await getUserProfile() setUser(userData) } catch (error) { console.error("Failed to fetch user profile:", error) } } void fetchUser() }, []) const handleLogout = async () => { try { const refreshToken = getRefreshToken() if (refreshToken) { await logoutUser(refreshToken) } } catch (error) { console.error("Logout API failed:", error) } finally { clearSessionTokens() setUser(null) setShowLogoutModal(false) onMobileClose?.() toast.success(t.logoutToast || "Successfully logged out!") navigate("/auth") } } const toggleLanguage = () => { const newLang = isRtl ? "en" : "fa" if (setLanguage) { setLanguage(newLang) } else { localStorage.setItem("language", newLang) window.location.reload() } } const navItems = [ { path: "/timesheet", icon: Clock3, label: t.sidebar?.timesheet || "Timesheet", }, { path: "/tags", icon: Tags, label: t.sidebar?.tags || "Tags", }, { path: "/clients", icon: Users, label: t.sidebar?.clients || "Clients", }, { path: "/projects", icon: Briefcase, label: t.sidebar?.projects || "Projects", }, { path: "/workspaces", icon: LayoutDashboard, label: t.sidebar?.workspaces || "Workspaces", }, { path: "/reports", icon: ChartColumn, label: t.sidebar?.reports || "Reports", }, ...(canViewLogs ? [ { path: "/logs", icon: History, label: t.sidebar?.logs || "Logs", }, ] : []), ] const renderNavItems = (mobile = false) => navItems.map((item) => { const Icon = item.icon return ( { if (mobile) onMobileClose?.() }} className={({ isActive }) => `flex items-center rounded-lg text-sm font-medium transition-colors ${ mobile ? "gap-3 px-4 py-3" : isCollapsed ? "justify-center px-0 py-2.5" : "gap-3 px-3 py-2.5" } ${ isActive ? "bg-blue-50 text-blue-600 dark:bg-blue-500/10 dark:text-blue-400" : "text-slate-600 hover:bg-slate-100 dark:text-slate-400 dark:hover:bg-slate-900/50" }` } > {(mobile || !isCollapsed) && ( {item.label} )} ) }) const renderMobileTopSection = () => { if (!user) { return null } return (
) } const renderMobileFooterSection = () => { if (!user) { return (
) } return (
) } return ( <> {/* Desktop sidebar */} {/* Mobile sidebar */}
{renderMobileTopSection()}
{renderMobileFooterSection()}
{showLogoutModal && (
setShowLogoutModal(false)} >
e.stopPropagation()} >

{t.confirmLogoutTitle || "Confirm Logout"}

{t.confirmLogoutMessage || "Are you sure you want to log out of your account?"}

)} ) }