Files
membership-fe/src/layouts/AdminLayout.js

97 lines
2.8 KiB
JavaScript

import React, { useState, useEffect } from 'react';
import { useTheme } from 'next-themes';
import { Menu } from 'lucide-react';
import AdminSidebar from '../components/AdminSidebar';
import { UsersProvider } from '../context/UsersContext';
const AdminLayout = ({ children }) => {
const [sidebarOpen, setSidebarOpen] = useState(true);
const [isMobile, setIsMobile] = useState(false);
const { theme } = useTheme();
const isDark = theme === 'dark';
// Initialize sidebar state from localStorage
useEffect(() => {
const savedState = localStorage.getItem('adminSidebarOpen');
if (savedState !== null) {
setSidebarOpen(JSON.parse(savedState));
}
}, []);
// Detect mobile viewport
useEffect(() => {
const checkMobile = () => {
setIsMobile(window.innerWidth < 768);
};
checkMobile();
window.addEventListener('resize', checkMobile);
return () => window.removeEventListener('resize', checkMobile);
}, []);
// Close sidebar by default on mobile
useEffect(() => {
if (isMobile) {
setSidebarOpen(false);
}
}, [isMobile]);
const toggleSidebar = () => {
const newState = !sidebarOpen;
setSidebarOpen(newState);
localStorage.setItem('adminSidebarOpen', JSON.stringify(newState));
};
const closeSidebar = () => {
setSidebarOpen(false);
localStorage.setItem('adminSidebarOpen', JSON.stringify(false));
};
return (
<UsersProvider>
<div className={`flex h-screen bg-background ${isDark ? 'dark' : ''}`}>
{/* Sidebar */}
<AdminSidebar
isOpen={sidebarOpen}
onToggle={toggleSidebar}
isMobile={isMobile}
/>
{/* Mobile Overlay */}
{isMobile && sidebarOpen && (
<div
className="fixed inset-0 bg-black/50 z-30 transition-opacity"
onClick={closeSidebar}
/>
)}
{/* Main Content Area */}
<main className="flex-1 overflow-y-auto scrollbar-dashboard">
{isMobile && (
<div className="sticky top-0 z-20 bg-background/90 backdrop-blur border-b border-[var(--neutral-800)] px-4 py-3 flex items-center gap-3">
<button
onClick={toggleSidebar}
className="p-2 rounded-lg hover:bg-[var(--neutral-800)]/20 transition-colors"
aria-label={sidebarOpen ? 'Close sidebar' : 'Open sidebar'}
>
<Menu className="h-5 w-5 text-primary" />
</button>
<span
className="text-sm font-semibold text-primary"
style={{ fontFamily: "'Inter', sans-serif" }}
>
Menu
</span>
</div>
)}
<div className="max-w-7xl mx-auto px-6 py-8">
{children}
</div>
</main>
</div>
</UsersProvider>
);
};
export default AdminLayout;