feat: 增加角色管理与奖池配置迁移,优化管理端权限与样式
This commit is contained in:
@@ -17,7 +17,7 @@ export function AdminShell({ children }: { children: ReactNode }) {
|
||||
<SidebarProvider defaultOpen>
|
||||
<AdminAppSidebar />
|
||||
<SidebarInset className="max-md:overflow-x-hidden">
|
||||
<header className="sticky top-0 z-30 flex min-h-14 items-center gap-3 border-b border-border bg-background/80 pl-4 pr-4 py-2 backdrop-blur-md">
|
||||
<header className="sticky top-0 z-30 flex h-14 shrink-0 items-center gap-3 border-b border-border bg-card/90 px-4 shadow-[0_1px_0_rgb(216_230_251_/_45%)] backdrop-blur-md">
|
||||
<SidebarTrigger />
|
||||
<Separator orientation="vertical" className="mr-1.5 h-4" />
|
||||
<AdminBreadcrumb />
|
||||
@@ -25,7 +25,7 @@ export function AdminShell({ children }: { children: ReactNode }) {
|
||||
<ShellToolbar />
|
||||
</div>
|
||||
</header>
|
||||
<div className="flex flex-1 flex-col px-6 pt-4 pb-6 md:px-8 md:pt-4 md:pb-8">
|
||||
<div className="flex flex-1 flex-col px-4 pt-4 pb-6 md:px-5 md:pt-4 md:pb-6">
|
||||
{children}
|
||||
</div>
|
||||
</SidebarInset>
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
import Link from "next/link";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { useMemo } from "react";
|
||||
import { SparklesIcon } from "lucide-react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import {
|
||||
@@ -39,28 +38,38 @@ export function AdminAppSidebar() {
|
||||
const visibleNav = useMemo(() => profile?.navigation ?? [], [profile?.navigation]);
|
||||
|
||||
return (
|
||||
<Sidebar collapsible="icon" variant="inset">
|
||||
<SidebarHeader className="border-b border-sidebar-border px-2 py-1.5">
|
||||
<SidebarMenu>
|
||||
<SidebarMenuItem>
|
||||
<Sidebar collapsible="icon" className="overflow-hidden">
|
||||
<SidebarHeader className="flex h-14 shrink-0 items-center gap-0 border-b border-sidebar-border p-0 px-2">
|
||||
<SidebarMenu className="h-full w-full">
|
||||
<SidebarMenuItem className="h-full">
|
||||
<SidebarMenuButton
|
||||
render={<Link href={ADMIN_BASE} />}
|
||||
className="gap-2 px-0 hover:bg-transparent"
|
||||
className="h-full min-h-0 justify-start px-1 py-0 hover:bg-transparent group-data-[collapsible=icon]:justify-center"
|
||||
>
|
||||
<SparklesIcon data-icon="inline-start" aria-hidden />
|
||||
<div className="flex flex-col items-start gap-0 group-data-[collapsible=icon]:hidden">
|
||||
<span className="font-semibold tracking-tight text-sidebar-foreground">
|
||||
{t("app.title", { ns: "common" })}
|
||||
</span>
|
||||
<span className="text-[11px] leading-tight text-sidebar-foreground/70">
|
||||
Lottery Admin
|
||||
</span>
|
||||
<div className="flex h-12 w-full items-center group-data-[collapsible=icon]:size-10 group-data-[collapsible=icon]:justify-center">
|
||||
<img
|
||||
src="/logo.png"
|
||||
alt="N lotto"
|
||||
className="h-auto max-h-11 w-full object-contain object-left group-data-[collapsible=icon]:max-h-8 group-data-[collapsible=icon]:object-center"
|
||||
/>
|
||||
</div>
|
||||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
</SidebarMenu>
|
||||
</SidebarHeader>
|
||||
<SidebarContent>
|
||||
<SidebarContent className="relative overflow-hidden">
|
||||
<div
|
||||
className="pointer-events-none absolute inset-x-0 bottom-0 h-[22rem] opacity-55 group-data-[collapsible=icon]:hidden"
|
||||
aria-hidden
|
||||
>
|
||||
<img
|
||||
src="/image6.png"
|
||||
alt=""
|
||||
className="h-full w-full object-cover object-bottom"
|
||||
/>
|
||||
<div className="absolute inset-x-0 top-0 h-28 bg-linear-to-b from-sidebar to-transparent" />
|
||||
<div className="absolute inset-0 bg-sidebar/20" />
|
||||
</div>
|
||||
<SidebarGroup>
|
||||
<SidebarGroupLabel>{t("sidebar.workspace", { ns: "common", defaultValue: "Workspace" })}</SidebarGroupLabel>
|
||||
<SidebarGroupContent>
|
||||
@@ -73,6 +82,7 @@ export function AdminAppSidebar() {
|
||||
tooltip={t(`nav.${item.segment}`, { ns: "common", defaultValue: item.label })}
|
||||
isActive={isActive(pathname, item)}
|
||||
render={<Link href={item.href} />}
|
||||
className="font-medium text-sidebar-foreground/90 hover:text-sidebar-accent-foreground data-active:bg-red-600 data-active:text-white data-active:shadow-sm"
|
||||
>
|
||||
<Icon data-icon="inline-start" aria-hidden />
|
||||
<span>{t(`nav.${item.segment}`, { ns: "common", defaultValue: item.label })}</span>
|
||||
|
||||
@@ -9,5 +9,5 @@ type ModuleScaffoldProps = {
|
||||
|
||||
/** 内容区容器;模块标题由侧栏导航体现,此处不再重复大标题与说明。 */
|
||||
export function ModuleScaffold({ children, className }: ModuleScaffoldProps) {
|
||||
return <div className={cn("mx-auto max-w-5xl", className)}>{children}</div>;
|
||||
return <div className={cn("mx-auto w-full max-w-none", className)}>{children}</div>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user