Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
69b0c0f976 |
@ -1,55 +1,94 @@
|
||||
<template>
|
||||
<div ref="dropdownRef">
|
||||
<div class="relative cursor-pointer" @click="openCart = !openCart">
|
||||
<i class="uil uil-shopping-cart text-[31px]"></i>
|
||||
<div v-if="checkoutStore.products && checkoutStore.products.length > 0"
|
||||
class="w-[15px] h-[15px] rounded-full bg-accent-green-light dark:bg-accent-green-light text-white flex items-center justify-center text-[9px] absolute top-1 right-0">
|
||||
{{ checkoutStore.products.length }}
|
||||
<div class="relative cursor-pointer"
|
||||
@click="openCart = !openCart"
|
||||
>
|
||||
<i class="uil uil-shopping-cart text-[31px]" />
|
||||
<div
|
||||
v-if="
|
||||
productStore.cart.cart_items
|
||||
&& productStore.cart.cart_items.length > 0
|
||||
"
|
||||
class="w-[15px] h-[15px] rounded-full bg-accent-green-light dark:bg-accent-green-light text-white flex items-center justify-center text-[9px] absolute top-1 right-0"
|
||||
>
|
||||
{{ productStore.cart.cart_items.length }}
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="openCart"
|
||||
class="absolute left-1/2 transform -translate-x-1/2 w-full px-4 sm:max-w-[768px] sm:px-[17px] md:max-w-[1000px] md:px-6 xl:max-w-[1920px] xl:px-20 right-0 z-50 flex items-center justify-end top-[100px] sm:top-[100px] md:top-[140px]"
|
||||
@click.self="openCart = !openCart">
|
||||
<div
|
||||
v-if="openCart"
|
||||
class="absolute left-1/2 transform -translate-x-1/2 w-full px-4 sm:max-w-[768px] sm:px-[17px] md:max-w-[1000px] md:px-6 xl:max-w-[1920px] xl:px-20 right-0 z-50 flex items-center justify-end top-[100px] sm:top-[100px] md:top-[140px]"
|
||||
@click.self="openCart = !openCart"
|
||||
>
|
||||
<div class="xl:w-[55%] md:w-[90%] w-full px-4 md:px-0">
|
||||
<div v-if="checkoutStore.products && checkoutStore.products.length > 0"
|
||||
class="w-full p-[25px] sm:p-[50px] bg-bg-light dark:bg-bg-dark border border-button rounded-xl sm:rounded-[32px] h-full space-25-55">
|
||||
<div
|
||||
v-if="
|
||||
productStore.cart.cart_items
|
||||
&& productStore.cart.cart_items.length > 0
|
||||
"
|
||||
class="w-full p-[25px] sm:p-[50px] bg-bg-light dark:bg-bg-dark border border-button rounded-xl sm:rounded-[32px] h-full space-25-55"
|
||||
>
|
||||
<div>
|
||||
<div v-for="(item, index) in checkoutStore.products" :key="index"
|
||||
class="py-[13px] sm:py-[25px] first:pt-0 border-b border-block">
|
||||
<!-- product -->
|
||||
<div
|
||||
v-for="item in productStore.cart.cart_items" :key="item.product_id"
|
||||
class="py-[13px] sm:py-[25px] first:pt-0 border-b border-block"
|
||||
>
|
||||
<div class="flex items-center h-[100px] sm:h-[205px]">
|
||||
<div class="min-w-[100px] sm:min-w-[205px] flex items-center justify-center h-[100px] sm:h-[205px]">
|
||||
<img :src="`/api/public/file/${item.picture_uuid}.webp`" alt=""
|
||||
class="max-w-full max-h-full object-contain">
|
||||
<div
|
||||
class="min-w-[100px] sm:min-w-[205px] flex items-center justify-center h-[100px] sm:h-[205px]"
|
||||
>
|
||||
<img
|
||||
:src="`/api/public/file/${item.picture_uuid}.webp`"
|
||||
alt=""
|
||||
class="max-w-full max-h-full object-contain"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col justify-between min-h-full w-full gap-[7px] sm:gap-[15px]">
|
||||
<div
|
||||
class="flex flex-col justify-between min-h-full w-full gap-[7px] sm:gap-[15px]"
|
||||
>
|
||||
<div class="w-full flex items-center justify-between">
|
||||
<h3
|
||||
class="text-[10px] sm:text-base md:text-lg text-xl font-bold leading-[130%] sm:leading-[150%] max-w-[100px] sm:max-w-[200px] md:max-w-[250px]">
|
||||
class="text-[10px] sm:text-base md:text-lg text-xl font-bold leading-[130%] sm:leading-[150%] max-w-[100px] sm:max-w-[200px] md:max-w-[250px]"
|
||||
>
|
||||
{{ item.name }}
|
||||
</h3>
|
||||
<i class="uil uil-trash-alt text-lg sm:text-2xl cursor-pointer"
|
||||
@click="productStore.deleteCartItem(item.cart_item_id)"></i>
|
||||
<i
|
||||
class="uil uil-trash-alt text-lg sm:text-2xl cursor-pointer"
|
||||
@click="productStore.deleteCartItem(item.cart_item_id)"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col gap-[10px]">
|
||||
<p
|
||||
class="text-accent-green-light dark:text-accent-green-dark font-inter text-[12px] sm:text-[21px] md:text-2xl leading-[150%] font-bold">
|
||||
{{ menuStore.formatPrice(Number(item.total_price)) }}
|
||||
class="text-accent-green-light dark:text-accent-green-dark font-inter text-[12px] sm:text-[21px] md:text-2xl leading-[150%] font-bold"
|
||||
>
|
||||
{{ item.total_price }}
|
||||
</p>
|
||||
<div class="flex items-center gap-[2px] sm:gap-2 text-xl">
|
||||
<div
|
||||
class="w-5 min-h-5 sm:w-11 sm:min-h-11 text-[10px] sm:text-lg flex items-center justify-center">
|
||||
<i class="uil uil-minus cursor-pointer text-gray dark:text-button-disabled hover:text-gray-200 transition-all"
|
||||
@click="productStore.decrementCartItem(item.cart_item_id)"></i>
|
||||
class="w-5 min-h-5 sm:w-11 sm:min-h-11 text-[10px] sm:text-lg flex items-center justify-center"
|
||||
>
|
||||
<i
|
||||
class="uil uil-minus cursor-pointer text-gray dark:text-button-disabled hover:text-gray-200 transition-all"
|
||||
@click="
|
||||
productStore.decrementCartItem(item.cart_item_id)
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="w-5 min-h-5 sm:w-10 sm:min-h-11 text-[10px] sm:text-xl border border-button flex items-center justify-center rounded-[4px]">
|
||||
class="w-5 min-h-5 sm:w-10 sm:min-h-11 text-[10px] sm:text-xl border border-button flex items-center justify-center rounded-[4px]"
|
||||
>
|
||||
{{ item.quantity }}
|
||||
</div>
|
||||
<div
|
||||
class="w-5 min-h-5 sm:w-11 sm:min-h-11 text-[10px] sm:text-lg flex items-center justify-center">
|
||||
<i class="uil uil-plus cursor-pointer hover:text-gray-200 transition-all"
|
||||
@click="productStore.incrementCartItem(item.product_id)"></i>
|
||||
class="w-5 min-h-5 sm:w-11 sm:min-h-11 text-[10px] sm:text-lg flex items-center justify-center"
|
||||
>
|
||||
<i
|
||||
class="uil uil-plus cursor-pointer hover:text-gray-200 transition-all"
|
||||
@click="
|
||||
productStore.incrementCartItem(item.product_id)
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -58,34 +97,52 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<h4 class="font-inter text-[12px] leading-[150%] font-bold uppercase sm:text-[24px]">
|
||||
{{
|
||||
$t('total_amount') }}
|
||||
<h4
|
||||
class="font-inter text-[12px] leading-[150%] font-bold uppercase sm:text-[24px]"
|
||||
>
|
||||
{{ $t("total_amount") }}
|
||||
</h4>
|
||||
<p
|
||||
class="text-accent-green-light dark:text-accent-green-dark font-inter text-[12px] sm:text-[21px] md:text-2xl leading-[150%] font-bold">
|
||||
{{ menuStore.formatPrice(Number(checkoutStore.fullProductsPrice)) }}
|
||||
class="text-accent-green-light dark:text-accent-green-dark font-inter text-[12px] sm:text-[21px] md:text-2xl leading-[150%] font-bold"
|
||||
>
|
||||
{{ productStore.cart.total_value }}
|
||||
</p>
|
||||
</div>
|
||||
<UiButtonArrow class="w-full" type="fill" :arrow="true" :full="true" @click="() => {
|
||||
if (userStore.isLogged) {
|
||||
menuStore.navigateToItem(menuStore.menuItems?.find((item) => item.id === 12))
|
||||
}
|
||||
else {
|
||||
menuStore.navigateToItem(menuStore.menuItems?.find((item) => item.id === 11))
|
||||
}
|
||||
openCart = false
|
||||
}">
|
||||
{{ userStore.isLogged
|
||||
? $t('to_checkout') : $t('login') }}
|
||||
<UiButtonArrow
|
||||
class="w-full"
|
||||
type="fill"
|
||||
:arrow="true"
|
||||
:full="true"
|
||||
@click="
|
||||
() => {
|
||||
if (userStore.isLogged) {
|
||||
menuStore.navigateToItem(
|
||||
menuStore.menuItems?.find((item) => item.id === 12),
|
||||
);
|
||||
}
|
||||
else {
|
||||
menuStore.navigateToItem(
|
||||
menuStore.menuItems?.find((item) => item.id === 11),
|
||||
);
|
||||
}
|
||||
openCart = false;
|
||||
}
|
||||
"
|
||||
>
|
||||
{{ userStore.isLogged ? $t("to_checkout") : $t("login") }}
|
||||
</UiButtonArrow>
|
||||
</div>
|
||||
<div v-else
|
||||
class="w-full p-[25px] sm:p-[50px] bg-bg-light dark:bg-bg-dark border border-button rounded-xl sm:rounded-[32px] flex items-center justify-center">
|
||||
<div
|
||||
v-else
|
||||
class="w-full p-[25px] sm:p-[50px] bg-bg-light dark:bg-bg-dark border border-button rounded-xl sm:rounded-[32px] flex items-center justify-center"
|
||||
>
|
||||
<div
|
||||
class="border border-block inline-flex items-center justify-center h-[140px] sm:h-[200px] text-center rounded-[8px]">
|
||||
<h4 class="font-inter text-base leading-[150%] font-bold uppercase sm:text-[20px] px-4 sm:px-10 md:text-xl">
|
||||
{{ $t('empty_cart') }}
|
||||
class="border border-block inline-flex items-center justify-center h-[140px] sm:h-[200px] text-center rounded-[8px]"
|
||||
>
|
||||
<h4
|
||||
class="font-inter text-base leading-[150%] font-bold uppercase sm:text-[20px] px-4 sm:px-10 md:text-xl"
|
||||
>
|
||||
{{ $t("empty_cart") }}
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
@ -98,7 +155,6 @@
|
||||
import { onClickOutside } from '@vueuse/core'
|
||||
|
||||
const productStore = useProductStore()
|
||||
const checkoutStore = useCheckoutStore()
|
||||
const openCart = ref(false)
|
||||
|
||||
const menuStore = useMenuStore()
|
||||
|
@ -32,11 +32,30 @@
|
||||
</ClientOnly>
|
||||
<div class="w-full flex items-center justify-between">
|
||||
<div class="flex items-center gap-[30px]">
|
||||
<p
|
||||
class="cursor-pointer"
|
||||
@click="
|
||||
menuStore.navigateToItem(
|
||||
menuStore.menuItems?.find((item) => item.id === 13),
|
||||
)
|
||||
"
|
||||
>
|
||||
button
|
||||
</p>
|
||||
<div>
|
||||
<i v-if="!userStore.isLogged"
|
||||
class="uil uil-user text-[31px] cursor-pointer"
|
||||
@click="menuStore.navigateToItem(menuStore.menuItems?.find((item) => item.id === 11))"></i>
|
||||
<div v-else class="py-[6px] px-3 border border-block rounded-sm">
|
||||
<i
|
||||
v-if="!userStore.isLogged"
|
||||
class="uil uil-user text-[31px] cursor-pointer"
|
||||
@click="
|
||||
menuStore.navigateToItem(
|
||||
menuStore.menuItems?.find((item) => item.id === 11),
|
||||
)
|
||||
"
|
||||
/>
|
||||
<div
|
||||
v-else
|
||||
class="py-[6px] px-3 border border-block rounded-sm"
|
||||
>
|
||||
{{ userStore.user }}
|
||||
</div>
|
||||
</div>
|
||||
@ -374,13 +393,13 @@ import CartPopup from './CartPopup.vue'
|
||||
import CountryCurrencySelector from './CountryCurrencySelector.vue'
|
||||
import LangSwitcher from './LangSwitcher.vue'
|
||||
|
||||
const menuStore = useMenuStore()
|
||||
const userStore = useUserStore()
|
||||
const productStore = useProductStore()
|
||||
const open = ref(false)
|
||||
const colorMode = useColorMode()
|
||||
const menuStore = useMenuStore()
|
||||
const checkoutStore = useCheckoutStore()
|
||||
|
||||
checkoutStore.getUserCart()
|
||||
productStore.getCart()
|
||||
|
||||
const route = useRoute()
|
||||
const isDark = computed({
|
||||
|
@ -14,30 +14,35 @@
|
||||
{{ component.front_section_lang[0].data.main_subtitle }}
|
||||
</h4>
|
||||
</div>
|
||||
<div class="rounded-2xl h-[340px] sm:h-[380px] md:min-w-[324px] xl:h-[800px] xl:min-w-[740px] m-0 sm:mx-10 md:m-0"
|
||||
:style="{
|
||||
backgroundImage: `url('/api/public/file/${component.img[0]}_l.webp')`,
|
||||
backgroundSize: 'cover',
|
||||
backgroundPosition: 'center',
|
||||
}"></div>
|
||||
<div
|
||||
class="rounded-2xl h-[340px] sm:h-[380px] md:min-w-[324px] xl:h-[800px] xl:min-w-[740px] m-0 sm:mx-10 md:m-0"
|
||||
:style="{
|
||||
backgroundImage: `url('/api/public/file/${component.img[0]}_l.webp')`,
|
||||
backgroundSize: 'cover',
|
||||
backgroundPosition: 'center',
|
||||
}"
|
||||
></div>
|
||||
</div>
|
||||
<div class="space-25-55-75">
|
||||
<h2 class="h2-bold-bounded">
|
||||
{{ component.front_section_lang[0].data.story_title }}
|
||||
</h2>
|
||||
<div class="flex flex-col-reverse md:flex-row w-full gap-6">
|
||||
<div class="rounded-2xl h-[390px] md:h-auto min-w-[40%] xl:min-w-[60%]" :style="{
|
||||
backgroundImage: `url('/api/public/file/${component.img[1]}_l.webp')`,
|
||||
backgroundSize: 'cover',
|
||||
backgroundPosition: 'center',
|
||||
}"></div>
|
||||
<div
|
||||
class="rounded-2xl h-[390px] md:h-auto min-w-[40%] xl:min-w-[60%]"
|
||||
:style="{
|
||||
backgroundImage: `url('/api/public/file/${component.img[1]}_l.webp')`,
|
||||
backgroundSize: 'cover',
|
||||
backgroundPosition: 'center',
|
||||
}"
|
||||
></div>
|
||||
<div class="flex flex-col">
|
||||
<div v-for="(item, index) in component.front_section_lang[0].data.story_description" :key="index">
|
||||
<p>{{ item }}</p>
|
||||
<div v-if="index < component.front_section_lang[0].data.story_description.length - 1">
|
||||
<br>
|
||||
</div>
|
||||
<p v-for="(item, index) in component.front_section_lang[0].data.story_description" :key="index">
|
||||
{{ item }}
|
||||
</p><div v-if="index < component.front_section_lang[0].data.story_description.length - 1">
|
||||
<br>
|
||||
</div>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col w-full gap-6">
|
||||
@ -45,12 +50,14 @@
|
||||
{{ component.front_section_lang[0].data.story_subtitle }}
|
||||
</h4>
|
||||
<div class="flex flex-col justify-between xl:max-w-[70%]">
|
||||
<div v-for="(el, indexEl) in component.front_section_lang[0].data.story_sub_description" :key="indexEl">
|
||||
<p>{{ el }}</p>
|
||||
<div v-if="indexEl < component.front_section_lang[0].data.story_sub_description.length - 1">
|
||||
<br>
|
||||
</div>
|
||||
<p v-for="(el, indexEl) in component.front_section_lang[0].data.story_sub_description"
|
||||
:key="indexEl"
|
||||
>
|
||||
{{ el }}
|
||||
</p><div v-if="indexEl < component.front_section_lang[0].data.story_sub_description.length - 1">
|
||||
<br>
|
||||
</div>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,15 +1,11 @@
|
||||
<template>
|
||||
<UiContainer v-if="checkoutStore.modalMadeOrder">
|
||||
<NuxtLink to="/" class="mt-6 text-blue-500 underline" @click="checkoutStore.modalMadeOrder = false">Go back home
|
||||
</NuxtLink>
|
||||
</UiContainer>
|
||||
|
||||
<UiContainer v-else>
|
||||
<UiContainer>
|
||||
<div class="xl:w-[85%] mx-auto space-25-55">
|
||||
<div class="space-25-55">
|
||||
<div class="w-full flex items-center sm:justify-center">
|
||||
<div
|
||||
class="flex items-center justify-between sm:justify-center sm:gap-[25px] text-gray dark:text-button-disabled w-full sm:w-auto">
|
||||
class="flex items-center justify-between sm:justify-center sm:gap-[25px] text-gray dark:text-button-disabled w-full sm:w-auto"
|
||||
>
|
||||
<div class="sm:px-6 sm:py-3 mx-auto">
|
||||
{{ $t("login") }}
|
||||
</div>
|
||||
@ -17,7 +13,8 @@
|
||||
{{ $t("address") }}
|
||||
</div>
|
||||
<div
|
||||
class="cursor-pointer transition-all text-inter hover:bg-button-hover bg-button text-white font-medium rounded-xl px-3 py-1 sm:px-6 sm:py-3">
|
||||
class="cursor-pointer transition-all text-inter hover:bg-button-hover bg-button text-white font-medium rounded-xl px-3 py-1 sm:px-6 sm:py-3"
|
||||
>
|
||||
{{ $t("summary") }}
|
||||
</div>
|
||||
<div class="hidden sm:block sm:px-6 sm:py-3 sm:mx-auto">
|
||||
@ -26,29 +23,40 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-3 gap-[30px]">
|
||||
<div class="col-start-1 col-end-2 sm:col-end-3 space-y-5">
|
||||
<div class="grid grid-cols-3 gap-[30px]">
|
||||
<div class="col-start-1 col-end-3 space-y-5">
|
||||
<h4 class="h4-uppercase-bold-inter">
|
||||
{{ component.front_section_lang[0].data.product_list }}
|
||||
Seznam produktů
|
||||
</h4>
|
||||
<div class="border-2 border-block rounded-[15px] p-[25px] sm:p-[50px] space-25-55">
|
||||
<div v-for="(item, index) in checkoutStore.products" :key="index">
|
||||
<div class="flex items-center h-[100px] sm:h-[150px]">
|
||||
<div class="min-w-[100px] sm:min-w-[150px] flex items-center justify-center h-[100px] sm:h-[150px]">
|
||||
<img :src="`/api/public/file/${item.picture_uuid}.webp`" alt=""
|
||||
class="max-w-full max-h-full object-contain">
|
||||
<div class="border-2 border-block rounded-2xl p-[50px] space-25-55">
|
||||
<div v-for="(item, index) in checkoutStore.products"
|
||||
:key="index"
|
||||
>
|
||||
<div class="flex items-center h-[150px]">
|
||||
<div
|
||||
class="min-w-[150px] flex items-center justify-center h-[150px]"
|
||||
>
|
||||
<img
|
||||
:src="`/api/public/file/${item.picture_uuid}.webp`"
|
||||
alt=""
|
||||
class="max-w-full max-h-full object-contain"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col justify-between min-h-full w-full gap-[7px] sm:gap-[15px]">
|
||||
<div
|
||||
class="flex flex-col justify-between min-h-full w-full gap-[7px] sm:gap-[15px]"
|
||||
>
|
||||
<div class="w-full flex items-center justify-between">
|
||||
<h3
|
||||
class="text-[10px] sm:text-base md:text-lg text-xl font-bold leading-[130%] sm:leading-[150%] max-w-[100px] sm:max-w-[200px] md:max-w-[250px]">
|
||||
class="text-[10px] sm:text-base md:text-lg text-xl font-bold leading-[130%] sm:leading-[150%] max-w-[100px] sm:max-w-[200px] md:max-w-[250px]"
|
||||
>
|
||||
{{ item.name }}
|
||||
</h3>
|
||||
</div>
|
||||
<div class="flex w-full justify-between gap-[10px]">
|
||||
<p
|
||||
class="text-accent-green-light dark:text-accent-green-dark font-inter text-[12px] sm:text-[21px] md:text-2xl leading-[150%] font-bold">
|
||||
class="text-accent-green-light dark:text-accent-green-dark font-inter text-[12px] sm:text-[21px] md:text-2xl leading-[150%] font-bold"
|
||||
>
|
||||
{{ item.total_price }}
|
||||
</p>
|
||||
</div>
|
||||
@ -57,196 +65,31 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="col-start-1 col-end-2 sm:col-end-3 xl:col-auto flex flex-col sm:flex-row xl:flex-col items-center gap-[30px]">
|
||||
<div class="space-y-5 w-full">
|
||||
<div class="">
|
||||
<div class="space-y-5">
|
||||
<h4 class="h4-uppercase-bold-inter">
|
||||
{{ component.front_section_lang[0].data.account_address }}
|
||||
Adresa účtu
|
||||
</h4>
|
||||
<div
|
||||
class="border-2 border-block rounded-[8px] px-[25px] py-[15px] flex flex-col gap-1 text-sm sm:text-lg md:text-xl">
|
||||
<span>{{ checkoutStore.defaultAddress?.address.name }} {{
|
||||
checkoutStore.defaultAddress?.address.surname }}</span>
|
||||
class="border-2 border-block rounded-2xl px-2 py-3 flex flex-col gap-1"
|
||||
>
|
||||
<span>{{ checkoutStore.defaultAddress?.address.name }}
|
||||
{{ checkoutStore.defaultAddress?.address.surname }}</span>
|
||||
<span>{{ checkoutStore.defaultAddress?.address.street }}</span>
|
||||
<span>{{ checkoutStore.defaultAddress?.address.postcode }} {{
|
||||
checkoutStore.defaultAddress?.address.city }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col space-y-5 w-full h-full">
|
||||
<h4 class="h4-uppercase-bold-inter">
|
||||
{{ component.front_section_lang[0].data.note }}
|
||||
</h4>
|
||||
<textarea id="1" v-model="checkoutStore.vNote"
|
||||
class="border-2 border-block rounded-[8px] p-[15px] w-full flex-1 resize-none placeholder:text-button"
|
||||
name="rty" :placeholder="component.front_section_lang[0].data.note"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-start-1 col-end-2 xl:col-end-3 space-y-5">
|
||||
<h4 class="h4-uppercase-bold-inter">
|
||||
{{ component.front_section_lang[0].data.delivery_type }}
|
||||
</h4>
|
||||
<div
|
||||
class="border-2 border-block rounded-[15px] p-[25px] sm:p-[50px] space-y-[25px] text-sm sm:text-lg md:text-xl">
|
||||
<div v-for="(delivery, index) in checkoutStore.deliveryOption" :key="index"
|
||||
class="flex flex-col cursor-pointer" @click="checkoutStore.setCurrentDelivery(delivery)">
|
||||
<div class="flex items-end justify-between">
|
||||
<div class="flex gap-[15px]">
|
||||
<div class="mt-1 w-4 h-4 border-2 border-button rounded-full">
|
||||
<div v-if="checkoutStore.currentDelivery === delivery"
|
||||
class="w-full h-full border-3 border-bg-light dark:border-bg-dark rounded-full bg-button">
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span>{{ delivery.delivery_supplier_name }}</span>
|
||||
<span>{{ delivery.country_name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<p class="font-inter text-lg sm:text-[21px] md:text-2xl leading-[150%] font-bold">
|
||||
{{ menuStore.formatPrice(Number(delivery.shippment_price)) }}
|
||||
</p>
|
||||
</div>
|
||||
<span>{{ checkoutStore.defaultAddress?.address.postcode }}
|
||||
{{ checkoutStore.defaultAddress?.address.city }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="space-y-5 w-full flex flex-col h-full">
|
||||
<h4 class="h4-uppercase-bold-inter">
|
||||
{{ component.front_section_lang[0].data.payment_method }}
|
||||
</h4>
|
||||
<div
|
||||
class="border-2 border-block rounded-[8px] px-[25px] py-[25px] sm:py-[15px] flex-1 flex flex-col gap-1 text-sm sm:text-xl overflow-auto">
|
||||
<UCarousel :prev-icon="'i-lucide-chevron-left'" :next-icon="'i-lucide-chevron-right'" :ui="{
|
||||
viewport: 'h-full w-full',
|
||||
container: 'h-full w-full',
|
||||
item: 'h-full w-full pl-7',
|
||||
prev: '-start-8 sm:-start-12 ring-0 text-button disable:text-block p-0 ring-inset ring-accented bg-inherit disabled:bg-inherit',
|
||||
next: '-end-8 sm:-end-12 ring-0 text-button disable:text-block p-0 text-[30px] bg-inherit disabled:bg-inherit',
|
||||
arrows: '',
|
||||
}" :prev="{ size: 'xl' }" :next="{ size: 'xl' }" arrows :items="checkoutStore.paymentMethods"
|
||||
class="relative sm:max-w-full mx-4 sm:mx-10 h-full">
|
||||
<template #default="{ item }">
|
||||
<div class="flex flex-col items-start justify-between h-full leading-[250%] sm:leading-[150%]">
|
||||
<span>{{ item.bank_name }}</span>
|
||||
<span>{{ item.country_name }}</span>
|
||||
<span>{{ item.street_and_number }}</span>
|
||||
<span>{{ item.iban }}</span>
|
||||
<span>{{ item.swift }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</UCarousel>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full border-y-2 border-block p-[25px] flex flex-col gap-[15px]">
|
||||
<div class="flex items-center justify-between">
|
||||
<p class="text-sm sm:text-xl">
|
||||
{{ component.front_section_lang[0].data.subtotal }}
|
||||
</p>
|
||||
<p class="text-lg sm:text-xl font-medium">
|
||||
{{
|
||||
menuStore.formatPrice(Number(checkoutStore.fullProductsPrice)) }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<p class="text-sm sm:text-xl">
|
||||
{{ component.front_section_lang[0].data.shipping_cost }}
|
||||
</p>
|
||||
<p class="text-lg sm:text-xl font-medium">
|
||||
{{
|
||||
menuStore.formatPrice(Number(checkoutStore.shippingPrice)) }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex items-center justify-between uppercase text-lg sm:text-xl">
|
||||
<p>{{ component.front_section_lang[0].data.total }}</p>
|
||||
<p
|
||||
class="text-accent-green-light dark:text-accent-green-dark font-inter text-xl sm:text-2xl leading-[150%] font-bold">
|
||||
{{ menuStore.formatPrice(Number(checkoutStore.fullPrice)) }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col sm:flex-row items-center justify-between mt-1 gap-[55px]">
|
||||
<div class="flex flex-col gap-1 text-white w-full">
|
||||
<div class="flex gap-3 text-black dark:text-white items-center">
|
||||
<input id="first" v-model="checkoutStore.vLegal" type="checkbox" name="first" />
|
||||
<!-- <label for="first" class="text-sm leading-snug">
|
||||
{{ $t("I accept ") }}
|
||||
<NuxtLink target="_blank"
|
||||
:to="{ name: 'lang-info-name', params: { lang: menuStore.selectedLanguage.iso_code, name: 'legal_statement.html' } }"
|
||||
class="underline cursor-pointer">
|
||||
{{ $t("the legal statement*") }}
|
||||
</NuxtLink>
|
||||
</label> -->
|
||||
<p class="text-sm sm:text-lg">
|
||||
{{ $t("I accept ") }} {{ $t("the legal statement*") }}
|
||||
</p>
|
||||
</div>
|
||||
<span v-if="checkoutStore.legalValidation" class="text-xs text-red-600 ml-6">
|
||||
{{ $t("You need to accept this") }}
|
||||
</span>
|
||||
|
||||
<div class="flex gap-3 text-black dark:text-white items-center mt-2">
|
||||
<input id="second" v-model="checkoutStore.vTerms" type="checkbox" name="second" />
|
||||
<!-- <label for="second" class="text-sm leading-snug">
|
||||
{{ $t("I accept ") }}
|
||||
<NuxtLink target="_blank"
|
||||
:to="{ name: 'lang-info-name', params: { lang: menuStore.selectedLanguage.iso_code, name: 'general_terms_and_conditions.html' } }"
|
||||
class="underline cursor-pointer">
|
||||
{{ $t("general terms and conditions*") }}
|
||||
</NuxtLink>
|
||||
</label> -->
|
||||
<p class="text-sm sm:text-lg">
|
||||
{{ $t("I accept ") }} {{ $t("general terms and conditions*") }}
|
||||
</p>
|
||||
</div>
|
||||
<span v-if="checkoutStore.termsValidation" class="text-xs text-red-600 ml-6">
|
||||
{{ $t("You need to accept this") }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<UiButtonArrow type="fill" :arrow="true" @click="checkoutStore.sendSummaryForm">
|
||||
{{ $t("Buy") }}
|
||||
</UiButtonArrow>
|
||||
</div>
|
||||
</div>
|
||||
</UiContainer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { UCarousel } from '#components'
|
||||
|
||||
const checkoutStore = useCheckoutStore()
|
||||
const menuStore = useMenuStore()
|
||||
|
||||
checkoutStore.getOrder()
|
||||
checkoutStore.getBankAccount()
|
||||
checkoutStore.getUserCart()
|
||||
checkoutStore.getDeliveryOptions()
|
||||
checkoutStore.getDefAddress()
|
||||
|
||||
defineProps<{
|
||||
component: {
|
||||
id: number
|
||||
name: string
|
||||
img: string[]
|
||||
component_name: string
|
||||
is_no_lang: boolean
|
||||
page_name: string
|
||||
front_section_lang: {
|
||||
data: {
|
||||
product_list: string
|
||||
account_address: string
|
||||
note: string
|
||||
delivery_type: string
|
||||
payment_method: string
|
||||
subtotal: string
|
||||
shipping_cost: string
|
||||
total: string
|
||||
accept: string
|
||||
legal: string
|
||||
terms: string
|
||||
}
|
||||
id_front_section: number
|
||||
id_lang: number
|
||||
}[]
|
||||
}
|
||||
}>()
|
||||
</script>
|
||||
|
@ -104,12 +104,9 @@ defineProps<{
|
||||
component_name: string
|
||||
is_no_lang: boolean
|
||||
page_name: string
|
||||
front_section_lang: {
|
||||
id_front_section: number
|
||||
id_lang: number
|
||||
}[]
|
||||
}
|
||||
}>()
|
||||
|
||||
const userStore = useUserStore()
|
||||
const menuStore = useMenuStore()
|
||||
</script>
|
||||
|
@ -1,40 +1,54 @@
|
||||
<template>
|
||||
<div>
|
||||
<nuxt-link :to="{
|
||||
name: `id-slug___${$i18n.locale}`,
|
||||
params: {
|
||||
id: menuStore.getProductMenu()?.id,
|
||||
slug: menuStore.getProductMenu()?.front_menu_lang.at(0)?.link_rewrite,
|
||||
},
|
||||
query: {
|
||||
prod_id: product.id,
|
||||
name: product.link_rewrite,
|
||||
},
|
||||
}">
|
||||
<nuxt-link
|
||||
:to="{
|
||||
name: `id-slug___${$i18n.locale}`,
|
||||
params: {
|
||||
id: menuStore.getProductMenu()?.id,
|
||||
slug: menuStore.getProductMenu()?.front_menu_lang.at(0)?.link_rewrite,
|
||||
},
|
||||
query: {
|
||||
prod_id: props.product?.id,
|
||||
name: props.product?.link_rewrite,
|
||||
},
|
||||
}"
|
||||
>
|
||||
<div
|
||||
class="w-[150px] sm:w-[260px] md:w-[330px] px-2 py-3 sm:py-5 sm:px-[15px] bg-block rounded-2xl flex flex-col items-center gap-[15px] sm:gap-[50px] h-full">
|
||||
<img :src="`/api/public/file/${product.cover_picture_uuid}.webp`" alt="Product Image"
|
||||
class="h-[95px] sm:h-[180px] md:h-[205px] rounded-[5px]" @error="handleImageError" />
|
||||
class="w-[150px] sm:w-[260px] md:w-[330px] px-2 py-3 sm:py-5 sm:px-[15px] bg-block rounded-2xl flex flex-col items-center gap-[15px] sm:gap-[50px]"
|
||||
>
|
||||
<img
|
||||
:src="`/api/public/file/${props.product?.cover_picture_uuid}.webp`"
|
||||
alt="Product Image"
|
||||
class="h-[95px] sm:h-[180px] md:h-[205px] rounded-[5px]"
|
||||
onerror="this.onerror=null; this.src='/photo.svg';"
|
||||
>
|
||||
|
||||
<div class="flex flex-col justify-between h-full w-full gap-[7px] sm:gap-[15px]">
|
||||
<div
|
||||
class="flex flex-col justify-between h-full w-full gap-[7px] sSm:gap-[15px]"
|
||||
>
|
||||
<div class="flex flex-col gap-[7px] sm:gap-[15px] w-full">
|
||||
<h3
|
||||
class="text-[10px] sm:text-base md:text-lg text-xl font-bold leading-[130%] sm:leading-[150%] text-bg-dark">
|
||||
{{ product.name }}
|
||||
class="text-[10px] sm:text-base md:text-lg text-xl font-bold leading-[130%] sm:leading-[150%] text-bg-dark"
|
||||
>
|
||||
{{ props.product?.name }}
|
||||
</h3>
|
||||
<p class="text-[9px] sm:text-[12px] text-sm text-bg-dark">
|
||||
{{ product.tax_name }}
|
||||
{{ props.product?.tax_name }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<p
|
||||
class="text-accent-green-light font-inter text-[12px] sm:text-[21px] md:text-2xl leading-[150%] font-bold">
|
||||
{{ product.formatted_price }}
|
||||
class="text-accent-green-light font-inter text-[12px] sm:text-[21px] md:text-2xl leading-[150%] font-bold"
|
||||
>
|
||||
{{ props.product?.formatted_price }}
|
||||
</p>
|
||||
<button
|
||||
class="w-[22px] h-[22px] sm:w-9 sm:h-9 md:w-12 md:h-12 rounded-[5px] text-bg-light sm:rounded-xl bg-button cursor-pointer hover:bg-button-hover transition-all flex items-center justify-center p-1"
|
||||
@click.stop.prevent="productStore.incrementCartItem(product.id)">
|
||||
<i class="uil uil-shopping-cart text-lg sm:text-2xl md:text-[31px]" />
|
||||
@click.self="productStore.incrementCartItem(props.product?.id)"
|
||||
>
|
||||
<i
|
||||
class="uil uil-shopping-cart text-lg sm:text-2xl md:text-[31px] cursor-pointer"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -44,22 +58,10 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
interface Product {
|
||||
id: number
|
||||
name: string
|
||||
link_rewrite: string
|
||||
tax_name: string
|
||||
formatted_price: string
|
||||
cover_picture_uuid: string
|
||||
}
|
||||
|
||||
defineProps<{ product: Product }>()
|
||||
const props = defineProps({
|
||||
product: Object,
|
||||
})
|
||||
|
||||
const productStore = useProductStore()
|
||||
const menuStore = useMenuStore()
|
||||
|
||||
function handleImageError(event: Event) {
|
||||
const img = event.target as HTMLImageElement
|
||||
img.src = '/photo.svg'
|
||||
}
|
||||
</script>
|
||||
|
@ -248,6 +248,17 @@ const goRight = () => {
|
||||
curImage.value = product.value.picture_uuids[0]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* INSERT INTO `front_page` (`created_at`, `updated_at`, `name`, `is_default`, `id`) VALUES ('2025-06-25 11:07:28.000','2025-06-25 11:07:28.000','product','0','13');
|
||||
* INSERT INTO `front_menu` (`created_at`, `updated_at`, `active`, `position_id`, `id_front_page`, `is_default`, `is_root`, `id`) VALUES ('2025-06-25 11:07:28.000','2025-06-25 11:07:28.000','1','1','13','0','0','13');
|
||||
* INSERT INTO `front_menu_lang` (`name`, `id_lang`, `id_front_menu`, `link_rewrite`) VALUES ('Product','2','13','product');
|
||||
* INSERT INTO `front_menu_lang` (`link_rewrite`, `id_front_menu`, `id_lang`, `name`) VALUES ('produkt','13','1','Produkt');
|
||||
* INSERT INTO `front_menu_lang` (`name`, `id_lang`, `id_front_menu`, `link_rewrite`) VALUES ('Produkt','3','13','produkt');
|
||||
* INSERT INTO `front_section` (`id`, `created_at`, `updated_at`, `name`, `img`, `component_name`, `is_no_lang`) VALUES ('32','2025-06-25 11:07:28.000','2025-06-25 11:07:28.000','product','[]','ProductBlock','1');
|
||||
* INSERT INTO `front_page_section` (`id_front_page`, `id_position`, `id_front_section`) VALUES ('13','1','32');
|
||||
* INSERT INTO `front_page_section` (`id_front_page`, `id_position`, `id_front_section`) VALUES ('13','2','4');
|
||||
*/
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
@ -8,50 +8,89 @@
|
||||
<div class="xl:hidden flex items-center w-full">
|
||||
<button
|
||||
class="h-[40px] w-full cursor-pointer rounded-[10px] px-[22px] transition-all sm:h-[50px] md:h-[65px] md:rounded-[15px] md:px-[42px] bg-button text-text-dark group-hover:bg-button-hover"
|
||||
@click="openCategories = !openCategories">
|
||||
@click="openCategories = !openCategories"
|
||||
>
|
||||
Otevřené kategorie a filtry
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<Transition>
|
||||
<div v-if="openCategories" class="min-w-[250px] px-5 sm:p-0 xl:hidden">
|
||||
<h1 class="font-bounded leading-[140%] font-bold text-[24px] mb-[25px]">
|
||||
<div v-if="openCategories"
|
||||
class="min-w-[250px] px-5 sm:p-0 xl:hidden"
|
||||
>
|
||||
<h1
|
||||
class="font-bounded leading-[140%] font-bold text-[24px] mb-[25px]"
|
||||
>
|
||||
{{ $t("category") }}
|
||||
</h1>
|
||||
<div class="flex flex-col gap-[25px]">
|
||||
<div>
|
||||
<div v-if="categoriesList && categoriesList.length < 1" class="animate-pulse">
|
||||
<div class="flex items-center justify-between mt-4 text-white rounded-lg cursor-pointer xl:pr-24">
|
||||
<div
|
||||
v-if="categoriesList && categoriesList.length < 1"
|
||||
class="animate-pulse"
|
||||
>
|
||||
<div
|
||||
class="flex items-center justify-between mt-4 text-white rounded-lg cursor-pointer xl:pr-24"
|
||||
>
|
||||
<div class="w-32 h-4 bg-gray-200 rounded" />
|
||||
<div class="w-4 h-4 bg-gray-200 rounded-full" />
|
||||
</div>
|
||||
</div>
|
||||
<CategoryTree :data="categoriesList" :active="categoryId" @change-category="changeCategory($event)" />
|
||||
<CategoryTree
|
||||
:data="categoriesList"
|
||||
:active="categoryId"
|
||||
@change-category="changeCategory($event)"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<p class="mb-[25px] text-lg font-extrabold text-black dark:text-white">
|
||||
<p
|
||||
class="mb-[25px] text-lg font-extrabold text-black dark:text-white"
|
||||
>
|
||||
{{ $t("filtered_by") }}
|
||||
</p>
|
||||
|
||||
<div v-for="(item, itemIndex) in filters" :key="itemIndex" :class="[
|
||||
'mb-[30px]',
|
||||
visibleFeatures[item.feature] && 'border-b border-block pb-2',
|
||||
]">
|
||||
<span class="flex justify-between items-center font-bold cursor-pointer mb-[25px] text-base"
|
||||
@click="toggleFeature(item.feature)">
|
||||
<div
|
||||
v-for="(item, itemIndex) in filters"
|
||||
:key="itemIndex"
|
||||
:class="[
|
||||
'mb-[30px]',
|
||||
visibleFeatures[item.feature] && 'border-b border-block pb-2',
|
||||
]"
|
||||
>
|
||||
<span
|
||||
class="flex justify-between items-center font-bold cursor-pointer mb-[25px] text-base"
|
||||
@click="toggleFeature(item.feature)"
|
||||
>
|
||||
{{ item.feature }}
|
||||
<span :class="[
|
||||
visibleFeatures[item.feature] && 'rotate-180',
|
||||
'transition-all',
|
||||
]"><i class="iconify i-lucide:chevron-down text-button shrink-0 size-6 ms-auto" /></span>
|
||||
<span
|
||||
:class="[
|
||||
visibleFeatures[item.feature] && 'rotate-180',
|
||||
'transition-all',
|
||||
]"
|
||||
><i
|
||||
class="iconify i-lucide:chevron-down text-button shrink-0 size-6 ms-auto"
|
||||
/></span>
|
||||
</span>
|
||||
<ul v-show="visibleFeatures[item.feature]" class="flex flex-col gap-5">
|
||||
<li v-for="filter in item.feature_values" :key="filter.value_id"
|
||||
class="flex items-center gap-[10px] cursor-pointer">
|
||||
<input :id="`${filter.value_id}`" v-model="selectedFilters"
|
||||
:value="`${filter.parent}.${filter.value_id}`" type="checkbox" class="border-button !bg-inherit">
|
||||
<label :for="`${filter.value_id}`"
|
||||
class="cursor-pointer flex items-center justify-between w-full text-base">
|
||||
<ul
|
||||
v-show="visibleFeatures[item.feature]"
|
||||
class="flex flex-col gap-5"
|
||||
>
|
||||
<li
|
||||
v-for="filter in item.feature_values"
|
||||
:key="filter.value_id"
|
||||
class="flex items-center gap-[10px] cursor-pointer"
|
||||
>
|
||||
<input
|
||||
:id="`${filter.value_id}`"
|
||||
v-model="selectedFilters"
|
||||
:value="`${filter.parent}.${filter.value_id}`"
|
||||
type="checkbox"
|
||||
class="border-button !bg-inherit"
|
||||
>
|
||||
<label
|
||||
:for="`${filter.value_id}`"
|
||||
class="cursor-pointer flex items-center justify-between w-full text-base"
|
||||
>
|
||||
<span>{{ filter.value }}</span>
|
||||
<span>12</span>
|
||||
</label>
|
||||
@ -70,13 +109,22 @@
|
||||
</h1>
|
||||
<div class="flex flex-col gap-12">
|
||||
<div>
|
||||
<div v-if="categoriesList && categoriesList.length < 1" class="animate-pulse">
|
||||
<div class="flex items-center justify-between mt-4 text-white rounded-lg cursor-pointer xl:pr-24">
|
||||
<div
|
||||
v-if="categoriesList && categoriesList.length < 1"
|
||||
class="animate-pulse"
|
||||
>
|
||||
<div
|
||||
class="flex items-center justify-between mt-4 text-white rounded-lg cursor-pointer xl:pr-24"
|
||||
>
|
||||
<div class="w-32 h-4 bg-gray-200 rounded" />
|
||||
<div class="w-4 h-4 bg-gray-200 rounded-full" />
|
||||
</div>
|
||||
</div>
|
||||
<CategoryTree :data="categoriesList" :active="categoryId" @change-category="changeCategory($event)" />
|
||||
<CategoryTree
|
||||
:data="categoriesList"
|
||||
:active="categoryId"
|
||||
@change-category="changeCategory($event)"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<p class="mb-10 text-2xl font-extrabold text-black dark:text-white">
|
||||
@ -91,28 +139,52 @@
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<div v-for="(item, itemIndex) in filters" :key="itemIndex" :class="[
|
||||
'mb-[30px]',
|
||||
visibleFeatures[item.feature] && 'border-b border-block pb-2',
|
||||
]">
|
||||
<span class="flex justify-between items-center font-bold cursor-pointer mb-[25px]"
|
||||
@click="toggleFeature(item.feature)">
|
||||
<div
|
||||
v-for="(item, itemIndex) in filters"
|
||||
:key="itemIndex"
|
||||
:class="[
|
||||
'mb-[30px]',
|
||||
visibleFeatures[item.feature] && 'border-b border-block pb-2',
|
||||
]"
|
||||
>
|
||||
<span
|
||||
class="flex justify-between items-center font-bold cursor-pointer mb-[25px]"
|
||||
@click="toggleFeature(item.feature)"
|
||||
>
|
||||
{{ item.feature }}
|
||||
<span :class="[
|
||||
visibleFeatures[item.feature] && 'rotate-180',
|
||||
'transition-all',
|
||||
]"><i class="iconify i-lucide:chevron-down text-button shrink-0 size-6 ms-auto" /></span>
|
||||
<span
|
||||
:class="[
|
||||
visibleFeatures[item.feature] && 'rotate-180',
|
||||
'transition-all',
|
||||
]"
|
||||
><i
|
||||
class="iconify i-lucide:chevron-down text-button shrink-0 size-6 ms-auto"
|
||||
/></span>
|
||||
</span>
|
||||
<ul v-show="visibleFeatures[item.feature]" class="flex flex-col gap-5">
|
||||
<li v-for="filter in item.feature_values" :key="filter.value_id"
|
||||
class="flex items-center gap-[10px] cursor-pointer">
|
||||
<ul
|
||||
v-show="visibleFeatures[item.feature]"
|
||||
class="flex flex-col gap-5"
|
||||
>
|
||||
<li
|
||||
v-for="filter in item.feature_values"
|
||||
:key="filter.value_id"
|
||||
class="flex items-center gap-[10px] cursor-pointer"
|
||||
>
|
||||
<!-- <input :id="`${filter.value_id}`" :value="`${filter.parent}.${filter.value_id}`"
|
||||
v-model="selectedFilters" type="checkbox" class="border-button !bg-inherit" />
|
||||
<label :for="`${filter.value_id}`" class="cursor-pointer">{{ filter.value }}</label> -->
|
||||
|
||||
<input :id="`${filter.value_id}`" v-model="selectedFilters"
|
||||
:value="`${filter.parent}.${filter.value_id}`" type="checkbox" class="border-button !bg-inherit">
|
||||
<label :for="`${filter.value_id}`" class="cursor-pointer flex items-center justify-between w-full">
|
||||
<input
|
||||
:id="`${filter.value_id}`"
|
||||
v-model="selectedFilters"
|
||||
:value="`${filter.parent}.${filter.value_id}`"
|
||||
type="checkbox"
|
||||
class="border-button !bg-inherit"
|
||||
>
|
||||
<label
|
||||
:for="`${filter.value_id}`"
|
||||
class="cursor-pointer flex items-center justify-between w-full"
|
||||
>
|
||||
<span>{{ filter.value }}</span>
|
||||
<span>12</span>
|
||||
</label>
|
||||
@ -125,33 +197,57 @@
|
||||
|
||||
<div class="w-full space-y-10">
|
||||
<!-- pop-up -->
|
||||
<div v-if="isInfo"
|
||||
class="w-full xl:w-[70%] mx-auto border-y border-block py-[15px] sm:p-[30px] flex gap-[55px] relative">
|
||||
<UButton variant="ghost"
|
||||
class="p-0 absolute right-0 top-2 sm:right-2 sm:top-2 cursor-pointer text-button font-light hover:bg-inherit hover:text-button-hover"
|
||||
size="xl" icon="i-lucide-x" @click="closeElement()" />
|
||||
<div
|
||||
v-if="isInfo"
|
||||
class="w-full xl:w-[70%] mx-auto border-y border-block py-[15px] sm:p-[30px] flex gap-[55px] relative"
|
||||
>
|
||||
<UButton
|
||||
variant="ghost"
|
||||
class="p-0 absolute right-0 top-2 sm:right-2 sm:top-2 cursor-pointer text-button font-light hover:bg-inherit hover:text-button-hover"
|
||||
size="xl"
|
||||
icon="i-lucide-x"
|
||||
@click="closeElement()"
|
||||
/>
|
||||
|
||||
<div class="flex flex-col sm:flex-row gap-[25px]">
|
||||
<div class="flex flex-col justify-between gap-[25px]">
|
||||
<h4 class="font-inter text-lg sm:text-[24px] leading-[150%] md:leading-[120%] font-bold">
|
||||
<h4
|
||||
class="font-inter text-lg sm:text-[24px] leading-[150%] md:leading-[120%] font-bold"
|
||||
>
|
||||
{{ component.front_section_lang[0].data.title }}
|
||||
</h4>
|
||||
<p>{{ component.front_section_lang[0].data.description }}</p>
|
||||
</div>
|
||||
<img class="max-w-[150px] mx-auto" :src="`/api/public/file/${component.img[0]}_m.webp')`">
|
||||
<img
|
||||
class="max-w-[150px] mx-auto"
|
||||
:src="`/api/public/file/${component.img[0]}_m.webp')`"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="products.length < 1" class="grid gap-12 pt-32 pb-16 md:grid-cols-2 2xl:grid-cols-3">
|
||||
<div
|
||||
v-if="products.length < 1"
|
||||
class="grid gap-12 pt-32 pb-16 md:grid-cols-2 2xl:grid-cols-3"
|
||||
>
|
||||
<!-- <TheProductSkeleton v-for="index in 6" :key="index" /> -->
|
||||
</div>
|
||||
|
||||
<!-- products -->
|
||||
<div v-else ref="loadingElement" class="flex flex-wrap justify-center gap-5 sm:gap-10">
|
||||
<Product v-for="product in products" :key="product.id" :product="product" />
|
||||
<div
|
||||
v-else
|
||||
ref="loadingElement"
|
||||
class="flex flex-wrap justify-center gap-5 sm:gap-10"
|
||||
>
|
||||
<Product
|
||||
v-for="product in products"
|
||||
:key="product.id"
|
||||
:product="product"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-if="reachedEnd" class="w-full flex justify-center">
|
||||
<div v-if="reachedEnd"
|
||||
class="w-full flex justify-center"
|
||||
>
|
||||
<p>
|
||||
{{ $t("FrontTranslations", "You reached end of the list.") }}
|
||||
</p>
|
||||
@ -201,9 +297,12 @@ defineProps<{
|
||||
|
||||
const openCategories = ref(false)
|
||||
const isInfo = ref<boolean>(true)
|
||||
const selectedFilters = ref<string[]>([])
|
||||
const selectedFilters = ref<any>([])
|
||||
const categoryId = ref<number>(1)
|
||||
|
||||
console.log(selectedFilters.value);
|
||||
|
||||
|
||||
const loading = ref(false)
|
||||
const reachedEnd = ref(false)
|
||||
|
||||
@ -386,12 +485,7 @@ async function loadMoreProducts() {
|
||||
}
|
||||
}
|
||||
|
||||
interface CategoryItem {
|
||||
id: number
|
||||
name: string
|
||||
}
|
||||
|
||||
const changeCategory = (item: CategoryItem) => {
|
||||
const changeCategory = (item: any) => {
|
||||
categoryId.value = item.id
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
<svg width="76" height="53" viewBox="0 0 76 53" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M76 49.8V2C76 0.9 75.1 0 74 0H2C0.9 0 0 0.9 0 2V50C0 52.5 3.3 52 2 52H74C77 52 75.6 47.4 76 49.8ZM6 48L28 19.3L46.4 43.4L49.9 48H6ZM55 48L50.5 42.2L58 32.4L69.9 48H55ZM72 44L59.6 27.8C58.8 26.7 57.2 26.7 56.4 27.8L48 38.8L29.6 14.8C28.8 13.7 27.2 13.7 26.4 14.8L4 44.1V4H72V44ZM49 10C45.1 10 42 13.1 42 17C42 20.9 45.1 24 49 24C52.9 24 56 20.9 56 17C56 13.1 52.8 10 49 10ZM49 20C47.4 20 46 18.7 46 17C46 15.3 47.3 14 49 14C50.7 14 52 15.3 52 17C52 18.7 50.6 20 49 20Z" fill="#525252"/>
|
||||
<path d="M76 49.8V2C76 0.9 75.1 0 74 0H2C0.9 0 0 0.9 0 2V50C0 52.5 3.3 52 2 52H74C77 52 75.6 47.4 76 49.8ZM6 48L28 19.3L46.4 43.4L49.9 48H6ZM55 48L50.5 42.2L58 32.4L69.9 48H55ZM72 44L59.6 27.8C58.8 26.7 57.2 26.7 56.4 27.8L48 38.8L29.6 14.8C28.8 13.7 27.2 13.7 26.4 14.8L4 44.1V4H72V44ZM49 10C45.1 10 42 13.1 42 17C42 20.9 45.1 24 49 24C52.9 24 56 20.9 56 17C56 13.1 52.8 10 49 10ZM49 20C47.4 20 46 18.7 46 17C46 15.3 47.3 14 49 14C50.7 14 52 15.3 52 17C52 18.7 50.6 20 49 20Z" fill="#004F3D"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 598 B After Width: | Height: | Size: 598 B |
@ -1,25 +1,14 @@
|
||||
import { validation } from '../utils/validation'
|
||||
import { REGEX_PHONE } from '../utils/regex'
|
||||
import type { GenericResponse, GenericResponseItems, UserCart } from '~/types'
|
||||
import type {
|
||||
AddressesList,
|
||||
CheckoutOrder,
|
||||
Payment,
|
||||
UserAddressOfficial,
|
||||
} from '~/types/checkout'
|
||||
import type { AddressesList, UserAddressOfficial } from '~/types/checkout'
|
||||
import type { CartProduct } from '~/types/product'
|
||||
|
||||
export const useCheckoutStore = defineStore('checkoutStore', () => {
|
||||
const { $toast } = useNuxtApp()
|
||||
const menuStore = useMenuStore()
|
||||
|
||||
const selectedIso = ref(menuStore.selectedCountry)
|
||||
|
||||
const vLegal = ref(false)
|
||||
const vTerms = ref(false)
|
||||
const vNote = ref('')
|
||||
const legalValidation = ref(false)
|
||||
const termsValidation = ref(false)
|
||||
const showSummary = ref(false)
|
||||
|
||||
// get address list
|
||||
const addressesList = ref<AddressesList[]>()
|
||||
@ -152,8 +141,8 @@ export const useCheckoutStore = defineStore('checkoutStore', () => {
|
||||
}
|
||||
const phoneValidation = ref<boolean | null>(null)
|
||||
|
||||
// send checkout form
|
||||
const userStore = useUserStore()
|
||||
// send form
|
||||
async function sendForm() {
|
||||
const phoneNum = vUseAccountPhoneNumber.value
|
||||
? accountPhoneNumber.value
|
||||
@ -196,16 +185,13 @@ export const useCheckoutStore = defineStore('checkoutStore', () => {
|
||||
},
|
||||
)
|
||||
|
||||
console.log(res)
|
||||
|
||||
if (res.status === 200) {
|
||||
$toast.success('Form successfully sent', {
|
||||
autoClose: 5000,
|
||||
dangerouslyHTMLString: true,
|
||||
})
|
||||
menuStore.navigateToItem(
|
||||
menuStore.menuItems?.find(item => item.id === 13),
|
||||
)
|
||||
// redirectToSummary();
|
||||
showSummary.value = true
|
||||
}
|
||||
else {
|
||||
$toast.error('Failed to send form. Please try again.', {
|
||||
@ -219,7 +205,10 @@ export const useCheckoutStore = defineStore('checkoutStore', () => {
|
||||
}
|
||||
}
|
||||
|
||||
// get checkout
|
||||
const changeActive = (item: AddressesList) => {
|
||||
activeAddress.value = item
|
||||
}
|
||||
|
||||
async function getCheckout() {
|
||||
try {
|
||||
await useMyFetch<GenericResponse<object>>(
|
||||
@ -274,8 +263,7 @@ export const useCheckoutStore = defineStore('checkoutStore', () => {
|
||||
}
|
||||
}
|
||||
|
||||
// get delivery options
|
||||
interface DeliveryOptionItem {
|
||||
type DeliveryOption = {
|
||||
country_iso: string
|
||||
country_name: string
|
||||
delivery_supplier_id: number
|
||||
@ -284,71 +272,62 @@ export const useCheckoutStore = defineStore('checkoutStore', () => {
|
||||
shippment_price: string
|
||||
}
|
||||
|
||||
const deliveryOption = ref<DeliveryOptionItem[]>([])
|
||||
const currentDelivery = ref<DeliveryOptionItem | null>(null)
|
||||
const shippingPrice = ref<number>(0)
|
||||
|
||||
// get delivery options
|
||||
const deliveryOption = ref()
|
||||
const currentDelivery = ref()
|
||||
const shippingPrice = ref()
|
||||
async function getDeliveryOptions() {
|
||||
try {
|
||||
const { data } = await useMyFetch<GenericResponseItems<DeliveryOptionItem[]>>(
|
||||
`/api/restricted/cart/checkout/delivery-options`,
|
||||
{
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
onErrorOccured: async (_, status) => {
|
||||
throw createError({
|
||||
statusCode: status,
|
||||
statusMessage: `HTTP error: ${status}`,
|
||||
})
|
||||
},
|
||||
const { data } = await useMyFetch<
|
||||
GenericResponseItems<DeliveryOption[]>
|
||||
>(`/api/restricted/cart/checkout/delivery-options`, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
)
|
||||
onErrorOccured: async (_, status) => {
|
||||
throw createError({
|
||||
statusCode: status,
|
||||
statusMessage: `HTTP error: ${status}`,
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
if (data.items && data.items.length > 0) {
|
||||
deliveryOption.value = data.items
|
||||
currentDelivery.value = data.items[0]
|
||||
shippingPrice.value = Number(data.items[0].shippment_price)
|
||||
fullPrice.value += shippingPrice.value
|
||||
}
|
||||
console.log(data)
|
||||
deliveryOption.value = data.items
|
||||
currentDelivery.value = data.items[0]
|
||||
shippingPrice.value = data.items[0].shippment_price
|
||||
fullPrice.value = Number(fullPrice.value) + Number(shippingPrice.value)
|
||||
}
|
||||
catch (error) {
|
||||
console.error('getDeliveryOptions error:', error)
|
||||
console.error('getUserCart error:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const setCurrentDelivery = (item: DeliveryOptionItem) => {
|
||||
shippingPrice.value = Number(item.shippment_price)
|
||||
currentDelivery.value = item
|
||||
fullPrice.value = Number(fullPrice.value) + Number(shippingPrice.value)
|
||||
}
|
||||
|
||||
interface Address {
|
||||
is_default: boolean | string
|
||||
country_iso: string
|
||||
}
|
||||
|
||||
const defaultAddress = ref<Address | undefined>()
|
||||
|
||||
const defaultAddress = ref()
|
||||
async function getDefAddress() {
|
||||
try {
|
||||
const { data } = await useMyFetch<GenericResponse<{ addresses: Address[] }>>(
|
||||
`/api/public/user`,
|
||||
{
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
onErrorOccured: async (_, status) => {
|
||||
throw createError({
|
||||
statusCode: status,
|
||||
statusMessage: `HTTP error: ${status}`,
|
||||
})
|
||||
},
|
||||
const { data } = await useMyFetch<
|
||||
GenericResponse<{
|
||||
addresses: [
|
||||
{
|
||||
is_default: boolean
|
||||
},
|
||||
]
|
||||
}>
|
||||
>(`/api/public/user`, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
)
|
||||
onErrorOccured: async (_, status) => {
|
||||
throw createError({
|
||||
statusCode: status,
|
||||
statusMessage: `HTTP error: ${status}`,
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
defaultAddress.value = data.addresses.find(
|
||||
el => el.is_default === true || el.is_default === 'true',
|
||||
(el: { is_default: boolean }) => el.is_default === true,
|
||||
)
|
||||
}
|
||||
catch (error) {
|
||||
@ -356,170 +335,6 @@ export const useCheckoutStore = defineStore('checkoutStore', () => {
|
||||
}
|
||||
}
|
||||
|
||||
// get bank data
|
||||
const paymentMethods = ref([] as Payment[])
|
||||
const fullAddress = ref<Address>()
|
||||
const currentPayment = ref<Payment | null>()
|
||||
async function getBankAccount() {
|
||||
try {
|
||||
const { data } = await useMyFetch<GenericResponse<Payment[]>>(
|
||||
`/api/restricted/suitable-bank-accounts/${menuStore.selectedCurrency.iso_code}/${fullAddress.value?.country_iso}`,
|
||||
{
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
onErrorOccured: async (_, status) => {
|
||||
throw createError({
|
||||
statusCode: status,
|
||||
statusMessage: `HTTP error: ${status}`,
|
||||
})
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
paymentMethods.value = data
|
||||
currentPayment.value = data[0]
|
||||
}
|
||||
catch (error) {
|
||||
console.error('getUserCart error:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// get order (summary)
|
||||
async function getOrder() {
|
||||
try {
|
||||
const { data } = await useMyFetch<GenericResponse<CheckoutOrder>>(
|
||||
`/api/restricted/cart/checkout/order`,
|
||||
{
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
onErrorOccured: async (_, status) => {
|
||||
throw createError({
|
||||
statusCode: status,
|
||||
statusMessage: `HTTP error: ${status}`,
|
||||
})
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
fullAddress.value = data.delivery_details.address
|
||||
}
|
||||
catch (error) {
|
||||
console.error('getOrder error:', error)
|
||||
}
|
||||
}
|
||||
|
||||
async function setNewAddress(indexItem: number) {
|
||||
currentPayment.value = paymentMethods.value.find(
|
||||
(item, index) => indexItem === index,
|
||||
)
|
||||
}
|
||||
|
||||
// send summary form
|
||||
async function sendSummaryForm() {
|
||||
legalValidation.value = !vLegal.value
|
||||
termsValidation.value = !vTerms.value
|
||||
|
||||
if (!vTerms.value && !vLegal.value) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
await useMyFetch<GenericResponse<object>>(
|
||||
`/api/restricted/cart/checkout/delivery`,
|
||||
{
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
accept_general_conditions: true,
|
||||
accept_long_purchase: true,
|
||||
address: fullAddress.value,
|
||||
delivery_option_id: currentDelivery.value?.id,
|
||||
note: vNote.value,
|
||||
}),
|
||||
onErrorOccured: async (_, status) => {
|
||||
throw createError({
|
||||
statusCode: status,
|
||||
statusMessage: `HTTP error: ${status}`,
|
||||
})
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
await putCheckoutBankAccount()
|
||||
await markOrder()
|
||||
await getUserCart()
|
||||
}
|
||||
catch (error) {
|
||||
console.error('uploadAddress error:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// put checkout bank-account
|
||||
async function putCheckoutBankAccount() {
|
||||
try {
|
||||
await useMyFetch<GenericResponse<object>>(
|
||||
`/api/restricted/cart/checkout/bank-account/${currentPayment.value?.id}`,
|
||||
{
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
onErrorOccured: async (_, status) => {
|
||||
throw createError({
|
||||
statusCode: status,
|
||||
statusMessage: `HTTP error: ${status}`,
|
||||
})
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
catch (error) {
|
||||
console.error('uploadAddress error:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const modalMadeOrder = ref(false)
|
||||
async function markOrder() {
|
||||
try {
|
||||
const res = await useMyFetch<GenericResponse<object>>(
|
||||
`/api/restricted/cart/checkout/order`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
onErrorOccured: async (_, status) => {
|
||||
throw createError({
|
||||
statusCode: status,
|
||||
statusMessage: `HTTP error: ${status}`,
|
||||
})
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
if (res.status === 200 || res.status === 201) {
|
||||
$toast.success('Address successfully added', {
|
||||
autoClose: 5000,
|
||||
dangerouslyHTMLString: true,
|
||||
})
|
||||
modalMadeOrder.value = true
|
||||
}
|
||||
else {
|
||||
$toast.error('Failed to add address. Please try again.', {
|
||||
autoClose: 5000,
|
||||
dangerouslyHTMLString: true,
|
||||
})
|
||||
}
|
||||
// window.location.href = `/golden-panel/my-purchases/${res._data?.data.id}`;
|
||||
}
|
||||
catch (error) {
|
||||
console.error('uploadAddress error:', error)
|
||||
}
|
||||
}
|
||||
return {
|
||||
addressesList,
|
||||
activeAddress,
|
||||
@ -544,6 +359,7 @@ export const useCheckoutStore = defineStore('checkoutStore', () => {
|
||||
vNewAddressCode,
|
||||
vNewAddressCity,
|
||||
vNewAddressCountry,
|
||||
showSummary,
|
||||
|
||||
products,
|
||||
fullPrice,
|
||||
@ -552,30 +368,16 @@ export const useCheckoutStore = defineStore('checkoutStore', () => {
|
||||
currentDelivery,
|
||||
shippingPrice,
|
||||
defaultAddress,
|
||||
paymentMethods,
|
||||
currentPayment,
|
||||
fullAddress,
|
||||
|
||||
vLegal,
|
||||
vTerms,
|
||||
vNote,
|
||||
legalValidation,
|
||||
termsValidation,
|
||||
modalMadeOrder,
|
||||
|
||||
changePrefix,
|
||||
getCheckout,
|
||||
getAddressList,
|
||||
getUserData,
|
||||
changeActive,
|
||||
uploadAddress,
|
||||
sendForm,
|
||||
getUserCart,
|
||||
getDeliveryOptions,
|
||||
getDefAddress,
|
||||
setCurrentDelivery,
|
||||
getBankAccount,
|
||||
getOrder,
|
||||
setNewAddress,
|
||||
sendSummaryForm,
|
||||
}
|
||||
})
|
||||
|
@ -132,7 +132,7 @@ export const useMenuStore = defineStore('menuStore', () => {
|
||||
}
|
||||
|
||||
function getProductMenu() {
|
||||
return menuItems.value?.find(item => item.id === 14)
|
||||
return menuItems.value?.find(item => item.id === 13)
|
||||
}
|
||||
|
||||
const getFirstImage = (size: 'l' | 'm' | 's' = 'm', needbaseurl: boolean) => {
|
||||
@ -149,11 +149,7 @@ export const useMenuStore = defineStore('menuStore', () => {
|
||||
}
|
||||
if (img.length > 0) {
|
||||
if (needbaseurl) {
|
||||
return `${req?.headers.get('x-forwarded-proto') || url.protocol}://${
|
||||
req?.headers.get('x-forwarded-host')
|
||||
|| url.host
|
||||
|| req?.headers.get('host')
|
||||
}${img[0]}`
|
||||
return `${req?.headers.get('x-forwarded-proto') || url.protocol}://${req?.headers.get('x-forwarded-host') || url.host || req?.headers.get('host')}${img[0]}`
|
||||
}
|
||||
return img[0]
|
||||
}
|
||||
@ -221,17 +217,6 @@ export const useMenuStore = defineStore('menuStore', () => {
|
||||
return meta
|
||||
})
|
||||
|
||||
const formatPrice = (value: number): string => {
|
||||
return value.toLocaleString(selectedLanguage.value.iso_code, {
|
||||
minimumFractionDigits: selectedCurrency.value.precision,
|
||||
maximumFractionDigits: selectedCurrency.value.precision,
|
||||
currency: selectedCurrency.value.iso_code,
|
||||
style: 'currency',
|
||||
currencyDisplay: 'symbol',
|
||||
currencySign: 'accounting',
|
||||
})
|
||||
}
|
||||
|
||||
// watches
|
||||
watch(
|
||||
() => $session.cookieData,
|
||||
@ -258,12 +243,10 @@ export const useMenuStore = defineStore('menuStore', () => {
|
||||
selectedLanguage,
|
||||
defaultMenu,
|
||||
headMeta,
|
||||
|
||||
navigateToShop,
|
||||
loadMenu,
|
||||
navigateToItem,
|
||||
getLocales,
|
||||
getProductMenu,
|
||||
formatPrice,
|
||||
}
|
||||
})
|
||||
|
@ -3,6 +3,7 @@ import type {
|
||||
GenericResponse,
|
||||
GenericResponseChildren,
|
||||
GenericResponseItems,
|
||||
UserCart,
|
||||
} from '~/types'
|
||||
import type { Product } from '~/types/product'
|
||||
|
||||
@ -11,8 +12,6 @@ export const useProductStore = defineStore('productStore', () => {
|
||||
const productList = ref<Product[]>()
|
||||
const modules = ref()
|
||||
|
||||
const checkoutStore = useCheckoutStore()
|
||||
|
||||
async function getList(count: number, categoryId = 1) {
|
||||
try {
|
||||
const { data } = await useMyFetch<GenericResponseItems<[]>>(
|
||||
@ -82,7 +81,7 @@ export const useProductStore = defineStore('productStore', () => {
|
||||
autoClose: 5000,
|
||||
dangerouslyHTMLString: true,
|
||||
})
|
||||
checkoutStore.getUserCart()
|
||||
getCart()
|
||||
}
|
||||
else {
|
||||
$toast.error('Failed to add item to cart. Please try again.', {
|
||||
@ -120,7 +119,7 @@ export const useProductStore = defineStore('productStore', () => {
|
||||
autoClose: 5000,
|
||||
dangerouslyHTMLString: true,
|
||||
})
|
||||
checkoutStore.getUserCart()
|
||||
getCart()
|
||||
}
|
||||
else {
|
||||
$toast.error('Failed to removed item from cart. Please try again.', {
|
||||
@ -158,7 +157,7 @@ export const useProductStore = defineStore('productStore', () => {
|
||||
autoClose: 5000,
|
||||
dangerouslyHTMLString: true,
|
||||
})
|
||||
checkoutStore.getUserCart()
|
||||
getCart()
|
||||
}
|
||||
else {
|
||||
$toast.error('Failed to removed item from cart. Please try again.', {
|
||||
@ -176,13 +175,37 @@ export const useProductStore = defineStore('productStore', () => {
|
||||
}
|
||||
}
|
||||
|
||||
const cart = ref({} as UserCart)
|
||||
async function getCart() {
|
||||
try {
|
||||
const { data } = await useMyFetch<GenericResponse<UserCart>>(
|
||||
`/api/public/user/cart`,
|
||||
{
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
onErrorOccured: (_, status) => {
|
||||
throw new Error(`HTTP error: ${status}`)
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
cart.value = data
|
||||
}
|
||||
catch (error) {
|
||||
console.error('getList error:', error)
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
productList,
|
||||
modules,
|
||||
cart,
|
||||
getList,
|
||||
getModules,
|
||||
incrementCartItem,
|
||||
decrementCartItem,
|
||||
deleteCartItem,
|
||||
getCart,
|
||||
}
|
||||
})
|
||||
|
@ -30,41 +30,3 @@ export interface UserAddressOfficial {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export interface Payment {
|
||||
bank_name: string
|
||||
city: string
|
||||
country_account_number: string
|
||||
country_iso: string
|
||||
country_name: string
|
||||
currency_iso: string
|
||||
iban: string
|
||||
id: number
|
||||
postcode: string
|
||||
street_and_number: string
|
||||
swift: string
|
||||
}
|
||||
|
||||
export interface CheckoutOrder {
|
||||
cart_id: number
|
||||
currency_iso: string
|
||||
customer_id: number
|
||||
delivery_details: {
|
||||
address: Address
|
||||
contact_email: string
|
||||
contact_phone_number: string
|
||||
delivery_option_id: number
|
||||
}
|
||||
payment_bank_account_id: number
|
||||
}
|
||||
|
||||
export interface Address {
|
||||
city: string
|
||||
country_iso: {
|
||||
str: string
|
||||
}
|
||||
name: string
|
||||
postcode: string
|
||||
street: string
|
||||
surname: string
|
||||
}
|
||||
|
Reference in New Issue
Block a user