This commit is contained in:
Parsa Nazer
2026-05-03 18:42:46 +03:30
17 changed files with 992 additions and 936 deletions
+3 -3
View File
@@ -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
View File
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>
+21 -6
View File
@@ -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>
+13 -11
View File
@@ -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
+12 -7
View File
@@ -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
+16 -10
View File
@@ -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 -3
View File
@@ -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
View File
@@ -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"
} }
} }
+27 -3
View File
@@ -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 />
+6 -5
View File
@@ -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();