Enhance category filtering in MarketPage and market store

- Added a new function `clearCategoryFilters` in the market store to reset selected category filters.
- Updated MarketPage to include an enhanced category filter UI with a clear all button, active filters summary, and improved badge styling for selected categories.
- Introduced computed properties for tracking selected categories and their count, improving user experience in managing filters.

These changes provide a more intuitive and user-friendly interface for category filtering in the market module.
This commit is contained in:
padreug 2025-09-25 23:19:58 +02:00
parent 8aa575ffb1
commit 526caa2689
2 changed files with 93 additions and 9 deletions

View file

@ -804,6 +804,10 @@ export const useMarketStore = defineStore('market', () => {
}
}
const clearCategoryFilters = () => {
filterData.value.categories = []
}
const updateSortOptions = (field: string, order: 'asc' | 'desc' = 'asc') => {
sortOptions.value = { field, order }
}
@ -881,6 +885,7 @@ export const useMarketStore = defineStore('market', () => {
updateFilterData,
clearFilters,
toggleCategoryFilter,
clearCategoryFilters,
updateSortOptions,
formatPrice,
addToStallCart,

View file

@ -52,19 +52,84 @@
</div>
</div>
<!-- Category Filters -->
<!-- Enhanced Category Filters -->
<div v-if="marketStore.allCategories.length > 0" class="mb-6">
<div class="flex flex-wrap gap-2">
<Badge
<div class="flex items-center justify-between mb-3">
<h3 class="text-lg font-semibold text-gray-700">Browse by Category</h3>
<Button
v-if="selectedCategoriesCount > 0"
@click="clearAllCategoryFilters"
variant="ghost"
size="sm"
class="text-sm"
>
Clear All ({{ selectedCategoriesCount }})
<X class="w-4 h-4 ml-1" />
</Button>
</div>
<div class="flex flex-wrap gap-3">
<div
v-for="category in marketStore.allCategories"
:key="category.category"
:variant="category.selected ? 'default' : 'secondary'"
class="cursor-pointer hover:bg-blue-100"
@click="marketStore.toggleCategoryFilter(category.category)"
class="group relative cursor-pointer transition-all duration-200 hover:scale-105"
>
{{ category.category }}
<span class="ml-1 text-xs">({{ category.count }})</span>
<Badge
:variant="category.selected ? 'default' : 'outline'"
class="px-4 py-2 text-sm font-medium transition-all duration-200"
:class="{
'bg-primary text-primary-foreground shadow-md': category.selected,
'hover:bg-primary/10 hover:border-primary': !category.selected,
'ring-2 ring-primary ring-offset-1': category.selected
}"
>
<div class="flex items-center gap-2">
<span>{{ category.category }}</span>
<div
class="px-2 py-0.5 rounded-full text-xs font-bold transition-colors"
:class="category.selected
? 'bg-primary-foreground/20 text-primary-foreground'
: 'bg-secondary text-secondary-foreground'"
>
{{ category.count }}
</div>
</div>
</Badge>
<!-- Selection indicator -->
<div
v-if="category.selected"
class="absolute -top-1 -right-1 w-3 h-3 bg-green-500 rounded-full border-2 border-white shadow-sm"
>
<Check class="w-2 h-2 text-white absolute top-0.5 left-0.5" />
</div>
</div>
</div>
<!-- Active Filters Summary -->
<div v-if="selectedCategoriesCount > 0" class="mt-4 p-3 bg-blue-50 rounded-lg border border-blue-200">
<div class="flex items-center justify-between">
<div class="flex items-center gap-2">
<Filter class="w-4 h-4 text-blue-600" />
<span class="text-sm font-medium text-blue-800">
Active Filters:
</span>
<div class="flex gap-1">
<Badge
v-for="category in selectedCategories"
:key="category"
variant="secondary"
class="text-xs"
>
{{ category }}
</Badge>
</div>
</div>
<div class="text-sm text-blue-600">
{{ productsToDisplay.length }} products found
</div>
</div>
</div>
</div>
@ -107,7 +172,7 @@ import { config } from '@/lib/config'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar'
import { ShoppingCart } from 'lucide-vue-next'
import { ShoppingCart, X, Check, Filter } from 'lucide-vue-next'
import MarketFuzzySearch from '../components/MarketFuzzySearch.vue'
import ProductCard from '../components/ProductCard.vue'
import type { Product } from '../types/market'
@ -232,6 +297,20 @@ const handleCategoryFilter = (category: string) => {
marketStore.toggleCategoryFilter(category)
}
// Computed properties for enhanced category filtering
const selectedCategoriesCount = computed(() => {
return marketStore.filterData.categories.length
})
const selectedCategories = computed(() => {
return marketStore.filterData.categories
})
// Clear all category filters
const clearAllCategoryFilters = () => {
marketStore.clearCategoryFilters()
}
onMounted(() => {
// Only load market if it hasn't been preloaded
if (needsToLoadMarket.value) {