refactor(guides) : consolidate duplicate guide and Stygian logic

This commit is contained in:
2026-10-07 01:41:13 +07:00 Unverified
parent 3c8f60433a
commit b35c1a4471
17 changed files with 268 additions and 171 deletions
+9 -14
View File
@@ -48,6 +48,7 @@ import {
import { Textarea } from "@/components/ui/textarea";
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";
import { supportsWeaponType } from "@/lib/catalog/lunaris";
import { isValidPercent } from "@/lib/guides/percent-input";
const rowSchema = z.object({
id: z.string(),
@@ -92,12 +93,6 @@ const parseWeaponDraft = (value: unknown): WeaponDraft | null => {
return parsed.success ? parsed.data : null;
};
function validPercent(value: string): boolean {
if (!value.trim()) return false;
const number = Number(value);
return Number.isFinite(number) && number >= -9999 && number <= 9999;
}
export function WeaponImageGenerator({
characters,
weapons,
@@ -118,9 +113,9 @@ export function WeaponImageGenerator({
character &&
draft.rows.every((row) =>
compatibleWeapons.some((weapon) => weapon.key === row.weaponKey) &&
(validPercent(row.overallPercent) || validPercent(row.personalPercent)),
(isValidPercent(row.overallPercent) || isValidPercent(row.personalPercent)),
) &&
draft.rows.some((row) => validPercent(row[draft.metric])),
draft.rows.some((row) => isValidPercent(row[draft.metric])),
);
const guide = useMemo<WeaponExportGuide>(() => ({
@@ -141,8 +136,8 @@ export function WeaponImageGenerator({
return [{
id: row.id,
refinement: row.refinement,
overallPercent: validPercent(row.overallPercent) ? row.overallPercent : null,
personalPercent: validPercent(row.personalPercent) ? row.personalPercent : null,
overallPercent: isValidPercent(row.overallPercent) ? row.overallPercent : null,
personalPercent: isValidPercent(row.personalPercent) ? row.personalPercent : null,
note: row.note.trim() || null,
weapon,
}];
@@ -261,13 +256,13 @@ export function WeaponImageGenerator({
</SelectGroup></SelectContent>
</Select>
</Field>
<Field data-invalid={Boolean(row.overallPercent) && !validPercent(row.overallPercent)}>
<Field data-invalid={Boolean(row.overallPercent) && !isValidPercent(row.overallPercent)}>
<FieldLabel htmlFor={`${row.id}-overall`}>Overall %</FieldLabel>
<Input id={`${row.id}-overall`} type="number" value={row.overallPercent} aria-invalid={Boolean(row.overallPercent) && !validPercent(row.overallPercent)} onChange={(event) => updateRow(row.id, { overallPercent: event.target.value })} />
<Input id={`${row.id}-overall`} type="number" value={row.overallPercent} aria-invalid={Boolean(row.overallPercent) && !isValidPercent(row.overallPercent)} onChange={(event) => updateRow(row.id, { overallPercent: event.target.value })} />
</Field>
<Field data-invalid={Boolean(row.personalPercent) && !validPercent(row.personalPercent)}>
<Field data-invalid={Boolean(row.personalPercent) && !isValidPercent(row.personalPercent)}>
<FieldLabel htmlFor={`${row.id}-personal`}>Personal %</FieldLabel>
<Input id={`${row.id}-personal`} type="number" value={row.personalPercent} aria-invalid={Boolean(row.personalPercent) && !validPercent(row.personalPercent)} onChange={(event) => updateRow(row.id, { personalPercent: event.target.value })} />
<Input id={`${row.id}-personal`} type="number" value={row.personalPercent} aria-invalid={Boolean(row.personalPercent) && !isValidPercent(row.personalPercent)} onChange={(event) => updateRow(row.id, { personalPercent: event.target.value })} />
</Field>
</div>
<Field>