Add priority and lazy loading to some images
This commit is contained in:
@@ -22,15 +22,16 @@ const emit = defineEmits<Emits>();
|
||||
<template>
|
||||
<button
|
||||
@click="emit('select', null)"
|
||||
:class="
|
||||
isSelected
|
||||
? 'ring-2 ring-offset-2 ring-blue-500 border-blue-500'
|
||||
: 'border-slate-200'
|
||||
"
|
||||
:class="isSelected ? 'ring-2 ring-offset-2 ring-blue-500 border-blue-500' : 'border-slate-200'"
|
||||
class="w-full p-5 border rounded-xl flex flex-col gap-4 transition-all cursor-pointer relative overflow-hidden"
|
||||
>
|
||||
<div class="aspect-square flex-center">
|
||||
<NuxtImg :src="gateway.picture" class="object-cover" />
|
||||
<NuxtImg
|
||||
:src="gateway.picture"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
class="object-cover"
|
||||
/>
|
||||
</div>
|
||||
<span class="typo-label-sm text-right text-black">
|
||||
{{ gateway.title }}
|
||||
@@ -43,7 +44,11 @@ const emit = defineEmits<Emits>();
|
||||
v-if="isSelected"
|
||||
class="bg-blue-500 rounded-md p-0.5 text-center bottom-4 left-4 text-slate-200 text-[10px] lg:text-xs absolute"
|
||||
>
|
||||
<Icon name="bi:check" size="20" class="**:fill-white" />
|
||||
<Icon
|
||||
name="bi:check"
|
||||
size="20"
|
||||
class="**:fill-white"
|
||||
/>
|
||||
</span>
|
||||
</Transition>
|
||||
</button>
|
||||
|
||||
@@ -30,15 +30,11 @@ const visible = computed({
|
||||
class="fixed inset-0 w-full h-svh z-9999 flex-center"
|
||||
v-if="visible"
|
||||
>
|
||||
<div
|
||||
class="overflow-y-auto max-h-svh absolute left-[50%] py-10 w-fit max-w-[50rem] translate-x-[-50%]"
|
||||
>
|
||||
<div class="overflow-y-auto max-h-svh absolute left-[50%] py-10 w-fit max-w-[50rem] translate-x-[-50%]">
|
||||
<DialogContent
|
||||
class="min-w-[30vw] max-w-[50vw] data-[state=open]:animate-content-show text-black font-iran-yekan-x focus:outline-none z-[100]"
|
||||
>
|
||||
<div
|
||||
class="w-full h-[350px] shrink-0 rounded-2xl relative overflow-hidden flex-center"
|
||||
>
|
||||
<div class="w-full h-[350px] shrink-0 rounded-2xl relative overflow-hidden flex-center">
|
||||
<div
|
||||
class="bg-custom-conic size-[200%] absolute -top-1/2 -left-1/2 animate-spin [animation-duration:3s] z-[1]"
|
||||
></div>
|
||||
@@ -48,6 +44,8 @@ const visible = computed({
|
||||
<NuxtImg
|
||||
class="aspect-square w-[300px]"
|
||||
src="/img/heymlz/heymlz-payment-progress.gif"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
/>
|
||||
|
||||
<div class="-translate-y-28 flex-center gap-3">
|
||||
@@ -55,9 +53,7 @@ const visible = computed({
|
||||
name="svg-spinners:3-dots-bounce"
|
||||
size="20"
|
||||
/>
|
||||
<span class="text-lg">
|
||||
در حال انتقال به درگاه پرداخت
|
||||
</span>
|
||||
<span class="text-lg"> در حال انتقال به درگاه پرداخت </span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -72,15 +68,7 @@ const visible = computed({
|
||||
.bg-custom-conic {
|
||||
background-size: 100% 100%;
|
||||
background-position: 0px 0px, 0px 0px;
|
||||
background-image: radial-gradient(
|
||||
142% 91% at -6% 90%,
|
||||
#ff000000 1%,
|
||||
#ff000000 99%
|
||||
),
|
||||
conic-gradient(
|
||||
from 0deg at 50% 50%,
|
||||
var(--color-blue-500) 0%,
|
||||
#ff000000 34%
|
||||
);
|
||||
background-image: radial-gradient(142% 91% at -6% 90%, #ff000000 1%, #ff000000 99%),
|
||||
conic-gradient(from 0deg at 50% 50%, var(--color-blue-500) 0%, #ff000000 34%);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -27,15 +27,19 @@ const { isLoading: cartImageIsLoading } = useImage({
|
||||
v-if="!cartImageIsLoading"
|
||||
class="size-[3.5rem] shrink-0 rounded-100 border border-gray-300 overflow-hidden"
|
||||
>
|
||||
<NuxtImg :src="image" alt="product" class="object-conver" />
|
||||
<NuxtImg
|
||||
:src="image"
|
||||
alt="product"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
class="object-conver"
|
||||
/>
|
||||
</div>
|
||||
<Skeleton
|
||||
v-else
|
||||
class="!size-[3.5rem] aspect-square shrink-0 !rounded-100 border border-slate-200"
|
||||
/>
|
||||
<span
|
||||
class="text-xs font-semibold lg:text-sm text-gray-800 line-clamp-2"
|
||||
>
|
||||
<span class="text-xs font-semibold lg:text-sm text-gray-800 line-clamp-2">
|
||||
{{ title }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -123,6 +123,8 @@ watch(
|
||||
>
|
||||
<NuxtImg
|
||||
:src="data.product.image"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
class="object-cover size-full"
|
||||
alt="product"
|
||||
/>
|
||||
|
||||
@@ -38,6 +38,8 @@ const remaining = computed(() => items.value.length - max.value);
|
||||
>
|
||||
<NuxtImg
|
||||
:src="item"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
alt="avatar"
|
||||
class="rounded-full object-cover w-full h-full"
|
||||
/>
|
||||
|
||||
@@ -51,6 +51,8 @@ const createdAt = usePersianTimeAgo(new Date(date.value));
|
||||
|
||||
<NuxtImg
|
||||
:src="image"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
class="group-hover:scale-105 transition-transform duration-200 absolute size-full object-cover z-10"
|
||||
alt=""
|
||||
/>
|
||||
@@ -98,6 +100,8 @@ const createdAt = usePersianTimeAgo(new Date(date.value));
|
||||
|
||||
<NuxtImg
|
||||
v-if="variant === 'lg'"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
:src="image"
|
||||
class="group-hover:scale-105 transition-transform duration-200 absolute size-full object-cover z-10"
|
||||
alt=""
|
||||
|
||||
@@ -41,6 +41,8 @@ const brands = ref([
|
||||
HEYMLZ
|
||||
</div>
|
||||
<NuxtImg
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
src="/img/heymlz/heymlz-logo.png"
|
||||
class="h-[25px] sm:h-[45px] invert"
|
||||
/>
|
||||
@@ -62,6 +64,8 @@ const brands = ref([
|
||||
class="flex items-center px-6 sm:px-10 h-[90px] sm:h-[140px]"
|
||||
>
|
||||
<NuxtImg
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
:src="brand"
|
||||
class="h-[25px] sm:h-[45px] opacity-25"
|
||||
/>
|
||||
@@ -70,23 +74,3 @@ const brands = ref([
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<!-- <NuxtImg
|
||||
src="/img/brands/brand-2.png"
|
||||
class="h-[25px] sm:h-[45px]"
|
||||
/>
|
||||
<NuxtImg
|
||||
src="/img/brands/brand-3.png"
|
||||
class="h-[25px] sm:h-[45px]"
|
||||
/>
|
||||
<NuxtImg
|
||||
src="/img/brands/brand-4.png"
|
||||
class="h-[25px] sm:h-[45px]"
|
||||
/>
|
||||
<NuxtImg
|
||||
src="/img/brands/brand-5.png"
|
||||
class="h-[25px] sm:h-[45px]"
|
||||
/>
|
||||
<NuxtImg
|
||||
src="/img/brands/brand-6.png"
|
||||
class="h-[25px] sm:h-[45px]"
|
||||
/> -->
|
||||
|
||||
@@ -44,6 +44,8 @@ const { colorObject } = useImageColor(`#category-image-${id.value}`);
|
||||
:id="`category-image-${id}`"
|
||||
class="group-hover:scale-105 transition-transform duration-200 absolute object-contain size-full"
|
||||
:src="picture"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
alt=""
|
||||
/>
|
||||
</Transition>
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
<NuxtImg
|
||||
src="/img/footer-bg.jpg"
|
||||
alt=""
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
class="absolute z-10 object-cover opacity-45"
|
||||
:style="{
|
||||
mask: 'linear-gradient(to bottom, black 0%, rgba(0,0,0,0) 100%',
|
||||
@@ -13,6 +15,8 @@
|
||||
<div class="flex items-center flex-col gap-8 pb-[10px] pt-[80px] lg:pt-[100px] lg:pb-[50px] justify-center">
|
||||
<img
|
||||
src="/img/heymlz/heymlz-small-idle.gif"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
class="size-[150px] lg:size-[220px] rounded-full drop-shadow-2xl"
|
||||
/>
|
||||
<span class="font-bold text-2xl lg:text-5xl text-gradient bg-gradient-to-l from-blue-500 to-blue-700">
|
||||
|
||||
@@ -124,6 +124,9 @@ const isHomePage = computed(() => route.path === "/");
|
||||
<div class="header-navbar-item flex items-center justify-end h-full">
|
||||
<NuxtImg
|
||||
src="/img/heymlz/heymlz-logomotion.gif"
|
||||
preload
|
||||
loading="eager"
|
||||
fetch-priority="high"
|
||||
class="h-2/3"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -35,24 +35,26 @@ const highlights = ref<Highlight[]>([
|
||||
|
||||
<template>
|
||||
<section class="w-full border-t-[0.5px] border-slate-200">
|
||||
<div
|
||||
class="w-full py-[3rem] lg:py-[5rem] gap-8 sm:gap-12 xl:gap-0 container grid grid-cols-2 lg:grid-cols-4"
|
||||
<div class="w-full py-[3rem] lg:py-[5rem] gap-8 sm:gap-12 xl:gap-0 container grid grid-cols-2 lg:grid-cols-4">
|
||||
<template
|
||||
v-for="(highlight, index) in highlights"
|
||||
:key="index"
|
||||
>
|
||||
<template v-for="(highlight, index) in highlights" :key="index">
|
||||
<div class="flex flex-col-center gap-[.75rem] px-5">
|
||||
<div class="size-[70px] md:size-[100px] flex-center">
|
||||
<NuxtImg :src="highlight.icon" class="w-full" />
|
||||
<NuxtImg
|
||||
:src="highlight.icon"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
class="w-full"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="w-full flex-col-center gap-[.25rem]">
|
||||
<span
|
||||
class="typo-sub-h-sm lg:typo-sub-h-md text-black text-center"
|
||||
>
|
||||
<span class="typo-sub-h-sm lg:typo-sub-h-md text-black text-center">
|
||||
{{ highlight.title }}
|
||||
</span>
|
||||
<p
|
||||
class="text-slate-500 typo-p-xs lg:typo-p-sm mt-1 text-center"
|
||||
>
|
||||
<p class="text-slate-500 typo-p-xs lg:typo-p-sm mt-1 text-center">
|
||||
{{ highlight.description }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -90,6 +90,8 @@ const changeSlide = (id: number) => {
|
||||
<NuxtImg
|
||||
class="absolute object-cover size-full"
|
||||
:src="slide.image"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
:alt="String(slide.id)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -67,6 +67,8 @@ const parallaxStyle = computed(() => {
|
||||
<NuxtImg
|
||||
:id="`product-image-${id}`"
|
||||
:src="picture"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
class="group-hover:scale-105 transition-transform duration-200 size-full object-contain absolute inset-0"
|
||||
alt="product-background"
|
||||
/>
|
||||
|
||||
@@ -42,6 +42,8 @@ const onSlideChange = (swiper: SwiperClass) => {
|
||||
:style="{
|
||||
filter: 'drop-shadow(0px 0px 20px rgba(0, 0, 0, 0.4))',
|
||||
}"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
src="/img/heymlz/heymlz-category-seat.gif"
|
||||
/>
|
||||
<Swiper
|
||||
|
||||
@@ -214,6 +214,9 @@ onUnmounted(() => {
|
||||
|
||||
<NuxtImg
|
||||
v-else
|
||||
preload
|
||||
loading="eager"
|
||||
fetch-priority="high"
|
||||
class="absolute inset-0 size-full object-cover"
|
||||
:src="slide.image!"
|
||||
:alt="slide.title"
|
||||
@@ -265,6 +268,8 @@ onUnmounted(() => {
|
||||
filter: 'drop-shadow(0px 0px 20px rgba(0, 0, 0, 0.4))',
|
||||
}"
|
||||
src="/img/heymlz/heymlz-seat.gif"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
/>
|
||||
|
||||
<Button
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
// import
|
||||
|
||||
import { Swiper, SwiperSlide } from "swiper/vue";
|
||||
@@ -7,7 +6,7 @@ import type { SwiperClass } from "swiper/react";
|
||||
|
||||
// types
|
||||
|
||||
type Props = {}
|
||||
type Props = {};
|
||||
|
||||
// props
|
||||
|
||||
@@ -23,7 +22,6 @@ const swiper_instance = ref<SwiperClass | null>(null);
|
||||
const onSwiper = (swiper: SwiperClass) => {
|
||||
swiper_instance.value = swiper;
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -31,6 +29,8 @@ const onSwiper = (swiper: SwiperClass) => {
|
||||
<NuxtImg
|
||||
class="absolute size-full object-cover"
|
||||
src="/img/hero-bg.jpg"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
alt=""
|
||||
/>
|
||||
<div class="absolute bg-black/60 size-full z-10" />
|
||||
@@ -50,15 +50,18 @@ const onSwiper = (swiper: SwiperClass) => {
|
||||
>
|
||||
<div class="flex justify-center items-center">
|
||||
<div class="max-w-[900px] px-4 text-white flex flex-col items-center gap-4">
|
||||
<Icon name="ci:instagram" size="28" class="**:stroke-white" />
|
||||
<p class="text-base xs:text-lg sm:typo-h-6 lg:typo-h-5 !font-normal !leading-[150%] lg:leading-[175%] max-sm:px-4 sm:max-w-[600px] lg:max-w-[800px] text-center">
|
||||
لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با
|
||||
استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله
|
||||
در ستون و سطرآنچنان که لازم.
|
||||
<Icon
|
||||
name="ci:instagram"
|
||||
size="28"
|
||||
class="**:stroke-white"
|
||||
/>
|
||||
<p
|
||||
class="text-base xs:text-lg sm:typo-h-6 lg:typo-h-5 !font-normal !leading-[150%] lg:leading-[175%] max-sm:px-4 sm:max-w-[600px] lg:max-w-[800px] text-center"
|
||||
>
|
||||
لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک
|
||||
است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم.
|
||||
</p>
|
||||
<span class="typo-p-sm md:typo-p-xl text-center">
|
||||
- منصور مرزبان
|
||||
</span>
|
||||
<span class="typo-p-sm md:typo-p-xl text-center"> - منصور مرزبان </span>
|
||||
</div>
|
||||
</div>
|
||||
</SwiperSlide>
|
||||
@@ -69,10 +72,8 @@ const onSwiper = (swiper: SwiperClass) => {
|
||||
v-for="(i, index) in 6"
|
||||
:class="swiper_instance?.realIndex === index ? 'bg-white' : 'bg-transparent'"
|
||||
class="border border-white size-1.5 md:size-2 rounded-full transition-all duration-200"
|
||||
>
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -88,6 +88,8 @@ watch(
|
||||
:src="homeData!.difreance_section.image1"
|
||||
class="select-none absolute size-full object-cover transition-[filter] duration-250 brightness-[95%]"
|
||||
:alt="homeData!.difreance_section.title1"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
/>
|
||||
<video
|
||||
v-else
|
||||
@@ -110,6 +112,8 @@ watch(
|
||||
:src="homeData!.difreance_section.image2"
|
||||
class="overlay-image select-none absolute object-cover size-full transition-[filter] duration-250 brightness-[95%]"
|
||||
:alt="homeData!.difreance_section.title2"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
/>
|
||||
<video
|
||||
v-else
|
||||
@@ -126,9 +130,7 @@ watch(
|
||||
:style="{
|
||||
left: `${clipPathPercent}%`,
|
||||
}"
|
||||
:class="[
|
||||
activeSlideVideo !== 'none' ? 'opacity-10' : '',
|
||||
]"
|
||||
:class="[activeSlideVideo !== 'none' ? 'opacity-10' : '']"
|
||||
class="select-none w-[5px] sm:w-2 bg-black h-full absolute left-0 flex items-center justify-center transition-opacity duration-250"
|
||||
>
|
||||
<div
|
||||
@@ -143,9 +145,7 @@ watch(
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="absolute bottom-0 p-6 md:p-10 w-full flex justify-between items-end transition-opacity"
|
||||
>
|
||||
<div class="absolute bottom-0 p-6 md:p-10 w-full flex justify-between items-end transition-opacity">
|
||||
<div
|
||||
class="flex flex-col gap-2 text-black transition-opacity"
|
||||
:class="activeSlideVideo === 'right' ? 'opacity-0' : ''"
|
||||
|
||||
@@ -106,6 +106,8 @@ const childImageVariants = {
|
||||
<NuxtImg
|
||||
:src="slide.background_image"
|
||||
class="absolute size-full object-cover"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
/>
|
||||
</motion.div>
|
||||
</template>
|
||||
@@ -133,6 +135,8 @@ const childImageVariants = {
|
||||
<NuxtImg
|
||||
class="w-[130px] sm:w-[180px] lg:w-[250px] xl:w-[300px] z-20 mt-40"
|
||||
:src="slide.image3"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
alt=""
|
||||
/>
|
||||
</motion.div>
|
||||
@@ -144,6 +148,8 @@ const childImageVariants = {
|
||||
<NuxtImg
|
||||
class="w-[130px] sm:w-[180px] lg:w-[250px] xl:w-[300px] z-20"
|
||||
:src="slide.image2"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
alt=""
|
||||
/>
|
||||
</motion.div>
|
||||
@@ -155,6 +161,8 @@ const childImageVariants = {
|
||||
<NuxtImg
|
||||
class="w-[130px] sm:w-[180px] lg:w-[250px] xl:w-[300px] z-20 mt-40"
|
||||
:src="slide.image1"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
alt=""
|
||||
/>
|
||||
</motion.div>
|
||||
@@ -222,6 +230,8 @@ const childImageVariants = {
|
||||
>
|
||||
<NuxtImg
|
||||
src="/img/heymlz/heymlz-falling.gif"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
class="absolute top-[101px] sm:top-[100px] lg:top-[117px] left-1/2 -translate-1/2 w-[200px] lg:w-[250px] drop-shadow-md"
|
||||
/>
|
||||
<Button
|
||||
|
||||
@@ -187,6 +187,8 @@ whenever(
|
||||
<NuxtImg
|
||||
class="size-[225px] sm:size-[250px] drop-shadow-2xl"
|
||||
src="/img/heymlz/heymlz-small-idle.gif"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
@@ -199,6 +201,8 @@ whenever(
|
||||
<NuxtImg
|
||||
class="size-[225px] sm:size-[250px] drop-shadow-2xl"
|
||||
src="/img/heymlz/heymlz-small-idle.gif"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
alt=""
|
||||
/>
|
||||
<div class="flex flex-col gap-4 items-center">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import useGetAccount from '~/composables/api/account/useGetAccount';
|
||||
import useGetAccount from "~/composables/api/account/useGetAccount";
|
||||
|
||||
// types
|
||||
|
||||
@@ -85,31 +85,34 @@ onMounted(() => {
|
||||
src="/img/heymlz/heymlz-full-body.jpg"
|
||||
class="size-full object-cover absolute"
|
||||
alt="profile"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
/>
|
||||
<NuxtImg
|
||||
v-else
|
||||
:src="account?.profile_photo ?? ''"
|
||||
class="size-full object-cover absolute"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
alt="profile"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="rounded-150 px-4 py-3 whitespace-pre-wrap overflow-hidden"
|
||||
:class="
|
||||
reverse
|
||||
? 'bg-slate-100 text-slate-600'
|
||||
: 'bg-black text-white'
|
||||
"
|
||||
:class="reverse ? 'bg-slate-100 text-slate-600' : 'bg-black text-white'"
|
||||
>
|
||||
<div
|
||||
v-if="!loadingContent"
|
||||
:id="`chat-message-content-${id}`"
|
||||
class="typo-p-sm font-normal whitespace-pre-wrap"
|
||||
v-html="content"
|
||||
>
|
||||
</div>
|
||||
></div>
|
||||
|
||||
<Icon v-else name="svg-spinners:3-dots-bounce" size="20" />
|
||||
<Icon
|
||||
v-else
|
||||
name="svg-spinners:3-dots-bounce"
|
||||
size="20"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -127,6 +127,8 @@ const limitedComments = computed(() => {
|
||||
>
|
||||
<NuxtImg
|
||||
src="/img/heymlz/heymlz-contact-us.gif"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
class="w-[200px] lg:w-[300px] translate-y-[-25px]"
|
||||
/>
|
||||
<span class="text-xl text-black font-semibold translate-y-[-25px]"> هیچ نظری ثبت نشده است </span>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<script lang="ts" setup>
|
||||
|
||||
// import
|
||||
|
||||
import type { ProductVariantProvideType } from "~/pages/product/[id].vue";
|
||||
@@ -7,7 +6,6 @@ import type { ProductVariantProvideType } from "~/pages/product/[id].vue";
|
||||
// provide / inject
|
||||
|
||||
const { selectedVariant } = inject("productVariant") as ProductVariantProvideType;
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -20,25 +18,21 @@ const { selectedVariant } = inject("productVariant") as ProductVariantProvideTyp
|
||||
<Accordion />
|
||||
</div>
|
||||
<div class="w-full lg:w-[450px] xl:w-[600px]">
|
||||
<div
|
||||
class="w-full bg-slate-50 rounded-xl flex-col-center px-5 py-16 sm:p-[5rem] gap-[1.5rem]"
|
||||
>
|
||||
<div class="w-full bg-slate-50 rounded-xl flex-col-center px-5 py-16 sm:p-[5rem] gap-[1.5rem]">
|
||||
<span class="typo-h-6 mb-8">داخل جعبه چیه؟</span>
|
||||
<div
|
||||
class="w-full grid grid-cols-2 gap-y-[1.5rem] sm:gap-x-[3rem]"
|
||||
>
|
||||
<div class="w-full grid grid-cols-2 gap-y-[1.5rem] sm:gap-x-[3rem]">
|
||||
<div
|
||||
v-for="inPackItem in selectedVariant!.in_pack_items"
|
||||
class="w-full flex-col-center gap-[.75rem]"
|
||||
>
|
||||
<div
|
||||
class="size-[6.25rem] rounded-full border-slate-200 bg-white flex-center"
|
||||
>
|
||||
<div class="size-[6.25rem] rounded-full border-slate-200 bg-white flex-center">
|
||||
<div class="size-11 relative">
|
||||
<NuxtImg
|
||||
class="size-full absolute object-cover"
|
||||
:src="inPackItem.cover"
|
||||
:alt="inPackItem.item_title"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -38,9 +38,7 @@ const profile = computed(() => {
|
||||
});
|
||||
|
||||
const username = computed(() => {
|
||||
return is_user.value
|
||||
? `${account.value?.first_name} ${account.value?.last_name}`
|
||||
: "ادمین پشتیبانی هی ملز";
|
||||
return is_user.value ? `${account.value?.first_name} ${account.value?.last_name}` : "ادمین پشتیبانی هی ملز";
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -54,7 +52,12 @@ const username = computed(() => {
|
||||
:class="is_user ? 'rounded-br-none' : 'rounded-bl-none'"
|
||||
>
|
||||
<div class="w-2/12 flex items-start justify-start">
|
||||
<NuxtImg :src="profile" class="size-16 rounded-full" />
|
||||
<NuxtImg
|
||||
:src="profile"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
class="size-16 rounded-full"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="w-10/12 flex flex-col items-start pt-2">
|
||||
@@ -65,9 +68,7 @@ const username = computed(() => {
|
||||
>
|
||||
{{ timeAgo }}
|
||||
</p>
|
||||
<p
|
||||
class="text-xs font-semibold text-dynamic-secondary line-clamp-1"
|
||||
>
|
||||
<p class="text-xs font-semibold text-dynamic-secondary line-clamp-1">
|
||||
{{ username }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -38,6 +38,9 @@ if (response.isError) {
|
||||
class="absolute object-cover size-full"
|
||||
:alt="article!.title"
|
||||
:src="article!.cover_image"
|
||||
preload
|
||||
loading="eager"
|
||||
fetch-priority="high"
|
||||
/>
|
||||
<div class="absolute bg-linear-to-t from-black/75 to-transparent size-full" />
|
||||
<div class="absolute pl-10 right-10 bottom-10 flex flex-col gap-6">
|
||||
@@ -62,6 +65,8 @@ if (response.isError) {
|
||||
class="size-full object-cover absolute"
|
||||
:src="article!.author.profile_photo"
|
||||
alt="article-author"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
/>
|
||||
</div>
|
||||
<span class="typo-label-sm">
|
||||
|
||||
@@ -61,6 +61,8 @@ const deliveryData = ref<DeliveryData>({
|
||||
<div class="flex items-center gap-3 py-3">
|
||||
<NuxtImg
|
||||
src="/img/location.gif"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
class="size-12 pb-1 -mr-3"
|
||||
/>
|
||||
<span class="typo-sub-h-xl -mr-3"> آدرس های شما </span>
|
||||
|
||||
@@ -6,7 +6,7 @@ import useGetCartOrders from "~/composables/api/orders/useGetCartOrders";
|
||||
// meta
|
||||
|
||||
useSeoMeta({
|
||||
title : "سبد خرید"
|
||||
title: "سبد خرید",
|
||||
});
|
||||
|
||||
definePageMeta({
|
||||
@@ -22,9 +22,7 @@ const { data: cart, isLoading: cartIsLoading } = useGetCartOrders();
|
||||
|
||||
// computed
|
||||
|
||||
const hasCartItem = computed(
|
||||
() => !!cart.value && cart.value.items.length! > 0
|
||||
);
|
||||
const hasCartItem = computed(() => !!cart.value && cart.value.items.length! > 0);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -38,11 +36,17 @@ const hasCartItem = computed(
|
||||
class="!w-36 !h-[43px] !rounded-lg"
|
||||
/>
|
||||
|
||||
<div v-else class="flex items-center w-full gap-2 lg:w-1/2">
|
||||
<NuxtImg src="/img/box.gif" class="size-12 pb-2" />
|
||||
<p class="font-semibold lg:text-lg text-black">
|
||||
{{ cart?.items.length }} مرسوله
|
||||
</p>
|
||||
<div
|
||||
v-else
|
||||
class="flex items-center w-full gap-2 lg:w-1/2"
|
||||
>
|
||||
<NuxtImg
|
||||
src="/img/box.gif"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
class="size-12 pb-2"
|
||||
/>
|
||||
<p class="font-semibold lg:text-lg text-black">{{ cart?.items.length }} مرسوله</p>
|
||||
</div>
|
||||
|
||||
<Skeleton
|
||||
@@ -53,7 +57,10 @@ const hasCartItem = computed(
|
||||
<DeleteCartAllModal v-else />
|
||||
</div>
|
||||
|
||||
<ul v-if="cartIsLoading" class="w-full flex flex-col gap-4 lg:gap-6">
|
||||
<ul
|
||||
v-if="cartIsLoading"
|
||||
class="w-full flex flex-col gap-4 lg:gap-6"
|
||||
>
|
||||
<Skeleton
|
||||
v-for="i in 4"
|
||||
:key="i"
|
||||
@@ -61,20 +68,38 @@ const hasCartItem = computed(
|
||||
/>
|
||||
</ul>
|
||||
|
||||
<div v-else class="w-full h-max">
|
||||
<div v-if="!cart?.items.length" class="flex flex-grow w-full">
|
||||
<Placeholder title="سبد خرید شما خالی است :(" icon="bi:cart">
|
||||
<div
|
||||
v-else
|
||||
class="w-full h-max"
|
||||
>
|
||||
<div
|
||||
v-if="!cart?.items.length"
|
||||
class="flex flex-grow w-full"
|
||||
>
|
||||
<Placeholder
|
||||
title="سبد خرید شما خالی است :("
|
||||
icon="bi:cart"
|
||||
>
|
||||
<template #actions>
|
||||
<NuxtLink :to="{ name: 'products' }">
|
||||
<Button class="rounded-full" size="md">
|
||||
<Button
|
||||
class="rounded-full"
|
||||
size="md"
|
||||
>
|
||||
<span> مشاهده محصولات </span>
|
||||
<Icon name="ci:left-rotation" size="24" />
|
||||
<Icon
|
||||
name="ci:left-rotation"
|
||||
size="24"
|
||||
/>
|
||||
</Button>
|
||||
</NuxtLink>
|
||||
</template>
|
||||
</Placeholder>
|
||||
</div>
|
||||
<ul v-else class="w-full flex flex-col gap-4 lg:gap-6">
|
||||
<ul
|
||||
v-else
|
||||
class="w-full flex flex-col gap-4 lg:gap-6"
|
||||
>
|
||||
<CartItem
|
||||
v-for="(item, index) in cart?.items"
|
||||
:key="index"
|
||||
|
||||
@@ -22,7 +22,7 @@ if (response.isError) {
|
||||
|
||||
<template>
|
||||
<div class="w-full">
|
||||
<LoadingOverlay />
|
||||
<!-- <LoadingOverlay /> -->
|
||||
<Hero class="mb-20 max-md:mt-[80px]" />
|
||||
<Preview />
|
||||
<ProductsShowcase class="lg:mb-12" />
|
||||
|
||||
@@ -9,8 +9,8 @@ import usePersianDate from "~/composables/global/usePersianDate";
|
||||
useSeoMeta({
|
||||
title: "نتیجه تراکنش",
|
||||
description: "",
|
||||
keywords : ""
|
||||
})
|
||||
keywords: "",
|
||||
});
|
||||
|
||||
definePageMeta({
|
||||
layout: "none",
|
||||
@@ -91,6 +91,8 @@ const statusTitle = computed(() => {
|
||||
class="aspect-square w-[220px] md:w-[280px] lg:w-[320px] absolute -top-[70px] md:-top-[110px] lg:-top-[138px] left-1/2 -translate-x-1/2 z-10 [filter:_drop-shadow(0px_4px_20px_rgba(0, 0, 0, 0.15))]"
|
||||
src="/img/heymlz/heymlz-seat.gif"
|
||||
:class="statusVariants.hue_deg"
|
||||
loading="lazy"
|
||||
fetch-priority="low"
|
||||
/>
|
||||
|
||||
<div
|
||||
|
||||
Reference in New Issue
Block a user