71 lines
1.8 KiB
Vue
71 lines
1.8 KiB
Vue
<script lang="ts" setup>
|
|
// import
|
|
|
|
import ChatButton from "~/components/product/ChatBox/ChatButton.vue";
|
|
import useGetProduct from "~/composables/api/product/useGetProduct";
|
|
import ProductsSlider from "~/components/global/product-detail/ProductsSlider.vue";
|
|
|
|
// state
|
|
|
|
const route = useRoute();
|
|
|
|
const id = route.params.id as string | undefined;
|
|
|
|
const { suspense: suspenseProduct, data: product } = useGetProduct(id);
|
|
|
|
useSeoMeta({
|
|
title: product.value?.name,
|
|
ogImage: product.value?.variants[0].images[0].image,
|
|
twitterImage: product.value?.variants[0].images[0].image,
|
|
ogDescription: product.value?.description,
|
|
twitterDescription: product.value?.description,
|
|
});
|
|
|
|
const selectedVariant = ref<ProductVariant>();
|
|
|
|
const showChatButton = ref(true);
|
|
|
|
// type
|
|
|
|
export type ProductVariantProvideType = {
|
|
selectedVariant: typeof selectedVariant;
|
|
changeSelectedVariant: (value: ProductVariant) => void;
|
|
};
|
|
|
|
// provide / inject
|
|
|
|
provide("productVariant", {
|
|
selectedVariant,
|
|
changeSelectedVariant: (value: ProductVariant) => (selectedVariant.value = value),
|
|
});
|
|
|
|
// ssr
|
|
|
|
const productResponse = await suspenseProduct();
|
|
|
|
if (productResponse.isError) {
|
|
throw createError({
|
|
statusCode: 404,
|
|
statusMessage: `error : product ${id} prefetch error`,
|
|
});
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="w-full flex flex-col">
|
|
<ProductHero />
|
|
<ProductVideo v-model:showChatButton="showChatButton" />
|
|
<ProductDetails />
|
|
<div class="py-20">
|
|
<ProductsSlider
|
|
title="محصولات مشابه"
|
|
:products="product!.related_products"
|
|
iconImage="/img/simulare-products-section.gif"
|
|
/>
|
|
</div>
|
|
<ProductComments :product="product!" />
|
|
|
|
<ChatButton :showChatButton="showChatButton" />
|
|
</div>
|
|
</template>
|