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