perf : improve via lighthouse
CI / Verify (push) Successful in 1m14s
CI / Build immutable images and deploy (push) Failing after 57s

This commit is contained in:
2026-09-08 18:11:15 +07:00 Unverified
parent 63b1ec6629
commit 9a3672dab3
10 changed files with 11999 additions and 40 deletions
+18 -2
View File
@@ -1,13 +1,27 @@
import Image from "next/image";
import Link from "next/link";
import { Suspense } from "react";
import { Button } from "@/components/ui/button";
import { VisitorPresence } from "@/components/public/visitor-presence";
import { getAdminSession } from "@/lib/auth/server";
export async function SiteHeader({ editHref = "/admin", guideId }: { editHref?: string; guideId?: string } = {}) {
async function AdminEditLink({ editHref }: { editHref: string }) {
const isAdmin = Boolean(await getAdminSession());
return isAdmin ? (
<Button
variant="ghost"
size="sm"
nativeButton={false}
render={<Link href={editHref} />}
>
ไปหน้าแก้ไข
</Button>
) : null;
}
export function SiteHeader({ editHref = "/admin", guideId }: { editHref?: string; guideId?: string } = {}) {
return (
<header className="border-b bg-background/95 supports-backdrop-filter:backdrop-blur">
<div className="mx-auto flex min-h-16 w-full max-w-7xl flex-wrap items-center gap-2 px-4 py-2 sm:px-6">
@@ -20,7 +34,9 @@ export async function SiteHeader({ editHref = "/admin", guideId }: { editHref?:
</Link>
<nav aria-label="Public navigation" className="flex items-center gap-1">
<VisitorPresence guideId={guideId} />
{isAdmin ? <Button variant="ghost" size="sm" nativeButton={false} render={<Link href={editHref} />}>ไปหน้าแก้ไข</Button> : null}
<Suspense fallback={null}>
<AdminEditLink editHref={editHref} />
</Suspense>
</nav>
</div>
</header>
+10 -9
View File
@@ -58,7 +58,7 @@ export function StructuredDirectory({ guides }: { guides: GuideCard[] }) {
</InputGroup>
{filtered.length ? (
<div className="grid gap-5 sm:grid-cols-2 lg:grid-cols-3">
{filtered.map((guide) => (
{filtered.map((guide, index) => (
<Link
key={guide.id}
href={`/${guide.slug}`}
@@ -70,20 +70,21 @@ export function StructuredDirectory({ guides }: { guides: GuideCard[] }) {
src={guide.coverUrl}
alt={`ไกด์ ${guide.name}`}
fill
preload={index === 0}
sizes="(min-width: 1024px) 33vw, (min-width: 640px) 50vw, 100vw"
className="object-cover"
/>
</div>
<CardHeader className="pt-5">
<CardTitle>{guide.name}</CardTitle>
{(presence?.byGuide[guide.id] ?? 0) > 0 ? (
<CardAction>
<Badge variant="secondary">
<UsersIcon data-icon="inline-start" />
{presence?.byGuide[guide.id]} คน
</Badge>
</CardAction>
) : null}
<CardAction
className={(presence?.byGuide[guide.id] ?? 0) > 0 ? undefined : "invisible"}
>
<Badge variant="secondary" className="min-w-14 tabular-nums">
<UsersIcon data-icon="inline-start" />
{presence?.byGuide[guide.id] ?? 0} คน
</Badge>
</CardAction>
<CardDescription className="line-clamp-3">
{guide.overview}
</CardDescription>
+12 -4
View File
@@ -9,13 +9,21 @@ export function VisitorPresence({ guideId }: { guideId?: string }) {
const counts = useVisitorPresence(guideId ?? null);
return (
<div className="flex items-center gap-1" aria-live="polite">
<Badge variant="secondary" title="ผู้เข้าชมทั้งหมดที่กำลังออนไลน์">
<Badge
variant="secondary"
className="min-w-24 tabular-nums"
title="ผู้เข้าชมทั้งหมดที่กำลังออนไลน์"
>
<UsersIcon data-icon="inline-start" />
ทั้งหมด {counts?.global ?? ""}
ทั้งหมด {counts?.global ?? "–"}
</Badge>
{guideId ? (
<Badge variant="outline" title="ผู้เข้าชม Guide นี้ที่กำลังออนไลน์">
Guide นี้ {counts?.guide ?? ""}
<Badge
variant="outline"
className="min-w-24 tabular-nums"
title="ผู้เข้าชม Guide นี้ที่กำลังออนไลน์"
>
Guide นี้ {counts?.guide ?? "–"}
</Badge>
) : null}
</div>