diff --git a/src/app/(dashboard)/dashboard-shell.tsx b/src/app/(dashboard)/dashboard-shell.tsx index 24a4afb..68c4d51 100644 --- a/src/app/(dashboard)/dashboard-shell.tsx +++ b/src/app/(dashboard)/dashboard-shell.tsx @@ -1,6 +1,6 @@ "use client"; -import { useCallback, useEffect, useState } from "react"; +import { useEffect } from "react"; import { useRouter } from "next/navigation"; import { AuthProvider, useAuth } from "@/hooks/use-auth"; import { Sidebar } from "@/components/layout/sidebar"; @@ -14,11 +14,6 @@ function DashboardShellInner({ children }: { children: React.ReactNode }) { const { user, loading } = useAuth(); const router = useRouter(); - // Sidebar drawer state — only used on mobile. On lg+ the sidebar is - // always visible and this stays at `false` (ignored by the component). - const [sidebarOpen, setSidebarOpen] = useState(false); - const closeSidebar = useCallback(() => setSidebarOpen(false), []); - useEffect(() => { if (!loading && !user) { router.push("/login"); @@ -40,11 +35,10 @@ function DashboardShellInner({ children }: { children: React.ReactNode }) { return (
- +
-
setSidebarOpen(true)} /> - {/* Thinner horizontal padding on mobile so cards have room to breathe. */} -
{children}
+
+
{children}
); diff --git a/src/components/layout/header.tsx b/src/components/layout/header.tsx index 3030b86..ab2038e 100644 --- a/src/components/layout/header.tsx +++ b/src/components/layout/header.tsx @@ -2,7 +2,7 @@ import { usePathname } from "next/navigation"; import { useAuth } from "@/hooks/use-auth"; -import { LogOut, Menu } from "lucide-react"; +import { LogOut } from "lucide-react"; const pageTitles: Record = { "/dashboard": "Dashboard", @@ -16,42 +16,24 @@ const pageTitles: Record = { function getPageTitle(pathname: string): string { if (pageTitles[pathname]) return pageTitles[pathname]; + const match = Object.entries(pageTitles).find(([path]) => - pathname.startsWith(path), + pathname.startsWith(path) ); return match ? match[1] : "Dashboard"; } -interface HeaderProps { - /** Wired to the shell's drawer state. Used only on mobile — the - * hamburger button is hidden on lg+. */ - onOpenSidebar?: () => void; -} - -export function Header({ onOpenSidebar }: HeaderProps) { +export function Header() { const pathname = usePathname(); const { profile, signOut } = useAuth(); const title = getPageTitle(pathname); return ( -
-
- {/* Hamburger — mobile only. 44×44 hit target per Apple HIG. */} - -

- {title} -

-
+
+

{title}

-
-
+
+
{profile?.full_name?.charAt(0)?.toUpperCase() ?? "U"}
@@ -63,9 +45,8 @@ export function Header({ onOpenSidebar }: HeaderProps) {
diff --git a/src/components/layout/sidebar.tsx b/src/components/layout/sidebar.tsx index f01d2cb..bf058ff 100644 --- a/src/components/layout/sidebar.tsx +++ b/src/components/layout/sidebar.tsx @@ -2,7 +2,6 @@ import Link from "next/link"; import { usePathname } from "next/navigation"; -import { useEffect } from "react"; import { cn } from "@/lib/utils"; import { useAuth } from "@/hooks/use-auth"; import { useTotalUnread } from "@/hooks/use-total-unread"; @@ -15,7 +14,6 @@ import { Zap, Settings, LogOut, - X, } from "lucide-react"; const navItems = [ @@ -31,177 +29,115 @@ const bottomNavItems = [ { href: "/settings", label: "Settings", icon: Settings }, ]; -interface SidebarProps { - /** Controlled on mobile by the Header's hamburger button. Ignored on lg+. */ - open?: boolean; - onClose?: () => void; -} - -export function Sidebar({ open = false, onClose }: SidebarProps) { +export function Sidebar() { const pathname = usePathname(); const { profile, signOut } = useAuth(); const totalUnread = useTotalUnread(); - // Close the drawer when route changes — users opened it to navigate, - // so once they pick a destination the drawer should get out of the way. - useEffect(() => { - onClose?.(); - // Only pathname drives this — onClose identity doesn't need to re-run it. - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [pathname]); - - // Lock body scroll and allow Escape to close while the drawer is open on - // mobile. No-ops on desktop because the sidebar isn't positioned there. - useEffect(() => { - if (!open) return; - const prev = document.body.style.overflow; - document.body.style.overflow = "hidden"; - const onKey = (e: KeyboardEvent) => { - if (e.key === "Escape") onClose?.(); - }; - window.addEventListener("keydown", onKey); - return () => { - document.body.style.overflow = prev; - window.removeEventListener("keydown", onKey); - }; - }, [open, onClose]); - return ( - <> - {/* Backdrop — only exists on mobile and only when open. Clicking - it closes the drawer. Hidden from lg+ since the sidebar is - part of the main flex row there. */} -
- - {/* Main navigation */} - - - {/* User section */} -
-
-
- {profile?.full_name?.charAt(0)?.toUpperCase() ?? "U"} -
-
-

- {profile?.full_name ?? "User"} -

-

- {profile?.email ?? ""} -

-
- -
-
- - +
+ ); }