This commit is contained in:
Mamalizz
2025-04-17 00:32:59 +03:30
6 changed files with 49 additions and 31 deletions
@@ -1,16 +1,15 @@
<script lang="ts" setup> <script lang="ts" setup>
// types // types
type Props = { type Props = {
maxQuantity: number; maxQuantity: number;
quantity: number; quantity: number;
} showSlider: boolean;
};
// props // props
defineProps<Props>(); defineProps<Props>();
</script> </script>
<template> <template>
@@ -22,7 +21,7 @@ defineProps<Props>();
</span> </span>
عدد از این محصول موجود است عدد از این محصول موجود است
</p> </p>
<div class="h-2 rounded-full relative bg-slate-200 w-full"> <div v-if="showSlider" class="h-2 rounded-full relative bg-slate-200 w-full">
<div <div
:style="{ width: `${quantity * (100 / maxQuantity)}%` }" :style="{ width: `${quantity * (100 / maxQuantity)}%` }"
class="h-full absolute right-0 rounded-full bg-black transition-all ease-out" class="h-full absolute right-0 rounded-full bg-black transition-all ease-out"
@@ -7,9 +7,7 @@ import type { ProductVariantProvideType } from "~/pages/product/[id].vue";
// provide / inject // provide / inject
const { selectedVariant } = inject( const { selectedVariant } = inject("productVariant") as ProductVariantProvideType;
"productVariant"
) as ProductVariantProvideType;
// state // state
@@ -46,15 +44,14 @@ watch(
); );
watch(selectedVariant, (newValue) => { watch(selectedVariant, (newValue) => {
quantity.value = newValue!.cart_quantity; quantity.value = newValue!.cart_quantity === 0 ? 1 : newValue!.cart_quantity;
}); });
// lifecycle // lifecycle
onMounted(() => { onMounted(() => {
quantity.value = selectedVariant.value!.cart_quantity; quantity.value = selectedVariant.value!.cart_quantity === 0 ? 1 : selectedVariant.value!.cart_quantity;
}); });
</script> </script>
<template> <template>
@@ -65,14 +62,20 @@ onMounted(() => {
:max="selectedVariant!.in_stock" :max="selectedVariant!.in_stock"
> >
<NumberFieldIncrement class="cursor-pointer"> <NumberFieldIncrement class="cursor-pointer">
<Icon name="ci:plus" class="**:stroke-slate-500 size-5" /> <Icon
name="ci:plus"
class="**:stroke-slate-500 size-5"
/>
</NumberFieldIncrement> </NumberFieldIncrement>
<div class="relative"> <div class="relative">
<div <div
:class="isAddCartItemPending ? 'opacity-100' : 'opacity-0'" :class="isAddCartItemPending ? 'opacity-100' : 'opacity-0'"
class="w-[40px] h-[25px] flex-center transition-all absolute bg-white" class="w-[40px] h-[25px] flex-center transition-all absolute bg-white"
> >
<Icon :name="'svg-spinners:180-ring-with-bg'" class="size-[25px]" /> <Icon
:name="'svg-spinners:180-ring-with-bg'"
class="size-[25px]"
/>
</div> </div>
<NumberFieldInput <NumberFieldInput
@input="onInput" @input="onInput"
@@ -81,7 +84,10 @@ onMounted(() => {
/> />
</div> </div>
<NumberFieldDecrement class="cursor-pointer"> <NumberFieldDecrement class="cursor-pointer">
<Icon name="ci:minus" class="**:stroke-slate-500 size-5" /> <Icon
name="ci:minus"
class="**:stroke-slate-500 size-5"
/>
</NumberFieldDecrement> </NumberFieldDecrement>
</NumberFieldRoot> </NumberFieldRoot>
</template> </template>
@@ -1,5 +1,4 @@
<script lang="ts" setup> <script lang="ts" setup>
// types // types
type Props = { type Props = {
@@ -7,33 +6,49 @@ type Props = {
title: string; title: string;
color: string; color: string;
price: string; price: string;
} };
// props // props
const props = defineProps<Props>(); const props = defineProps<Props>();
const { picture, price, title, color } = toRefs(props); const { picture, price, title, color } = toRefs(props);
// methods
const scrollToTop = () => {
window.scrollTo({ top: 0, behavior: "smooth" });
};
</script> </script>
<template> <template>
<div class="max-w-[500px] w-full h-[116px] flex items-center justify-between py-2 pe-6 ps-2 bg-white rounded-150"> <div
class="max-w-[500px] w-full h-[116px] flex items-center justify-between py-2 pe-6 ps-2 gap-4 bg-white rounded-150"
>
<div class="flex items-center gap-4"> <div class="flex items-center gap-4">
<div class="relative size-[100px] rounded-100 overflow-hidden border-[0.5px] border-slate-200"> <div class="relative size-[100px] rounded-100 overflow-hidden border-[0.5px] border-slate-200">
<NuxtImg :src="picture" :alt="title" class="object-cover absolute" /> <NuxtImg
:src="picture"
:alt="title"
class="object-cover absolute"
/>
</div> </div>
<div class="flex flex-col gap-1.5"> <div class="flex flex-col gap-1.5">
<span class="typo-sub-h-md text-black">{{ title }}</span> <span class="typo-sub-h-md text-black">{{ title }}</span>
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<span class="typo-p-sm text-slate-500">رنگ</span> <span class="typo-p-sm text-slate-500">رنگ</span>
<ColorCircle class="!size-5" :style="{backgroundColor: color}" /> <ColorCircle
class="!size-5"
:style="{ backgroundColor: color }"
/>
</div> </div>
<span class="typo-p-md text-black">{{ price }}</span> <span class="typo-p-md text-black">{{ price }}</span>
</div> </div>
</div> </div>
<Button class="rounded-full max-sm:h-[45px]"> <Button
افزودن @click="scrollToTop"
<span class="max-sm:hidden">به سبد</span> class="rounded-full max-sm:h-[45px]"
>
مشاهده
</Button> </Button>
</div> </div>
</template> </template>
+1 -1
View File
@@ -139,7 +139,7 @@ watch(
<Transition name="fade" :duration="250"> <Transition name="fade" :duration="250">
<NuxtImg <NuxtImg
v-if="showHeymlzAnimation" v-if="showHeymlzAnimation"
src="/img/heymlz/heymlz-pulling.gif" src="/img/heymlz/heymlz-pullingg.gif"
class="size-[250px] sm:size-[400px] absolute translate-x-[-62px] sm:translate-x-[-107px] z-10 top-[50%] -translate-y-1/2" class="size-[250px] sm:size-[400px] absolute translate-x-[-62px] sm:translate-x-[-107px] z-10 top-[50%] -translate-y-1/2"
:style="{ :style="{
left: `${clipPathPercent}%`, left: `${clipPathPercent}%`,
+4 -6
View File
@@ -37,13 +37,10 @@ const addItemToCart = async () => {
// watch // watch
watch( watch([selectedVariantId, product], ([selectedVariantId, product]) => {
() => selectedVariantId.value, const newVariant = product!.variants.find((variant) => variant.id === selectedVariantId)!;
(newId) => {
const newVariant = product.value!.variants.find((variant) => variant.id === newId)!;
changeSelectedVariant(newVariant); changeSelectedVariant(newVariant);
} });
);
watch( watch(
() => selectedColor.value, () => selectedColor.value,
@@ -193,6 +190,7 @@ watch(
<div class="w-full flex flex-col gap-6 mt-10"> <div class="w-full flex flex-col gap-6 mt-10">
<RemainQuantity <RemainQuantity
:showSlider="selectedVariant!.cart_quantity === 0"
:maxQuantity="selectedVariant!.in_stock" :maxQuantity="selectedVariant!.in_stock"
:quantity="selectedQuantity" :quantity="selectedQuantity"
/> />

Before

Width:  |  Height:  |  Size: 1012 KiB

After

Width:  |  Height:  |  Size: 1012 KiB