22 <div v-if =" data?.product" >
33 <section >
44 <div class =" container flex flex-wrap items-center pt-4 pb-12 mx-auto" >
5- <div
6- class =" grid grid-cols-1 gap-4 mt-8 lg:grid-cols-2 xl:grid-cols-2 md:grid-cols-2 sm:grid-cols-2"
7- >
8- <ProductImage
9- :alt =" data.product.name"
10- :src =" data.product.image.sourceUrl"
11- />
5+ <div class =" grid grid-cols-1 gap-4 mt-8 lg:grid-cols-2 xl:grid-cols-2 md:grid-cols-2 sm:grid-cols-2" >
6+ <ProductImage :alt =" data.product.name" :src =" data.product.image.sourceUrl" />
127 <div class =" ml-8" >
138 <p class =" text-3xl font-bold text-left" >
149 {{ data.product.name }}
1510 </p >
16- <div v-if =" data.product.onSale" class =" flex" >
17- <p class =" pt-1 mt-4 text-3xl text-gray-900" >
18- <span v-if =" data.productvariations" >
19- {{ filteredVariantPrice(data.product.price) }}</span
20- >
21- <span v-else >{{ data.product.salePrice }}</span >
22- </p >
23- <p class =" pt-1 pl-8 mt-4 text-2xl text-gray-900 line-through" >
24- <span v-if =" data.productvariations" >
25- {{ filteredVariantPrice(data.product.price, "right") }}</span
26- >
27- <span v-else >{{ data.product.regularPrice }}</span >
28- </p >
29- </div >
30- <p v-else class =" pt-1 mt-4 text-2xl text-gray-900" >
31- {{ data.product.price }}
32- </p >
33- <br />
34- <p class =" pt-1 mt-4 text-2xl text-gray-900" >
11+ <ProductPrice :variantPrice =" filteredVariantPrice(data.product.price)" :onSale =" data.product.onSale"
12+ :hasVariations =" hasVariations(data)" :salePrice =" data.product.salePrice"
13+ :regularPrice =" data.product.regularPrice" :nonSalePrice =" data.product.price" priceFontSize =" big" />
14+ <p class =" pt-1 mt-6 text-2xl text-gray-900" >
3515 {{ stripHTML(data.product.description) }}
3616 </p >
37- <p
38- v-if =" data.product.stockQuantity"
39- class =" pt-1 mt-4 text-2xl text-gray-900"
40- >
17+ <p v-if =" data.product.stockQuantity" class =" pt-1 mt-4 text-2xl text-gray-900" >
4118 {{ data.product.stockQuantity }} in stock
4219 </p >
43- <p
44- v-if =" data.product.variations"
45- class =" pt-1 mt-4 text-xl text-gray-900"
46- >
20+ <p v-if =" data.product.variations" class =" pt-1 mt-4 text-xl text-gray-900" >
4721 <span class =" py-2" >Varianter</span >
48- <select
49- id =" variant"
50- name =" variant"
51- class =" block w-64 px-6 py-2 bg-white border border-gray-500 rounded-lg focus:outline-none focus:shadow-outline"
52- >
53- <option
54- v-for =" (variation, index) in data.product.variations.nodes"
55- :key =" variation.databaseId"
56- :value =" variation.databaseId"
57- :selected =" index === 0"
58- >
22+ <select id =" variant" name =" variant"
23+ class =" block w-64 px-6 py-2 bg-white border border-gray-500 rounded-lg focus:outline-none focus:shadow-outline" >
24+ <option v-for =" (variation, index) in data.product.variations.nodes" :key =" variation.databaseId"
25+ :value =" variation.databaseId" :selected =" index === 0" >
5926 {{ filteredVariantName(data.product.name, variation.name) }}
6027 ({{ variation.stockQuantity }} in stock)
6128 </option >
6229 </select >
6330 </p >
6431 <div class =" pt-1 mt-2" >
65- <CommonButton
66- @common-button-click =" addProductToCart(data.product)"
67- :is-loading =" isLoading"
68- >
69- ADD TO CART</CommonButton
70- >
32+ <CommonButton @common-button-click =" addProductToCart(data.product)" :is-loading =" isLoading" >
33+ ADD TO CART</CommonButton >
7134 </div >
7235 </div >
7336 </div >
7740</template >
7841
7942<script setup>
43+ /**
44+ * Vue.js component that displays a single product.
45+ *
46+ * @component
47+ * @example
48+ * < single- product id= " 1" slug= " example-product" >< / single- product>
49+ * @prop {string} id - The ID of the product to display.
50+ * @prop {string} slug - The slug of the product to display.
51+ */
8052import GET_SINGLE_PRODUCT_QUERY from " @/apollo/queries/GET_SINGLE_PRODUCT_QUERY.gql" ;
8153import ADD_TO_CART_MUTATION from " @/apollo/mutations/ADD_TO_CART_MUTATION.gql" ;
8254
8355import ProductImage from " @/components/Products/ProductImage.vue" ;
56+ import ProductPrice from " @/components/Products/ProductPrice.vue" ;
8457
8558import {
8659 stripHTML ,
8760 filteredVariantPrice ,
8861 filteredVariantName ,
62+ hasVariations ,
8963} from " @/utils/functions" ;
9064
9165import { useCart } from " @/store/useCart" ;
@@ -102,6 +76,12 @@ const props = defineProps({
10276const variables = { id: props .id , slug: props .slug };
10377const { data } = await useAsyncQuery (GET_SINGLE_PRODUCT_QUERY , variables);
10478
79+ /**
80+ * Adds a product to the cart by calling the addToCart mutation with the given product.
81+ *
82+ * @param {object} product - The product to add to the cart.
83+ * @return {Promise<void>} A Promise that resolves when the product has been successfully added to the cart.
84+ */
10585const addProductToCart = async (product ) => {
10686 const productId = product .databaseId ? product .databaseId : product;
10787 const productQueryInput = {
0 commit comments