108 lines
2.8 KiB
TypeScript
108 lines
2.8 KiB
TypeScript
import type { ReactNode } from "react";
|
||
import Link from "next/link";
|
||
import LogoutButton from "@/components/logout-button";
|
||
import type { PublicUser } from "@/lib/types";
|
||
|
||
interface NavigationShellProps {
|
||
currentUser: PublicUser;
|
||
activePath: string;
|
||
title: string;
|
||
description: string;
|
||
children: ReactNode;
|
||
}
|
||
|
||
export default function NavigationShell({
|
||
currentUser,
|
||
activePath,
|
||
title,
|
||
description,
|
||
children,
|
||
}: NavigationShellProps) {
|
||
const navigationItems = [
|
||
{
|
||
href: "/studio",
|
||
label: "生成中心",
|
||
description: "输入 Prompt,生成并下载图片",
|
||
},
|
||
{
|
||
href: "/history",
|
||
label: "历史记录",
|
||
description:
|
||
currentUser.role === "admin"
|
||
? "查看所有用户生成过的图片"
|
||
: "回看自己曾经生成的图片",
|
||
},
|
||
...(currentUser.role === "admin"
|
||
? [
|
||
{
|
||
href: "/admin",
|
||
label: "管理后台",
|
||
description: "用户、角色和额度配置",
|
||
},
|
||
]
|
||
: []),
|
||
];
|
||
|
||
return (
|
||
<div className="dashboard-shell">
|
||
<aside className="dashboard-sidebar">
|
||
<div className="brand-lockup">
|
||
<div className="brand-mark" />
|
||
<div>
|
||
<p className="eyebrow">Image Prompt Studio</p>
|
||
<h1>Apple-like Workspace</h1>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="sidebar-card">
|
||
<span className="sidebar-label">当前用户</span>
|
||
<strong>{currentUser.username}</strong>
|
||
<p className="sidebar-copy">
|
||
{currentUser.role === "admin"
|
||
? "管理员,无限额"
|
||
: "普通用户,受额度限制"}
|
||
</p>
|
||
</div>
|
||
|
||
<nav className="sidebar-nav">
|
||
{navigationItems.map((item) => (
|
||
<Link
|
||
key={item.href}
|
||
href={item.href}
|
||
className={
|
||
item.href === activePath
|
||
? "sidebar-link sidebar-link-active"
|
||
: "sidebar-link"
|
||
}
|
||
>
|
||
<strong>{item.label}</strong>
|
||
<span>{item.description}</span>
|
||
</Link>
|
||
))}
|
||
</nav>
|
||
|
||
<div className="sidebar-actions">
|
||
<LogoutButton />
|
||
</div>
|
||
</aside>
|
||
|
||
<main className="dashboard-main">
|
||
<header className="page-hero">
|
||
<div>
|
||
<p className="eyebrow">Workspace</p>
|
||
<h2>{title}</h2>
|
||
<p className="hero-copy">{description}</p>
|
||
</div>
|
||
<div className="hero-orbs" aria-hidden="true">
|
||
<div className="hero-orb hero-orb-blue" />
|
||
<div className="hero-orb hero-orb-pink" />
|
||
<div className="hero-orb hero-orb-silver" />
|
||
</div>
|
||
</header>
|
||
|
||
<div className="page-content">{children}</div>
|
||
</main>
|
||
</div>
|
||
);
|
||
}
|