added pagination

This commit is contained in:
Mamalizz
2025-01-19 19:19:16 +03:30
parent 2748a024d8
commit 02ca612716
+72 -29
View File
@@ -8,31 +8,48 @@ import { PRODUCT_RANGE } from "~/constants";
// state
const route = useRoute();
const params: GetProductsFilters = useUrlSearchParams("history", {
initialValue: {
search: "",
sort: "newest",
price_gte: PRODUCT_RANGE.min,
price_lte: PRODUCT_RANGE.max,
in_stock: false,
has_discount: false,
category: "",
page: "1",
},
});
const params: GetProductsFilters & { page: number } =
useUrlSearchParams("history");
const search = ref(params.search ?? "");
const searchDebounced = refDebounced(search, 1000);
// computed
// provide / inject
const page = computed(() => (route.query["page"] ? +route.query["page"] : 1));
provide("params", params);
// queries
const { data: products, isLoading: productsIsLoading } = useGetProducts(
params,
page
);
const { data, isLoading: productsIsLoading } = useGetProducts(params);
// life-cycle
onMounted(() => {
if (!("range" in params)) {
params.range = [];
params.range[0] = PRODUCT_RANGE.min;
params.range[1] = PRODUCT_RANGE.max;
}
const products = computed(() => {
return data.value?.results.flat();
});
const paginationData = computed(() => {
return data!.value?.results.map((_, i: number) => {
return { type: "page", value: i };
});
});
// watch
watch(
() => searchDebounced.value,
(newValue) => {
params.search = newValue;
}
);
</script>
<template>
@@ -54,24 +71,50 @@ onMounted(() => {
<div class="w-full flex items-center justify-end gap-4">
<Input
placeholder="جست و جو محصول ..."
v-model="search"
class="bg-slate-50 !border-slate-200 hover:border-slate-300 focus:!border-slate-800 !rounded-full w-8/12"
/>
<FilterButton />
</div>
</div>
<ul class="w-full grid grid-cols-3 gap-[1.5rem]">
<li v-for="i in 9" :key="i">
<ProductCard
brand="Samsung"
title="Galaxy S20 Ultra"
picture="/assets/img/product-1.jpg"
:colors="['#0000ff', '#00ff00', 'red']"
:price="599"
:rate="2.4"
tag="New"
/>
</li>
<ul
v-if="productsIsLoading"
class="w-full grid grid-cols-3 gap-[1.5rem]"
>
<Skeleton
v-for="i in 9"
:key="i"
class="w-full !h-[31.25rem] !rounded-2xl"
/>
</ul>
<div v-else class="w-full h-max">
<div v-if="!products?.length" class="flex flex-grow px-5 w-full">
<div
class="flex-col flex-grow 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" />
<span class="text-lg text-gray-500">
محصولی یافت نشد :(
</span>
</div>
</div>
<ul v-else class="w-full grid grid-cols-3 gap-[1.5rem]">
<li v-for="(product, index) in products" :key="index">
<ProductCard
brand="Samsung"
:title="product.name"
picture="/assets/img/product-1.jpg"
:colors="['#0000ff', '#00ff00', 'red']"
:price="product.price"
:rate="product.rating"
tag="New"
/>
</li>
</ul>
<div class="w-full flex-center py-10">
<Pagination :items="paginationData" :total="data?.count" />
</div>
</div>
</div>
</template>