merge and add list texts for detail model
This commit is contained in:
@@ -45,106 +45,111 @@ const emptySlidesCount = computed(() => {
|
||||
const changeSlide = (id: number) => {
|
||||
emit("update:selectedSlide", id);
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col relative gap-6">
|
||||
<div
|
||||
class="bg-white brightness-[97%] w-full relative aspect-square overflow-hidden rounded-[12px] md:rounded-200"
|
||||
>
|
||||
<Transition name="zoom" mode="out-in">
|
||||
<NuxtImg
|
||||
:key="selectedSlideDetail.id"
|
||||
class="size-full absolute object-contain"
|
||||
:src="selectedSlideDetail.image"
|
||||
:alt="selectedSlideDetail.name"
|
||||
/>
|
||||
</Transition>
|
||||
</div>
|
||||
|
||||
<div class="relative w-full">
|
||||
<Swiper
|
||||
:slides-per-view="3"
|
||||
:space-between="20"
|
||||
@swiper="onSwiper"
|
||||
class="w-full"
|
||||
<div class="sticky top-10">
|
||||
<div class="flex flex-col relative gap-6">
|
||||
<div
|
||||
class="bg-white brightness-[97%] w-full relative aspect-square overflow-hidden rounded-[12px] md:rounded-200"
|
||||
>
|
||||
<SwiperSlide
|
||||
class="py-4"
|
||||
v-for="slide in slides"
|
||||
:key="slide.id"
|
||||
<Transition
|
||||
name="zoom"
|
||||
mode="out-in"
|
||||
>
|
||||
<div
|
||||
@click="changeSlide(slide.id)"
|
||||
:class="
|
||||
selectedSlide === slide.id
|
||||
? '!border-black'
|
||||
: 'border-transparent'
|
||||
"
|
||||
class="active:scale-95 hover:border-slate-200 transition-all cursor-pointer brightness-[97%] bg-white aspect-square border-2 rounded-[12px] md:rounded-200 w-full overflow-hidden relative"
|
||||
<NuxtImg
|
||||
:key="selectedSlideDetail.id"
|
||||
class="size-full absolute object-contain"
|
||||
:src="selectedSlideDetail.image"
|
||||
:alt="selectedSlideDetail.name"
|
||||
/>
|
||||
</Transition>
|
||||
</div>
|
||||
|
||||
<div class="relative w-full">
|
||||
<Swiper
|
||||
:slides-per-view="3"
|
||||
:space-between="20"
|
||||
@swiper="onSwiper"
|
||||
class="w-full"
|
||||
>
|
||||
<SwiperSlide
|
||||
class="py-4"
|
||||
v-for="slide in slides"
|
||||
:key="slide.id"
|
||||
>
|
||||
<NuxtImg
|
||||
class="absolute object-cover size-full"
|
||||
:src="slide.image"
|
||||
:alt="String(slide.id)"
|
||||
/>
|
||||
</div>
|
||||
</SwiperSlide>
|
||||
<SwiperSlide
|
||||
v-if="emptySlidesCount > 0"
|
||||
v-for="slide in emptySlidesCount"
|
||||
:key="slide"
|
||||
class="py-4"
|
||||
<div
|
||||
@click="changeSlide(slide.id)"
|
||||
:class="selectedSlide === slide.id ? '!border-black' : 'border-transparent'"
|
||||
class="active:scale-95 hover:border-slate-200 transition-all cursor-pointer brightness-[97%] bg-white aspect-square border-2 rounded-[12px] md:rounded-200 w-full overflow-hidden relative"
|
||||
>
|
||||
<NuxtImg
|
||||
class="absolute object-cover size-full"
|
||||
:src="slide.image"
|
||||
:alt="String(slide.id)"
|
||||
/>
|
||||
</div>
|
||||
</SwiperSlide>
|
||||
<SwiperSlide
|
||||
v-if="emptySlidesCount > 0"
|
||||
v-for="slide in emptySlidesCount"
|
||||
:key="slide"
|
||||
class="py-4"
|
||||
>
|
||||
<div
|
||||
class="brightness-[97%] flex-center bg-white aspect-square rounded-[12px] md:rounded-200 w-full"
|
||||
>
|
||||
<Icon
|
||||
name="ci:image-slash"
|
||||
class="size-[40px] sm:size-[60px] **:fill-black/20"
|
||||
/>
|
||||
</div>
|
||||
</SwiperSlide>
|
||||
</Swiper>
|
||||
|
||||
<div
|
||||
v-if="slides.length > 3"
|
||||
@click="swiper_instance?.slidePrev()"
|
||||
class="absolute z-20 -right-4 shadow-lg cursor-pointer shadow-black/10 bottom-[50%] translate-y-1/2 bg-white rounded-full size-10 xs:size-11.5 flex justify-center items-center"
|
||||
>
|
||||
<div class="brightness-[97%] flex-center bg-white aspect-square rounded-[12px] md:rounded-200 w-full">
|
||||
<Icon name="ci:image-slash" class="size-[40px] sm:size-[60px] **:fill-black/20" />
|
||||
</div>
|
||||
</SwiperSlide>
|
||||
</Swiper>
|
||||
<Icon
|
||||
name="ci:arrow-right"
|
||||
class="**:stroke-black size-5 xs:size-6"
|
||||
:class="swiper_instance?.isBeginning ? '**:stroke-black/30' : ''"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="slides.length > 3"
|
||||
@click="swiper_instance?.slidePrev()"
|
||||
class="absolute z-20 -right-4 shadow-lg cursor-pointer shadow-black/10 bottom-[50%] translate-y-1/2 bg-white rounded-full size-10 xs:size-11.5 flex justify-center items-center"
|
||||
>
|
||||
<Icon
|
||||
name="ci:arrow-right"
|
||||
class="**:stroke-black size-5 xs:size-6"
|
||||
:class="swiper_instance?.isBeginning ? '**:stroke-black/30' : ''"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="slides.length > 3"
|
||||
@click="swiper_instance?.slideNext()"
|
||||
class="absolute z-20 -left-4 shadow-lg cursor-pointer shadow-black/10 bottom-[50%] translate-y-1/2 bg-white rounded-full size-10 xs:size-11.5 flex justify-center items-center"
|
||||
>
|
||||
<Icon
|
||||
name="ci:arrow-left"
|
||||
class="**:stroke-black size-5 xs:size-6"
|
||||
:class="swiper_instance?.isEnd ? '**:stroke-black/30' : ''"
|
||||
/>
|
||||
<div
|
||||
v-if="slides.length > 3"
|
||||
@click="swiper_instance?.slideNext()"
|
||||
class="absolute z-20 -left-4 shadow-lg cursor-pointer shadow-black/10 bottom-[50%] translate-y-1/2 bg-white rounded-full size-10 xs:size-11.5 flex justify-center items-center"
|
||||
>
|
||||
<Icon
|
||||
name="ci:arrow-left"
|
||||
class="**:stroke-black size-5 xs:size-6"
|
||||
:class="swiper_instance?.isEnd ? '**:stroke-black/30' : ''"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="grid grid-cols-3 gap-6">-->
|
||||
<!-- <div-->
|
||||
<!-- @click="changeSlide(slide.id)"-->
|
||||
<!-- v-for="slide in slides"-->
|
||||
<!-- :class="-->
|
||||
<!-- selectedSlide === slide.id-->
|
||||
<!-- ? '!ring-black'-->
|
||||
<!-- : 'ring-transparent'-->
|
||||
<!-- "-->
|
||||
<!-- class="active:scale-95 hover:ring-slate-200 transition-all cursor-pointer brightness-[97%] bg-white aspect-square ring-2 ring-offset-4 rounded-[12px] md:rounded-200 w-full overflow-hidden relative"-->
|
||||
<!-- :key="slide.id"-->
|
||||
<!-- >-->
|
||||
<!-- <img-->
|
||||
<!-- class="absolute object-cover size-full"-->
|
||||
<!-- :src="slide.image"-->
|
||||
<!-- :alt="String(slide.id)"-->
|
||||
<!-- />-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
<!-- <div class="grid grid-cols-3 gap-6">-->
|
||||
<!-- <div-->
|
||||
<!-- @click="changeSlide(slide.id)"-->
|
||||
<!-- v-for="slide in slides"-->
|
||||
<!-- :class="-->
|
||||
<!-- selectedSlide === slide.id-->
|
||||
<!-- ? '!ring-black'-->
|
||||
<!-- : 'ring-transparent'-->
|
||||
<!-- "-->
|
||||
<!-- class="active:scale-95 hover:ring-slate-200 transition-all cursor-pointer brightness-[97%] bg-white aspect-square ring-2 ring-offset-4 rounded-[12px] md:rounded-200 w-full overflow-hidden relative"-->
|
||||
<!-- :key="slide.id"-->
|
||||
<!-- >-->
|
||||
<!-- <img-->
|
||||
<!-- class="absolute object-cover size-full"-->
|
||||
<!-- :src="slide.image"-->
|
||||
<!-- :alt="String(slide.id)"-->
|
||||
<!-- />-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
<script lang="ts" setup>
|
||||
|
||||
import type { ProductVariantProvideType } from '~/pages/product/[id].vue';
|
||||
import type { ProductVariantProvideType } from "~/pages/product/[id].vue";
|
||||
|
||||
// provide / inject
|
||||
|
||||
const { selectedVariant } = inject("productVariant") as ProductVariantProvideType;
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -21,9 +19,7 @@ const { selectedVariant } = inject("productVariant") as ProductVariantProvideTyp
|
||||
:value="'item' + detailItem.detail_category"
|
||||
class="overflow-hidden"
|
||||
>
|
||||
<AccordionHeader
|
||||
class="border-t border-slate-200 py-[1.5rem] flex justify-between items-center"
|
||||
>
|
||||
<AccordionHeader class="border-t border-slate-200 py-[1.5rem] flex justify-between items-center">
|
||||
<span class="typo-sub-h-md text-black">{{ detailItem.detail_category }}</span>
|
||||
<AccordionTrigger class="group">
|
||||
<Icon
|
||||
@@ -36,21 +32,22 @@ const { selectedVariant } = inject("productVariant") as ProductVariantProvideTyp
|
||||
<AccordionContent
|
||||
class="data-[state=open]:animate-slide-down pb-[1.5rem] data-[state=closed]:animate-slide-up overflow-hidden"
|
||||
>
|
||||
<div
|
||||
class="w-full grid grid-cols-2 gap-y-[1.5rem] gap-x-[1rem]"
|
||||
>
|
||||
<div class="w-full grid grid-cols-2 gap-y-[1.5rem] gap-x-[1rem]">
|
||||
<div
|
||||
v-for="item in detailItem.detail"
|
||||
v-for="item in detailItem.details"
|
||||
class="flex flex-col gap-y-[1.5rem]"
|
||||
>
|
||||
<span
|
||||
class="typo-sub-h-lg text-black w-full pt-[1.5rem]"
|
||||
>
|
||||
<span class="typo-sub-h-lg text-black w-full pt-[1.5rem]">
|
||||
{{ item.title }}
|
||||
</span>
|
||||
<ul class="list-disc w-full ps-5">
|
||||
<li
|
||||
v-for="detail in [ item.detail_text1, item.detail_text2, item.detail_text3, item.detail_text4 ]"
|
||||
v-for="detail in [
|
||||
item.detail_text1,
|
||||
item.detail_text2,
|
||||
item.detail_text3,
|
||||
item.detail_text4,
|
||||
]"
|
||||
class="text-slate-500 typo-p-md"
|
||||
>
|
||||
{{ detail }}
|
||||
@@ -62,4 +59,4 @@ const { selectedVariant } = inject("productVariant") as ProductVariantProvideTyp
|
||||
</AccordionItem>
|
||||
</AccordionRoot>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
@@ -28,7 +28,7 @@ const onSwiper = (swiper: SwiperClass) => {
|
||||
|
||||
<div class="w-full mt-44 lg:mt-64 relative">
|
||||
<NuxtImg
|
||||
class="aspect-square w-[240px] md:w-[300px] lg:w-[350px] translate-y-[-164px] md:translate-y-[-206px] lg:translate-y-[-240px] absolute left-1/2 -translate-x-1/2 z-10"
|
||||
class="aspect-square w-[210px] sm:w-[240px] md:w-[300px] lg:w-[350px] translate-y-[-164px] md:translate-y-[-206px] lg:translate-y-[-240px] absolute left-1/2 -translate-x-1/2 z-10"
|
||||
:style="{
|
||||
filter: 'drop-shadow(0px 0px 20px rgba(0, 0, 0, 0.4))',
|
||||
}"
|
||||
|
||||
@@ -242,9 +242,9 @@ onUnmounted(() => {
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<h3 class="typo-h-6 md:typo-h-4 lg:typo-h-1 tracking-[-2px] text-white">
|
||||
<NuxtLink :to="slide.link" class="typo-h-6 md:typo-h-4 lg:typo-h-1 tracking-[-2px] text-white">
|
||||
{{ slide.title }}
|
||||
</h3>
|
||||
</NuxtLink>
|
||||
</div>
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="truncate typo-p-xs md:typo-p-sm lg:typo-p-lg text-white">
|
||||
|
||||
@@ -10,7 +10,7 @@ import { useAuth } from "~/composables/api/auth/useAuth";
|
||||
|
||||
// provide-inject
|
||||
|
||||
const { isOpen } = inject("isOpen") as any;
|
||||
const { isOpen, closeChat } = inject("isOpen") as any;
|
||||
|
||||
// state
|
||||
|
||||
@@ -128,7 +128,7 @@ whenever(
|
||||
<Transition :name="isMobile ? 'fade-down' : 'fade-right-to-left'">
|
||||
<div
|
||||
v-if="isOpen"
|
||||
class="fixed z-50 max-xs:inset-0 xs:right-8 xs:bottom-8 w-full xs:w-[450px] transition-all duration-500 overflow-hidden h-svh xs:h-[700px] xs:rounded-250 shadow-2xl shadow-black/30 pt-[40px] bg-white"
|
||||
class="fixed z-9999 max-xs:inset-0 xs:right-8 xs:bottom-8 w-full xs:w-[450px] transition-all duration-500 overflow-hidden h-svh xs:h-[700px] xs:rounded-250 shadow-2xl shadow-black/30 pt-[40px] bg-white"
|
||||
>
|
||||
<CloseButton :disabled="!!isCreateMessagePending" />
|
||||
|
||||
@@ -185,7 +185,7 @@ whenever(
|
||||
class="w-full h-full flex items-center justify-center absolute inset-0"
|
||||
>
|
||||
<NuxtImg
|
||||
class="size-[250px] drop-shadow-2xl"
|
||||
class="size-[225px] sm:size-[250px] drop-shadow-2xl"
|
||||
src="/img/heymlz/heymlz-small-idle.gif"
|
||||
alt=""
|
||||
/>
|
||||
@@ -197,7 +197,7 @@ whenever(
|
||||
v-else
|
||||
>
|
||||
<NuxtImg
|
||||
class="size-[250px] drop-shadow-2xl"
|
||||
class="size-[225px] sm:size-[250px] drop-shadow-2xl"
|
||||
src="/img/heymlz/heymlz-small-idle.gif"
|
||||
alt=""
|
||||
/>
|
||||
@@ -207,9 +207,22 @@ whenever(
|
||||
من میتونم هر سوالی رو درمورد این محصول جواب بدم اگه میخوای شروع کنیم روی دکمه زیر کلیک کن
|
||||
</p>
|
||||
</div>
|
||||
<NuxtLink to="/signin">
|
||||
<Button class="mt-8 rounded-full px-10">ورود به فروشگاه</Button>
|
||||
</NuxtLink>
|
||||
<div class="flex-center gap-4">
|
||||
<Button
|
||||
@click="closeChat"
|
||||
class="mt-8 rounded-full px-10"
|
||||
>
|
||||
بستن
|
||||
</Button>
|
||||
<NuxtLink to="/signin">
|
||||
<Button
|
||||
variant="outlined"
|
||||
class="mt-8 rounded-full px-10"
|
||||
>
|
||||
ورود به فروشگاه
|
||||
</Button>
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
|
||||
Vendored
+1
-1
@@ -70,7 +70,7 @@ declare global {
|
||||
|
||||
type ProductDetail = {
|
||||
id: number;
|
||||
detail: ProductDetailItem[];
|
||||
details: ProductDetailItem[];
|
||||
detail_category: number;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user