connected to new url param

This commit is contained in:
Mamalizz
2025-10-03 21:40:34 +03:30
parent b60a8962d7
commit 20280b319b
@@ -2,62 +2,44 @@
// imports
import useGetResellersCategories from "~/composables/api/resellers/useGetResellersCategories";
import useGetResellersProducts, {
type GetResellersProductsFilters,
} from "~/composables/api/resellers/useGetResellersProducts";
import { PRODUCT_RANGE } from "~/constants";
import useGetResellersProducts from "~/composables/api/resellers/useGetResellersProducts";
import { useAppParams } from "~/composables/global/useAppParams";
import { PRODUCT_RANGE, PRODUCTS_SORTS } from "~/constants";
// state
const route = useRoute();
const router = useRouter();
const params = inject("params") as GetResellersProductsFilters;
const { sort, in_stock, has_discount, price_gte, price_lte, search, page, slug } = useAppParams();
const isSideShow = useState("side-modal-resellers-product-filters");
const currentCategory = computed({
get: () => {
return Array.isArray(route.params.slug) ? route.params.slug[1] ?? undefined : undefined;
return Array.isArray(slug.value) ? slug.value[1] ?? undefined : undefined;
},
set: (newValue) => {
router.push({ path: `/resellers/category/${newValue}`, query: { ...route.query } });
isSideShow.value = false;
router.push({
name: "resellers-slug",
params: { slug: ["category", `${newValue}`] },
query: { ...route.query },
});
},
});
const sort_filter = ref([
{ title: "جدیدترین ها", value: "newest" },
{ title: "گران ترین ها", value: "price" },
{ title: "ارزان ترین ها", value: "-price" },
]);
const sliderValue = ref([params.price_gte ?? PRODUCT_RANGE.min, params.price_lte ?? PRODUCT_RANGE.max]);
const has_discount = ref(Boolean(params.has_discount) ?? false);
const in_stock = ref(Boolean(params.in_stock) ?? false);
const sliderValue = ref([price_gte.value ?? PRODUCT_RANGE.min, price_lte.value ?? PRODUCT_RANGE.max]);
const sliderValueDebounced = refDebounced(sliderValue, 1000);
const filtersSuccessMessage = ref<{ title: string; status: string } | null>(null);
// queries
const filters = computed(() => {
return {
sort: params.sort ?? "newest",
search: params.search ?? "",
price_gte: params.price_gte ?? PRODUCT_RANGE.min,
price_lte: params.price_lte ?? PRODUCT_RANGE.max,
in_stock: params.in_stock ?? false,
has_discount: params.has_discount ?? false,
category: currentCategory.value,
page: params.page ?? 1,
};
});
const { data: categories, suspense } = useGetResellersCategories();
await suspense();
const { isPending: productsIsPending, status: productsStatus } = useGetResellersProducts(filters);
const { isPending: productsIsPending } = useGetResellersProducts();
// computed
@@ -70,48 +52,23 @@ const allCategories = computed(() => {
// methods
const resetFilters = () => {
params.search = "";
params.sort = "";
search.value = "";
sort.value = "";
sliderValue.value = [PRODUCT_RANGE.min, PRODUCT_RANGE.max];
has_discount.value = false;
in_stock.value = false;
has_discount.value = "false";
in_stock.value = "false";
page.value = 1;
router.push({ path: `/resellers/`, query: { ...route.query } });
isSideShow.value = false;
};
// watch
watch(
() => sliderValueDebounced.value,
(newValue) => {
params.price_gte = newValue[0];
params.price_lte = newValue[1];
}
);
watch(
() => [has_discount.value, in_stock.value],
([newHasDiscount, newInStock]) => {
params.has_discount = newHasDiscount;
params.in_stock = newInStock;
}
);
watch(
() => productsStatus.value,
(nv) => {
if (nv == "success") {
filtersSuccessMessage.value = {
title: "فیلتر اعمال شد",
status: nv,
};
} else if (nv == "error") {
filtersSuccessMessage.value = {
title: "خطایی در اعمال فیلتر رخ داد",
status: nv,
};
}
setTimeout(() => {
filtersSuccessMessage.value = null;
}, 4000);
price_gte.value = newValue[0];
price_lte.value = newValue[1];
}
);
</script>
@@ -129,13 +86,13 @@ watch(
</div>
<div class="w-full flex items-center gap-2">
<button
v-for="(sort, index) in sort_filter"
v-for="(sort_filter, index) in PRODUCTS_SORTS"
:key="index"
@click="params.sort = sort.value"
:class="params.sort == sort.value ? 'bg-black text-white' : 'bg-slate-100'"
@click="sort = sort_filter.value"
:class="sort == sort_filter.value ? 'bg-black text-white' : 'bg-slate-100'"
class="py-1 px-3 cursor-pointer text-nowrap transition-all rounded-md text-xs lg:text-sm"
>
{{ sort.title }}
{{ sort_filter.title }}
</button>
</div>
</div>
@@ -209,32 +166,31 @@ watch(
</div>
</div>
<div class="w-full flex flex-col items-center gap-5">
<Transition
enter-active-class="animate__animated animate__fadeInUp animate__faster"
leave-active-class="animate__animated animate__fadeOutDown animate__faster"
<div class="flex items-center gap-4 w-full">
<Button
:disabled="productsIsPending"
variant="primary"
@click="isSideShow = false"
class="w-full rounded-xl py-3 !cursor-pointer disabled:pointer-events-none z-[3]"
>
<div
v-if="!!filtersSuccessMessage"
class="w-max rounded-full py-1.5 px-3 text-xs border flex-center gap-0.5 z-[2]"
:class="
filtersSuccessMessage.status == 'success'
? 'text-success-600 bg-success-100 border-success-600'
: ' text-danger-600 bg-danger-100 border-danger-600'
"
<Transition
name="fade"
mode="out-in"
>
<span class="text-sm">{{ filtersSuccessMessage.title }}</span>
<Icon
:name="filtersSuccessMessage.status == 'success' ? 'bi:check' : 'bi:x'"
size="20"
/>
</div>
</Transition>
<span class="flex-center gap-3 text-sm">
اعمال فیلتر
<Icon
name="ci:plus"
size="20"
/>
</span>
</Transition>
</Button>
<Button
:disabled="productsIsPending"
variant="solid"
@click="resetFilters"
class="w-full rounded-full py-4 !cursor-pointer disabled:pointer-events-none z-[3]"
class="w-full rounded-xl py-3 !cursor-pointer disabled:pointer-events-none z-[3]"
>
<Transition
name="fade"
@@ -242,7 +198,7 @@ watch(
>
<span
v-if="productsIsPending"
class="flex-center gap-3"
class="flex-center gap-3 text-sm"
>
در حال دریافت اطلاعات
<Icon
@@ -252,7 +208,7 @@ watch(
</span>
<span
v-else
class="flex-center gap-3"
class="flex-center gap-3 text-sm"
>
بازنشانی به پیش فرض
<Icon