Merge branch 'main' of https://github.com/Byeto-Company/hossein_por_shop
This commit is contained in:
@@ -36,7 +36,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&:disabled {
|
&:disabled {
|
||||||
@apply bg-slate-100 text-slate-400;
|
@apply bg-slate-200/50 text-slate-400;
|
||||||
|
|
||||||
svg[class~="iconify"] path {
|
svg[class~="iconify"] path {
|
||||||
@apply stroke-slate-400;
|
@apply stroke-slate-400;
|
||||||
@@ -61,7 +61,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&:disabled {
|
&:disabled {
|
||||||
@apply bg-slate-100 text-slate-400;
|
@apply bg-slate-200/50 text-slate-400;
|
||||||
|
|
||||||
svg[class~="iconify"] path {
|
svg[class~="iconify"] path {
|
||||||
@apply stroke-slate-400;
|
@apply stroke-slate-400;
|
||||||
@@ -82,7 +82,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&:disabled {
|
&:disabled {
|
||||||
@apply bg-slate-100 text-slate-400;
|
@apply bg-slate-200/50 text-slate-400;
|
||||||
|
|
||||||
svg[class~="iconify"] path {
|
svg[class~="iconify"] path {
|
||||||
@apply stroke-slate-400;
|
@apply stroke-slate-400;
|
||||||
|
|||||||
+809
-828
File diff suppressed because it is too large
Load Diff
@@ -35,6 +35,8 @@ const { mutateAsync: deleteSpecialDiscountCode, isPending: deleteSpecialDiscount
|
|||||||
|
|
||||||
const { mutateAsync: pay, isPending: paymentIsPending } = usePayOrder();
|
const { mutateAsync: pay, isPending: paymentIsPending } = usePayOrder();
|
||||||
|
|
||||||
|
const isTermsAccepted = ref(false);
|
||||||
|
|
||||||
// computed
|
// computed
|
||||||
|
|
||||||
const nextPage = computed(() => route.meta.nextPage as { name: string; label: string; query?: string } | undefined);
|
const nextPage = computed(() => route.meta.nextPage as { name: string; label: string; query?: string } | undefined);
|
||||||
@@ -99,7 +101,7 @@ const handleSubmitSpecialDiscountCode = () => {
|
|||||||
});
|
});
|
||||||
specialDiscountCode.value = "";
|
specialDiscountCode.value = "";
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -141,7 +143,7 @@ const handlePayment = () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -155,7 +157,7 @@ watch(
|
|||||||
} else {
|
} else {
|
||||||
discountCode.value = "";
|
discountCode.value = "";
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@@ -166,7 +168,7 @@ watch(
|
|||||||
} else {
|
} else {
|
||||||
specialDiscountCode.value = "";
|
specialDiscountCode.value = "";
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -312,6 +314,7 @@ watch(
|
|||||||
class="w-full rounded-100"
|
class="w-full rounded-100"
|
||||||
@click="handlePayment"
|
@click="handlePayment"
|
||||||
variant="primary"
|
variant="primary"
|
||||||
|
:disabled="!isTermsAccepted"
|
||||||
>
|
>
|
||||||
{{ nextPage?.label }}
|
{{ nextPage?.label }}
|
||||||
</Button>
|
</Button>
|
||||||
@@ -329,6 +332,40 @@ watch(
|
|||||||
</Button>
|
</Button>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-if="nextPage?.name == 'payment'"
|
||||||
|
class="flex items-center gap-3 ps-2 pt-1 pb-3"
|
||||||
|
>
|
||||||
|
<label class="translate-y-0.5">
|
||||||
|
<input
|
||||||
|
id="payment-terms-accept-checkbox"
|
||||||
|
v-model="isTermsAccepted"
|
||||||
|
type="checkbox"
|
||||||
|
hidden
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
@click="isTermsAccepted = !isTermsAccepted"
|
||||||
|
class="rounded-sm size-5 border-[1.5px] cursor-pointer transition-colors"
|
||||||
|
:class="isTermsAccepted ? 'border-blue-500 bg-blue-500' : 'border-slate-400 bg-transparent'"
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
name="ci:bi-check"
|
||||||
|
class="-translate-x-px **:fill-white transition-all"
|
||||||
|
:class="isTermsAccepted ? 'opacity-100' : 'opacity-0'"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</label>
|
||||||
|
<div class="whitespace-nowrap text-sm">
|
||||||
|
<NuxtLink
|
||||||
|
to="/terms"
|
||||||
|
class="text-blue-600 underline"
|
||||||
|
>
|
||||||
|
قوانین و مقررات
|
||||||
|
</NuxtLink>
|
||||||
|
را خوانده و قبول دارم
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<PaymentPendingModal v-model:isShow="paymentIsPending" />
|
<PaymentPendingModal v-model:isShow="paymentIsPending" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,14 +6,16 @@ type Props = {
|
|||||||
startIcon?: string;
|
startIcon?: string;
|
||||||
endIcon?: string;
|
endIcon?: string;
|
||||||
loading?: boolean;
|
loading?: boolean;
|
||||||
|
disabled?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
// props
|
// props
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
variant: "solid",
|
variant: "solid",
|
||||||
size: "lg",
|
size: "lg",
|
||||||
|
disabled: false,
|
||||||
});
|
});
|
||||||
const { variant, size, loading } = toRefs(props);
|
const { variant, size, loading, disabled } = toRefs(props);
|
||||||
|
|
||||||
// computed
|
// computed
|
||||||
const classes = computed(() => {
|
const classes = computed(() => {
|
||||||
@@ -32,17 +34,30 @@ const classes = computed(() => {
|
|||||||
"btn-md": size.value === "md",
|
"btn-md": size.value === "md",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"pointer-events-none opacity-80 cursor-not-allowed": loading.value,
|
"pointer-events-none cursor-not-allowed": loading.value || disabled.value,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<button :class="classes" :disabled="loading">
|
<button
|
||||||
<Icon v-if="!loading && startIcon" :name="startIcon" />
|
:class="classes"
|
||||||
|
:disabled="loading || disabled"
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
v-if="!loading && startIcon"
|
||||||
|
:name="startIcon"
|
||||||
|
/>
|
||||||
<slot v-if="!loading" />
|
<slot v-if="!loading" />
|
||||||
<Icon v-if="!loading && endIcon" :name="endIcon" />
|
<Icon
|
||||||
<Icon v-if="loading" name="ci:svg-spinners-3-dots-fade" class="my-0.5" />
|
v-if="!loading && endIcon"
|
||||||
|
:name="endIcon"
|
||||||
|
/>
|
||||||
|
<Icon
|
||||||
|
v-if="loading"
|
||||||
|
name="ci:svg-spinners-3-dots-fade"
|
||||||
|
class="my-0.5"
|
||||||
|
/>
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ watch(
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
immediate: true,
|
immediate: true,
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
watch(isOpen, async (newValue) => {
|
watch(isOpen, async (newValue) => {
|
||||||
@@ -109,7 +109,7 @@ watch(isOpen, async (newValue) => {
|
|||||||
{
|
{
|
||||||
background: "white",
|
background: "white",
|
||||||
},
|
},
|
||||||
"="
|
"=",
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
gsapTimeline
|
gsapTimeline
|
||||||
@@ -120,7 +120,7 @@ watch(isOpen, async (newValue) => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
filter: prevNavbarStyle.value.itemFilter,
|
filter: prevNavbarStyle.value.itemFilter,
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
.fromTo(
|
.fromTo(
|
||||||
"#header-navbar",
|
"#header-navbar",
|
||||||
@@ -130,7 +130,7 @@ watch(isOpen, async (newValue) => {
|
|||||||
{
|
{
|
||||||
background: prevNavbarStyle.value.background,
|
background: prevNavbarStyle.value.background,
|
||||||
},
|
},
|
||||||
"="
|
"=",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -161,7 +161,7 @@ onMounted(() => {
|
|||||||
|
|
||||||
<div class="container relative z-10">
|
<div class="container relative z-10">
|
||||||
<div class="flex h-[70svh] max-h-200 bg-white rounded-b-2xl border-t border-slate-200">
|
<div class="flex h-[70svh] max-h-200 bg-white rounded-b-2xl border-t border-slate-200">
|
||||||
<div class="bg-slate-100 p-4 flex flex-col overflow-y-auto mask-b-from-90% pb-8">
|
<div class="bg-slate-100 p-4 flex flex-col overflow-y-auto mask-b-from-90% pb-8 w-70">
|
||||||
<button
|
<button
|
||||||
v-for="(item, index) in items"
|
v-for="(item, index) in items"
|
||||||
:key="item.title"
|
:key="item.title"
|
||||||
@@ -183,19 +183,21 @@ onMounted(() => {
|
|||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
:key="selectedItem"
|
:key="selectedItem"
|
||||||
class="grid grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 p-4 gap-2 text-back w-full h-fit"
|
class="columns-2 lg:columns-3 xl:columns-4 space-y-6 p-4 text-back w-full h-fit"
|
||||||
:style="{
|
:style="{
|
||||||
// gridTemplateRows: 'repeat(5, auto)',
|
// gridTemplateRows: 'repeat(5, auto)',
|
||||||
// justifyContent: 'center',
|
// justifyContent: 'center',
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<template
|
<div
|
||||||
v-for="mainItem in selectedItemSubItems"
|
v-for="mainItem in selectedItemSubItems"
|
||||||
:key="mainItem.title"
|
:key="mainItem.title"
|
||||||
|
class="flex flex-col gap-2 break-inside-avoid"
|
||||||
>
|
>
|
||||||
|
<span
|
||||||
<span class="text-primary px-4 py-2 flex items-center gap-2 text-sm max-lg:text-xs font-semibold">
|
class="text-primary px-4 flex items-center gap-2 text-sm max-lg:text-xs font-semibold"
|
||||||
<span class="w-2 h-[3px] rounded-full bg-blue-400"> </span>
|
>
|
||||||
|
<span class="w-0.5 h-2 rounded-full bg-blue-400"> </span>
|
||||||
{{ mainItem.title }}
|
{{ mainItem.title }}
|
||||||
</span>
|
</span>
|
||||||
<NuxtLink
|
<NuxtLink
|
||||||
@@ -208,7 +210,7 @@ onMounted(() => {
|
|||||||
{{ item.title }}
|
{{ item.title }}
|
||||||
</span>
|
</span>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
</template>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Transition>
|
</Transition>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="overflow-hidden rounded-3xl w-full bg-neutral-200">
|
<div class="overflow-hidden rounded-3xl w-full bg-neutral-200">
|
||||||
<video
|
<video
|
||||||
src="/video/curtain-blue.webm"
|
src="/video/curtain-red.webm"
|
||||||
class="w-full"
|
class="w-full"
|
||||||
autoplay
|
autoplay
|
||||||
muted
|
muted
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ watch(
|
|||||||
() => [shouldPauseVideos.value, swiper_instance.value?.realIndex],
|
() => [shouldPauseVideos.value, swiper_instance.value?.realIndex],
|
||||||
() => {
|
() => {
|
||||||
updateVideoStates();
|
updateVideoStates();
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
// lifecycle
|
// lifecycle
|
||||||
@@ -64,7 +64,7 @@ const initializeGsapAnimation = () => {
|
|||||||
{
|
{
|
||||||
height: "80svh",
|
height: "80svh",
|
||||||
borderRadius: "20px",
|
borderRadius: "20px",
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
.fromTo(
|
.fromTo(
|
||||||
slidesPerView,
|
slidesPerView,
|
||||||
@@ -74,7 +74,7 @@ const initializeGsapAnimation = () => {
|
|||||||
{
|
{
|
||||||
value: 1.2,
|
value: 1.2,
|
||||||
},
|
},
|
||||||
"="
|
"=",
|
||||||
)
|
)
|
||||||
.fromTo(
|
.fromTo(
|
||||||
".header-navbar-item",
|
".header-navbar-item",
|
||||||
@@ -84,16 +84,18 @@ const initializeGsapAnimation = () => {
|
|||||||
{
|
{
|
||||||
filter: "invert(0%)",
|
filter: "invert(0%)",
|
||||||
},
|
},
|
||||||
"="
|
"=",
|
||||||
)
|
)
|
||||||
.fromTo(
|
.fromTo(
|
||||||
"#header-navbar",
|
"#header-navbar",
|
||||||
{
|
{
|
||||||
|
boxShadow: "0 10px 15px -3px rgba(0,0,0,0)",
|
||||||
background: "transparent",
|
background: "transparent",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
boxShadow: "0 10px 15px -3px rgba(0,0,0,0.05)",
|
||||||
background: "white",
|
background: "white",
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
.fromTo(
|
.fromTo(
|
||||||
"#header-slider-wrapper",
|
"#header-slider-wrapper",
|
||||||
@@ -108,13 +110,14 @@ const initializeGsapAnimation = () => {
|
|||||||
},
|
},
|
||||||
scale: 1,
|
scale: 1,
|
||||||
},
|
},
|
||||||
"="
|
"=",
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const resetTimelineForMobile = () => {
|
const resetTimelineForMobile = () => {
|
||||||
gsap.to("#header-navbar", {
|
gsap.to("#header-navbar", {
|
||||||
background: "white",
|
background: "white",
|
||||||
|
boxShadow: "0 10px 15px -3px rgba(0,0,0,0.05)"
|
||||||
});
|
});
|
||||||
gsap.to(".header-navbar-item", {
|
gsap.to(".header-navbar-item", {
|
||||||
filter: "invert(0%)",
|
filter: "invert(0%)",
|
||||||
@@ -243,7 +246,9 @@ onUnmounted(() => {
|
|||||||
class="transition-all cursor-pointer flex-center bg-white z-10 size-full rounded-full"
|
class="transition-all cursor-pointer flex-center bg-white z-10 size-full rounded-full"
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
:name="isMuted ? 'ci:bi-volume-mute-fill' : 'ci:bi-volume-up-fill'"
|
:name="
|
||||||
|
isMuted ? 'ci:bi-volume-mute-fill' : 'ci:bi-volume-up-fill'
|
||||||
|
"
|
||||||
class="text-black size-4 md:size-[18px] lg:size-[24px]"
|
class="text-black size-4 md:size-[18px] lg:size-[24px]"
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ const childImageVariants = {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<section class="relative z-[999] h-[115svh] min-h-[1000px] max-h-350 pb-20 bg-black overflow-y-hidden flex-center">
|
<section class="relative h-[115svh] min-h-[1000px] max-h-350 pb-20 bg-black overflow-y-hidden flex-center">
|
||||||
<AnimatePresence mode="popLayout">
|
<AnimatePresence mode="popLayout">
|
||||||
<template
|
<template
|
||||||
v-for="(slide, index) in homeData!.show_case_slider"
|
v-for="(slide, index) in homeData!.show_case_slider"
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ const { selectedVariant } = inject("productVariant") as ProductVariantProvideTyp
|
|||||||
<template>
|
<template>
|
||||||
<section class="w-full container py-20 flex flex-col gap-y-[1.5rem]">
|
<section class="w-full container py-20 flex flex-col gap-y-[1.5rem]">
|
||||||
<div class="w-full flex">
|
<div class="w-full flex">
|
||||||
<span class="text-black max-lg:hidden typo-h-4 mb-4"> جزيات محصول </span>
|
<span class="text-black max-lg:hidden typo-h-4 mb-4"> جزئيات محصول </span>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-full flex items-start justify-between gap-[3rem] max-lg:flex-col-reverse">
|
<div class="w-full flex items-start justify-between gap-[3rem] max-lg:flex-col-reverse">
|
||||||
<div class="flex-1 w-full">
|
<div class="flex-1 w-full">
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ const currentCategory = computed({
|
|||||||
router.push({
|
router.push({
|
||||||
name: "products-slug",
|
name: "products-slug",
|
||||||
params: { slug: ["category", newValue] },
|
params: { slug: ["category", newValue] },
|
||||||
query: { ...route.query },
|
query: { ...route.query, page: "1" },
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -65,8 +65,8 @@ const resetFilters = () => {
|
|||||||
search.value = "";
|
search.value = "";
|
||||||
sort.value = "";
|
sort.value = "";
|
||||||
sliderValue.value = [PRODUCT_RANGE.min, PRODUCT_RANGE.max];
|
sliderValue.value = [PRODUCT_RANGE.min, PRODUCT_RANGE.max];
|
||||||
has_discount.value = "false";
|
has_discount.value = false;
|
||||||
in_stock.value = "false";
|
in_stock.value = false;
|
||||||
page.value = 1;
|
page.value = 1;
|
||||||
|
|
||||||
isSideShow.value = false;
|
isSideShow.value = false;
|
||||||
@@ -164,13 +164,11 @@ watch(
|
|||||||
|
|
||||||
<div class="flex items-center justify-between w-full gap-5">
|
<div class="flex items-center justify-between w-full gap-5">
|
||||||
<span class="text-black max-lg:text-sm">فقط کالاهای تخفیف دار</span>
|
<span class="text-black max-lg:text-sm">فقط کالاهای تخفیف دار</span>
|
||||||
|
|
||||||
<Switch v-model="has_discount" />
|
<Switch v-model="has_discount" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-center justify-between w-full gap-5">
|
<div class="flex items-center justify-between w-full gap-5">
|
||||||
<span class="text-black max-lg:text-sm">فقط کالاهای موجود</span>
|
<span class="text-black max-lg:text-sm">فقط کالاهای موجود</span>
|
||||||
|
|
||||||
<Switch v-model="in_stock" />
|
<Switch v-model="in_stock" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -55,8 +55,8 @@ const resetFilters = () => {
|
|||||||
search.value = "";
|
search.value = "";
|
||||||
sort.value = "";
|
sort.value = "";
|
||||||
sliderValue.value = [PRODUCT_RANGE.min, PRODUCT_RANGE.max];
|
sliderValue.value = [PRODUCT_RANGE.min, PRODUCT_RANGE.max];
|
||||||
has_discount.value = "false";
|
has_discount.value = false;
|
||||||
in_stock.value = "false";
|
in_stock.value = false;
|
||||||
page.value = 1;
|
page.value = 1;
|
||||||
|
|
||||||
isSideShow.value = false;
|
isSideShow.value = false;
|
||||||
@@ -155,13 +155,11 @@ watch(
|
|||||||
|
|
||||||
<div class="flex items-center justify-between w-full gap-5">
|
<div class="flex items-center justify-between w-full gap-5">
|
||||||
<span class="text-black max-lg:text-sm">فقط کالاهای تخفیف دار</span>
|
<span class="text-black max-lg:text-sm">فقط کالاهای تخفیف دار</span>
|
||||||
|
|
||||||
<Switch v-model="has_discount" />
|
<Switch v-model="has_discount" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-center justify-between w-full gap-5">
|
<div class="flex items-center justify-between w-full gap-5">
|
||||||
<span class="text-black max-lg:text-sm">فقط کالاهای موجود</span>
|
<span class="text-black max-lg:text-sm">فقط کالاهای موجود</span>
|
||||||
|
|
||||||
<Switch v-model="in_stock" />
|
<Switch v-model="in_stock" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ const useGetProducts = () => {
|
|||||||
sort,
|
sort,
|
||||||
in_stock,
|
in_stock,
|
||||||
has_discount,
|
has_discount,
|
||||||
slug,
|
|
||||||
price_gte,
|
price_gte,
|
||||||
price_lte,
|
price_lte,
|
||||||
};
|
};
|
||||||
@@ -45,24 +44,11 @@ const useGetProducts = () => {
|
|||||||
watch(
|
watch(
|
||||||
() => filters_clone.value,
|
() => filters_clone.value,
|
||||||
() => {
|
() => {
|
||||||
queryClient.cancelQueries({
|
|
||||||
queryKey: [
|
|
||||||
QUERY_KEYS.products,
|
|
||||||
searchDebounced,
|
|
||||||
sort,
|
|
||||||
in_stock,
|
|
||||||
has_discount,
|
|
||||||
products_category,
|
|
||||||
price_gte,
|
|
||||||
price_lte,
|
|
||||||
page,
|
|
||||||
],
|
|
||||||
});
|
|
||||||
page.value = 1;
|
page.value = 1;
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true,
|
deep: true,
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
|
|||||||
@@ -15,13 +15,12 @@ export const useAppParams = () => {
|
|||||||
mode: "replace",
|
mode: "replace",
|
||||||
});
|
});
|
||||||
|
|
||||||
const page = useRouteQuery<number | undefined>("page", 1, {
|
const page = useRouteQuery("page", "1", {
|
||||||
mode: "push",
|
mode: "push",
|
||||||
transform: (value) => (!!value ? +value : undefined),
|
transform: {
|
||||||
});
|
get: (v) => Number(v),
|
||||||
|
set: (v: number) => String(v),
|
||||||
const category = useRouteQuery<string | undefined>("category", "", {
|
},
|
||||||
mode: "replace",
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const status = useRouteQuery<string | undefined>("status", undefined, {
|
const status = useRouteQuery<string | undefined>("status", undefined, {
|
||||||
@@ -36,12 +35,20 @@ export const useAppParams = () => {
|
|||||||
mode: "replace",
|
mode: "replace",
|
||||||
});
|
});
|
||||||
|
|
||||||
const in_stock = useRouteQuery<string>("in_stock", "false", {
|
const in_stock = useRouteQuery("in_stock", "false", {
|
||||||
mode: "replace",
|
mode: "replace",
|
||||||
|
transform: {
|
||||||
|
get: (v) => v === "true",
|
||||||
|
set: (v: boolean) => (v ? "true" : "false"),
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const has_discount = useRouteQuery<string>("has_discount", "false", {
|
const has_discount = useRouteQuery("has_discount", "false", {
|
||||||
mode: "replace",
|
mode: "replace",
|
||||||
|
transform: {
|
||||||
|
get: (v) => v === "true",
|
||||||
|
set: (v: boolean) => (v ? "true" : "false"),
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const tracking_code = useRouteQuery<string>("tracking_code", "", {
|
const tracking_code = useRouteQuery<string>("tracking_code", "", {
|
||||||
@@ -52,7 +59,7 @@ export const useAppParams = () => {
|
|||||||
() => page.value,
|
() => page.value,
|
||||||
() => {
|
() => {
|
||||||
y.value = 0;
|
y.value = 0;
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -60,7 +67,6 @@ export const useAppParams = () => {
|
|||||||
sort,
|
sort,
|
||||||
search,
|
search,
|
||||||
page,
|
page,
|
||||||
category,
|
|
||||||
price_gte,
|
price_gte,
|
||||||
price_lte,
|
price_lte,
|
||||||
in_stock,
|
in_stock,
|
||||||
|
|||||||
@@ -6,9 +6,12 @@ export default defineNuxtConfig({
|
|||||||
css: ["~/assets/css/tailwind.css", "swiper/css", "animate.css/animate.min.css"],
|
css: ["~/assets/css/tailwind.css", "swiper/css", "animate.css/animate.min.css"],
|
||||||
|
|
||||||
routeRules: {
|
routeRules: {
|
||||||
"/products": { prerender: false, ssr: false },
|
// "/": { swr: 600 },
|
||||||
"/profile": { prerender: false, ssr: false },
|
// "/product/**" : { swr : 600 },
|
||||||
"/profile/**": { prerender: false, ssr: false },
|
// "/article/**" : { swr: 600 },
|
||||||
|
"/products": { ssr: false },
|
||||||
|
"/profile": { ssr: false },
|
||||||
|
"/profile/**": { ssr: false },
|
||||||
},
|
},
|
||||||
|
|
||||||
app: {
|
app: {
|
||||||
|
|||||||
+29
-29
@@ -15,53 +15,53 @@
|
|||||||
"postinstall": "nuxt prepare"
|
"postinstall": "nuxt prepare"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@formkit/auto-animate": "^0.8.2",
|
"@formkit/auto-animate": "^0.8.4",
|
||||||
"@nuxt/icon": "^1.10.3",
|
"@nuxt/icon": "^1.15.0",
|
||||||
"@nuxt/image": "^1.10.0",
|
"@nuxt/image": "^1.11.0",
|
||||||
"@nuxtjs/google-fonts": "^3.2.0",
|
"@nuxtjs/google-fonts": "^3.2.0",
|
||||||
"@nuxtjs/seo": "^3.0.3",
|
"@nuxtjs/seo": "^3.4.0",
|
||||||
"@tanstack/vue-query": "^5.62.2",
|
"@tanstack/vue-query": "^5.100.8",
|
||||||
"@tanstack/vue-query-devtools": "^5.62.3",
|
"@tanstack/vue-query-devtools": "^5.91.0",
|
||||||
"@vite-pwa/nuxt": "^0.10.6",
|
"@vite-pwa/nuxt": "^0.10.8",
|
||||||
"@vue/language-server": "^2.2.8",
|
"@vue/language-server": "^2.2.12",
|
||||||
"@vuelidate/core": "^2.0.3",
|
"@vuelidate/core": "^2.0.3",
|
||||||
"@vuelidate/validators": "^2.0.4",
|
"@vuelidate/validators": "^2.0.4",
|
||||||
"@vueuse/integrations": "^12.7.0",
|
"@vueuse/integrations": "^12.8.2",
|
||||||
"@vueuse/nuxt": "^13.3.0",
|
"@vueuse/nuxt": "^13.9.0",
|
||||||
"@vueuse/router": "^13.9.0",
|
"@vueuse/router": "^13.9.0",
|
||||||
"animate.css": "^4.1.1",
|
"animate.css": "^4.1.1",
|
||||||
"axios": "^1.8.1",
|
"axios": "^1.15.2",
|
||||||
"baseline-browser-mapping": "^2.10.22",
|
"baseline-browser-mapping": "^2.10.25",
|
||||||
"caniuse-lite": "^1.0.30001791",
|
"caniuse-lite": "^1.0.30001791",
|
||||||
"date-fns-jalali": "^4.1.0-0",
|
"date-fns-jalali": "^4.1.0-0",
|
||||||
"fast-average-color": "^9.4.0",
|
"fast-average-color": "^9.5.2",
|
||||||
"gsap": "^3.12.7",
|
"gsap": "^3.15.0",
|
||||||
"jalali-ts": "^8.0.0",
|
"jalali-ts": "^8.0.0",
|
||||||
"motion-v": "^1.1.1",
|
"motion-v": "^1.10.3",
|
||||||
"nuxt": "^3.15.4",
|
"nuxt": "^3.21.4",
|
||||||
"ogl": "^1.0.11",
|
"ogl": "^1.0.11",
|
||||||
"reka-ui": "^1.0.0-alpha.6",
|
"reka-ui": "^1.0.0-alpha.11",
|
||||||
"sanitize-html": "^2.15.0",
|
"sanitize-html": "^2.17.3",
|
||||||
"swiper": "^11.2.6",
|
"swiper": "^11.2.10",
|
||||||
"universal-cookie": "^7.2.2",
|
"universal-cookie": "^7.2.2",
|
||||||
"vue": "^3.5.12",
|
"vue": "^3.5.33",
|
||||||
"vue-image-zoomer": "^2.4.4",
|
"vue-image-zoomer": "^2.4.4",
|
||||||
"vue-router": "latest",
|
"vue-router": "latest",
|
||||||
"vue-skeletor": "^1.0.6",
|
"vue-skeletor": "^1.0.6",
|
||||||
"vue3-marquee": "^4.2.2",
|
"vue3-marquee": "^4.2.2",
|
||||||
"vue3-persian-datetime-picker": "^1.2.2",
|
"vue3-persian-datetime-picker": "^1.2.2",
|
||||||
"web-push": "^3.6.7",
|
"web-push": "^3.6.7",
|
||||||
"workbox-window": "^7.3.0"
|
"workbox-window": "^7.4.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tailwindcss/postcss": "^4.1.4",
|
"@tailwindcss/postcss": "^4.2.4",
|
||||||
"@types/node": "^22.13.11",
|
"@types/node": "^22.19.17",
|
||||||
"@types/sanitize-html": "^2.13.0",
|
"@types/sanitize-html": "^2.16.1",
|
||||||
"@types/web-push": "^3.6.4",
|
"@types/web-push": "^3.6.4",
|
||||||
"autoprefixer": "^10.4.20",
|
"autoprefixer": "^10.5.0",
|
||||||
"postcss": "^8.5.3",
|
"postcss": "^8.5.13",
|
||||||
"tailwindcss": "^4.1.4",
|
"tailwindcss": "^4.2.4",
|
||||||
"typescript": "^5.8.2",
|
"typescript": "^5.9.3",
|
||||||
"vue-tsc": "^2.2.8"
|
"vue-tsc": "^2.2.12"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
// imports
|
// imports
|
||||||
|
|
||||||
import useGetAllAddress from "~/composables/api/account/useGetAllAddress";
|
import useGetAllAddress from "~/composables/api/account/useGetAllAddress";
|
||||||
import { useToast } from "~/composables/global/useToast";
|
|
||||||
import useGetCartOrders from "~/composables/api/orders/useGetCartOrders";
|
import useGetCartOrders from "~/composables/api/orders/useGetCartOrders";
|
||||||
|
|
||||||
// meta
|
// meta
|
||||||
@@ -27,6 +26,7 @@ type DeliveryData = {
|
|||||||
tipax: boolean;
|
tipax: boolean;
|
||||||
pishtaz: boolean;
|
pishtaz: boolean;
|
||||||
peyk: boolean;
|
peyk: boolean;
|
||||||
|
deka: boolean;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -48,8 +48,9 @@ const deliveryData = ref<DeliveryData>({
|
|||||||
address: selectedAddress.value,
|
address: selectedAddress.value,
|
||||||
deliveryMethod: {
|
deliveryMethod: {
|
||||||
peyk: false,
|
peyk: false,
|
||||||
pishtaz: true,
|
pishtaz: false,
|
||||||
tipax: false,
|
tipax: false,
|
||||||
|
deka: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@@ -109,6 +110,29 @@ const deliveryData = ref<DeliveryData>({
|
|||||||
</span>
|
</span>
|
||||||
|
|
||||||
<label
|
<label
|
||||||
|
@click="deliveryData.deliveryMethod.deka = true"
|
||||||
|
:class="deliveryData.deliveryMethod.deka ? 'ring-black ring-offset-2 ring-2' : ''"
|
||||||
|
class="flex flex-col select-none w-full gap-2 p-3 transition-all border cursor-pointer delivery-option focus-within:ring-2 ring-blue-500 ring-offset-2 focus-within:border-blue-500 rounded-100 border-slate-200 bg-slate-50"
|
||||||
|
>
|
||||||
|
<div class="flex items-center justify-between w-full">
|
||||||
|
<div class="flex items-center gap-2.5">
|
||||||
|
<SwitchRoot
|
||||||
|
v-model="deliveryData.deliveryMethod.deka"
|
||||||
|
:defaultValue="false"
|
||||||
|
class="w-[3rem] h-[1.8rem] shrink-0 flex data-[state=unchecked]:bg-slate-200 data-[state=checked]:bg-blue-500 border border-slate-200 data-[state=checked]:border-blue-500/20 rounded-full relative transition-all focus-within:outline-none"
|
||||||
|
>
|
||||||
|
<SwitchThumb
|
||||||
|
class="size-6 my-auto bg-white text-sm ms-1 flex items-center justify-center shadow-xl rounded-full transition-transform translate-x-0.5 will-change-transform data-[state=checked]:-translate-x-[68%]"
|
||||||
|
/>
|
||||||
|
</SwitchRoot>
|
||||||
|
<span class="w-full text-slate-800 text-sm lg:text-[1rem]">دکا پست</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span class="text-slate-800 text-sm lg:text-[1rem]"> ۱۵۰٬۰۰۰ تومان </span>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<!-- <label
|
||||||
@click="deliveryData.deliveryMethod.pishtaz = true"
|
@click="deliveryData.deliveryMethod.pishtaz = true"
|
||||||
:class="deliveryData.deliveryMethod.pishtaz ? 'ring-black ring-offset-2 ring-2' : ''"
|
:class="deliveryData.deliveryMethod.pishtaz ? 'ring-black ring-offset-2 ring-2' : ''"
|
||||||
class="flex flex-col select-none w-full gap-2 p-3 transition-all border cursor-pointer delivery-option focus-within:ring-2 ring-blue-500 ring-offset-2 focus-within:border-blue-500 rounded-100 border-slate-200 bg-slate-50"
|
class="flex flex-col select-none w-full gap-2 p-3 transition-all border cursor-pointer delivery-option focus-within:ring-2 ring-blue-500 ring-offset-2 focus-within:border-blue-500 rounded-100 border-slate-200 bg-slate-50"
|
||||||
@@ -147,7 +171,7 @@ const deliveryData = ref<DeliveryData>({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span class="text-slate-800 text-sm lg:text-[1rem]"> ۱۵۰٬۰۰۰ تومان </span>
|
<span class="text-slate-800 text-sm lg:text-[1rem]"> ۱۵۰٬۰۰۰ تومان </span>
|
||||||
</label>
|
</label> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<OrderSummary />
|
<OrderSummary />
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
|
||||||
|
// import
|
||||||
|
|
||||||
|
import { useAppParams } from "~/composables/global/useAppParams";
|
||||||
|
import useGetProducts from "~/composables/api/products/useGetProducts";
|
||||||
|
|
||||||
// meta
|
// meta
|
||||||
|
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
@@ -11,11 +17,6 @@ definePageMeta({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// import
|
|
||||||
|
|
||||||
import { useAppParams } from "~/composables/global/useAppParams";
|
|
||||||
import useGetProducts from "~/composables/api/products/useGetProducts";
|
|
||||||
|
|
||||||
// state
|
// state
|
||||||
|
|
||||||
const { search } = useAppParams();
|
const { search } = useAppParams();
|
||||||
|
|||||||
Reference in New Issue
Block a user