refactor: flatten admin settings actions

This commit is contained in:
Your Name 2026-05-29 15:32:21 +08:00
parent 1307095960
commit 1abbd740a3

View File

@ -2,72 +2,20 @@
import Link from "next/link"; import Link from "next/link";
import { ArrowLeft } from "lucide-react"; import { ArrowLeft } from "lucide-react";
import { useRouter } from "next/navigation";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { import {
Select, Select,
SelectContent, SelectContent,
SelectGroup,
SelectItem, SelectItem,
SelectLabel,
SelectSeparator,
SelectTrigger, SelectTrigger,
SelectValue, SelectValue,
} from "@/components/ui/select"; } from "@/components/ui/select";
import { Separator } from "@/components/ui/separator"; import { Separator } from "@/components/ui/separator";
import { ADMIN_SETTINGS_NAV_GROUPS } from "../_lib/settings-navigation"; import { ADMIN_SETTINGS_NAV_GROUPS } from "../_lib/settings-navigation";
import type { AdminSettingsNavGroup, AdminSettingsNavItem } from "../_lib/types"; import type { AdminSettingsNavItem } from "../_lib/types";
import { cn } from "@/lib/utils";
function getActiveGroup(activeTab: string) { const ALL_SETTINGS_ITEMS = ADMIN_SETTINGS_NAV_GROUPS.flatMap((group) => group.items);
return ADMIN_SETTINGS_NAV_GROUPS.find((group) =>
group.items.some((item) => item.value === activeTab)
);
}
function SettingsGroupTab({
group,
isActive,
onTabChange,
}: {
group: AdminSettingsNavGroup;
isActive: boolean;
onTabChange: (value: string) => void;
}) {
const defaultItem = group.items[0];
const hasHref = Boolean(defaultItem?.href);
const className = cn(
"h-10 w-full justify-center rounded-2xl border px-4 text-sm font-medium shadow-none transition-colors",
isActive
? "border-foreground/10 bg-foreground text-background hover:bg-foreground/90 hover:text-background dark:border-white/20 dark:bg-white dark:text-black dark:hover:bg-white/90"
: "border-border/70 bg-zinc-50/80 text-muted-foreground hover:bg-background hover:text-foreground"
);
if (!defaultItem) return null;
if (hasHref) {
return (
<Button
asChild
className={className}
size="sm"
variant="ghost"
>
<Link href={defaultItem.href!}>{group.title}</Link>
</Button>
);
}
return (
<Button
className={className}
onClick={() => onTabChange(defaultItem.value)}
size="sm"
variant="ghost"
>
{group.title}
</Button>
);
}
function SettingsQuickAction({ function SettingsQuickAction({
activeTab, activeTab,
@ -125,35 +73,30 @@ export function AdminSettingsNavigation({
activeTab: string; activeTab: string;
onTabChange: (value: string) => void; onTabChange: (value: string) => void;
}) { }) {
const activeGroup = getActiveGroup(activeTab); const router = useRouter();
const groupButtons = ADMIN_SETTINGS_NAV_GROUPS.map((group) => ({ const activeItem = ALL_SETTINGS_ITEMS.find((item) => item.value === activeTab);
group, const handleSelectChange = (value: string) => {
isActive: group.items.some((item) => item.value === activeTab), const nextItem = ALL_SETTINGS_ITEMS.find((item) => item.value === value);
})); if (nextItem?.href) {
router.push(nextItem.href);
return;
}
onTabChange(value);
};
return ( return (
<div className="rounded-2xl border bg-background px-4 py-3 shadow-sm"> <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 flex-col gap-2 md:hidden">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Select onValueChange={onTabChange} value={activeTab}> <Select onValueChange={handleSelectChange} value={activeTab}>
<SelectTrigger className="h-9 flex-1 border-border/70 bg-background shadow-none"> <SelectTrigger className="h-9 flex-1 border-border/70 bg-background shadow-none">
<SelectValue placeholder="选择设置项" /> <SelectValue placeholder={activeItem?.label || "选择设置项"} />
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent>
{ADMIN_SETTINGS_NAV_GROUPS.map((group, groupIndex) => ( {ALL_SETTINGS_ITEMS.map((item) => (
<SelectGroup key={group.title}> <SelectItem key={item.value} value={item.value}>
<SelectLabel>{group.title}</SelectLabel> {item.label}
{group.items </SelectItem>
.filter((item) => !item.href)
.map((item) => (
<SelectItem key={item.value} value={item.value}>
{item.label}
</SelectItem>
))}
{groupIndex < ADMIN_SETTINGS_NAV_GROUPS.length - 1 ? (
<SelectSeparator />
) : null}
</SelectGroup>
))} ))}
</SelectContent> </SelectContent>
</Select> </Select>
@ -172,7 +115,7 @@ export function AdminSettingsNavigation({
</div> </div>
<div className="flex flex-wrap gap-1"> <div className="flex flex-wrap gap-1">
{(activeGroup?.items ?? []).map((item) => ( {ALL_SETTINGS_ITEMS.map((item) => (
<SettingsQuickAction <SettingsQuickAction
activeTab={activeTab} activeTab={activeTab}
item={item} item={item}
@ -188,50 +131,28 @@ export function AdminSettingsNavigation({
Admin Console Admin Console
</div> </div>
{activeGroup ? ( {activeItem ? (
<> <>
<span className="h-1 w-1 shrink-0 rounded-full bg-border" /> <span className="h-1 w-1 shrink-0 rounded-full bg-border" />
<span className="shrink-0 text-muted-foreground text-xs"> <span className="shrink-0 text-muted-foreground text-xs">
{activeGroup.title} {activeItem.label}
</span> </span>
</> </>
) : null} ) : null}
<Separator className="mx-1 h-5 shrink-0" orientation="vertical" /> <Separator className="mx-1 h-5 shrink-0" orientation="vertical" />
<div className="flex min-w-0 flex-1 items-center gap-3 overflow-hidden"> <div className="flex min-w-0 flex-1 items-center gap-2 overflow-x-auto">
<div className="grid w-[420px] min-w-[420px] grid-cols-3 gap-2"> {ALL_SETTINGS_ITEMS.map((item) => (
{groupButtons.map(({ group, isActive }) => ( <div className="min-w-[118px] flex-1" key={item.value}>
<SettingsGroupTab
group={group}
isActive={isActive}
key={group.title}
onTabChange={onTabChange}
/>
))}
</div>
<Separator className="h-6 shrink-0" orientation="vertical" />
<div
className="grid min-w-0 flex-1 gap-2"
style={{
gridTemplateColumns: `repeat(${Math.max(
activeGroup?.items.length || 1,
1
)}, minmax(0, 1fr))`,
}}
>
{(activeGroup?.items ?? []).map((item) => (
<SettingsQuickAction <SettingsQuickAction
activeTab={activeTab} activeTab={activeTab}
item={item} item={item}
key={item.value}
onTabChange={onTabChange} onTabChange={onTabChange}
stretched stretched
/> />
))} </div>
</div> ))}
</div> </div>
<Button <Button