diff --git a/src/lib/components/collection/CollectionFilters.svelte b/src/lib/components/collection/CollectionFilters.svelte index bbd596bd..f12fb9b7 100644 --- a/src/lib/components/collection/CollectionFilters.svelte +++ b/src/lib/components/collection/CollectionFilters.svelte @@ -2,6 +2,9 @@ import { CHARACTER_SEASON_NAMES, CHARACTER_SERIES_NAMES } from '$lib/types/enums' import { RACE_LABELS } from '$lib/utils/race' import { GENDER_LABELS } from '$lib/utils/gender' + import type { CollectionSortKey } from '$lib/types/api/collection' + import MultiSelect from '$lib/components/ui/MultiSelect.svelte' + import Select from '$lib/components/ui/Select.svelte' interface Props { elementFilters?: number[] @@ -11,7 +14,9 @@ raceFilters?: number[] proficiencyFilters?: number[] genderFilters?: number[] + sortBy?: CollectionSortKey onFiltersChange?: (filters: CollectionFilterState) => void + onSortChange?: (sort: CollectionSortKey) => void /** Which filter groups to show */ showFilters?: { element?: boolean @@ -22,8 +27,8 @@ proficiency?: boolean gender?: boolean } - /** Layout mode */ - layout?: 'horizontal' | 'vertical' + /** Whether to show the sort dropdown */ + showSort?: boolean } export interface CollectionFilterState { @@ -44,7 +49,9 @@ raceFilters = $bindable([]), proficiencyFilters = $bindable([]), genderFilters = $bindable([]), + sortBy = $bindable('name_asc'), onFiltersChange, + onSortChange, showFilters = { element: true, rarity: true, @@ -54,9 +61,19 @@ proficiency: true, gender: true }, - layout = 'horizontal' + showSort = true }: Props = $props() + // Sort options + const sortOptions: { value: CollectionSortKey; label: string }[] = [ + { value: 'name_asc', label: 'Name A → Z' }, + { value: 'name_desc', label: 'Name Z → A' }, + { value: 'element_asc', label: 'Element ↑' }, + { value: 'element_desc', label: 'Element ↓' }, + { value: 'proficiency_asc', label: 'Proficiency ↑' }, + { value: 'proficiency_desc', label: 'Proficiency ↓' } + ] + // Constants const elements = [ { value: 0, label: 'Null', color: '#888' }, @@ -77,13 +94,13 @@ 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: 3, label: 'Axe' }, + { value: 4, label: 'Spear' }, + { value: 5, label: 'Bow' }, + { value: 6, label: 'Staff' }, { value: 7, label: 'Melee' }, - { value: 8, label: 'Bow' }, - { value: 9, label: 'Harp' }, + { value: 8, label: 'Harp' }, + { value: 9, label: 'Gun' }, { value: 10, label: 'Katana' } ] @@ -124,45 +141,46 @@ }) } - function toggleFilter( - current: number[], - value: number, - setter: (val: number[]) => void - ) { - if (current.includes(value)) { - setter(current.filter((v) => v !== value)) - } else { - setter([...current, value]) - } + function handleElementChange(value: number[]) { + elementFilters = value emitChange() } - function toggleElement(value: number) { - toggleFilter(elementFilters, value, (v) => (elementFilters = v)) + function handleRarityChange(value: number[]) { + rarityFilters = value + emitChange() } - function toggleRarity(value: number) { - toggleFilter(rarityFilters, value, (v) => (rarityFilters = v)) + function handleSeasonChange(value: number[]) { + seasonFilters = value + emitChange() } - function toggleSeason(value: number) { - toggleFilter(seasonFilters, value, (v) => (seasonFilters = v)) + function handleSeriesChange(value: number[]) { + seriesFilters = value + emitChange() } - function toggleSeries(value: number) { - toggleFilter(seriesFilters, value, (v) => (seriesFilters = v)) + function handleRaceChange(value: number[]) { + raceFilters = value + emitChange() } - function toggleRace(value: number) { - toggleFilter(raceFilters, value, (v) => (raceFilters = v)) + function handleProficiencyChange(value: number[]) { + proficiencyFilters = value + emitChange() } - function toggleProficiency(value: number) { - toggleFilter(proficiencyFilters, value, (v) => (proficiencyFilters = v)) + function handleGenderChange(value: number[]) { + genderFilters = value + emitChange() } - function toggleGender(value: number) { - toggleFilter(genderFilters, value, (v) => (genderFilters = v)) + function handleSortChange(value: CollectionSortKey | undefined) { + if (value) { + sortBy = value + onSortChange?.(value) + } } function clearAll() { @@ -187,231 +205,123 @@ ) -
- {#if showFilters.element} -
- Element -
- {#each elements as element} - - {/each} -
-
- {/if} +
+
+ {#if showFilters.element} + + {/if} - {#if showFilters.rarity} -
- Rarity -
- {#each rarities as rarity} - - {/each} -
-
- {/if} + {#if showFilters.rarity} + + {/if} - {#if showFilters.season} -
- Season -
- {#each seasons as season} - - {/each} -
-
- {/if} + {#if showFilters.season} + + {/if} - {#if showFilters.series} -
- Series -
- {#each series as s} - - {/each} -
-
- {/if} + {#if showFilters.series} + + {/if} - {#if showFilters.race} -
- Race -
- {#each races as race} - - {/each} -
-
- {/if} + {#if showFilters.race} + + {/if} - {#if showFilters.proficiency} -
- Proficiency -
- {#each proficiencies as prof} - - {/each} -
-
- {/if} + {#if showFilters.proficiency} + + {/if} - {#if showFilters.gender} -
- Gender -
- {#each genders as gender} - - {/each} -
-
- {/if} + {#if showFilters.gender} + + {/if} - {#if hasActiveFilters} - + {#if hasActiveFilters} + + {/if} +
+ + {#if showSort} +
+