109 lines
3.8 KiB
JavaScript
109 lines
3.8 KiB
JavaScript
import React, { useState, useEffect } from 'react';
|
|
import { Outlet, useLocation } from 'react-router-dom';
|
|
import {
|
|
Sun,
|
|
Moon,
|
|
} from 'lucide-react';
|
|
import { cn } from '@/lib/utils';
|
|
import { useDocumentMetadata } from '@/hooks/useDocumentMetadata';
|
|
import { GrSidebar } from '../components/GrSidebar';
|
|
import { useGrStore } from '../services/useGrStore';
|
|
|
|
export const GrLayout = () => {
|
|
useDocumentMetadata('Cockpit GR', 'gr');
|
|
const [isSidebarCollapsed, setIsSidebarCollapsed] = useState(false);
|
|
const [isDarkMode, setIsDarkMode] = useState(false); // Default to Light as per screenshots
|
|
|
|
const { initEnvironment } = useGrStore();
|
|
const location = useLocation();
|
|
|
|
// Hide sidebar on mobile if we are on the 'Novo Cadastro' (edit/new) page
|
|
const isFormPage = location.pathname.includes('/novo');
|
|
|
|
useEffect(() => {
|
|
initEnvironment();
|
|
}, [initEnvironment]);
|
|
|
|
useEffect(() => {
|
|
if (isDarkMode) {
|
|
document.documentElement.classList.add('dark');
|
|
} else {
|
|
document.documentElement.classList.remove('dark');
|
|
}
|
|
}, [isDarkMode]);
|
|
|
|
return (
|
|
<div className={cn(
|
|
"flex min-h-screen font-inter selection:bg-[var(--gr-primary)]/30",
|
|
isDarkMode ? "dark bg-[#141414] text-slate-100" : "bg-[var(--gr-panel-empty)] text-slate-900"
|
|
)}>
|
|
{/* Sidebar Component */}
|
|
<div className={cn(
|
|
"hidden md:block fixed inset-y-0 left-0 z-50 transition-all duration-300",
|
|
isFormPage ? "md:hidden" : ""
|
|
)}>
|
|
<GrSidebar
|
|
isCollapsed={isSidebarCollapsed}
|
|
onToggle={() => setIsSidebarCollapsed(!isSidebarCollapsed)}
|
|
/>
|
|
</div>
|
|
|
|
{/* Main Content Area */}
|
|
<main
|
|
className={cn(
|
|
"flex-1 transition-all duration-300 min-h-screen flex flex-col min-w-0",
|
|
isFormPage
|
|
? "ml-0"
|
|
: (isSidebarCollapsed ? "md:ml-[90px]" : "md:ml-[270px]")
|
|
)}
|
|
>
|
|
{/* Header */}
|
|
<header className={cn(
|
|
"h-14 px-6 sticky top-0 z-40 flex items-center justify-between transition-colors duration-300",
|
|
isDarkMode
|
|
? "bg-[#161616]/80 backdrop-blur-md border-b border-white/5"
|
|
: "bg-white/80 backdrop-blur-md border-b border-slate-200"
|
|
)}>
|
|
<div className="flex items-center gap-4">
|
|
<h1 className={cn(
|
|
"font-bold text-lg tracking-wide transition-colors",
|
|
isDarkMode ? "text-[var(--gr-primary)]" : "text-slate-800"
|
|
)}>
|
|
Cockpit <span className="text-[var(--gr-primary)]">GR</span>
|
|
</h1>
|
|
</div>
|
|
|
|
<div className="flex items-center gap-4">
|
|
{/* Theme Toggle */}
|
|
<button
|
|
onClick={() => setIsDarkMode(!isDarkMode)}
|
|
className={cn(
|
|
"p-2 rounded-xl transition-all duration-300",
|
|
isDarkMode
|
|
? "bg-white/5 text-slate-400 hover:text-white hover:bg-white/10"
|
|
: "bg-slate-100 text-slate-500 hover:text-[var(--gr-primary)] hover:bg-slate-200"
|
|
)}
|
|
>
|
|
{isDarkMode ? <Sun size={18} /> : <Moon size={18} />}
|
|
</button>
|
|
</div>
|
|
</header>
|
|
|
|
{/* Content */}
|
|
<div className="flex-1 min-w-0 flex flex-col">
|
|
<div className={cn(
|
|
"flex-1 w-full rounded-tl-[40px] overflow-hidden flex flex-col transition-all duration-300",
|
|
isDarkMode
|
|
? "bg-[#1b1b1b] border border-white/5 shadow-2xl shadow-black/20"
|
|
: "bg-white border border-slate-200 shadow-xl shadow-slate-200/50"
|
|
)}>
|
|
<div className="flex-1 overflow-hidden flex flex-col p-4 md:p-8">
|
|
<Outlet />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
);
|
|
};
|