ai-chatbot/app/(admin)/settings/_components/admin-settings-navigation.tsx
2026-05-29 15:41:45 +08:00

157 lines
4.6 KiB
TypeScript

"use client";
import Link from "next/link";
import { ArrowLeft } from "lucide-react";
import { useRouter } from "next/navigation";
import { Button } from "@/components/ui/button";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { ADMIN_SETTINGS_NAV_GROUPS } from "../_lib/settings-navigation";
import type { AdminSettingsNavItem } from "../_lib/types";
const ALL_SETTINGS_ITEMS = ADMIN_SETTINGS_NAV_GROUPS.flatMap((group) => group.items);
function SettingsQuickAction({
activeTab,
item,
onTabChange,
stretched = false,
}: {
activeTab: string;
item: AdminSettingsNavItem;
onTabChange: (value: string) => void;
stretched?: boolean;
}) {
const Icon = item.icon;
const className =
item.value === activeTab
? "border-foreground/10 bg-foreground text-background shadow-sm hover:!bg-foreground/90 hover:!text-background dark:border-white/20 dark:bg-white dark:text-black dark:hover:!bg-white/90 dark:hover:!text-black"
: "border-transparent bg-transparent text-muted-foreground hover:!border-border/80 hover:!bg-zinc-100 hover:!text-foreground dark:hover:!bg-zinc-900/50";
const layoutClassName = stretched
? "h-10 w-full min-w-0 justify-center gap-2 rounded-2xl border px-4"
: "h-9 shrink-0 gap-2 rounded-full border px-3.5";
if (item.href) {
return (
<Button
asChild
className={`${layoutClassName} ${className}`}
size="sm"
variant="ghost"
>
<Link href={item.href}>
<Icon className="h-4 w-4" />
<span className={stretched ? "truncate" : ""}>{item.label}</span>
</Link>
</Button>
);
}
return (
<Button
className={`${layoutClassName} ${className}`}
onClick={() => onTabChange(item.value)}
size="sm"
variant="ghost"
>
<Icon className="h-4 w-4" />
<span className={stretched ? "truncate" : ""}>{item.label}</span>
</Button>
);
}
export function AdminSettingsNavigation({
activeTab,
onTabChange,
}: {
activeTab: string;
onTabChange: (value: string) => void;
}) {
const router = useRouter();
const activeItem = ALL_SETTINGS_ITEMS.find((item) => item.value === activeTab);
const handleSelectChange = (value: string) => {
const nextItem = ALL_SETTINGS_ITEMS.find((item) => item.value === value);
if (nextItem?.href) {
router.push(nextItem.href);
return;
}
onTabChange(value);
};
return (
<div className="rounded-2xl border bg-background px-4 py-3 shadow-sm">
<div className="flex flex-col gap-2 md:hidden">
<div className="flex items-center gap-2">
<Select onValueChange={handleSelectChange} value={activeTab}>
<SelectTrigger className="h-9 flex-1 border-border/70 bg-background shadow-none">
<SelectValue placeholder={activeItem?.label || "选择设置项"} />
</SelectTrigger>
<SelectContent>
{ALL_SETTINGS_ITEMS.map((item) => (
<SelectItem key={item.value} value={item.value}>
{item.label}
</SelectItem>
))}
</SelectContent>
</Select>
<Button
asChild
className="h-9 rounded-full border-border/70 px-3 text-[13px]"
size="sm"
variant="outline"
>
<Link href="/">
<ArrowLeft className="h-3.5 w-3.5" />
返回
</Link>
</Button>
</div>
<div className="flex flex-wrap gap-1">
{ALL_SETTINGS_ITEMS.map((item) => (
<SettingsQuickAction
activeTab={activeTab}
item={item}
key={item.value}
onTabChange={onTabChange}
/>
))}
</div>
</div>
<div className="hidden min-w-0 items-center gap-3 md:flex">
<div className="flex min-w-0 flex-1 items-center gap-2 overflow-x-auto">
{ALL_SETTINGS_ITEMS.map((item) => (
<div className="min-w-[118px] flex-1" key={item.value}>
<SettingsQuickAction
activeTab={activeTab}
item={item}
onTabChange={onTabChange}
stretched
/>
</div>
))}
</div>
<Button
asChild
className="h-9 shrink-0 rounded-full border-border/70 px-3.5 text-[13px]"
size="sm"
variant="outline"
>
<Link href="/">
<ArrowLeft className="h-3.5 w-3.5" />
返回工作台
</Link>
</Button>
</div>
</div>
);
}