登入驗證以及使用者按鈕
This commit is contained in:
@@ -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 >
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user