diff --git a/src/lib/features/database/weapons/schema.ts b/src/lib/features/database/weapons/schema.ts index 0ecffe4d..ad764ece 100644 --- a/src/lib/features/database/weapons/schema.ts +++ b/src/lib/features/database/weapons/schema.ts @@ -7,6 +7,7 @@ export const WeaponEditSchema = z.object({ element: z.number().int().min(0), proficiency1: z.number().int().min(0).optional().default(0), proficiency2: z.number().int().min(0).optional().default(0), + promotions: z.array(z.number().int().min(1)), min_hp: z.number().int().min(0), max_hp: z.number().int().min(0), max_hp_flb: z.number().int().min(0), @@ -23,17 +24,19 @@ export type WeaponEdit = z.infer export function toEditData(model: any): WeaponEdit { return { name: model?.name ?? '', - granblue_id: model?.granblue_id ?? '', + granblue_id: model?.granblueId ?? model?.granblue_id ?? '', rarity: model?.rarity ?? 1, element: model?.element ?? 0, proficiency1: Array.isArray(model?.proficiency) ? (model.proficiency[0] ?? 0) : (model?.proficiency ?? 0), proficiency2: Array.isArray(model?.proficiency) ? (model.proficiency[1] ?? 0) : 0, - min_hp: model?.hp?.min_hp ?? 0, - max_hp: model?.hp?.max_hp ?? 0, - max_hp_flb: model?.hp?.max_hp_flb ?? 0, - min_atk: model?.atk?.min_atk ?? 0, - max_atk: model?.atk?.max_atk ?? 0, - max_atk_flb: model?.atk?.max_atk_flb ?? 0, + promotions: model?.promotions ?? [], + // API returns camelCase after transformation + min_hp: model?.hp?.minHp ?? model?.hp?.min_hp ?? 0, + max_hp: model?.hp?.maxHp ?? model?.hp?.max_hp ?? 0, + max_hp_flb: model?.hp?.maxHpFlb ?? model?.hp?.max_hp_flb ?? 0, + min_atk: model?.atk?.minAtk ?? model?.atk?.min_atk ?? 0, + max_atk: model?.atk?.maxAtk ?? model?.atk?.max_atk ?? 0, + max_atk_flb: model?.atk?.maxAtkFlb ?? model?.atk?.max_atk_flb ?? 0, flb: model?.uncap?.flb ?? false, ulb: model?.uncap?.ulb ?? false, transcendence: model?.uncap?.transcendence ?? false @@ -47,6 +50,7 @@ export function toPayload(edit: WeaponEdit) { rarity: edit.rarity, element: edit.element, proficiency: [edit.proficiency1, edit.proficiency2].filter(v => v !== 0), + promotions: edit.promotions, hp: { min_hp: edit.min_hp, max_hp: edit.max_hp, diff --git a/src/lib/features/database/weapons/sections/WeaponTaxonomySection.svelte b/src/lib/features/database/weapons/sections/WeaponTaxonomySection.svelte index 67b9a71a..27e1bd5d 100644 --- a/src/lib/features/database/weapons/sections/WeaponTaxonomySection.svelte +++ b/src/lib/features/database/weapons/sections/WeaponTaxonomySection.svelte @@ -10,6 +10,7 @@ import { getElementLabel, getElementOptions } from '$lib/utils/element' import { getProficiencyOptions } from '$lib/utils/proficiency' import { getWeaponSeriesOptions, getWeaponSeriesSlug } from '$lib/utils/weaponSeries' + import { PROMOTION_NAMES, getPromotionNames } from '$lib/types/enums' type ElementName = 'wind' | 'fire' | 'water' | 'earth' | 'dark' | 'light' @@ -38,6 +39,12 @@ const proficiencyOptions = getProficiencyOptions() const seriesOptions = [{ value: 0, label: 'None' }, ...getWeaponSeriesOptions()] + // Promotion options for multiselect + const promotionOptions = Object.entries(PROMOTION_NAMES).map(([value, label]) => ({ + value: Number(value), + label + })) + // Get element name for checkbox theming const elementName = $derived.by((): ElementName | undefined => { const el = editMode ? editData.element : weapon?.element @@ -55,6 +62,12 @@ .map((w) => w.charAt(0).toUpperCase() + w.slice(1)) .join(' ') } + + // Format promotions for display + function formatPromotionsDisplay(promotions: number[]): string { + if (!promotions || promotions.length === 0) return '—' + return getPromotionNames(promotions).join(', ') + } @@ -112,6 +125,15 @@ type="checkbox" element={elementName} /> + {:else} @@ -126,5 +148,6 @@ + {/if}