Filter products using select instead of toggles
This commit is contained in:
@@ -6,12 +6,12 @@ import { Product } from '@/types';
|
||||
import Fuse from 'fuse.js';
|
||||
import { Input } from '@/components/ui/crm-input'
|
||||
import { Button } from '@/components/ui/crm-button'
|
||||
import { Delete, Search, Plus } from "lucide-vue-next"
|
||||
import { Delete, Search, Plus, CheckIcon, ChevronDown } from "lucide-vue-next"
|
||||
import PlaceholderPattern from '@/components/PlaceholderPattern.vue';
|
||||
import { toCurrency, toRoundedCurrency } from '@/lib/utils';
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
|
||||
import { Kbd, KbdGroup } from '@/components/ui/kbd'
|
||||
import { Toggle } from '@/components/ui/toggle'
|
||||
import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue, SelectSeparator } from '@/components/ui/select'
|
||||
|
||||
interface Props {
|
||||
productsData: Product[];
|
||||
@@ -21,6 +21,7 @@ const searchQuery = ref('')
|
||||
const searchField = ref()
|
||||
|
||||
const categoryVisibility = ref<Record<string, boolean>>({});
|
||||
const selectedCategory = ref<string>("all")
|
||||
|
||||
onMounted(() => {
|
||||
initializeCategoryVisibility();
|
||||
@@ -40,11 +41,6 @@ const fuse = computed(() => {
|
||||
})
|
||||
|
||||
const filteredProducts = computed(() => {
|
||||
const visibleCategories = Object.entries(categoryVisibility.value)
|
||||
.filter(([_, isVisible]) => isVisible)
|
||||
.map(([categoryName]) => categoryName);
|
||||
|
||||
if (visibleCategories.length == 0) return []
|
||||
|
||||
let products = props.productsData;
|
||||
|
||||
@@ -54,9 +50,12 @@ const filteredProducts = computed(() => {
|
||||
}
|
||||
|
||||
// Filter nach Kategorien
|
||||
products = products.filter(product =>
|
||||
product.category?.name && visibleCategories.includes(product.category.name)
|
||||
);
|
||||
if (selectedCategory.value !== "all") {
|
||||
products = products.filter(product =>
|
||||
product.category?.name &&
|
||||
product.category.name == selectedCategory.value
|
||||
);
|
||||
}
|
||||
|
||||
return products;
|
||||
});
|
||||
@@ -71,6 +70,7 @@ const categories = computed(() => {
|
||||
return Array.from(categorySet).sort();
|
||||
});
|
||||
|
||||
|
||||
const initializeCategoryVisibility = () => {
|
||||
const visibility: Record<string, boolean> = {};
|
||||
props.productsData.forEach(product => {
|
||||
@@ -99,7 +99,26 @@ const toggleAllCategories = () => {
|
||||
<AppLayout title="Produkte">
|
||||
|
||||
<AppHeader>
|
||||
<template #left></template>
|
||||
<template #left>
|
||||
<!-- Category select -->
|
||||
<Select v-model="selectedCategory">
|
||||
<SelectTrigger class="w-[180px] bg-background">
|
||||
<SelectValue placeholder="Kategorie" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectItem value="all">
|
||||
Alle
|
||||
</SelectItem>
|
||||
<SelectSeparator />
|
||||
<SelectItem v-for="category in categories" :value="category">
|
||||
{{ category }}
|
||||
</SelectItem>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</template>
|
||||
|
||||
<template #middle>
|
||||
<!-- Search field -->
|
||||
<Input ref="search-field" id="search" type="text" placeholder="Filtern" class="px-8 bg-background"
|
||||
@@ -135,19 +154,12 @@ const toggleAllCategories = () => {
|
||||
</template>
|
||||
</AppHeader>
|
||||
|
||||
<div class="flex items-center justify-center mb-8">
|
||||
<Toggle :modelValue="allCategoriesVisible" variant="outline" size="sm" aria-label="Alle Kategorien"
|
||||
@click="toggleAllCategories">Alle</Toggle>
|
||||
<Toggle v-for="category in categories" v-model="categoryVisibility[category]" variant="outline" size="sm"
|
||||
:aria-label="'Kategorie ' + category">{{ category }}</Toggle>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-wrap gap-8 lg:gap-12">
|
||||
<div v-for="product in filteredProducts"
|
||||
class="w-[calc(50%-4*var(--spacing))] md:w-[calc(33%-5.333*var(--spacing))] lg:w-[calc(25%-9*var(--spacing))] xl:w-[calc(20%-9.6*var(--spacing))] flex flex-col gap-4">
|
||||
<div class="w-full relative aspect-4/3 overflow-hidden rounded-lg">
|
||||
<img v-if="product.image" :src="'storage/uploads/products/' + product.image"
|
||||
class="size-full object-cover" loading="lazy" />
|
||||
class="size-full object-cover dark:brightness-75" loading="lazy" />
|
||||
<PlaceholderPattern v-else />
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user