"use client"; import { PlusIcon, RotateCcwIcon, Trash2Icon } from "lucide-react"; import { useMemo } from "react"; import * as z from "zod"; import { ArtifactSelect, CharacterSelect, WeaponSelect, type AdminCatalogArtifact, type AdminCatalogCharacter, type AdminCatalogWeapon } from "@/components/admin/ui/catalog-select"; import { ConstellationSelect, RefinementSelect } from "@/components/admin/ui/option-select"; import { useImageGeneratorDraft } from "@/components/admin/use-image-generator-draft"; import { GuideImageExport } from "@/components/public/guide-image-export"; import { TeamExportImage, type TeamExportData } from "@/components/public/team-search"; 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 { Textarea } from "@/components/ui/textarea"; import { supportsWeaponType } from "@/lib/catalog/lunaris"; const memberSchema = z.object({ characterKey: z.string(), weaponKey: z.string(), artifactKey: z.string(), secondArtifactKey: z.string(), constellation: z.enum(["0", "1", "2", "3", "4", "5", "6", "0-6"]), refinement: z.enum(["1", "2", "3", "4", "5", "1-5"]), damage: z.string() }); const draftSchema = z.object({ title: z.string(), rotationSeconds: z.string(), combo: z.string(), members: z.array(memberSchema).max(4) }); type TeamDraft = z.infer; type TeamMemberDraft = TeamDraft["members"][number]; const emptyMember = (): TeamMemberDraft => ({ characterKey: "", weaponKey: "", artifactKey: "", secondArtifactKey: "", constellation: "0", refinement: "1", damage: "0" }); const INITIAL_TEAM_DRAFT: TeamDraft = { title: "", rotationSeconds: "20", combo: "", members: [] }; const parseTeamDraft = (value: unknown): TeamDraft | null => { const parsed = draftSchema.safeParse(value); return parsed.success ? parsed.data : null; }; const numericValue = (value: string) => Number.isFinite(Number(value)) ? Number(value) : 0; export function TeamImageGenerator({ characters, weapons, artifacts }: { characters: AdminCatalogCharacter[]; weapons: AdminCatalogWeapon[]; artifacts: AdminCatalogArtifact[] }) { const [draft, setDraft, resetDraft] = useImageGeneratorDraft("buzz-sheet:admin-image:team", INITIAL_TEAM_DRAFT, parseTeamDraft); const selectedKeys = draft.members.map((member) => member.characterKey).filter(Boolean); const valid = Boolean(draft.title.trim() && draft.combo.trim() && numericValue(draft.rotationSeconds) > 0 && draft.members.length && draft.members.every((member) => member.characterKey && member.weaponKey && member.artifactKey && member.secondArtifactKey !== member.artifactKey && numericValue(member.damage) >= 0) && new Set(selectedKeys).size === draft.members.length && draft.members.some((member) => numericValue(member.damage) > 0)); const exportTeam = useMemo(() => ({ title: draft.title.trim() || "Team", rotationSeconds: draft.rotationSeconds, combo: draft.combo, members: draft.members.flatMap((member, position) => { const character = characters.find((item) => item.key === member.characterKey); if (!character) return []; return [{ position, constellation: member.constellation, refinement: member.refinement, damage: member.damage, character, weapon: weapons.find((item) => item.key === member.weaponKey) ?? null, artifact: artifacts.find((item) => item.key === member.artifactKey) ?? null, secondArtifact: artifacts.find((item) => item.key === member.secondArtifactKey) ?? null }]; }), }), [artifacts, characters, draft, weapons]); const updateMember = (index: number, update: Partial) => setDraft((current) => ({ ...current, members: current.members.map((member, memberIndex) => memberIndex === index ? { ...member, ...update } : member) })); return
ข้อมูล Teamรองรับตัวละคร 1–4 คน และคำนวณ DPS อัตโนมัติ {!draft.members.length ? ยังไม่มี Teamเพิ่มตัวละครคนแรกเพื่อเริ่มกรอกข้อมูล Team : <> ชื่อ Team setDraft((current) => ({ ...current, title: event.target.value }))} /> ระยะเวลา Rotation (วินาที) setDraft((current) => ({ ...current, rotationSeconds: event.target.value }))} /> Combo