feat(guides): organize schemas and export teams
CI / Verify (push) Successful in 1m6s
CI / Build immutable images and deploy (push) Successful in 2m19s

This commit is contained in:
2026-08-29 18:52:01 +00:00 Unverified
parent ac9a733370
commit 17214a3625
13 changed files with 3751 additions and 46 deletions
+1 -1
View File
@@ -40,7 +40,7 @@ export function CreateGuideFlow({ characters, existingKeys }: { characters: Char
<Field>
<FieldLabel>Guide Image</FieldLabel>
{cover ? (
<div className="relative aspect-video overflow-hidden rounded-lg border">
<div className="relative aspect-square max-w-md overflow-hidden rounded-lg border">
<Image src={cover.url} alt={`Guide cover ${selected.name}`} fill className="object-cover" />
</div>
) : null}
+1 -1
View File
@@ -21,5 +21,5 @@ export function GuideOverviewForm({ guide }: { guide: { id: string; version: num
initialVersion: guide.version,
persist: (next, expectedVersion) => saveGuideOverview(guide.id, { ...next, expectedVersion }),
});
return <Card><CardHeader><CardTitle>Overview</CardTitle><CardDescription>ภาพและข้อความนี้แสดงบนหน้าแรกและส่วนแนะนำของ Guide</CardDescription></CardHeader><CardContent><FieldGroup><Field><FieldLabel>Guide Image</FieldLabel><div className="relative aspect-video max-w-2xl overflow-hidden rounded-lg border"><Image src={cover.url} alt={`Guide ${guide.name}`} fill className="object-cover" /></div><MediaUploader onReady={(asset) => setCover(asset)} /></Field><Field><FieldLabel htmlFor="guide-overview">Overview</FieldLabel><Textarea id="guide-overview" value={overview} maxLength={500} onChange={(event) => setOverview(event.target.value)} /><FieldDescription>{overview.length}/500 ตัวอักษร</FieldDescription></Field></FieldGroup></CardContent><CardFooter className="justify-end"><AutosaveStatus state={autosave} /></CardFooter></Card>;
return <Card><CardHeader><CardTitle>Overview</CardTitle><CardDescription>ภาพและข้อความนี้แสดงบนหน้าแรกและส่วนแนะนำของ Guide</CardDescription></CardHeader><CardContent><FieldGroup><Field><FieldLabel>Guide Image</FieldLabel><div className="relative aspect-square max-w-md overflow-hidden rounded-lg border"><Image src={cover.url} alt={`Guide ${guide.name}`} fill className="object-cover" /></div><MediaUploader onReady={(asset) => setCover(asset)} /></Field><Field><FieldLabel htmlFor="guide-overview">Overview</FieldLabel><Textarea id="guide-overview" value={overview} maxLength={500} onChange={(event) => setOverview(event.target.value)} /><FieldDescription>{overview.length}/500 ตัวอักษร</FieldDescription></Field></FieldGroup></CardContent><CardFooter className="justify-end"><AutosaveStatus state={autosave} /></CardFooter></Card>;
}
+1 -1
View File
@@ -47,7 +47,7 @@ export function StructuredDashboard({ guides, trash, syncJob, catalogVersion }:
{guides.length ? (
<div className="grid gap-5 md:grid-cols-2 xl:grid-cols-3">{guides.map((guide) => (
<Card key={guide.id} className="overflow-hidden py-0">
<div className="relative aspect-video bg-muted"><Image src={guide.coverUrl} alt={`Guide ${guide.name}`} fill className="object-cover" /></div>
<div className="relative aspect-square bg-muted"><Image src={guide.coverUrl} alt={`Guide ${guide.name}`} fill className="object-cover" /></div>
<CardHeader className="pt-5"><CardTitle>{guide.name}</CardTitle><CardDescription className="line-clamp-2">{guide.overview}</CardDescription><CardAction><Badge variant="secondary">v{guide.version}</Badge></CardAction></CardHeader>
<CardContent><p className="text-xs text-muted-foreground">แก้ไขล่าสุด {new Date(guide.updatedAt).toLocaleString("th-TH")}</p></CardContent>
<CardFooter className="justify-between pb-5"><Button render={<Link href={`/admin/${guide.characterKey}`} />} nativeButton={false}>แก้ไข Guide</Button><AlertDialog><AlertDialogTrigger render={<Button variant="ghost" size="icon" />}><Trash2Icon /><span className="sr-only">ย้าย {guide.name} ไปถังขยะ</span></AlertDialogTrigger><AlertDialogContent><AlertDialogHeader><AlertDialogTitle>ย้าย {guide.name} ไปถังขยะ?</AlertDialogTitle><AlertDialogDescription>Guide จะหายจากหน้าเว็บไซต์ทันที และสามารถกู้คืนได้ภายหลัง</AlertDialogDescription></AlertDialogHeader><AlertDialogFooter><AlertDialogCancel>ยกเลิก</AlertDialogCancel><AlertDialogAction onClick={() => run(() => moveGuideToTrash(guide.id), "ย้ายไปถังขยะแล้ว")}>ย้ายไปถังขยะ</AlertDialogAction></AlertDialogFooter></AlertDialogContent></AlertDialog></CardFooter>