Updated
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
// provide / inject
|
// provide / inject
|
||||||
|
|
||||||
import type { ProductVariantProvideType } from "~/pages/product/[id].vue";
|
import type { ProductVariantProvideType } from "~/pages/product/types";
|
||||||
|
|
||||||
const { selectedVariant } = inject("productVariant") as ProductVariantProvideType;
|
const { selectedVariant } = inject("productVariant") as ProductVariantProvideType;
|
||||||
|
|
||||||
|
|||||||
@@ -5,13 +5,17 @@
|
|||||||
import useGetProduct from "~/composables/api/product/useGetProduct";
|
import useGetProduct from "~/composables/api/product/useGetProduct";
|
||||||
import { sanitize } from "isomorphic-dompurify";
|
import { sanitize } from "isomorphic-dompurify";
|
||||||
import type { ProductVariantProvideType } from "~/pages/product/[id].vue";
|
import type { ProductVariantProvideType } from "~/pages/product/[id].vue";
|
||||||
|
import useAddCartItem from "~/composables/api/orders/useAddCartItem";
|
||||||
|
import { useAuth } from "~/composables/api/auth/useAuth";
|
||||||
|
|
||||||
// state
|
// state
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const id = route.params.id as string | undefined;
|
const id = route.params.id as string | undefined;
|
||||||
|
|
||||||
const { data: product } = useGetProduct(id);
|
const { token } = useAuth();
|
||||||
|
const { data: product, refetch: refetchProduct } = useGetProduct(id);
|
||||||
|
const { mutateAsync: addCartItem, isPending: isAddCartItemPending } = useAddCartItem();
|
||||||
|
|
||||||
const selectedVariantId = ref(product.value!.variants[0].id);
|
const selectedVariantId = ref(product.value!.variants[0].id);
|
||||||
const selectedQuantity = ref(1);
|
const selectedQuantity = ref(1);
|
||||||
@@ -23,6 +27,16 @@ const selectedColor = ref(product.value!.colors[0]);
|
|||||||
|
|
||||||
const { selectedVariant, changeSelectedVariant } = inject("productVariant") as ProductVariantProvideType;
|
const { selectedVariant, changeSelectedVariant } = inject("productVariant") as ProductVariantProvideType;
|
||||||
|
|
||||||
|
// method
|
||||||
|
|
||||||
|
const addItemToCart = async () => {
|
||||||
|
await addCartItem({
|
||||||
|
id: selectedVariant.value!.id,
|
||||||
|
quantity: selectedQuantity.value
|
||||||
|
});
|
||||||
|
await refetchProduct();
|
||||||
|
};
|
||||||
|
|
||||||
// computed
|
// computed
|
||||||
|
|
||||||
const sanitizedProductDescription = computed(() => {
|
const sanitizedProductDescription = computed(() => {
|
||||||
@@ -44,7 +58,7 @@ watch(() => selectedColor.value, (newValue) => {
|
|||||||
immediate: true
|
immediate: true
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(() => selectedVariant.value, (newValue) => {
|
watch(() => selectedVariant.value!, (newValue) => {
|
||||||
selectedQuantity.value = 1;
|
selectedQuantity.value = 1;
|
||||||
selectedSlide.value = newValue.images[0].id;
|
selectedSlide.value = newValue.images[0].id;
|
||||||
});
|
});
|
||||||
@@ -60,24 +74,24 @@ watch(() => selectedVariant.value, (newValue) => {
|
|||||||
<div class="flex items-end gap-4">
|
<div class="flex items-end gap-4">
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<span
|
<span
|
||||||
v-if="selectedVariant.discount > 0"
|
v-if="selectedVariant!.discount > 0"
|
||||||
class="typo-p-lg relative flex-center w-fit"
|
class="typo-p-lg relative flex-center w-fit"
|
||||||
:class="'after:w-full after:h-[2px] after:bg-black after:absolute'"
|
:class="'after:w-full after:h-[2px] after:bg-black after:absolute'"
|
||||||
>
|
>
|
||||||
{{ selectedVariant.price }}
|
{{ selectedVariant!.price }}
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="typo-p-2xl relative flex-center w-fit font-medium"
|
class="typo-p-2xl relative flex-center w-fit font-medium"
|
||||||
>
|
>
|
||||||
{{ selectedVariant.discount > 0 ? selectedVariant.price : selectedVariant.price }}
|
{{ selectedVariant!.discount > 0 ? selectedVariant!.price : selectedVariant!.price }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="selectedVariant.discount > 0"
|
v-if="selectedVariant!.discount > 0"
|
||||||
class="text-white bg-blue-500 mb-1 px-4 py-2 text-xs rounded-full flex items-center gap-1"
|
class="text-white bg-blue-500 mb-1 px-4 py-2 text-xs rounded-full flex items-center gap-1"
|
||||||
>
|
>
|
||||||
<Icon name="material-symbols:percent" class="size-4" />
|
<Icon name="material-symbols:percent" class="size-4" />
|
||||||
{{ selectedVariant.discount }}
|
{{ selectedVariant!.discount }}
|
||||||
درصد تخفیف
|
درصد تخفیف
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -87,7 +101,7 @@ watch(() => selectedVariant.value, (newValue) => {
|
|||||||
<Slider
|
<Slider
|
||||||
class="w-full lg:w-1/2 lg:max-w-[620px]"
|
class="w-full lg:w-1/2 lg:max-w-[620px]"
|
||||||
v-model:selectedSlide="selectedSlide"
|
v-model:selectedSlide="selectedSlide"
|
||||||
:slides="selectedVariant.images"
|
:slides="selectedVariant!.images"
|
||||||
/>
|
/>
|
||||||
<div class="lg:w-1/2 flex flex-col gap-3 lg:mt-12">
|
<div class="lg:w-1/2 flex flex-col gap-3 lg:mt-12">
|
||||||
<NuxtLink
|
<NuxtLink
|
||||||
@@ -101,24 +115,24 @@ watch(() => selectedVariant.value, (newValue) => {
|
|||||||
<div class="flex items-end gap-4">
|
<div class="flex items-end gap-4">
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<span
|
<span
|
||||||
v-if="selectedVariant.discount > 0"
|
v-if="selectedVariant!.discount > 0"
|
||||||
class="typo-p-lg relative flex-center w-fit"
|
class="typo-p-lg relative flex-center w-fit"
|
||||||
:class="'after:w-full after:h-[2px] after:bg-black after:absolute'"
|
:class="'after:w-full after:h-[2px] after:bg-black after:absolute'"
|
||||||
>
|
>
|
||||||
{{ selectedVariant.price }}
|
{{ selectedVariant!.price }}
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="typo-p-2xl relative flex-center w-fit font-medium"
|
class="typo-p-2xl relative flex-center w-fit font-medium"
|
||||||
>
|
>
|
||||||
{{ selectedVariant.discount > 0 ? selectedVariant.price : selectedVariant.price }}
|
{{ selectedVariant!.discount > 0 ? selectedVariant!.price : selectedVariant!.price }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="selectedVariant.discount > 0"
|
v-if="selectedVariant!.discount > 0"
|
||||||
class="text-white bg-blue-500 mb-1 px-4 py-2 text-xs rounded-full flex items-center gap-1"
|
class="text-white bg-blue-500 mb-1 px-4 py-2 text-xs rounded-full flex items-center gap-1"
|
||||||
>
|
>
|
||||||
<Icon name="material-symbols:percent" class="size-4" />
|
<Icon name="material-symbols:percent" class="size-4" />
|
||||||
{{ selectedVariant.discount }}
|
{{ selectedVariant!.discount }}
|
||||||
<span class="max-sm:hidden">درصد</span>
|
<span class="max-sm:hidden">درصد</span>
|
||||||
تخفیف
|
تخفیف
|
||||||
</div>
|
</div>
|
||||||
@@ -166,18 +180,50 @@ watch(() => selectedVariant.value, (newValue) => {
|
|||||||
<div class="w-full flex flex-col gap-6 mt-10">
|
<div class="w-full flex flex-col gap-6 mt-10">
|
||||||
|
|
||||||
<RemainQuantity
|
<RemainQuantity
|
||||||
:maxQuantity="selectedVariant.in_stock"
|
:maxQuantity="selectedVariant!.in_stock"
|
||||||
:quantity="selectedQuantity"
|
:quantity="selectedQuantity"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="w-full flex gap-3">
|
<div class="w-full flex gap-3">
|
||||||
<Button class="w-full rounded-full" end-icon="ci:plus">
|
<template v-if="token">
|
||||||
افزودن به سبد خرید
|
<Button
|
||||||
</Button>
|
v-if="selectedVariant!.cart_quantity === 0"
|
||||||
|
@click="addItemToCart"
|
||||||
|
:loading="isAddCartItemPending"
|
||||||
|
:disabled="isAddCartItemPending"
|
||||||
|
class="w-full rounded-full"
|
||||||
|
end-icon="ci:plus"
|
||||||
|
>
|
||||||
|
|
||||||
|
افزودن به سبد خرید
|
||||||
|
</Button>
|
||||||
|
<NuxtLink v-else to="/cart" class="w-full">
|
||||||
|
<Button
|
||||||
|
class="w-full rounded-full h-full"
|
||||||
|
end-icon="ci:cart"
|
||||||
|
>
|
||||||
|
مشاهده در سبد خرید
|
||||||
|
</Button>
|
||||||
|
</NuxtLink>
|
||||||
|
</template>
|
||||||
|
<NuxtLink v-else to="/signin" class="w-full">
|
||||||
|
<Button
|
||||||
|
class="w-full rounded-full h-full"
|
||||||
|
end-icon="ci:user"
|
||||||
|
>
|
||||||
|
ابتدا وارد شوید
|
||||||
|
</Button>
|
||||||
|
</NuxtLink>
|
||||||
|
|
||||||
<QuantityCounter
|
<QuantityCounter
|
||||||
|
v-if="selectedVariant!.cart_quantity === 0"
|
||||||
|
:disable="isAddCartItemPending"
|
||||||
v-model="selectedQuantity"
|
v-model="selectedQuantity"
|
||||||
:max="selectedVariant.in_stock"
|
:max="selectedVariant!.in_stock"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<UpdateQuantity v-else />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<InfoCard />
|
<InfoCard />
|
||||||
|
|||||||
Reference in New Issue
Block a user