Tech4biz-channel/Channel-Frontend/src/components/layout/MainLayout.tsx

100 lines
4.7 KiB
TypeScript

import { Outlet, Link } from '@tanstack/react-router';
import { useAuthStore } from '../../hooks/use-auth';
import { useThemeStore } from '../../hooks/use-theme';
import { motion } from 'framer-motion';
import { LayoutDashboard, FolderKanban, FileSignature, Users, LogOut, Sun, Moon } from 'lucide-react';
export const MainLayout = () => {
const { isAuthenticated, logout, user } = useAuthStore();
const { theme, toggleTheme } = useThemeStore();
if (!isAuthenticated) {
return <Outlet />;
}
const NAV_ITEMS = [
{ name: 'Dashboard', path: '/', icon: LayoutDashboard },
{ name: 'Asset Library', path: '/assets', icon: FolderKanban },
{ name: 'Legal Documents', path: '/legal', icon: FileSignature },
{ name: 'Directory', path: '/directory', icon: Users },
];
return (
<div className="flex h-screen bg-ink-50 text-ink-900 overflow-hidden font-sans transition-colors duration-500">
{/* Sidebar */}
<motion.aside
initial={{ x: -300 }}
animate={{ x: 0 }}
className="w-72 bg-ink-0 border-r border-ink-200 flex flex-col relative z-20"
>
<div className="h-24 flex items-center px-8 border-b border-ink-200">
<div className="flex items-center gap-4">
<div className="relative flex items-center justify-center w-11 h-11 rounded-2xl bg-ink-0 border border-ink-200 shadow-sm p-1">
<img src="/logo.png" alt="Tech4Biz" className="w-full h-full object-contain" />
</div>
<span className="font-extrabold text-xl tracking-tight text-ink-900">Tech4Biz</span>
</div>
</div>
<nav className="flex-1 px-4 py-8 space-y-2 overflow-y-auto">
{NAV_ITEMS.map((item) => (
<Link
key={item.path}
to={item.path}
className="flex items-center gap-4 px-4 py-3.5 rounded-xl transition-all duration-300 text-ink-500 hover:text-ink-900 hover:bg-ink-100 group"
activeProps={{ className: 'bg-ink-100 text-ink-900 border border-ink-300 shadow-sm' }}
activeOptions={{ exact: item.path === '/' }}
>
<item.icon className="w-5 h-5 transition-transform group-hover:scale-110" />
<span className="font-semibold tracking-wide text-sm">{item.name}</span>
</Link>
))}
</nav>
<div className="p-5 border-t border-ink-200 bg-ink-50">
<div className="flex items-center justify-between mb-4">
<p className="text-[10px] font-bold text-ink-400 uppercase tracking-widest">Theme Preference</p>
<button
onClick={toggleTheme}
className="p-2 rounded-lg bg-ink-0 border border-ink-200 text-ink-500 hover:text-ink-900 hover:shadow-sm transition-all group"
>
{theme === 'dark' ? <Sun className="w-4 h-4 group-hover:rotate-90 transition-transform" /> : <Moon className="w-4 h-4 group-hover:-rotate-12 transition-transform" />}
</button>
</div>
<div className="flex items-center gap-4 p-3.5 rounded-2xl bg-ink-0 border border-ink-200 mb-4 shadow-sm">
<div className="w-10 h-10 rounded-full bg-gradient-to-br from-ink-900 to-ink-800 flex items-center justify-center text-ink-0 text-sm font-bold shadow-lg">
{user?.email?.charAt(0).toUpperCase()}
</div>
<div className="flex-1 min-w-0">
<p className="text-sm font-bold text-ink-900 truncate">{user?.email}</p>
<p className="text-xs text-ink-500 font-medium truncate tracking-wide">{user?.role}</p>
</div>
</div>
<button
onClick={() => {
logout();
window.location.href = '/login';
}}
className="w-full flex items-center justify-center gap-2.5 px-4 py-3 rounded-xl text-sm font-bold tracking-wide text-red-600 hover:bg-red-500/10 transition-colors border border-transparent hover:border-red-200"
>
<LogOut className="w-4 h-4" />
SECURE LOGOUT
</button>
</div>
</motion.aside>
{/* Main Content */}
<main className="flex-1 flex flex-col relative overflow-hidden bg-ink-50 transition-colors duration-500">
{/* Soft Monochromatic Accent Glows */}
<div className="absolute top-0 right-0 w-[500px] h-[500px] bg-ink-900/5 rounded-full blur-[150px] pointer-events-none" />
<div className="absolute bottom-0 left-1/4 w-[400px] h-[400px] bg-ink-900/5 rounded-full blur-[120px] pointer-events-none" />
<div className="flex-1 overflow-y-auto p-10 relative z-10">
<Outlet />
</div>
</main>
</div>
);
};
export default MainLayout;