feat : use same size as admin for nav bar

This commit is contained in:
2026-10-08 22:34:49 +07:00 Unverified
parent 065099b2b1
commit 36063fc214
6 changed files with 66 additions and 62 deletions
+32 -30
View File
@@ -63,36 +63,38 @@ export default async function StructuredEditorPage({
<div className="min-h-svh"> <div className="min-h-svh">
<AdminHeader /> <AdminHeader />
<main className="mx-auto flex w-full max-w-7xl flex-col gap-6 px-4 pb-4 sm:px-6 sm:pb-6 lg:px-8 lg:pb-8"> <main className="mx-auto flex w-full max-w-7xl flex-col gap-6 px-4 pb-4 sm:px-6 sm:pb-6 lg:px-8 lg:pb-8">
<header className="flex items-center gap-4"> <div className="flex flex-col">
<Button <header className="flex items-center gap-4">
variant="ghost" <Button
size="icon" variant="ghost"
render={<Link href="/admin" />} size="icon"
nativeButton={false} render={<Link href="/admin" />}
aria-label="กลับ Dashboard" nativeButton={false}
> aria-label="กลับ Dashboard"
<ArrowLeftIcon /> >
</Button> <ArrowLeftIcon />
<div className="relative size-16 shrink-0 overflow-hidden rounded-lg border"> </Button>
<Image src={guide.coverUrl} alt={guide.name} fill sizes="64px" className="object-cover" /> <div className="relative size-16 shrink-0 overflow-hidden rounded-lg border">
</div> <Image src={guide.coverUrl} alt={guide.name} fill sizes="64px" className="object-cover" />
<div className="min-w-0"> </div>
<p className="text-sm text-muted-foreground">{guide.name}</p> <div className="min-w-0">
<h1 className="whitespace-nowrap font-heading text-3xl font-semibold"> <p className="text-sm text-muted-foreground">{guide.name}</p>
{sectionTitle} <h1 className="whitespace-nowrap font-heading text-3xl font-semibold">
</h1> {sectionTitle}
<EditorPresence guideId={guide.id} section={sectionTitle} /> </h1>
</div> <EditorPresence guideId={guide.id} section={sectionTitle} />
<Button className="ml-auto" variant="outline" render={<Link href={`/admin/${guide.characterKey}/preview/${page}`} target="_blank" />} nativeButton={false}> </div>
Preview <Button className="ml-auto" variant="outline" render={<Link href={`/admin/${guide.characterKey}/preview/${page}`} target="_blank" />} nativeButton={false}>
</Button> Preview
</header> </Button>
<GuideSectionNav </header>
guideId={guide.id} <GuideSectionNav
characterKey={guide.characterKey} guideId={guide.id}
current={page} characterKey={guide.characterKey}
extras={extraSections.map(({ id, slug, title }) => ({ id, slug, title }))} current={page}
/> extras={extraSections.map(({ id, slug, title }) => ({ id, slug, title }))}
/>
</div>
<GuideSectionEditor <GuideSectionEditor
key={`${editorSection}:${extraSection?.id ?? "fixed"}:${guide.version}`} key={`${editorSection}:${extraSection?.id ?? "fixed"}:${guide.version}`}
section={editorSection} section={editorSection}
+20 -18
View File
@@ -39,24 +39,26 @@ export default async function GuideOverviewPage({ params }: { params: Promise<{
<div className="min-h-svh"> <div className="min-h-svh">
<AdminHeader /> <AdminHeader />
<main className="mx-auto flex w-full max-w-7xl flex-col gap-8 px-4 pb-4 sm:px-6 sm:pb-6 lg:px-8 lg:pb-8"> <main className="mx-auto flex w-full max-w-7xl flex-col gap-8 px-4 pb-4 sm:px-6 sm:pb-6 lg:px-8 lg:pb-8">
<header className="flex flex-wrap items-center gap-4"> <div className="flex flex-col">
<Button variant="ghost" size="icon" render={<Link href="/admin" />} nativeButton={false} aria-label="กลับ Dashboard"> <header className="flex flex-wrap items-center gap-4">
<ArrowLeftIcon /> <Button variant="ghost" size="icon" render={<Link href="/admin" />} nativeButton={false} aria-label="กลับ Dashboard">
</Button> <ArrowLeftIcon />
<div className="relative size-16 overflow-hidden rounded-lg border"> </Button>
<Image src={guide.coverUrl} alt={guide.name} fill sizes="64px" className="object-cover" /> <div className="relative size-16 overflow-hidden rounded-lg border">
</div> <Image src={guide.coverUrl} alt={guide.name} fill sizes="64px" className="object-cover" />
<div className="min-w-0 flex-1"> </div>
<p className="text-sm text-muted-foreground">เลือกส่วนที่ต้องการแก้ไข</p> <div className="min-w-0 flex-1">
<h1 className="font-heading text-3xl font-semibold">{guide.name}</h1> <p className="text-sm text-muted-foreground">เลือกส่วนที่ต้องการแก้ไข</p>
<EditorPresence guideId={guide.id} section="Overview" /> <h1 className="font-heading text-3xl font-semibold">{guide.name}</h1>
</div> <EditorPresence guideId={guide.id} section="Overview" />
<GuideVisibilityControl guideId={guide.id} guideName={guide.name} isPublic={guide.isPublic} version={guide.version} /> </div>
<Button variant="outline" render={<Link href={`/admin/${guide.characterKey}/preview`} target="_blank" />} nativeButton={false}> <GuideVisibilityControl guideId={guide.id} guideName={guide.name} isPublic={guide.isPublic} version={guide.version} />
Preview <Button variant="outline" render={<Link href={`/admin/${guide.characterKey}/preview`} target="_blank" />} nativeButton={false}>
</Button> Preview
</header> </Button>
<GuideSectionNav guideId={guide.id} characterKey={guide.characterKey} current="overview" extras={extras} /> </header>
<GuideSectionNav guideId={guide.id} characterKey={guide.characterKey} current="overview" extras={extras} />
</div>
<GuideOverviewForm key={guide.version} guide={guide} /> <GuideOverviewForm key={guide.version} guide={guide} />
<div className="grid gap-4 md:grid-cols-2"> <div className="grid gap-4 md:grid-cols-2">
{sections.map(({ slug, title, description }) => ( {sections.map(({ slug, title, description }) => (
+1 -1
View File
@@ -10,7 +10,7 @@ export function EditorPresence({ guideId, section }: { guideId: string; section:
const presence = useAdminPresence(guideId, section); const presence = useAdminPresence(guideId, section);
const editors = presence?.editorsByGuide[guideId] ?? []; const editors = presence?.editorsByGuide[guideId] ?? [];
return ( return (
<div className="flex flex-col items-end gap-1"> <div className="flex flex-col items-start gap-1">
<div className="flex flex-wrap items-center gap-1" aria-live="polite"> <div className="flex flex-wrap items-center gap-1" aria-live="polite">
<Badge variant="secondary"> <Badge variant="secondary">
<UsersIcon data-icon="inline-start" /> <UsersIcon data-icon="inline-start" />
+9 -9
View File
@@ -10,10 +10,10 @@ import { navigationIconPath } from "@/lib/navigation";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
const sections = [ const sections = [
{ slug: "weapon", label: "อาวุธ" }, { slug: "weapon", label: "Weapons" },
{ slug: "artifact", label: "อาร์ติแฟกต์และค่าสถานะ" }, { slug: "artifact", label: "Artifacts & Stats" },
{ slug: "constellations", label: "กลุ่มดาว" }, { slug: "constellations", label: "Constellations" },
{ slug: "team", label: "คำนวณทีม" }, { slug: "team", label: "Team Calc" },
] as const; ] as const;
export function GuideSectionNav({ export function GuideSectionNav({
@@ -36,7 +36,7 @@ export function GuideSectionNav({
}; };
return ( return (
<ScrollableNav <ScrollableNav
ariaLabel="เมนูแก้ไข Guide" ariaLabel="Guide editor navigation"
activeKey={current} activeKey={current}
className="w-full rounded-xl border bg-card p-2" className="w-full rounded-xl border bg-card p-2"
> >
@@ -46,12 +46,12 @@ export function GuideSectionNav({
onClick={confirmNavigation} onClick={confirmNavigation}
aria-current={current === "overview" ? "page" : undefined} aria-current={current === "overview" ? "page" : undefined}
className={cn( 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", "flex min-h-8 shrink-0 items-center gap-2 whitespace-nowrap 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", 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" /> <Image src={navigationIconPath("overview")!} alt="" width={20} height={20} className="size-5 object-contain" />
ภาพรวม Overview
</Link> </Link>
{sections.map((section) => { {sections.map((section) => {
const iconPath = navigationIconPath(section.slug); const iconPath = navigationIconPath(section.slug);
@@ -63,7 +63,7 @@ export function GuideSectionNav({
onClick={confirmNavigation} onClick={confirmNavigation}
aria-current={current === section.slug ? "page" : undefined} aria-current={current === section.slug ? "page" : undefined}
className={cn( 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", "flex min-h-8 shrink-0 items-center gap-2 whitespace-nowrap 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", current === section.slug ? "bg-muted text-foreground" : "text-muted-foreground hover:bg-muted hover:text-foreground",
)} )}
> >
@@ -80,7 +80,7 @@ export function GuideSectionNav({
onClick={confirmNavigation} onClick={confirmNavigation}
aria-current={current === extra.slug ? "page" : undefined} aria-current={current === extra.slug ? "page" : undefined}
className={cn( 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", "flex min-h-8 shrink-0 items-center gap-2 whitespace-nowrap 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", current === extra.slug ? "bg-muted text-foreground" : "text-muted-foreground hover:bg-muted hover:text-foreground",
)} )}
> >
+3 -3
View File
@@ -80,13 +80,13 @@ export function GuidePageShell({
<ScrollableNav <ScrollableNav
ariaLabel={`เมนูคู่มือ ${guide.name}`} ariaLabel={`เมนูคู่มือ ${guide.name}`}
activeKey={section ?? "overview"} activeKey={section ?? "overview"}
className="min-h-11 w-full rounded-xl border bg-card p-1 sm:p-2" className="w-full rounded-xl border bg-card p-2"
> >
<Link <Link
href={baseHref} href={baseHref}
aria-current={!section ? "page" : undefined} aria-current={!section ? "page" : undefined}
className={cn( className={cn(
"flex min-h-11 shrink-0 items-center gap-2 whitespace-nowrap rounded-md px-3 text-sm transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring", "flex min-h-8 shrink-0 items-center gap-2 whitespace-nowrap rounded-md px-3 text-sm transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring",
!section !section
? "bg-primary/15 font-semibold text-primary" ? "bg-primary/15 font-semibold text-primary"
: "text-muted-foreground hover:bg-muted hover:text-foreground", : "text-muted-foreground hover:bg-muted hover:text-foreground",
@@ -108,7 +108,7 @@ export function GuidePageShell({
href={`${baseHref}/${item.slug}`} href={`${baseHref}/${item.slug}`}
aria-current={section === item.slug ? "page" : undefined} aria-current={section === item.slug ? "page" : undefined}
className={cn( className={cn(
"flex min-h-11 shrink-0 items-center gap-2 whitespace-nowrap rounded-md px-3 text-sm transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring", "flex min-h-8 shrink-0 items-center gap-2 whitespace-nowrap rounded-md px-3 text-sm transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring",
section === item.slug section === item.slug
? "bg-primary/15 font-semibold text-primary" ? "bg-primary/15 font-semibold text-primary"
: "text-muted-foreground hover:bg-muted hover:text-foreground", : "text-muted-foreground hover:bg-muted hover:text-foreground",
+1 -1
View File
@@ -3,7 +3,7 @@
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "next dev --turbopack", "dev": "bun --bun next dev --turbopack",
"build": "next build", "build": "next build",
"start": "next start", "start": "next start",
"lint": "eslint .", "lint": "eslint .",