refactor: flatten admin settings actions
This commit is contained in:
parent
1307095960
commit
1abbd740a3
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user