Merge branch 'main' of https://github.com/Byeto-Company/hossein_por_shop
This commit is contained in:
@@ -3,18 +3,21 @@
|
|||||||
// types
|
// types
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
selectable?: boolean,
|
||||||
selected?: boolean;
|
selected?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
// props
|
// props
|
||||||
|
|
||||||
defineProps<Props>();
|
withDefaults(defineProps<Props>(), {
|
||||||
|
selectable: false
|
||||||
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="size-[25px] rounded-full transition-all ring-2 ring-offset-4 shadow-black/30 shadow-inner"
|
class="size-[25px] rounded-full transition-all shadow-black/30 shadow-inner"
|
||||||
:class="selected ? 'ring-blue-500' : 'ring-transparent'"
|
:class="[selectable ? 'ring-2 ring-offset-4 ' : '', selected ? 'ring-blue-500' : 'ring-transparent']"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
@@ -1,33 +1,54 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
// import
|
||||||
|
|
||||||
|
import type { LoadingOverlayProvideType } from "~/pages/index.vue";
|
||||||
|
|
||||||
|
// provide / inject
|
||||||
|
|
||||||
|
const { showLoadingOverlay } = inject("loadingOverlay") as LoadingOverlayProvideType;
|
||||||
|
|
||||||
// state
|
// state
|
||||||
|
|
||||||
const { $gsap: gsap } = useNuxtApp();
|
const { $gsap: gsap } = useNuxtApp();
|
||||||
|
|
||||||
|
const shouldRenderLoadingOverlay = ref(true);
|
||||||
|
|
||||||
// lifecycle
|
// lifecycle
|
||||||
|
|
||||||
onMounted(() => {
|
watch(() => showLoadingOverlay.value, (value) => {
|
||||||
const timeline = gsap.timeline();
|
if (!value) {
|
||||||
|
const timeline = gsap.timeline();
|
||||||
|
|
||||||
timeline
|
timeline
|
||||||
.to("#loading-overlay", {
|
.to("#loading-overlay", {
|
||||||
scale: 1
|
scale: 1
|
||||||
})
|
})
|
||||||
.to("#loading-overlay", {
|
.to("#loading-overlay", {
|
||||||
scale: 0.8,
|
scale: 0.8,
|
||||||
opacity: 0,
|
opacity: 0,
|
||||||
delay: 5
|
delay: 3
|
||||||
})
|
})
|
||||||
.to("#loading-overlay", {
|
.to("#loading-overlay", {
|
||||||
opacity: 0,
|
opacity: 0,
|
||||||
y: "20%"
|
y: "20%",
|
||||||
});
|
onComplete: () => {
|
||||||
|
shouldRenderLoadingOverlay.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
once: true
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div id="loading-overlay" class="fixed inset-0 size-full z-9999 flex-center bg-black">
|
<div
|
||||||
|
v-if="shouldRenderLoadingOverlay"
|
||||||
|
id="loading-overlay"
|
||||||
|
class="fixed inset-0 size-full z-9999 flex-center bg-black"
|
||||||
|
>
|
||||||
<img id="loading-overlay-image" src="/video/loading-2.gif" class="opacity-0 scale-70 absolute z-20" alt="" />
|
<img id="loading-overlay-image" src="/video/loading-2.gif" class="opacity-0 scale-70 absolute z-20" alt="" />
|
||||||
<div
|
<div
|
||||||
id="loading-overlay-gradient"
|
id="loading-overlay-gradient"
|
||||||
@@ -41,7 +62,7 @@ onMounted(() => {
|
|||||||
#loading-overlay-image {
|
#loading-overlay-image {
|
||||||
animation-name: loading-overlay-image-animation;
|
animation-name: loading-overlay-image-animation;
|
||||||
animation-duration: 1s;
|
animation-duration: 1s;
|
||||||
animation-delay: 0.75s;
|
animation-delay: 0.35s;
|
||||||
animation-fill-mode: forwards;
|
animation-fill-mode: forwards;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ const onSwiper = (swiper: SwiperClass) => {
|
|||||||
brand="برند محصول"
|
brand="برند محصول"
|
||||||
:title="product.name"
|
:title="product.name"
|
||||||
:picture="product.variants[0].images[0].image"
|
:picture="product.variants[0].images[0].image"
|
||||||
:colors="product.variants.map(v => v.color)"
|
:colors="product.colors"
|
||||||
:price="product.variants[0].price"
|
:price="product.variants[0].price"
|
||||||
:rate="product.rating"
|
:rate="product.rating"
|
||||||
:dark-layer="true"
|
:dark-layer="true"
|
||||||
|
|||||||
@@ -5,6 +5,11 @@
|
|||||||
import { Swiper, SwiperSlide } from "swiper/vue";
|
import { Swiper, SwiperSlide } from "swiper/vue";
|
||||||
import type { SwiperClass } from "swiper/react";
|
import type { SwiperClass } from "swiper/react";
|
||||||
import useHomeData from "~/composables/api/home/useHomeData";
|
import useHomeData from "~/composables/api/home/useHomeData";
|
||||||
|
import type { LoadingOverlayProvideType } from "~/pages/index.vue";
|
||||||
|
|
||||||
|
// provide / inject
|
||||||
|
|
||||||
|
const { changeLoadingOverlay } = inject("loadingOverlay") as LoadingOverlayProvideType;
|
||||||
|
|
||||||
// state
|
// state
|
||||||
|
|
||||||
@@ -31,6 +36,7 @@ let gsapTimeline: gsap.core.Timeline;
|
|||||||
// methods
|
// methods
|
||||||
|
|
||||||
const onSwiper = (swiper: SwiperClass) => {
|
const onSwiper = (swiper: SwiperClass) => {
|
||||||
|
changeLoadingOverlay(false);
|
||||||
swiper_instance.value = swiper;
|
swiper_instance.value = swiper;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -105,7 +111,7 @@ onMounted(() => {
|
|||||||
padding: "0px 80px"
|
padding: "0px 80px"
|
||||||
}, {
|
}, {
|
||||||
padding: "0px 40px"
|
padding: "0px 40px"
|
||||||
}, "=")
|
}, "=");
|
||||||
|
|
||||||
ScrollTrigger.create({
|
ScrollTrigger.create({
|
||||||
trigger: "#header-slider-container",
|
trigger: "#header-slider-container",
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ watch(() => selectedVariant.value, (newValue) => {
|
|||||||
v-for="color in product!.colors"
|
v-for="color in product!.colors"
|
||||||
:key="color"
|
:key="color"
|
||||||
@click="selectedColor = color"
|
@click="selectedColor = color"
|
||||||
|
selectable
|
||||||
:selected="selectedColor === color "
|
:selected="selectedColor === color "
|
||||||
:style="{backgroundColor: color}"
|
:style="{backgroundColor: color}"
|
||||||
class="cursor-pointer"
|
class="cursor-pointer"
|
||||||
|
|||||||
@@ -4,10 +4,32 @@
|
|||||||
|
|
||||||
import useHomeData from "~/composables/api/home/useHomeData";
|
import useHomeData from "~/composables/api/home/useHomeData";
|
||||||
|
|
||||||
|
// type
|
||||||
|
|
||||||
|
export type LoadingOverlayProvideType = {
|
||||||
|
showLoadingOverlay: Ref<boolean>,
|
||||||
|
changeLoadingOverlay: (value: boolean) => void,
|
||||||
|
}
|
||||||
|
|
||||||
// state
|
// state
|
||||||
|
|
||||||
const { suspense } = useHomeData();
|
const { suspense } = useHomeData();
|
||||||
|
|
||||||
|
const showLoadingOverlay = ref(true);
|
||||||
|
|
||||||
|
// method
|
||||||
|
|
||||||
|
const changeLoadingOverlay = (value: boolean) => {
|
||||||
|
showLoadingOverlay.value = value;
|
||||||
|
};
|
||||||
|
|
||||||
|
// provide / inject
|
||||||
|
|
||||||
|
provide("loadingOverlay", {
|
||||||
|
showLoadingOverlay,
|
||||||
|
changeLoadingOverlay
|
||||||
|
});
|
||||||
|
|
||||||
// ssr
|
// ssr
|
||||||
|
|
||||||
const response = await suspense();
|
const response = await suspense();
|
||||||
@@ -23,7 +45,7 @@ if (response.isError) {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<!-- <LoadingOverlay />-->
|
<LoadingOverlay />
|
||||||
<Hero />
|
<Hero />
|
||||||
<Preview />
|
<Preview />
|
||||||
<ProductsShowcase />
|
<ProductsShowcase />
|
||||||
|
|||||||
Reference in New Issue
Block a user