Fix up sidebar
This commit is contained in:
@@ -1,118 +1,24 @@
|
|||||||
import { useState } from 'react';
|
import { SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar";
|
||||||
import { NavLink, useLocation } from 'react-router-dom';
|
import { AppSidebar } from "./AppSidebar";
|
||||||
import {
|
|
||||||
LayoutDashboard,
|
|
||||||
Settings,
|
|
||||||
Package,
|
|
||||||
ShoppingBag,
|
|
||||||
PackagePlus,
|
|
||||||
BarChart4,
|
|
||||||
LogOut,
|
|
||||||
} from 'lucide-react';
|
|
||||||
import { cn } from '@/lib/utils';
|
|
||||||
import { Button } from '../ui/button';
|
|
||||||
import { useNavigate } from 'react-router-dom';
|
|
||||||
|
|
||||||
const links = [
|
interface MainLayoutProps {
|
||||||
{ title: 'Dashboard', path: '/', icon: <LayoutDashboard /> },
|
children: React.ReactNode;
|
||||||
{ title: 'Products', path: '/products', icon: <Package /> },
|
}
|
||||||
{ title: 'Import', path: '/import', icon: <PackagePlus /> },
|
|
||||||
{ title: 'Orders', path: '/orders', icon: <ShoppingBag /> },
|
|
||||||
{ title: 'Purchase Orders', path: '/purchase-orders', icon: <ShoppingBag /> },
|
|
||||||
{ title: 'Analytics', path: '/analytics', icon: <BarChart4 /> },
|
|
||||||
{ title: 'Settings', path: '/settings', icon: <Settings /> },
|
|
||||||
];
|
|
||||||
|
|
||||||
export function MainLayout({ children }: { children: React.ReactNode }) {
|
|
||||||
const [open, setOpen] = useState(true);
|
|
||||||
const location = useLocation();
|
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
const handleLogout = () => {
|
|
||||||
sessionStorage.removeItem('isLoggedIn');
|
|
||||||
sessionStorage.removeItem('token');
|
|
||||||
navigate('/login');
|
|
||||||
};
|
|
||||||
|
|
||||||
|
export function MainLayout({ children }: MainLayoutProps) {
|
||||||
return (
|
return (
|
||||||
<div className="flex h-screen">
|
<SidebarProvider defaultOpen>
|
||||||
<aside
|
<div className="flex min-h-screen w-full pr-2">
|
||||||
className={cn(
|
<AppSidebar />
|
||||||
'border-r h-full transition-all duration-300 ease-in-out',
|
<main className="flex-1 overflow-hidden">
|
||||||
open ? 'w-64' : 'w-20',
|
<div className="flex h-14 w-full items-center border-b px-4 gap-4">
|
||||||
)}
|
<SidebarTrigger />
|
||||||
>
|
</div>
|
||||||
<div className="flex items-center justify-between p-4">
|
<div className="overflow-auto h-[calc(100vh-3.5rem)] max-w-[1500px]">
|
||||||
<h1
|
{children}
|
||||||
className={cn(
|
</div>
|
||||||
'text-xl font-bold transition-all duration-300 ease-in-out',
|
</main>
|
||||||
open ? 'block' : 'hidden',
|
</div>
|
||||||
)}
|
</SidebarProvider>
|
||||||
>
|
|
||||||
Inventory
|
|
||||||
</h1>
|
|
||||||
<button
|
|
||||||
className="p-1.5 rounded-md hover:bg-gray-200"
|
|
||||||
onClick={() => setOpen(!open)}
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
className="w-5 h-5"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
strokeWidth="2"
|
|
||||||
stroke="currentColor"
|
|
||||||
fill="none"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
>
|
|
||||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
|
||||||
<path d="M4 6l16 0"></path>
|
|
||||||
<path d="M4 12l16 0"></path>
|
|
||||||
<path d="M4 18l12 0"></path>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<nav className="p-4 space-y-2">
|
|
||||||
{links.map((link) => (
|
|
||||||
<NavLink
|
|
||||||
key={link.path}
|
|
||||||
to={link.path}
|
|
||||||
className={cn(
|
|
||||||
'flex items-center gap-2 p-2 rounded-md transition-all duration-300 ease-in-out',
|
|
||||||
location.pathname === link.path
|
|
||||||
? 'bg-gray-200'
|
|
||||||
: 'hover:bg-gray-100',
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{link.icon}
|
|
||||||
<span
|
|
||||||
className={cn(
|
|
||||||
'transition-all duration-300 ease-in-out',
|
|
||||||
open ? 'block' : 'hidden',
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{link.title}
|
|
||||||
</span>
|
|
||||||
</NavLink>
|
|
||||||
))}
|
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
className="w-full flex items-center gap-2"
|
|
||||||
onClick={handleLogout}
|
|
||||||
>
|
|
||||||
<LogOut />
|
|
||||||
<span
|
|
||||||
className={cn(
|
|
||||||
'transition-all duration-300 ease-in-out',
|
|
||||||
open ? 'block' : 'hidden',
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
Logout
|
|
||||||
</span>
|
|
||||||
</Button>
|
|
||||||
</nav>
|
|
||||||
</aside>
|
|
||||||
<main className="flex-1 p-8 overflow-y-auto">{children}</main>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -82,8 +82,8 @@
|
|||||||
|
|
||||||
--sidebar-background: 240 5.9% 10%;
|
--sidebar-background: 240 5.9% 10%;
|
||||||
--sidebar-foreground: 240 4.8% 95.9%;
|
--sidebar-foreground: 240 4.8% 95.9%;
|
||||||
--sidebar-primary: 0 0% 98%;
|
--sidebar-primary: 224.3 76.3% 48%;
|
||||||
--sidebar-primary-foreground: 240 5.9% 10%;
|
--sidebar-primary-foreground: 0 0% 100%;
|
||||||
--sidebar-accent: 240 3.7% 15.9%;
|
--sidebar-accent: 240 3.7% 15.9%;
|
||||||
--sidebar-accent-foreground: 240 4.8% 95.9%;
|
--sidebar-accent-foreground: 240 4.8% 95.9%;
|
||||||
--sidebar-border: 240 3.7% 15.9%;
|
--sidebar-border: 240 3.7% 15.9%;
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ export function Login() {
|
|||||||
console.log('Login response status:', response.status);
|
console.log('Login response status:', response.status);
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
const data = await response.json().catch(e => ({ error: 'Failed to parse error response' }));
|
const data = await response.json().catch(() => ({ error: 'Failed to parse error response' }));
|
||||||
console.error('Login failed:', data);
|
console.error('Login failed:', data);
|
||||||
throw new Error(data.error || 'Login failed');
|
throw new Error(data.error || 'Login failed');
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user