inogen/app/components/dashboard/layout.tsx
2025-10-10 19:11:38 +03:30

108 lines
3.2 KiB
TypeScript

import { useState } from "react";
import { cn } from "~/lib/utils";
import { Header } from "./header";
import { Sidebar } from "./sidebar";
import { StrategicAlignmentPopup } from "./strategic-alignment-popup";
interface DashboardLayoutProps {
children: React.ReactNode;
className?: string;
title?: string;
}
export function DashboardLayout({
children,
className,
title,
}: DashboardLayoutProps) {
const [isSidebarCollapsed, setIsSidebarCollapsed] = useState(false);
const [isMobileSidebarOpen, setIsMobileSidebarOpen] = useState(false);
const [isStrategicAlignmentPopupOpen, setIsStrategicAlignmentPopupOpen] =
useState(false);
const [currentTitle, setCurrentTitle] = useState<string | undefined>(
title ?? "صفحه اول"
);
const [currentTitleIcon, setCurrentTitleIcon] = useState<
React.ComponentType<{ className?: string }> | null | undefined
>(undefined);
const toggleSidebarCollapse = () => {
setIsSidebarCollapsed(!isSidebarCollapsed);
};
const toggleMobileSidebar = () => {
setIsMobileSidebarOpen(!isMobileSidebarOpen);
};
return (
<div
className="h-screen flex overflow-hidden bg-[linear-gradient(to_bottom_left,#464861,20%,#111628)] relative overflow-x-hidden"
dir="rtl"
>
{/* Gradient overlay */}
<div className="absolute inset-0 pointer-events-none" />
{/* Mobile sidebar overlay */}
{isMobileSidebarOpen && (
<div
className="fixed inset-0 z-40 lg:hidden"
onClick={() => setIsMobileSidebarOpen(false)}
>
<div className="absolute inset-0 bg-black opacity-75" />
</div>
)}
{/* Sidebar */}
<div
className={cn(
"fixed inset-y-0 right-0 z-50 flex flex-col lg:static lg:inset-auto lg:translate-x-0 transition-transform duration-300 ease-in-out",
isMobileSidebarOpen
? "translate-x-0"
: "translate-x-full lg:translate-x-0"
)}
>
<Sidebar
isCollapsed={isSidebarCollapsed}
onToggleCollapse={toggleSidebarCollapse}
className="h-full flex-shrink-0 relative z-10"
onStrategicAlignmentClick={() =>
setIsStrategicAlignmentPopupOpen(true)
}
onTitleChange={(info) => {
setCurrentTitle(info.title);
setCurrentTitleIcon(info.icon ?? null);
}}
/>
</div>
{/* Main content area */}
<div className="flex flex-col flex-1 min-w-0 overflow-hidden">
{/* Header */}
<Header
onToggleSidebar={toggleMobileSidebar}
className="flex-shrink-0"
title={currentTitle}
titleIcon={currentTitleIcon}
/>
{/* Main content */}
<main
className={cn(
"flex-1 overflow-x-hidden overflow-y-auto focus:outline-none transition-all duration-300 min-w-0",
className
)}
>
<div className="relative h-full min-w-0 w-full z-10 overflow-x-hidden p-5">
{children}
</div>
</main>
</div>
<StrategicAlignmentPopup
open={isStrategicAlignmentPopupOpen}
onOpenChange={setIsStrategicAlignmentPopupOpen}
/>
</div>
);
}
export default DashboardLayout;