登入驗證以及使用者按鈕
All checks were successful
Koori-ERP-Deploy-System / deploy-demo (push) Has been skipped
Koori-ERP-Deploy-System / deploy-production (push) Successful in 55s

This commit is contained in:
2026-01-07 14:44:01 +08:00
parent 19c60a6126
commit ef1fc47cff
10 changed files with 380 additions and 69 deletions

View File

@@ -1,5 +1,4 @@
import {
ChevronDown,
ChevronRight,
Package,
ShoppingCart,
@@ -11,13 +10,24 @@ import {
Warehouse,
Truck,
Contact2,
FileText
FileText,
LogOut,
User,
ChevronDown
} from "lucide-react";
import { Toaster } from "sonner";
import { useState, useEffect } from "react";
import { Link, usePage } from "@inertiajs/react";
import { cn } from "@/lib/utils";
import BreadcrumbNav, { BreadcrumbItemType } from "@/Components/shared/BreadcrumbNav";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/Components/ui/dropdown-menu";
interface MenuItem {
id: string;
@@ -34,7 +44,9 @@ export default function AuthenticatedLayout({
children: React.ReactNode,
breadcrumbs?: BreadcrumbItemType[]
}) {
const { url } = usePage();
const { url, props } = usePage();
// @ts-ignore
const user = props.auth?.user || { name: 'Guest', username: 'guest' };
const [isCollapsed, setIsCollapsed] = useState(() => {
if (typeof window !== "undefined") {
return localStorage.getItem("sidebar-collapsed") === "true";
@@ -243,6 +255,38 @@ export default function AuthenticatedLayout({
<span className="font-bold text-slate-900"> ERP</span>
</Link>
</div>
{/* User Menu */}
<DropdownMenu modal={false}>
<DropdownMenuTrigger className="flex items-center gap-2 outline-none group">
<div className="hidden md:flex flex-col items-end mr-1">
<span className="text-sm font-medium text-slate-700 group-hover:text-slate-900 transition-colors">
{user.name}
</span>
<span className="text-xs text-slate-500">
{user.username || 'Administrator'}
</span>
</div>
<div className="h-9 w-9 bg-slate-100 rounded-full flex items-center justify-center text-slate-600 group-hover:bg-primary-lightest group-hover:text-primary-main transition-all">
<User className="h-5 w-5" />
</div>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-56 z-[100]" sideOffset={8}>
<DropdownMenuLabel></DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem asChild>
<Link
href={route('logout')}
method="post"
as="button"
className="w-full flex items-center cursor-pointer text-red-600 focus:text-red-600 focus:bg-red-50"
>
<LogOut className="mr-2 h-4 w-4" />
<span></span>
</Link>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</header>
{/* Sidebar Desktop */}
@@ -281,15 +325,17 @@ export default function AuthenticatedLayout({
{isCollapsed ? <PanelLeftOpen className="h-5 w-5" /> : <PanelLeftClose className="h-5 w-5" />}
</button>
</div>
</aside>
</aside >
{/* Mobile Sidebar Overlay */}
{isMobileOpen && (
<div
className="fixed inset-0 bg-slate-900/50 backdrop-blur-sm z-[70] lg:hidden"
onClick={() => setIsMobileOpen(false)}
/>
)}
{
isMobileOpen && (
<div
className="fixed inset-0 bg-slate-900/50 backdrop-blur-sm z-[70] lg:hidden"
onClick={() => setIsMobileOpen(false)}
/>
)
}
{/* Mobile Sidebar Drawer */}
<aside className={cn(
@@ -329,6 +375,6 @@ export default function AuthenticatedLayout({
</div>
<Toaster richColors closeButton position="top-center" />
</main>
</div>
</div >
);
}