- Update food, outfits, props, home-decor pages and components - Add permissions page and sidebar updates - Update API client and all API modules (auth, food, dances, etc.) - Add card model migrations for optional fields - Update Django views, serializers, and authentication - Add affinity level migrations and user app updates - Add project documentation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
50 lines
1.8 KiB
TypeScript
50 lines
1.8 KiB
TypeScript
"use client"
|
||
|
||
import type React from "react"
|
||
import { useEffect, useState } from "react"
|
||
import { usePathname } from "next/navigation"
|
||
import { cn } from "@/lib/utils"
|
||
import { Sidebar } from "@/components/sidebar"
|
||
import { hasPathPermission, getUserRole } from "@/lib/permissions"
|
||
import { Button } from "@/components/ui/button"
|
||
import { ShieldX } from "lucide-react"
|
||
import Link from "next/link"
|
||
|
||
interface DashboardShellProps extends React.HTMLAttributes<HTMLDivElement> {}
|
||
|
||
export function DashboardShell({ children, className, ...props }: DashboardShellProps) {
|
||
const pathname = usePathname()
|
||
const [allowed, setAllowed] = useState<boolean | null>(null)
|
||
|
||
useEffect(() => {
|
||
setAllowed(hasPathPermission(pathname))
|
||
}, [pathname])
|
||
|
||
const showAccessDenied = allowed === false
|
||
|
||
return (
|
||
<div className="grid min-h-screen w-full md:grid-cols-[280px_1fr] bg-gradient-to-br from-gray-50 to-white">
|
||
<Sidebar />
|
||
<main className={cn("flex flex-col relative overflow-hidden", className)} {...props}>
|
||
<div className="flex-1 space-y-6 p-8 pt-6">
|
||
{showAccessDenied ? (
|
||
<div className="flex flex-col items-center justify-center h-[60vh]">
|
||
<ShieldX className="h-16 w-16 text-red-400 mb-4" />
|
||
<h1 className="text-2xl font-bold mb-2">无访问权限</h1>
|
||
<p className="text-gray-500 mb-2">
|
||
您当前的角色({getUserRole()})没有访问此页面的权限
|
||
</p>
|
||
<p className="text-gray-400 text-sm mb-6">请联系超级管理员获取相应权限</p>
|
||
<Button asChild>
|
||
<Link href="/">返回仪表盘</Link>
|
||
</Button>
|
||
</div>
|
||
) : (
|
||
children
|
||
)}
|
||
</div>
|
||
</main>
|
||
</div>
|
||
)
|
||
}
|