62 lines
1.9 KiB
TypeScript
62 lines
1.9 KiB
TypeScript
import React from 'react';
|
|
import { Outlet } from 'react-router-dom';
|
|
import { useAuth } from '@/contexts/useAuth';
|
|
import { useIsMobile } from '@/hooks/use-mobile';
|
|
import { useAppShell } from '@/business/app-shell/hooks';
|
|
import { AppFooter } from '@/components/app-shell/AppFooter';
|
|
import { AppShellSkeleton } from '@/components/ui/app-shell-skeleton';
|
|
|
|
import Sidebar from '@/components/frameworks/Sidebar';
|
|
import TopBar from '@/components/frameworks/TopBar';
|
|
|
|
const AppLayout: React.FC = () => {
|
|
const { user, profile, loading: authLoading } = useAuth();
|
|
const isMobile = useIsMobile();
|
|
const {
|
|
mobileOverlayVisible,
|
|
sidebarProps,
|
|
topBarProps,
|
|
shellOutletContext,
|
|
footerProps,
|
|
setMobileSidebarOpen,
|
|
} = useAppShell({ user, profile, isMobile });
|
|
|
|
if (authLoading) {
|
|
return <AppShellSkeleton />;
|
|
}
|
|
|
|
return (
|
|
<div className="h-screen w-full flex bg-gradient-to-br from-slate-950 via-slate-900 to-slate-950 overflow-hidden">
|
|
{/* Mobile sidebar overlay */}
|
|
{mobileOverlayVisible && (
|
|
<div className="fixed inset-0 bg-black/50 backdrop-blur-sm z-30" onClick={() => setMobileSidebarOpen(false)} />
|
|
)}
|
|
|
|
{/* Sidebar */}
|
|
<div className={`${isMobile ? `fixed left-0 top-0 h-full z-40 transform transition-transform duration-300 ${mobileOverlayVisible ? 'translate-x-0' : '-translate-x-full'}` : 'relative'}`}>
|
|
<Sidebar {...sidebarProps} />
|
|
</div>
|
|
|
|
|
|
{/* Main content area */}
|
|
<div className="flex-1 flex flex-col min-w-0 overflow-hidden">
|
|
<TopBar {...topBarProps} />
|
|
|
|
<main
|
|
aria-label="Main content"
|
|
className="flex-1 overflow-y-auto p-4 outline-none md:p-6 lg:p-8"
|
|
tabIndex={0}
|
|
>
|
|
<div className="max-w-7xl mx-auto">
|
|
<Outlet context={shellOutletContext} />
|
|
</div>
|
|
|
|
<AppFooter {...footerProps} />
|
|
</main>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default AppLayout;
|