Add min/max price filter on results page

Two number inputs next to the text filter let users set a price
range. Results outside the range are hidden instantly. Products
with null prices are excluded when a filter is active.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
mariosemes
2026-03-27 07:58:05 +01:00
parent 73f4abbab0
commit 9f06449bae

View File

@@ -11,6 +11,8 @@
let sortBy = $state('price'); let sortBy = $state('price');
let sortAsc = $state(true); let sortAsc = $state(true);
let filterText = $state(''); let filterText = $state('');
let priceMin = $state('');
let priceMax = $state('');
let excludedStores = $state(new Set()); let excludedStores = $state(new Set());
// Per-store progress tracking // Per-store progress tracking
@@ -105,6 +107,14 @@
if (excludedStores.size > 0) { if (excludedStores.size > 0) {
items = items.filter(r => !excludedStores.has(r.storeName)); items = items.filter(r => !excludedStores.has(r.storeName));
} }
const min = priceMin !== '' ? parseFloat(priceMin) : null;
const max = priceMax !== '' ? parseFloat(priceMax) : null;
if (min !== null && !isNaN(min)) {
items = items.filter(r => r.price !== null && r.price >= min);
}
if (max !== null && !isNaN(max)) {
items = items.filter(r => r.price !== null && r.price <= max);
}
items.sort((a, b) => { items.sort((a, b) => {
let cmp = 0; let cmp = 0;
switch (sortBy) { switch (sortBy) {
@@ -309,6 +319,14 @@
class="w-full pl-10 pr-4 py-2.5 bg-surface-raised border border-surface-border rounded-lg text-sm class="w-full pl-10 pr-4 py-2.5 bg-surface-raised border border-surface-border rounded-lg text-sm
text-text-primary placeholder-text-tertiary focus:border-accent/50 focus:ring-1 focus:ring-accent/20 focus:outline-none transition-all" /> text-text-primary placeholder-text-tertiary focus:border-accent/50 focus:ring-1 focus:ring-accent/20 focus:outline-none transition-all" />
</div> </div>
<div class="flex items-center gap-1.5 whitespace-nowrap">
<span class="text-2xs text-text-tertiary">Price:</span>
<input type="number" bind:value={priceMin} placeholder="Min" step="0.01" min="0"
class="w-20 px-2 py-1.5 bg-surface-raised border border-surface-border rounded text-xs text-text-primary placeholder-text-tertiary focus:border-accent/50 focus:outline-none" />
<span class="text-text-tertiary"></span>
<input type="number" bind:value={priceMax} placeholder="Max" step="0.01" min="0"
class="w-20 px-2 py-1.5 bg-surface-raised border border-surface-border rounded text-xs text-text-primary placeholder-text-tertiary focus:border-accent/50 focus:outline-none" />
</div>
<span class="text-xs text-text-tertiary whitespace-nowrap"> <span class="text-xs text-text-tertiary whitespace-nowrap">
{filteredAndSorted().length} of {results.length} {filteredAndSorted().length} of {results.length}
</span> </span>