Updated
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
|
||||||
// import
|
// import
|
||||||
|
|
||||||
import useGetProduct from "~/composables/api/product/useGetProduct";
|
import useGetProduct from "~/composables/api/product/useGetProduct";
|
||||||
@@ -31,61 +30,78 @@ const { selectedVariant, changeSelectedVariant } = inject("productVariant") as P
|
|||||||
const addItemToCart = async () => {
|
const addItemToCart = async () => {
|
||||||
await addCartItem({
|
await addCartItem({
|
||||||
id: selectedVariant.value!.id,
|
id: selectedVariant.value!.id,
|
||||||
quantity: selectedQuantity.value
|
quantity: selectedQuantity.value,
|
||||||
});
|
});
|
||||||
await refetchProduct();
|
await refetchProduct();
|
||||||
};
|
};
|
||||||
|
|
||||||
// watch
|
// watch
|
||||||
|
|
||||||
watch(() => selectedVariantId.value, (newId) => {
|
watch(
|
||||||
const newVariant = product.value!.variants.find(variant => variant.id === newId)!;
|
() => selectedVariantId.value,
|
||||||
changeSelectedVariant(newVariant);
|
(newId) => {
|
||||||
});
|
const newVariant = product.value!.variants.find((variant) => variant.id === newId)!;
|
||||||
|
changeSelectedVariant(newVariant);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
watch(() => selectedColor.value, (newValue) => {
|
watch(
|
||||||
const filteredVariants = product.value!.variants.filter(v => v.color === newValue);
|
() => selectedColor.value,
|
||||||
selectedVariantId.value = filteredVariants[0].id;
|
(newValue) => {
|
||||||
selectedVariant.value = filteredVariants[0];
|
const filteredVariants = product.value!.variants.filter((v) => v.color === newValue);
|
||||||
}, {
|
selectedVariantId.value = filteredVariants[0].id;
|
||||||
immediate: true
|
selectedVariant.value = filteredVariants[0];
|
||||||
});
|
},
|
||||||
|
{
|
||||||
watch(() => selectedVariant.value!, (newValue) => {
|
immediate: true,
|
||||||
selectedQuantity.value = 1;
|
}
|
||||||
selectedSlide.value = newValue.images[0].id;
|
);
|
||||||
});
|
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => selectedVariant.value!,
|
||||||
|
(newValue) => {
|
||||||
|
selectedQuantity.value = 1;
|
||||||
|
selectedSlide.value = newValue.images[0].id;
|
||||||
|
}
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="flex max-lg:flex-col gap-12 xl:gap-16 container pt-[5rem] pb-28">
|
<div class="flex max-lg:flex-col gap-12 xl:gap-16 container pt-[5rem] pb-28">
|
||||||
<div class="flex flex-col gap-3 lg:hidden">
|
<div class="flex flex-col gap-3 lg:hidden">
|
||||||
<NuxtLink to="#" class="typo-label-sm"> {{ product!.category.name }}</NuxtLink>
|
<NuxtLink
|
||||||
<h1 class="typo-h-6 xs:typo-h-5 sm:typo-h-4 lg:typo-h-2"> {{ product!.name }} </h1>
|
to="#"
|
||||||
|
class="typo-label-sm"
|
||||||
|
>
|
||||||
|
{{ product!.category.name }}</NuxtLink
|
||||||
|
>
|
||||||
|
<h1 class="typo-h-6 xs:typo-h-5 sm:typo-h-4 lg:typo-h-2">
|
||||||
|
{{ product!.name }}
|
||||||
|
</h1>
|
||||||
<div class="flex w-full items-center justify-between h-[85px]">
|
<div class="flex w-full items-center justify-between h-[85px]">
|
||||||
<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-md sm: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-md sm: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-3 sm:px-4 py-1.5 sm: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-3.5 sm:size-4"
|
||||||
|
/>
|
||||||
{{ selectedVariant!.discount }}
|
{{ selectedVariant!.discount }}
|
||||||
درصد تخفیف
|
<span class="max-sm:hidden"> تخفیف درصد </span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Rating :rate="3" />
|
<Rating :rate="3" />
|
||||||
@@ -103,7 +119,9 @@ watch(() => selectedVariant.value!, (newValue) => {
|
|||||||
>
|
>
|
||||||
{{ product!.category.name }}
|
{{ product!.category.name }}
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
<h1 class="typo-h-4 xl:typo-h-3 max-lg:hidden"> {{ product!.name }} </h1>
|
<h1 class="typo-h-4 xl:typo-h-3 max-lg:hidden">
|
||||||
|
{{ product!.name }}
|
||||||
|
</h1>
|
||||||
<div class="flex w-full items-center justify-between h-[85px] max-lg:hidden">
|
<div class="flex w-full items-center justify-between h-[85px] max-lg:hidden">
|
||||||
<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">
|
||||||
@@ -114,9 +132,7 @@ watch(() => selectedVariant.value!, (newValue) => {
|
|||||||
>
|
>
|
||||||
{{ 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>
|
||||||
@@ -124,37 +140,42 @@ watch(() => selectedVariant.value!, (newValue) => {
|
|||||||
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>
|
||||||
|
|
||||||
<Rating :rate="3" class="sm:hidden" />
|
<Rating
|
||||||
|
:rate="3"
|
||||||
|
class="sm:hidden"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Rating :rate="3" class="max-sm:hidden" />
|
<Rating
|
||||||
|
:rate="3"
|
||||||
|
class="max-sm:hidden"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="py-8 typo-p-md text-slate-500 text-justify [&_a]:text-blue-400 [&_strong]:font-bold [&_u]:text-red-400"
|
class="py-8 typo-sm max-sm:leading-[175%] sm:typo-p-md text-slate-500 text-justify [&_a]:text-blue-400 [&_strong]:font-bold [&_u]:text-red-400"
|
||||||
v-html="product!.description"
|
v-html="product!.description"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="flex items-center gap-4">
|
<div class="flex items-center gap-4">
|
||||||
<span class="typo-p-lg">
|
<span class="typo-md sm:typo-p-lg"> تنوع رنگی : </span>
|
||||||
تنوع رنگی :
|
|
||||||
</span>
|
|
||||||
<div class="flex items-center gap-4 py-4">
|
<div class="flex items-center gap-4 py-4">
|
||||||
<ColorCircle
|
<ColorCircle
|
||||||
v-for="color in product!.colors"
|
v-for="color in product!.colors"
|
||||||
:key="color"
|
:key="color"
|
||||||
@click="selectedColor = color"
|
@click="selectedColor = color"
|
||||||
selectable
|
selectable
|
||||||
:selected="selectedColor === color "
|
:selected="selectedColor === color"
|
||||||
:style="{backgroundColor: color}"
|
:style="{ backgroundColor: color }"
|
||||||
class="cursor-pointer"
|
class="cursor-pointer"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -162,7 +183,7 @@ watch(() => selectedVariant.value!, (newValue) => {
|
|||||||
|
|
||||||
<div class="flex items-center gap-6 flex-wrap">
|
<div class="flex items-center gap-6 flex-wrap">
|
||||||
<ProductVariant
|
<ProductVariant
|
||||||
@click="variant.in_stock > 0 ? selectedVariantId = variant.id : undefined"
|
@click="variant.in_stock > 0 ? (selectedVariantId = variant.id) : undefined"
|
||||||
v-for="variant in product!.variants.filter(p => p.color === selectedColor)"
|
v-for="variant in product!.variants.filter(p => p.color === selectedColor)"
|
||||||
:key="variant.id"
|
:key="variant.id"
|
||||||
:variantDetail="variant"
|
:variantDetail="variant"
|
||||||
@@ -171,7 +192,6 @@ watch(() => selectedVariant.value!, (newValue) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<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"
|
||||||
@@ -184,24 +204,31 @@ watch(() => selectedVariant.value!, (newValue) => {
|
|||||||
@click="addItemToCart"
|
@click="addItemToCart"
|
||||||
:loading="isAddCartItemPending"
|
:loading="isAddCartItemPending"
|
||||||
:disabled="isAddCartItemPending"
|
:disabled="isAddCartItemPending"
|
||||||
class="w-full rounded-full"
|
class="w-full rounded-full max-sm:h-[48px]"
|
||||||
end-icon="ci:plus"
|
end-icon="ci:plus"
|
||||||
>
|
>
|
||||||
|
|
||||||
افزودن به سبد خرید
|
افزودن به سبد خرید
|
||||||
</Button>
|
</Button>
|
||||||
<NuxtLink v-else to="/cart" class="w-full">
|
<NuxtLink
|
||||||
|
v-else
|
||||||
|
to="/cart"
|
||||||
|
class="w-full"
|
||||||
|
>
|
||||||
<Button
|
<Button
|
||||||
class="w-full rounded-full h-full"
|
class="w-full rounded-full h-full max-sm:h-[48px]"
|
||||||
end-icon="ci:cart"
|
end-icon="ci:cart"
|
||||||
>
|
>
|
||||||
مشاهده در سبد خرید
|
مشاهده در سبد خرید
|
||||||
</Button>
|
</Button>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
</template>
|
</template>
|
||||||
<NuxtLink v-else to="/signin" class="w-full">
|
<NuxtLink
|
||||||
|
v-else
|
||||||
|
to="/signin"
|
||||||
|
class="w-full"
|
||||||
|
>
|
||||||
<Button
|
<Button
|
||||||
class="w-full rounded-full h-full"
|
class="w-full rounded-full h-full max-sm:h-[48px]"
|
||||||
end-icon="ci:user"
|
end-icon="ci:user"
|
||||||
>
|
>
|
||||||
ابتدا وارد شوید
|
ابتدا وارد شوید
|
||||||
@@ -216,13 +243,11 @@ watch(() => selectedVariant.value!, (newValue) => {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<UpdateQuantity v-else />
|
<UpdateQuantity v-else />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<InfoCard />
|
<InfoCard />
|
||||||
|
|
||||||
<Share />
|
<Share />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user