From 34db5dd6aa5222c4c9383f807040a83b7c355639 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Sun, 4 Jan 2026 19:53:36 -0800 Subject: [PATCH] refactor SearchContent filters layout with inline clear links --- .../components/sidebar/SearchContent.svelte | 215 +++++++++++------- 1 file changed, 134 insertions(+), 81 deletions(-) diff --git a/src/lib/components/sidebar/SearchContent.svelte b/src/lib/components/sidebar/SearchContent.svelte index 4467fa5f..c88c8fac 100644 --- a/src/lib/components/sidebar/SearchContent.svelte +++ b/src/lib/components/sidebar/SearchContent.svelte @@ -6,11 +6,15 @@ import type { SearchResult } from '$lib/api/adapters/search.adapter' import { searchQueries, type SearchFilters } from '$lib/api/queries/search.queries' import { collectionQueries } from '$lib/api/queries/collection.queries' + import { entityQueries } from '$lib/api/queries/entity.queries' import Button from '../ui/Button.svelte' + import Select from '../ui/Select.svelte' import Icon from '../Icon.svelte' import Input from '../ui/Input.svelte' import CharacterTags from '$lib/components/tags/CharacterTags.svelte' import ElementPicker from '../ui/element-picker/ElementPicker.svelte' + import RarityPicker from '../ui/rarity-picker/RarityPicker.svelte' + import ProficiencyPicker from '../ui/proficiency-picker/ProficiencyPicker.svelte' import { useInfiniteLoader } from '$lib/stores/loaderState.svelte' import { getCharacterImage, getWeaponImage, getSummonImage } from '$lib/features/database/detail/image' import type { AddItemResult, SearchMode } from '$lib/types/api/search' @@ -43,6 +47,7 @@ let elementFilters = $state([]) let rarityFilters = $state([]) let proficiencyFilters = $state([]) + let seriesFilter = $state(undefined) // Search mode state (only available when authUserId is provided) let searchMode = $state('all') @@ -61,25 +66,7 @@ { value: 6, label: 'Light', color: 'var(--light-bg)' } ] - const rarities = [ - { value: 1, label: 'R' }, - { value: 2, label: 'SR' }, - { value: 3, label: 'SSR' } - ] - - const proficiencies = [ - { value: 1, label: 'Sabre' }, - { value: 2, label: 'Dagger' }, - { value: 3, label: 'Spear' }, - { value: 4, label: 'Axe' }, - { value: 5, label: 'Staff' }, - { value: 6, label: 'Gun' }, - { value: 7, label: 'Melee' }, - { value: 8, label: 'Bow' }, - { value: 9, label: 'Harp' }, - { value: 10, label: 'Katana' } - ] - + // Debounce search query changes $effect(() => { const query = searchQuery @@ -99,6 +86,28 @@ } }) + // Series query - fetch list based on current type + const seriesQuery = createQuery(() => { + switch (type) { + case 'weapon': + return entityQueries.weaponSeriesList() + case 'character': + return entityQueries.characterSeriesList() + case 'summon': + return entityQueries.summonSeriesList() + } + }) + + // Build series options for dropdown (use ID for API filtering) + const seriesOptions = $derived.by(() => { + const data = seriesQuery.data + if (!data) return [] + return data.map((s) => ({ + value: s.id, + label: s.name.en + })) + }) + // Build filters object for query // Use requiredProficiencies for mainhand selection if set, otherwise use user-selected filters const effectiveProficiencies = $derived( @@ -108,7 +117,8 @@ const filters = $derived({ element: elementFilters.length > 0 ? elementFilters : undefined, rarity: rarityFilters.length > 0 ? rarityFilters : undefined, - proficiency: type === 'weapon' && effectiveProficiencies ? effectiveProficiencies : undefined + proficiency: type === 'weapon' && effectiveProficiencies ? effectiveProficiencies : undefined, + series: seriesFilter ? [seriesFilter] : undefined }) // Helper to map collection items to search result format with collectionId @@ -282,20 +292,16 @@ elementFilters = Array.isArray(value) ? value : value !== undefined ? [value] : [] } - function toggleRarityFilter(rarity: number) { - if (rarityFilters.includes(rarity)) { - rarityFilters = rarityFilters.filter(r => r !== rarity) - } else { - rarityFilters = [...rarityFilters, rarity] - } + function handleRarityChange(value: number | number[]) { + rarityFilters = Array.isArray(value) ? value : value !== undefined ? [value] : [] } - function toggleProficiencyFilter(prof: number) { - if (proficiencyFilters.includes(prof)) { - proficiencyFilters = proficiencyFilters.filter(p => p !== prof) - } else { - proficiencyFilters = [...proficiencyFilters, prof] - } + function handleSeriesChange(value: string | undefined) { + seriesFilter = value + } + + function handleProficiencyChange(value: number | number[]) { + proficiencyFilters = Array.isArray(value) ? value : value !== undefined ? [value] : [] } function getImageUrl(item: AddItemResult): string { @@ -354,54 +360,78 @@ {/if}
- -
- - -
+ +
+
+
+ + {#if rarityFilters.length > 0} + { e.preventDefault(); rarityFilters = [] }}>Clear + {/if} +
+ +
- -
- -
- {#each rarities as rarity} - - {/each} +
+
+ + {#if elementFilters.length > 0} + { e.preventDefault(); elementFilters = [] }}>Clear + {/if} +
+
- - {#if type === 'weapon' && !requiredProficiencies} + + {#if (type === 'weapon' || type === 'character') && !requiredProficiencies}
- -
- {#each proficiencies as prof} - - {/each} +
+ + {#if proficiencyFilters.length > 0} + { e.preventDefault(); proficiencyFilters = [] }}>Clear + {/if}
+
{/if} + + +
+
+ + {#if seriesFilter} + { e.preventDefault(); seriesFilter = undefined }}>Clear + {/if} +
+