feat(team-calc) : add second artifact selection
CI / Verify (push) Successful in 58s
CI / Build immutable images and deploy (push) Successful in 1m59s

This commit is contained in:
2026-09-02 07:34:50 +07:00 Unverified
parent 2c069bf5e9
commit cab7a36f2a
12 changed files with 3308 additions and 12 deletions
+7 -4
View File
@@ -111,7 +111,7 @@ type ArtifactProfile = { sands: string[]; goblet: string[]; circlet: string[]; s
type ConstellationValue = { level: number; detail: string; cumulativePercent: string; isGreat: boolean };
type CatalogConstellation = { level: number; name: string; description: string; iconUrl: string | null };
type CatalogTalent = { type: "NA" | "E" | "Q"; name: string; iconUrl: string | null };
type TeamValue = { id: string; title: string; rotationSeconds: string; combo: string; members: Array<{ characterKey: string; weaponKey: string | null; artifactKey: string | null; constellation: number; refinement: number; damage: string }> };
type TeamValue = { id: string; title: string; rotationSeconds: string; combo: string; members: Array<{ characterKey: string; weaponKey: string | null; artifactKey: string | null; secondArtifactKey: string | null; constellation: number; refinement: number; damage: string }> };
let clientIdCounter = 0;
@@ -564,7 +564,7 @@ function ConstellationEditor({ guide, initial, catalogConstellations }: EditorBa
}
function TeamEditor({ guide, characters, weapons, artifacts, initial }: EditorBase) {
const fallbackMembers = Array.from({ length: 4 }, () => ({ characterKey: "", weaponKey: null, artifactKey: null, constellation: 0, refinement: 1, damage: "0" }));
const fallbackMembers = Array.from({ length: 4 }, () => ({ characterKey: "", weaponKey: null, artifactKey: null, secondArtifactKey: null, constellation: 0, refinement: 1, damage: "0" }));
const teamSensors = useSensors(
useSensor(PointerSensor),
useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }),
@@ -635,10 +635,13 @@ function TeamEditor({ guide, characters, weapons, artifacts, initial }: EditorBa
</CardHeader>
<CardContent>
<FieldGroup>
<Field><FieldLabel className="flex items-center gap-2"><UserRoundIcon />ตัวละคร</FieldLabel><CatalogPicker items={characters} value={member.characterKey} placeholder="ค้นหาชื่อตัวละคร…" onChange={(characterKey) => setTeams(teams.map((item, index) => index === teamIndex ? { ...item, members: item.members.map((candidate, inner) => inner === memberIndex ? { ...candidate, characterKey, weaponKey: null, artifactKey: null, constellation: 0, refinement: 1 } : candidate) } : item))} /></Field>
<Field><FieldLabel className="flex items-center gap-2"><UserRoundIcon />ตัวละคร</FieldLabel><CatalogPicker items={characters} value={member.characterKey} placeholder="ค้นหาชื่อตัวละคร…" onChange={(characterKey) => setTeams(teams.map((item, index) => index === teamIndex ? { ...item, members: item.members.map((candidate, inner) => inner === memberIndex ? { ...candidate, characterKey, weaponKey: null, artifactKey: null, secondArtifactKey: null, constellation: 0, refinement: 1 } : candidate) } : item))} /></Field>
<Field><FieldLabel className="flex items-center gap-2"><ChartNoAxesCombinedIcon />Damage</FieldLabel><Input type="number" min="0" step="0.01" value={member.damage} onChange={(event) => setTeams(teams.map((item, index) => index === teamIndex ? { ...item, members: item.members.map((candidate, inner) => inner === memberIndex ? { ...candidate, damage: event.target.value } : candidate) } : item))} /></Field>
<div className="grid grid-cols-[minmax(0,1fr)_auto] items-end gap-4"><Field className="min-w-0"><FieldLabel className="flex items-center gap-2"><SwordIcon />Weapon</FieldLabel><CatalogPicker items={compatibleWeapons} value={member.weaponKey ?? ""} placeholder="ค้นหาอาวุธที่รองรับ…" rarityBackground onChange={(weaponKey) => setTeams(teams.map((item, index) => index === teamIndex ? { ...item, members: item.members.map((candidate, inner) => inner === memberIndex ? { ...candidate, weaponKey: weaponKey || null } : candidate) } : item))} /></Field><Field className="shrink-0"><FieldLabel className="flex items-center gap-2"><RefreshCcwIcon />Refinement</FieldLabel><ToggleGroup className="flex-nowrap" variant="outline" value={[`R${member.refinement}`]} onValueChange={(selected) => { const refinement = selected[0]; if (refinement) setTeams(teams.map((item, index) => index === teamIndex ? { ...item, members: item.members.map((candidate, inner) => inner === memberIndex ? { ...candidate, refinement: Number(refinement.slice(1)) } : candidate) } : item)); }}>{[1, 2, 3, 4, 5].map((refinement) => <ToggleGroupItem className={SELECTED_TOGGLE_CLASS} key={refinement} value={`R${refinement}`}>R{refinement}</ToggleGroupItem>)}</ToggleGroup></Field></div>
<Field><FieldLabel className="flex items-center gap-2"><GemIcon />Artifact set</FieldLabel><CatalogPicker items={artifacts} value={member.artifactKey ?? ""} placeholder="ค้นหาชุด Artifact…" rarityBackground onChange={(artifactKey) => setTeams(teams.map((item, index) => index === teamIndex ? { ...item, members: item.members.map((candidate, inner) => inner === memberIndex ? { ...candidate, artifactKey: artifactKey || null } : candidate) } : item))} /></Field>
<div className="grid grid-cols-2 gap-4">
<Field><FieldLabel className="flex items-center gap-2"><GemIcon />Artifact set 1</FieldLabel><CatalogPicker items={artifacts} value={member.artifactKey ?? ""} placeholder="ค้นหาชุด Artifact…" rarityBackground onChange={(artifactKey) => setTeams(teams.map((item, index) => index === teamIndex ? { ...item, members: item.members.map((candidate, inner) => inner === memberIndex ? { ...candidate, artifactKey: artifactKey || null } : candidate) } : item))} /></Field>
<Field><FieldLabel className="flex items-center gap-2"><GemIcon />Artifact set 2</FieldLabel><CatalogPicker items={artifacts} value={member.secondArtifactKey ?? ""} placeholder="ค้นหาชุด Artifact…" rarityBackground onChange={(secondArtifactKey) => setTeams(teams.map((item, index) => index === teamIndex ? { ...item, members: item.members.map((candidate, inner) => inner === memberIndex ? { ...candidate, secondArtifactKey: secondArtifactKey || null } : candidate) } : item))} /></Field>
</div>
<Field><FieldLabel className="flex items-center gap-2"><SparklesIcon />Constellation</FieldLabel><ToggleGroup className="flex-wrap justify-start" variant="outline" value={[`C${member.constellation}`]} onValueChange={(selected) => { const constellation = selected[0]; if (constellation) setTeams(teams.map((item, index) => index === teamIndex ? { ...item, members: item.members.map((candidate, inner) => inner === memberIndex ? { ...candidate, constellation: Number(constellation.slice(1)) } : candidate) } : item)); }}>{[0, 1, 2, 3, 4, 5, 6].map((constellation) => <ToggleGroupItem className={SELECTED_TOGGLE_CLASS} key={constellation} value={`C${constellation}`}>C{constellation}</ToggleGroupItem>)}</ToggleGroup></Field>
</FieldGroup>
</CardContent>