Redesign category page and make it responsive
This commit is contained in:
+69
-70
@@ -1,5 +1,4 @@
|
||||
<script lang="ts" setup>
|
||||
|
||||
// import
|
||||
|
||||
import useGetCategories from "~/composables/api/product/useGetCategories";
|
||||
@@ -11,22 +10,35 @@ const { data: categories, suspense } = useGetCategories();
|
||||
const search = ref("");
|
||||
const debouncedSearch = refDebounced(search, 300);
|
||||
|
||||
const selectedCategory = ref("همه دسته ها");
|
||||
|
||||
// computed
|
||||
|
||||
const mainCategoriesMenu = computed(() => {
|
||||
const categoriesList = categories.value
|
||||
? categories.value.map((category) => category.name)
|
||||
: [];
|
||||
categoriesList.unshift("همه دسته ها");
|
||||
|
||||
return categoriesList;
|
||||
});
|
||||
|
||||
const filteredCategories = computed(() => {
|
||||
if (categories.value) {
|
||||
return categories.value
|
||||
.flatMap((mainCategory) => mainCategory.subcategorys)
|
||||
.filter((category) => {
|
||||
if (selectedCategory.value === "همه دسته ها") {
|
||||
return category.name.includes(debouncedSearch.value);
|
||||
}
|
||||
|
||||
if (debouncedSearch.value.length > 0) {
|
||||
return categories.value!.map((cat) => {
|
||||
const copyOfCategory = { ...cat };
|
||||
copyOfCategory.subcategorys = copyOfCategory.subcategorys.filter((subcat) => {
|
||||
return subcat.name.includes(debouncedSearch.value);
|
||||
return (
|
||||
category.name.includes(debouncedSearch.value) &&
|
||||
category.parent === selectedCategory.value
|
||||
);
|
||||
});
|
||||
|
||||
return copyOfCategory;
|
||||
});
|
||||
}
|
||||
|
||||
return categories.value!;
|
||||
return [];
|
||||
});
|
||||
|
||||
// ssr
|
||||
@@ -36,78 +48,65 @@ const response = await suspense();
|
||||
if (response.isError) {
|
||||
throw createError({
|
||||
statusCode: 500,
|
||||
statusMessage: `Error in categories page prefetch`
|
||||
statusMessage: `Error in categories page prefetch`,
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="container">
|
||||
<div class="py-[5rem] flex gap-6 justify-between items-center">
|
||||
<span class="typo-h-3 text-black">دسته بندی ها</span>
|
||||
<Input
|
||||
class="max-w-[400px] w-full rounded-full"
|
||||
variant="outlined"
|
||||
placeholder="جستجو..."
|
||||
v-model="search"
|
||||
>
|
||||
<template #endItem>
|
||||
<div class="flex items-center gap-1">
|
||||
<Icon
|
||||
class="translate-y-[-1px]"
|
||||
name="ci:search"
|
||||
size="24"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</Input>
|
||||
</div>
|
||||
<Transition name="fade" mode="out-in">
|
||||
<div
|
||||
class="flex flex-col gap-20"
|
||||
v-if="filteredCategories.some(cat => cat.subcategorys.length > 0)"
|
||||
>
|
||||
|
||||
<template v-for="mainCategory in filteredCategories">
|
||||
<div
|
||||
class="flex flex-col gap-12"
|
||||
v-if="mainCategory.subcategorys.length > 0"
|
||||
>
|
||||
<div class="w-full flex items-center justify-between gap-8">
|
||||
<div class="flex items-center gap-2">
|
||||
<!-- <img :src="mainCategory.icon" alt="" class="w-[30px] opacity-50" />-->
|
||||
<span class="typo-h-5">
|
||||
{{ mainCategory.name }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="h-px w-full bg-slate-200" />
|
||||
</div>
|
||||
<div
|
||||
v-auto-animate
|
||||
class="grid grid-cols-3 gap-4 w-full"
|
||||
>
|
||||
<CategoryCard
|
||||
v-for="category in mainCategory.subcategorys"
|
||||
:key="category.id"
|
||||
:id="category.id"
|
||||
:category="category.name"
|
||||
:picture="category.image"
|
||||
:count="20"
|
||||
description="یک دسته بندی تستasdasd"
|
||||
dark-layer
|
||||
<div class="pt-20 pb-8 sm:py-20 flex gap-12 sm:gap-6 justify-between items-center max-sm:flex-col max-sm:items-start">
|
||||
<span class="typo-h-5 lg:typo-h-4 text-black">دسته بندی ها</span>
|
||||
<div class="flex items-center gap-4 sm:gap-8 max-sm:w-full">
|
||||
<Input
|
||||
class="max-w-[400px] w-full rounded-full h-[38px] lg:h-[50px]"
|
||||
variant="outlined"
|
||||
placeholder="جستجو..."
|
||||
v-model="search"
|
||||
>
|
||||
<template #endItem>
|
||||
<div class="flex items-center gap-1">
|
||||
<Icon
|
||||
class="translate-y-[-1px] size-[18px] lg:size-[24px]"
|
||||
name="ci:search"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</Input>
|
||||
|
||||
<Select
|
||||
class="whitespace-nowrap max-sm:w-full"
|
||||
:options="mainCategoriesMenu"
|
||||
variant="outlined"
|
||||
placeholder="انتخاب کنید"
|
||||
v-model="selectedCategory"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Transition name="fade" mode="out-in">
|
||||
<div
|
||||
v-if="filteredCategories.length > 0"
|
||||
v-auto-animate
|
||||
class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4 sm:gap-8 w-full"
|
||||
>
|
||||
<CategoryCard
|
||||
v-for="category in filteredCategories"
|
||||
:key="category.id"
|
||||
:id="category.id"
|
||||
:category="category.name"
|
||||
:picture="category.image"
|
||||
:count="20"
|
||||
description="یک دسته بندی تست"
|
||||
dark-layer
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-else class="flex w-full mt-12">
|
||||
<div v-else class="flex w-full sm:mt-12">
|
||||
<div
|
||||
class="flex-col flex-grow py-[12rem] gap-6 border-2 border-slate-200 border-dashed size-full rounded-100 flex-center"
|
||||
class="flex-col flex-grow py-32 sm:py-[12rem] gap-6 border-2 border-slate-200 border-dashed size-full rounded-100 flex-center"
|
||||
>
|
||||
<Icon name="bi:search" size="50" class="**:fill-gray-500" />
|
||||
<Icon name="bi:search" class="**:fill-gray-500 size-[40px] sm:size-[50px]" />
|
||||
<span class="text-lg text-gray-500">
|
||||
دسته بندی یافت نشد :(
|
||||
</span>
|
||||
|
||||
Reference in New Issue
Block a user