diff --git a/components/admin/guide-section-editor.tsx b/components/admin/guide-section-editor.tsx index 71d9e12..d054a8d 100644 --- a/components/admin/guide-section-editor.tsx +++ b/components/admin/guide-section-editor.tsx @@ -37,6 +37,7 @@ import { extraSectionSchema, mainStatOptions, substatOptions, + talentLevelOptions, teamSectionSchema, weaponSectionSchema, } from "@/lib/guides/schemas"; @@ -51,7 +52,7 @@ type ArtifactValue = { id: string; name: string; rows: Array<{ firstArtifactKey: type ArtifactProfile = { sands: string[]; goblet: string[]; circlet: string[]; substats: string[]; targets: Array<{ stat: string; value: string }>; talents: Array<{ type: "NA" | "E" | "Q"; priority: number; level?: string }>; note: string | null } | null; type ConstellationValue = { level: number; detail: string; cumulativePercent: string }; type CatalogConstellation = { level: number; name: string; description: string; iconUrl: string | null }; -type CatalogTalent = { type: "NA" | "E" | "Q"; name: string; description: string; iconUrl: string | null }; +type CatalogTalent = { type: "NA" | "E" | "Q"; name: string; iconUrl: string | null }; type TeamValue = { title: string; rotationSeconds: string; combo: string; members: Array<{ characterKey: string; weaponKey: string | null; artifactKey: string | null; constellation: number; refinement: number; damage: string }> }; export interface GuideSectionEditorProps { @@ -103,6 +104,21 @@ function StatSelect({ label, options, value, max, onChange }: { label: string; o ); } +function TalentLevelPicker({ value, onChange }: { value?: string; onChange: (value?: string) => void }) { + const selected = talentLevelOptions.find((level) => level === value) ?? null; + return ( + onChange(next ?? undefined)}> + + + ไม่พบระดับ + + {(level) => ระดับ {level}} + + + + ); +} + function RowActions({ index, length, move, remove }: { index: number; length: number; move: (from: number, to: number) => void; remove?: () => void }) { return
{remove ? : null}
; } @@ -160,7 +176,15 @@ function ArtifactEditor({ guide, artifacts, initial, catalogTalents }: EditorBas const defaults = DEFAULT_TARGET_STATS.map((stat) => existing.find((target) => target.stat === stat) ?? { stat, value: "" }); return [...defaults, ...existing.filter((target) => !DEFAULT_TARGET_STATS.includes(target.stat as (typeof DEFAULT_TARGET_STATS)[number]))]; }); - const [talents, setTalents] = useState(profile?.talents.length ? profile.talents : (["NA", "E", "Q"] as const).map((type, priority) => ({ type, priority: priority + 1, level: "" }))); + const [talents, setTalents] = useState>(() => { + const source: Array<{ type: "NA" | "E" | "Q"; priority: number; level?: string }> = profile?.talents.length + ? profile.talents + : (["NA", "E", "Q"] as const).map((type, priority) => ({ type, priority: priority + 1 })); + return source.map((talent) => ({ + ...talent, + level: talent.level && talentLevelOptions.includes(talent.level as (typeof talentLevelOptions)[number]) ? talent.level : undefined, + })); + }); const [note, setNote] = useState(profile?.note ?? ""); const value = { groups: groups.map((group) => ({ ...group, rows: group.rows.map((row) => ({ ...row, percent: Number(row.percent) })) })), sands, goblet, circlet, substats, targets: targets.filter((target) => target.stat.trim() && target.value.trim()), talents, note: note || null }; const autosave = useAutosave({ value, valid: artifactSectionSchema.safeParse({ ...value, expectedVersion: guide.version }).success, initialVersion: guide.version, persist: (next, expectedVersion) => saveArtifactSection(guide.id, { ...next, expectedVersion }) }); @@ -175,7 +199,7 @@ function ArtifactEditor({ guide, artifacts, initial, catalogTalents }: EditorBas Recommended Statsเลือกค่าจากรายการแทนปุ่ม และเลือก Main Stat ได้สูงสุด 2 ค่าต่อชิ้น -
Target Stats{targets.map((target, index) =>
setTargets(targets.map((item, itemIndex) => itemIndex === index ? { ...item, stat: event.target.value } : item))} /> setTargets(targets.map((item, itemIndex) => itemIndex === index ? { ...item, value: event.target.value } : item))} />
)}
Talent Priority{orderedTalents.map((talent, index) => { const catalogTalent = catalogTalents.find((item) => item.type === talent.type); return {catalogTalent?.iconUrl ? : null}{index + 1}. {catalogTalent?.name ?? talent.type}{catalogTalent?.description ?? talent.type} setTalents(moveItem(orderedTalents, from, to).map((item, priority) => ({ ...item, priority: priority + 1 })))} />ระดับเป้าหมาย setTalents(talents.map((item) => item.type === talent.type ? { ...item, level: event.target.value } : item))} />; })}
Note (optional)