Files
buzz-sheet/components/admin/guide-section-nav.tsx
T
gunshiz e0794822b1
CI / Verify (push) Successful in 1m18s
CI / Build immutable images and deploy (push) Successful in 1m57s
feat(i18n) : add personal languages and compact weapon exports
2026-09-14 16:44:44 +07:00

96 lines
3.7 KiB
TypeScript

"use client";
import { useTranslation } from "@/components/i18n/locale-provider";
import Image from "next/image";
import Link from "next/link";
import type { MouseEvent } from "react";
import { AddExtraButton } from "@/components/admin/guide-extra-controls";
import { ScrollableNav } from "@/components/public/scrollable-nav";
import { navigationIconPath } from "@/lib/navigation";
import { cn } from "@/lib/utils";
const sections = [
{ slug: "weapon", label: "Weapons" },
{ slug: "artifact", label: "Artifacts & Stats" },
{ slug: "constellations", label: "Constellations" },
{ slug: "team", label: "Team Calc" },
] as const;
export function GuideSectionNav({
guideId,
characterKey,
current,
extras,
}: {
guideId: string;
characterKey: string;
current: string;
extras: Array<{ id: string; slug: string; title: string }>;
}) {
const { t } = useTranslation();
const confirmNavigation = (event: MouseEvent<HTMLAnchorElement>) => {
const browserWindow = window as Window & { __guideHasUnsavedChanges?: boolean };
if (typeof window !== "undefined" && browserWindow.__guideHasUnsavedChanges && !window.confirm(t("ข้อมูลยังบันทึกไม่เสร็จหรือไม่ถูกต้อง ต้องการออกจากหน้านี้หรือไม่?"))) {
event.preventDefault();
}
};
return (
<ScrollableNav
ariaLabel={t("เมนูแก้ไข Guide")}
className="w-full rounded-xl border bg-card p-2"
>
<Link
href={`/admin/${characterKey}`}
prefetch={false}
onClick={confirmNavigation}
className={cn(
"flex min-h-8 shrink-0 items-center gap-2 rounded-md px-3 text-sm outline-none focus-visible:ring-2 focus-visible:ring-ring",
current === "overview" ? "bg-muted text-foreground" : "text-muted-foreground hover:bg-muted hover:text-foreground",
)}
>
<Image src={navigationIconPath("overview")!} alt="" width={20} height={20} className="size-5 object-contain" />
{t("Overview")}</Link>
{sections.map((section) => {
const iconPath = navigationIconPath(section.slug);
return (
<Link
key={section.slug}
href={`/admin/${characterKey}/${section.slug}`}
prefetch={false}
onClick={confirmNavigation}
className={cn(
"flex min-h-8 shrink-0 items-center gap-2 rounded-md px-3 text-sm outline-none focus-visible:ring-2 focus-visible:ring-ring",
current === section.slug ? "bg-muted text-foreground" : "text-muted-foreground hover:bg-muted hover:text-foreground",
)}
>
{iconPath ? <Image src={iconPath} alt="" width={20} height={20} className="size-5 object-contain" /> : null}
{t(section.label)}
</Link>
);
})}
{extras.map((extra) => (
<Link
key={extra.id}
href={`/admin/${characterKey}/${extra.slug}`}
prefetch={false}
onClick={confirmNavigation}
className={cn(
"flex min-h-8 shrink-0 items-center gap-2 rounded-md px-3 text-sm outline-none focus-visible:ring-2 focus-visible:ring-ring",
current === extra.slug ? "bg-muted text-foreground" : "text-muted-foreground hover:bg-muted hover:text-foreground",
)}
>
<Image src={navigationIconPath("extra")!} alt="" width={20} height={20} className="size-5 object-contain" />
{extra.title}
</Link>
))}
<AddExtraButton
guideId={guideId}
characterKey={characterKey}
size="icon-sm"
label=""
/>
</ScrollableNav>
);
}