diff --git a/components/admin/guide-overview-form.tsx b/components/admin/guide-overview-form.tsx index b43fba8..af11921 100644 --- a/components/admin/guide-overview-form.tsx +++ b/components/admin/guide-overview-form.tsx @@ -7,23 +7,28 @@ import { saveGuideOverview } from "@/app/admin/actions"; import { AutosaveStatus } from "@/components/admin/autosave-status"; import { MediaUploader } from "@/components/admin/media-uploader"; import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"; -import { Field, FieldDescription, FieldGroup, FieldLabel } from "@/components/ui/field"; +import { Field, FieldDescription, FieldError, FieldGroup, FieldLabel } from "@/components/ui/field"; +import { Input } from "@/components/ui/input"; import { Textarea } from "@/components/ui/textarea"; import { useAutosave } from "@/hooks/use-autosave"; import { adminDraftKey } from "@/lib/editor/local-draft"; +import { parseYouTubeUrl } from "@/lib/guides/youtube"; -export function GuideOverviewForm({ guide }: { guide: { id: string; version: number; overview: string; coverMediaId: string; coverUrl: string; name: string } }) { +export function GuideOverviewForm({ guide }: { guide: { id: string; version: number; overview: string; youtubeUrl: string | null; coverMediaId: string; coverUrl: string; name: string } }) { const [overview, setOverview] = useState(guide.overview); + const [youtubeUrl, setYoutubeUrl] = useState(guide.youtubeUrl ?? ""); const [cover, setCover] = useState({ id: guide.coverMediaId, url: guide.coverUrl }); - const value = { coverMediaId: cover.id, overview }; + const invalidYoutubeUrl = Boolean(youtubeUrl.trim() && !parseYouTubeUrl(youtubeUrl.trim())); + const value = { coverMediaId: cover.id, overview, youtubeUrl }; const incompleteIssues = [ !cover.id ? "กรุณาอัปโหลด Guide Image" : null, !overview.trim() ? "กรุณากรอก Overview" : null, + invalidYoutubeUrl ? "กรุณาใส่ลิงก์วิดีโอ YouTube ที่ถูกต้อง" : null, ].filter((issue): issue is string => Boolean(issue)); - const localDraft = { overview, cover }; + const localDraft = { overview, youtubeUrl, cover }; const autosave = useAutosave({ value, - valid: Boolean(cover.id && overview.trim()), + valid: Boolean(cover.id && overview.trim() && !invalidYoutubeUrl), initialVersion: guide.version, persist: (next, expectedVersion) => saveGuideOverview(guide.id, { ...next, expectedVersion }), storageKey: adminDraftKey(guide.id, "overview"), @@ -33,12 +38,19 @@ export function GuideOverviewForm({ guide }: { guide: { id: string; version: num const draft = candidate as Record; if (typeof draft.overview !== "string" || !draft.cover || typeof draft.cover !== "object") return null; const draftCover = draft.cover as Record; - return typeof draftCover.id === "string" && typeof draftCover.url === "string" ? candidate as typeof localDraft : null; + if (typeof draftCover.id !== "string" || typeof draftCover.url !== "string") return null; + if (draft.youtubeUrl !== undefined && typeof draft.youtubeUrl !== "string") return null; + return { + overview: draft.overview, + youtubeUrl: typeof draft.youtubeUrl === "string" ? draft.youtubeUrl : "", + cover: { id: draftCover.id, url: draftCover.url }, + }; }, restoreLocalDraft: (draft) => { setOverview(draft.overview); + setYoutubeUrl(draft.youtubeUrl); setCover(draft.cover); }, }); - return Overviewภาพและข้อความนี้แสดงบนหน้าแรกและส่วนแนะนำของ GuideGuide Image
{`Guide
setCover(asset)} />
Overview