car_mms/app/components/layout/DashboardLayout.tsx
2025-09-11 14:22:27 +03:00

170 lines
5.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { ReactNode, useState, useEffect } from 'react';
import { Form } from '@remix-run/react';
import { Sidebar } from './Sidebar';
import { Container } from './Container';
import { Flex } from './Flex';
import { Text, Button } from '../ui';
interface DashboardLayoutProps {
children: ReactNode;
user: {
id: number;
name: string;
authLevel: number;
};
}
export function DashboardLayout({ children, user }: DashboardLayoutProps) {
const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
const [isMobile, setIsMobile] = useState(false);
// Handle responsive behavior
useEffect(() => {
const checkMobile = () => {
const mobile = window.innerWidth < 768;
setIsMobile(mobile);
// Auto-collapse sidebar on mobile
if (mobile) {
setSidebarCollapsed(true);
}
};
checkMobile();
window.addEventListener('resize', checkMobile);
return () => window.removeEventListener('resize', checkMobile);
}, []);
// Load sidebar state from localStorage
useEffect(() => {
const savedState = localStorage.getItem('sidebarCollapsed');
if (savedState !== null && !isMobile) {
setSidebarCollapsed(JSON.parse(savedState));
}
}, [isMobile]);
// Save sidebar state to localStorage
const handleSidebarToggle = () => {
const newState = !sidebarCollapsed;
setSidebarCollapsed(newState);
if (!isMobile) {
localStorage.setItem('sidebarCollapsed', JSON.stringify(newState));
}
};
const handleMobileMenuClose = () => {
setMobileMenuOpen(false);
};
const getAuthLevelText = (authLevel: number) => {
switch (authLevel) {
case 1:
return "مدير عام";
case 2:
return "مدير";
case 3:
return "مستخدم";
default:
return "غير محدد";
}
};
return (
<div className="min-h-screen bg-gray-50 flex" dir="rtl">
{/* Sidebar */}
<Sidebar
isCollapsed={sidebarCollapsed}
onToggle={handleSidebarToggle}
isMobile={isMobile}
isOpen={mobileMenuOpen}
onClose={handleMobileMenuClose}
userAuthLevel={user.authLevel}
/>
{/* Main Content */}
<div className={`
flex-1 min-h-screen transition-all duration-300 ease-in-out
${!isMobile ? (sidebarCollapsed ? 'mr-16' : 'mr-64') : 'mr-0'}
`}>
{/* Header */}
<div className="bg-white shadow-sm border-b border-gray-200 sticky top-0 z-10">
<div className="max-w-full mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex justify-between items-center py-4">
{/* Mobile menu button and title */}
<div className="flex items-center gap-4">
{isMobile && (
<button
onClick={() => setMobileMenuOpen(true)}
className="p-2 rounded-md text-gray-400 hover:text-gray-600 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500"
>
<svg
className="h-6 w-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M4 6h16M4 12h16M4 18h16"
/>
</svg>
</button>
)}
{/* Page title - only show on mobile when sidebar is closed */}
{isMobile && (
<h1 className="text-lg font-semibold text-gray-900">
لوحة التحكم
</h1>
)}
</div>
{/* User info and actions */}
<div className="flex items-center gap-4">
<div className="text-right">
<div className="text-sm text-gray-600">
مرحباً، <span className="font-medium text-gray-900">{user.name}</span>
</div>
<div className="text-xs text-gray-500">
{getAuthLevelText(user.authLevel)}
</div>
</div>
<Form action="/logout" method="post">
<button
type="submit"
className="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-white bg-red-600 hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 transition-colors duration-150"
>
<svg
className="h-4 w-4 mr-1"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"
/>
</svg>
خروج
</button>
</Form>
</div>
</div>
</div>
</div>
{/* Page Content */}
<main className="flex-1 p-6">
{children}
</main>
</div>
</div>
);
}