diff --git a/src/App.tsx b/src/App.tsx index bf8ffff..8559fa8 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,4 +1,5 @@ import { createBrowserRouter, RouterProvider, Navigate, Outlet } from "react-router-dom" +import { useState } from "react" import { ThemeProvider } from "./components/ThemeProvider" import { LanguageProvider } from "./components/LanguageProvider" import { Toaster } from "./components/ui/toaster" @@ -21,12 +22,17 @@ import Tags from "./pages/Tags" import Timesheet from "./pages/Timesheet" const MainLayout = () => { + const [mobileSidebarOpen, setMobileSidebarOpen] = useState(false) + return (
- + setMobileSidebarOpen(false)} + />
- + setMobileSidebarOpen(true)} />
diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index 46df4f4..1e6b0f5 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -3,14 +3,18 @@ import { useNavigate } from "react-router-dom" import { useTranslation } from "../hooks/useTranslation" import { Button } from "./ui/button" import { SettingsMenu } from "./SettingsMenu" -import { LogOut, User, Moon, Sun, Globe, Command } from "lucide-react" +import { LogOut, User, Moon, Sun, Globe, Command, Menu } from "lucide-react" import { logoutUser, getUserProfile } from "../api/users" import { WorkspaceSelector } from "./WorkspaceSelector" import { toast } from "sonner" import { NotificationBell } from "./notifications/NotificationBell" import { clearSessionTokens, getAccessToken, getRefreshToken } from "../lib/session" -export function Navbar() { +type NavbarProps = { + onOpenSidebar?: () => void +} + +export function Navbar({ onOpenSidebar }: NavbarProps) { const { t, lang, setLanguage } = useTranslation() const navigate = useNavigate() const [showLogoutModal, setShowLogoutModal] = useState(false) @@ -106,12 +110,22 @@ export function Navbar() { return ( <>
-
navigate("/")}> +
+ +
navigate("/")}> {t.title || "Qlockify"}
+
{user && } diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx index 743892a..88afb63 100644 --- a/src/components/Sidebar.tsx +++ b/src/components/Sidebar.tsx @@ -1,8 +1,9 @@ -import { useState } from 'react'; -import { NavLink } from 'react-router-dom'; +import { useState } from 'react'; +import { NavLink } from 'react-router-dom'; import { Users, LayoutDashboard, + X, PanelLeftClose, PanelLeftOpen, PanelRightClose, @@ -11,12 +12,17 @@ import { Clock3, Tags, } from 'lucide-react'; -import { useTranslation } from '../hooks/useTranslation'; - -export const Sidebar = () => { - const [isCollapsed, setIsCollapsed] = useState(false); - - const { t, lang } = useTranslation(); +import { useTranslation } from '../hooks/useTranslation'; + +type SidebarProps = { + mobileOpen?: boolean; + onMobileClose?: () => void; +}; + +export const Sidebar = ({ mobileOpen = false, onMobileClose }: SidebarProps) => { + const [isCollapsed, setIsCollapsed] = useState(false); + + const { t, lang } = useTranslation(); const isRtl = lang === 'fa'; const ToggleIcon = isRtl @@ -49,57 +55,112 @@ export const Sidebar = () => { icon: Briefcase, label: t.sidebar?.projects || 'Projects' }, - ]; - - return ( - - ); -}; + ]; + + 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} + )} + + ); + }); + + return ( + <> + + +
+ +
+ + +
+ + ); +};