From 139e6028086282850bc23db56c77d8347e9c2cba Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 3 Dec 2025 11:59:26 -0800 Subject: [PATCH] fetch weapon series from API in collection filters --- .../collection/AddToCollectionModal.svelte | 2 +- .../collection/CollectionFilters.svelte | 41 ++++++++++++++++--- .../collection/WeaponEditPane.svelte | 31 +++++++------- .../collection/weapons/+page.svelte | 2 +- 4 files changed, 54 insertions(+), 22 deletions(-) diff --git a/src/lib/components/collection/AddToCollectionModal.svelte b/src/lib/components/collection/AddToCollectionModal.svelte index fc0b1199..c6c9c6bb 100644 --- a/src/lib/components/collection/AddToCollectionModal.svelte +++ b/src/lib/components/collection/AddToCollectionModal.svelte @@ -45,7 +45,7 @@ let elementFilters = $state([]) let rarityFilters = $state([]) let seasonFilters = $state([]) - let seriesFilters = $state([]) + let seriesFilters = $state<(number | string)[]>([]) let raceFilters = $state([]) let proficiencyFilters = $state([]) let genderFilters = $state([]) diff --git a/src/lib/components/collection/CollectionFilters.svelte b/src/lib/components/collection/CollectionFilters.svelte index 3bb7f3b2..cc3baa9b 100644 --- a/src/lib/components/collection/CollectionFilters.svelte +++ b/src/lib/components/collection/CollectionFilters.svelte @@ -7,6 +7,8 @@ import MultiSelect from '$lib/components/ui/MultiSelect.svelte' import Select from '$lib/components/ui/Select.svelte' import Icon from '$lib/components/Icon.svelte' + import { createQuery, queryOptions } from '@tanstack/svelte-query' + import { entityAdapter } from '$lib/api/adapters/entity.adapter' type EntityType = 'character' | 'weapon' | 'summon' @@ -16,7 +18,8 @@ elementFilters?: number[] rarityFilters?: number[] seasonFilters?: number[] - seriesFilters?: number[] + /** Series filters - number[] for characters, string[] for weapons (UUIDs) */ + seriesFilters?: (number | string)[] raceFilters?: number[] proficiencyFilters?: number[] genderFilters?: number[] @@ -47,7 +50,8 @@ element: number[] rarity: number[] season: number[] - series: number[] + /** Series filters - number[] for characters, string[] for weapons (UUIDs) */ + series: (number | string)[] race: number[] proficiency: number[] gender: number[] @@ -149,17 +153,44 @@ { value: 10, label: 'Katana' } ] + // Fetch weapon series from API (only when entityType is weapon) + const weaponSeriesQuery = createQuery(() => + queryOptions({ + queryKey: ['weaponSeries', 'list'] as const, + queryFn: () => entityAdapter.getWeaponSeriesList(), + enabled: entityType === 'weapon', + staleTime: 1000 * 60 * 60, // 1 hour + gcTime: 1000 * 60 * 60 * 24 // 24 hours + }) + ) + // Convert record maps to arrays for iteration const seasons = Object.entries(CHARACTER_SEASON_NAMES).map(([value, label]) => ({ value: Number(value), label })) - const series = Object.entries(CHARACTER_SERIES_NAMES).map(([value, label]) => ({ + // Character series (hardcoded enum) + const characterSeries = Object.entries(CHARACTER_SERIES_NAMES).map(([value, label]) => ({ value: Number(value), label })) + // Build series options based on entity type + // For weapons: use API-fetched series with string IDs + // For characters: use hardcoded enum with number values + const seriesOptions = $derived.by(() => { + if (entityType === 'weapon' && weaponSeriesQuery.data) { + return weaponSeriesQuery.data + .sort((a, b) => a.order - b.order) + .map((s) => ({ + value: s.id, + label: s.name.en + })) + } + return characterSeries + }) + const races = Object.entries(RACE_LABELS) .filter(([value]) => Number(value) !== 0) // Exclude Unknown .map(([value, label]) => ({ @@ -201,7 +232,7 @@ emitChange() } - function handleSeriesChange(value: number[]) { + function handleSeriesChange(value: (number | string)[]) { seriesFilters = value emitChange() } @@ -281,7 +312,7 @@ {#if effectiveShowFilters.series} = { - 2: { name: 'Dark Opus', slots: 2, keySeries: 3 }, - 3: { name: 'Ultima', slots: 3, keySeries: 13 }, - 17: { name: 'Draconic', slots: 2, keySeries: 27 }, - 22: { name: 'Astral', slots: 1, keySeries: 19 }, - 34: { name: 'Superlative', slots: 2, keySeries: 40 } + // Weapon key slot configuration by series slug + const WEAPON_KEY_SLOTS: Record = { + 'dark-opus': 2, + 'ultima': 3, + 'draconic': 2, + 'draconic-providence': 2, + 'superlative': 2 } - const weaponKeyConfig = $derived(WEAPON_KEY_SERIES[series]) - const hasWeaponKeys = $derived(!!weaponKeyConfig) - const keySlotCount = $derived(weaponKeyConfig?.slots ?? 0) - const keySeries = $derived(weaponKeyConfig?.keySeries ?? 0) + // Check if series has weapon keys using the utility (handles both formats) + const hasWeaponKeys = $derived(seriesHasWeaponKeys(series)) + const keySlotCount = $derived(seriesSlug ? (WEAPON_KEY_SLOTS[seriesSlug] ?? 2) : 0) const hasAxSkills = $derived(weaponData?.ax === true) const axType = $derived(weaponData?.axType ?? 1) @@ -272,7 +273,7 @@
{#if keySlotCount >= 1} = 2} = 3} ([]) let rarityFilters = $state([]) let proficiencyFilters = $state([]) - let seriesFilters = $state([]) + let seriesFilters = $state<(number | string)[]>([]) // Sort state let sortBy = $state('name_asc')