"use client"; import { PlusIcon, RotateCcwIcon } from "lucide-react"; import { useMemo } from "react"; import * as z from "zod"; import { ImageCatalogPicker, type ImageCatalogCharacter, } from "@/components/admin/image-generator-fields"; import { useImageGeneratorDraft } from "@/components/admin/use-image-generator-draft"; import { ConstellationImage, type ConstellationImageGroup, type ConstellationImageGuide, } from "@/components/public/constellation-image"; import { GuideImageExport } from "@/components/public/guide-image-export"; import { Button } from "@/components/ui/button"; import { Card, CardAction, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, } from "@/components/ui/empty"; import { Field, FieldGroup, FieldLabel } from "@/components/ui/field"; import { Input } from "@/components/ui/input"; import { Switch } from "@/components/ui/switch"; import { Textarea } from "@/components/ui/textarea"; const rowSchema = z.object({ level: z.number().int().min(1).max(6), cumulativePercent: z.string(), isGreat: z.boolean(), }); const draftSchema = z.object({ characterKey: z.string(), note: z.string(), rows: z.array(rowSchema).max(6).refine((rows) => rows.length === 0 || rows.length === 6), }); type ConstellationDraft = z.infer; const INITIAL_CONSTELLATION_DRAFT: ConstellationDraft = { characterKey: "", note: "", rows: [], }; const constellationRows = (): ConstellationDraft["rows"] => Array.from({ length: 6 }, (_, index) => ({ level: index + 1, cumulativePercent: "100", isGreat: false, })); const parseConstellationDraft = (value: unknown): ConstellationDraft | null => { const parsed = draftSchema.safeParse(value); return parsed.success ? parsed.data : null; }; function validPercent(value: string): boolean { const number = Number(value); return value.trim().length > 0 && Number.isFinite(number) && number >= -9999 && number <= 9999; } export function ConstellationImageGenerator({ characters, }: { characters: ImageCatalogCharacter[]; }) { const [draft, setDraft, resetDraft] = useImageGeneratorDraft( "buzz-sheet:admin-image:constellation", INITIAL_CONSTELLATION_DRAFT, parseConstellationDraft, ); const character = characters.find((item) => item.key === draft.characterKey); const valid = Boolean(character && draft.rows.every((row) => validPercent(row.cumulativePercent))); const guide = useMemo(() => ({ coverUrl: character?.imageUrl ?? "", character: { name: character?.name ?? "Character", splashImageUrl: character?.splashImageUrl ?? character?.imageUrl ?? null, }, }), [character]); const group = useMemo(() => ({ note: draft.note.trim() || null, rows: draft.rows, }), [draft.note, draft.rows]); return (
ข้อมูล Constellation กรอกดาเมจสะสม C1–C6 เทียบกับ C0 ที่ 100% {!draft.rows.length ? ( ยังไม่มี Constellation สร้างรายการ C1–C6 เพื่อเริ่มกรอกเปอร์เซ็นต์ดาเมจ ) : ( <> ตัวละคร setDraft((current) => ({ ...current, characterKey }))} /> โน้ตท้ายภาพ (ถ้ามี)