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 { ArrowLeft } from "lucide-react";
import { useRouter } from "next/navigation";
import { Button } from "@/components/ui/button";
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectLabel,
SelectSeparator,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { Separator } from "@/components/ui/separator";
import { ADMIN_SETTINGS_NAV_GROUPS } from "../_lib/settings-navigation";
import type { AdminSettingsNavGroup, AdminSettingsNavItem } from "../_lib/types";
import { cn } from "@/lib/utils";
import type { AdminSettingsNavItem } from "../_lib/types";
function getActiveGroup(activeTab: string) {
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>
);
}
const ALL_SETTINGS_ITEMS = ADMIN_SETTINGS_NAV_GROUPS.flatMap((group) => group.items);
function SettingsQuickAction({
activeTab,
@ -125,35 +73,30 @@ export function AdminSettingsNavigation({
activeTab: string;
onTabChange: (value: string) => void;
}) {
const activeGroup = getActiveGroup(activeTab);
const groupButtons = ADMIN_SETTINGS_NAV_GROUPS.map((group) => ({
group,
isActive: group.items.some((item) => item.value === activeTab),
}));
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={onTabChange} value={activeTab}>
<Select onValueChange={handleSelectChange} value={activeTab}>
<SelectTrigger className="h-9 flex-1 border-border/70 bg-background shadow-none">
<SelectValue placeholder="选择设置项" />
<SelectValue placeholder={activeItem?.label || "选择设置项"} />
</SelectTrigger>
<SelectContent>
{ADMIN_SETTINGS_NAV_GROUPS.map((group, groupIndex) => (
<SelectGroup key={group.title}>
<SelectLabel>{group.title}</SelectLabel>
{group.items
.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>
{ALL_SETTINGS_ITEMS.map((item) => (
<SelectItem key={item.value} value={item.value}>
{item.label}
</SelectItem>
))}
</SelectContent>
</Select>
@ -172,7 +115,7 @@ export function AdminSettingsNavigation({
</div>
<div className="flex flex-wrap gap-1">
{(activeGroup?.items ?? []).map((item) => (
{ALL_SETTINGS_ITEMS.map((item) => (
<SettingsQuickAction
activeTab={activeTab}
item={item}
@ -188,50 +131,28 @@ export function AdminSettingsNavigation({
Admin Console
</div>
{activeGroup ? (
{activeItem ? (
<>
<span className="h-1 w-1 shrink-0 rounded-full bg-border" />
<span className="shrink-0 text-muted-foreground text-xs">
{activeGroup.title}
{activeItem.label}
</span>
</>
) : null}
<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="grid w-[420px] min-w-[420px] grid-cols-3 gap-2">
{groupButtons.map(({ group, isActive }) => (
<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) => (
<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}
key={item.value}
onTabChange={onTabChange}
stretched
/>
))}
</div>
</div>
))}
</div>
<Button