COURTRIX / src /components /dashboard /dashboard-shell.tsx
Ali-Developments's picture
Upload 125 files
ad79323 verified
Raw
History Blame Contribute Delete
3.7 kB
"use client";
import { useEffect, useState } from "react";
import { Menu01Icon } from "@hugeicons/core-free-icons";
import { DashboardSidebar } from "@/components/dashboard/dashboard-sidebar";
import { AppLogo } from "@/components/shared/app-logo";
import { Icon } from "@/components/shared/icon";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
const SIDEBAR_STORAGE_KEY = "courtrix_sidebar_collapsed";
type DashboardShellProps = {
user: {
firstName: string;
lastName: string;
email: string;
};
children: React.ReactNode;
};
export function DashboardShell({ user, children }: DashboardShellProps) {
const [isDesktopCollapsed, setIsDesktopCollapsed] = useState(() => {
if (typeof window === "undefined") {
return false;
}
return window.localStorage.getItem(SIDEBAR_STORAGE_KEY) === "true";
});
const [isMobile, setIsMobile] = useState(() => {
if (typeof window === "undefined") {
return false;
}
return window.matchMedia("(max-width: 1023px)").matches;
});
const [isMobileOpen, setIsMobileOpen] = useState(false);
useEffect(() => {
const mediaQuery = window.matchMedia("(max-width: 1023px)");
const handleViewportChange = () => {
const mobile = mediaQuery.matches;
setIsMobile(mobile);
if (mobile) {
setIsMobileOpen(false);
}
};
mediaQuery.addEventListener("change", handleViewportChange);
return () => mediaQuery.removeEventListener("change", handleViewportChange);
}, []);
function toggleDesktopCollapse() {
setIsDesktopCollapsed((current) => {
const next = !current;
window.localStorage.setItem(SIDEBAR_STORAGE_KEY, String(next));
return next;
});
}
return (
<div className="flex min-h-screen bg-[var(--background)]" dir="rtl">
{/* Sidebar - placed first in DOM means it will be on the right in RTL */}
<aside
className={cn(
"hidden lg:block sticky top-0 h-screen shrink-0 border-l border-[var(--border)] transition-[width] duration-300",
isDesktopCollapsed ? "w-[92px]" : "w-[290px]"
)}
>
<DashboardSidebar
collapsed={isDesktopCollapsed}
onToggleCollapse={toggleDesktopCollapse}
user={user}
/>
</aside>
<div className="flex-1 min-w-0 flex flex-col h-screen overflow-y-auto">
<div className="p-4 lg:p-8">
<div className="mb-6 flex items-center justify-between gap-3 lg:hidden">
<Button size="icon" variant="outline" onClick={() => setIsMobileOpen(true)}>
<Icon icon={Menu01Icon} size={18} />
</Button>
<AppLogo />
</div>
<main className="mx-auto max-w-[1200px] space-y-5">{children}</main>
</div>
</div>
{isMobile ? (
<div
className={cn(
"fixed inset-0 z-40 bg-[rgba(20,13,7,0.5)] backdrop-blur-[2px] transition-opacity lg:hidden",
isMobileOpen
? "pointer-events-auto opacity-100"
: "pointer-events-none opacity-0",
)}
onClick={() => setIsMobileOpen(false)}
>
<div
className={cn(
"absolute inset-y-0 right-0 w-[290px] max-w-full transform p-3 transition-transform",
isMobileOpen ? "translate-x-0" : "translate-x-full",
)}
onClick={(event) => event.stopPropagation()}
>
<DashboardSidebar
mobile
onCloseMobile={() => setIsMobileOpen(false)}
user={user}
/>
</div>
</div>
) : null}
</div>
);
}