fix eslint
This commit is contained in:
@ -1,167 +1,55 @@
|
|||||||
<template>
|
<template>
|
||||||
<div ref="dropdownRef">
|
<div ref="dropdownRef">
|
||||||
<div @click="openCart = !openCart" class="relative cursor-pointer">
|
<div class="relative cursor-pointer" @click="openCart = !openCart">
|
||||||
<i class="uil uil-shopping-cart text-[31px]"></i>
|
<i class="uil uil-shopping-cart text-[31px]"></i>
|
||||||
<div v-if="checkoutStore.products && checkoutStore.products.length > 0"
|
<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">
|
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>
|
{{ checkoutStore.products.length }}
|
||||||
</div>
|
</div>
|
||||||
<div v-if="openCart" @click.self="openCart = !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]">
|
|
||||||
<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>
|
|
||||||
<div v-for="item in checkoutStore.products"
|
|
||||||
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>
|
|
||||||
|
|
||||||
<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]">
|
|
||||||
{{ item.name }}
|
|
||||||
</h3>
|
|
||||||
<i @click="productStore.deleteCartItem(item.cart_item_id)"
|
|
||||||
class="uil uil-trash-alt text-lg sm:text-2xl cursor-pointer"></i>
|
|
||||||
</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)) }}
|
|
||||||
</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>
|
|
||||||
</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]">
|
|
||||||
{{ 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>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</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>
|
|
||||||
<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)) }}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<UiButtonArrow @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
|
|
||||||
}" class="w-full" type="fill" :arrow="true" :full="true">{{ 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
|
|
||||||
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>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div v-if="openCart"
|
||||||
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]"
|
||||||
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">
|
||||||
@click.self="openCart = !openCart"
|
|
||||||
>
|
|
||||||
<div class="xl:w-[55%] md:w-[90%] w-full px-4 md:px-0">
|
<div class="xl:w-[55%] md:w-[90%] w-full px-4 md:px-0">
|
||||||
<div
|
<div v-if="checkoutStore.products && checkoutStore.products.length > 0"
|
||||||
v-if="
|
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">
|
||||||
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>
|
||||||
<!-- product -->
|
<div v-for="(item, index) in checkoutStore.products" :key="index"
|
||||||
<div
|
class="py-[13px] sm:py-[25px] first:pt-0 border-b border-block">
|
||||||
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="flex items-center h-[100px] sm:h-[205px]">
|
||||||
<div
|
<div class="min-w-[100px] sm:min-w-[205px] flex items-center justify-center h-[100px] sm:h-[205px]">
|
||||||
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">
|
||||||
<img
|
|
||||||
:src="`/api/public/file/${item.picture_uuid}.webp`"
|
|
||||||
alt=""
|
|
||||||
class="max-w-full max-h-full object-contain"
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div class="flex flex-col justify-between min-h-full w-full gap-[7px] sm:gap-[15px]">
|
||||||
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">
|
<div class="w-full flex items-center justify-between">
|
||||||
<h3
|
<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 }}
|
{{ item.name }}
|
||||||
</h3>
|
</h3>
|
||||||
<i
|
<i class="uil uil-trash-alt text-lg sm:text-2xl cursor-pointer"
|
||||||
class="uil uil-trash-alt text-lg sm:text-2xl cursor-pointer"
|
@click="productStore.deleteCartItem(item.cart_item_id)"></i>
|
||||||
@click="productStore.deleteCartItem(item.cart_item_id)"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col gap-[10px]">
|
<div class="flex flex-col gap-[10px]">
|
||||||
<p
|
<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">
|
||||||
>
|
{{ menuStore.formatPrice(Number(item.total_price)) }}
|
||||||
{{ item.total_price }}
|
|
||||||
</p>
|
</p>
|
||||||
<div class="flex items-center gap-[2px] sm:gap-2 text-xl">
|
<div class="flex items-center gap-[2px] sm:gap-2 text-xl">
|
||||||
<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"
|
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"
|
||||||
<i
|
@click="productStore.decrementCartItem(item.cart_item_id)"></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>
|
||||||
<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 }}
|
{{ item.quantity }}
|
||||||
</div>
|
</div>
|
||||||
<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"
|
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"
|
||||||
<i
|
@click="productStore.incrementCartItem(item.product_id)"></i>
|
||||||
class="uil uil-plus cursor-pointer hover:text-gray-200 transition-all"
|
|
||||||
@click="
|
|
||||||
productStore.incrementCartItem(item.product_id)
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -170,52 +58,34 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<h4
|
<h4 class="font-inter text-[12px] leading-[150%] font-bold uppercase sm:text-[24px]">
|
||||||
class="font-inter text-[12px] leading-[150%] font-bold uppercase sm:text-[24px]"
|
{{
|
||||||
>
|
$t('total_amount') }}
|
||||||
{{ $t("total_amount") }}
|
|
||||||
</h4>
|
</h4>
|
||||||
<p
|
<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">
|
||||||
>
|
{{ menuStore.formatPrice(Number(checkoutStore.fullProductsPrice)) }}
|
||||||
{{ productStore.cart.total_value }}
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<UiButtonArrow
|
<UiButtonArrow class="w-full" type="fill" :arrow="true" :full="true" @click="() => {
|
||||||
class="w-full"
|
if (userStore.isLogged) {
|
||||||
type="fill"
|
menuStore.navigateToItem(menuStore.menuItems?.find((item) => item.id === 12))
|
||||||
:arrow="true"
|
}
|
||||||
:full="true"
|
else {
|
||||||
@click="
|
menuStore.navigateToItem(menuStore.menuItems?.find((item) => item.id === 11))
|
||||||
() => {
|
}
|
||||||
if (userStore.isLogged) {
|
openCart = false
|
||||||
menuStore.navigateToItem(
|
}">
|
||||||
menuStore.menuItems?.find((item) => item.id === 12),
|
{{ userStore.isLogged
|
||||||
);
|
? $t('to_checkout') : $t('login') }}
|
||||||
}
|
|
||||||
else {
|
|
||||||
menuStore.navigateToItem(
|
|
||||||
menuStore.menuItems?.find((item) => item.id === 11),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
openCart = false;
|
|
||||||
}
|
|
||||||
"
|
|
||||||
>
|
|
||||||
{{ userStore.isLogged ? $t("to_checkout") : $t("login") }}
|
|
||||||
</UiButtonArrow>
|
</UiButtonArrow>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div v-else
|
||||||
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">
|
||||||
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
|
<div
|
||||||
class="border border-block inline-flex items-center justify-center h-[140px] sm:h-[200px] text-center rounded-[8px]"
|
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">
|
||||||
<h4
|
{{ $t('empty_cart') }}
|
||||||
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>
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -229,7 +99,7 @@ import { onClickOutside } from '@vueuse/core'
|
|||||||
|
|
||||||
const productStore = useProductStore()
|
const productStore = useProductStore()
|
||||||
const checkoutStore = useCheckoutStore()
|
const checkoutStore = useCheckoutStore()
|
||||||
const openCart = ref(false);
|
const openCart = ref(false)
|
||||||
|
|
||||||
const menuStore = useMenuStore()
|
const menuStore = useMenuStore()
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
|
@ -34,8 +34,8 @@
|
|||||||
<div class="flex items-center gap-[30px]">
|
<div class="flex items-center gap-[30px]">
|
||||||
<div>
|
<div>
|
||||||
<i v-if="!userStore.isLogged"
|
<i v-if="!userStore.isLogged"
|
||||||
@click="menuStore.navigateToItem(menuStore.menuItems?.find((item) => item.id === 11))"
|
class="uil uil-user text-[31px] cursor-pointer"
|
||||||
class="uil uil-user text-[31px] cursor-pointer"></i>
|
@click="menuStore.navigateToItem(menuStore.menuItems?.find((item) => item.id === 11))"></i>
|
||||||
<div v-else class="py-[6px] px-3 border border-block rounded-sm">
|
<div v-else class="py-[6px] px-3 border border-block rounded-sm">
|
||||||
{{ userStore.user }}
|
{{ userStore.user }}
|
||||||
</div>
|
</div>
|
||||||
@ -375,11 +375,10 @@ import CountryCurrencySelector from './CountryCurrencySelector.vue'
|
|||||||
import LangSwitcher from './LangSwitcher.vue'
|
import LangSwitcher from './LangSwitcher.vue'
|
||||||
|
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
const productStore = useProductStore()
|
|
||||||
const open = ref(false)
|
const open = ref(false)
|
||||||
const colorMode = useColorMode()
|
const colorMode = useColorMode()
|
||||||
const menuStore = useMenuStore();
|
const menuStore = useMenuStore()
|
||||||
const checkoutStore = useCheckoutStore();
|
const checkoutStore = useCheckoutStore()
|
||||||
|
|
||||||
checkoutStore.getUserCart()
|
checkoutStore.getUserCart()
|
||||||
|
|
||||||
|
@ -14,35 +14,30 @@
|
|||||||
{{ component.front_section_lang[0].data.main_subtitle }}
|
{{ component.front_section_lang[0].data.main_subtitle }}
|
||||||
</h4>
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
<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"
|
||||||
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="{
|
||||||
:style="{
|
backgroundImage: `url('/api/public/file/${component.img[0]}_l.webp')`,
|
||||||
backgroundImage: `url('/api/public/file/${component.img[0]}_l.webp')`,
|
backgroundSize: 'cover',
|
||||||
backgroundSize: 'cover',
|
backgroundPosition: 'center',
|
||||||
backgroundPosition: 'center',
|
}"></div>
|
||||||
}"
|
|
||||||
></div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="space-25-55-75">
|
<div class="space-25-55-75">
|
||||||
<h2 class="h2-bold-bounded">
|
<h2 class="h2-bold-bounded">
|
||||||
{{ component.front_section_lang[0].data.story_title }}
|
{{ component.front_section_lang[0].data.story_title }}
|
||||||
</h2>
|
</h2>
|
||||||
<div class="flex flex-col-reverse md:flex-row w-full gap-6">
|
<div class="flex flex-col-reverse md:flex-row w-full gap-6">
|
||||||
<div
|
<div class="rounded-2xl h-[390px] md:h-auto min-w-[40%] xl:min-w-[60%]" :style="{
|
||||||
class="rounded-2xl h-[390px] md:h-auto min-w-[40%] xl:min-w-[60%]"
|
backgroundImage: `url('/api/public/file/${component.img[1]}_l.webp')`,
|
||||||
:style="{
|
backgroundSize: 'cover',
|
||||||
backgroundImage: `url('/api/public/file/${component.img[1]}_l.webp')`,
|
backgroundPosition: 'center',
|
||||||
backgroundSize: 'cover',
|
}"></div>
|
||||||
backgroundPosition: 'center',
|
|
||||||
}"
|
|
||||||
></div>
|
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<p v-for="(item, index) in component.front_section_lang[0].data.story_description" :key="index">
|
<div v-for="(item, index) in component.front_section_lang[0].data.story_description" :key="index">
|
||||||
{{ item }}
|
<p>{{ item }}</p>
|
||||||
</p><div v-if="index < component.front_section_lang[0].data.story_description.length - 1">
|
<div v-if="index < component.front_section_lang[0].data.story_description.length - 1">
|
||||||
<br>
|
<br>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col w-full gap-6">
|
<div class="flex flex-col w-full gap-6">
|
||||||
@ -50,14 +45,12 @@
|
|||||||
{{ component.front_section_lang[0].data.story_subtitle }}
|
{{ component.front_section_lang[0].data.story_subtitle }}
|
||||||
</h4>
|
</h4>
|
||||||
<div class="flex flex-col justify-between xl:max-w-[70%]">
|
<div class="flex flex-col justify-between xl:max-w-[70%]">
|
||||||
<p v-for="(el, indexEl) in component.front_section_lang[0].data.story_sub_description"
|
<div v-for="(el, indexEl) in component.front_section_lang[0].data.story_sub_description" :key="indexEl">
|
||||||
:key="indexEl"
|
<p>{{ el }}</p>
|
||||||
>
|
<div v-if="indexEl < component.front_section_lang[0].data.story_sub_description.length - 1">
|
||||||
{{ el }}
|
<br>
|
||||||
</p><div v-if="indexEl < component.front_section_lang[0].data.story_sub_description.length - 1">
|
</div>
|
||||||
<br>
|
|
||||||
</div>
|
</div>
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,160 +1,173 @@
|
|||||||
<template>
|
<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-if="checkoutStore.modalMadeOrder">
|
<UiContainer v-else>
|
||||||
<NuxtLink to="/" class="mt-6 text-blue-500 underline" @click="checkoutStore.modalMadeOrder = false">Go back home
|
<div class="xl:w-[85%] mx-auto space-25-55">
|
||||||
</NuxtLink>
|
<div class="space-25-55">
|
||||||
</UiContainer>
|
<div class="w-full flex items-center sm:justify-center">
|
||||||
|
<div
|
||||||
<UiContainer v-else>
|
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="xl:w-[85%] mx-auto space-25-55">
|
<div class="sm:px-6 sm:py-3 mx-auto">
|
||||||
<div class="space-25-55">
|
{{ $t("login") }}
|
||||||
<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">
|
|
||||||
<div class="sm:px-6 sm:py-3 mx-auto">
|
|
||||||
{{ $t("login") }}
|
|
||||||
</div>
|
|
||||||
<div class="sm:px-6 sm:py-3 mx-auto">
|
|
||||||
{{ $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">
|
|
||||||
{{ $t("summary") }}
|
|
||||||
</div>
|
|
||||||
<div class="hidden sm:block sm:px-6 sm:py-3 sm:mx-auto">
|
|
||||||
{{ $t("order_placed") }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-3 gap-[30px]">
|
<div class="sm:px-6 sm:py-3 mx-auto">
|
||||||
<div class="col-start-1 col-end-2 sm:col-end-3 space-y-5">
|
{{ $t("address") }}
|
||||||
<h4 class="h4-uppercase-bold-inter">{{ component.front_section_lang[0].data.product_list }}</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>
|
|
||||||
|
|
||||||
<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]">
|
|
||||||
{{ 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">
|
|
||||||
{{ item.total_price }}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</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">
|
|
||||||
<h4 class="h4-uppercase-bold-inter">{{ component.front_section_lang[0].data.account_address }}
|
|
||||||
</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>
|
|
||||||
<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 v-model="checkoutStore.vNote"
|
|
||||||
class="border-2 border-block rounded-[8px] p-[15px] w-full flex-1 resize-none placeholder:text-button"
|
|
||||||
name="rty" id="1" :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 @click="checkoutStore.setCurrentDelivery(delivery)"
|
|
||||||
v-for="delivery in checkoutStore.deliveryOption" class="flex flex-col cursor-pointer">
|
|
||||||
<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>
|
|
||||||
</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 :prevIcon="'i-lucide-chevron-left'" :nextIcon="'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>
|
||||||
<div class="w-full border-y-2 border-block p-[25px] flex flex-col gap-[15px]">
|
<div
|
||||||
<div class="flex items-center justify-between">
|
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">
|
||||||
<p class="text-sm sm:text-xl">{{ component.front_section_lang[0].data.subtotal }}</p>
|
{{ $t("summary") }}
|
||||||
<p class="text-lg sm:text-xl font-medium">{{
|
</div>
|
||||||
menuStore.formatPrice(Number(checkoutStore.fullProductsPrice)) }}
|
<div class="hidden sm:block sm:px-6 sm:py-3 sm:mx-auto">
|
||||||
</p>
|
{{ $t("order_placed") }}
|
||||||
|
</div>
|
||||||
|
</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">
|
||||||
|
<h4 class="h4-uppercase-bold-inter">
|
||||||
|
{{ component.front_section_lang[0].data.product_list }}
|
||||||
|
</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>
|
</div>
|
||||||
<div class="flex items-center justify-between">
|
|
||||||
<p class="text-sm sm:text-xl">{{ component.front_section_lang[0].data.shipping_cost }}</p>
|
<div class="flex flex-col justify-between min-h-full w-full gap-[7px] sm:gap-[15px]">
|
||||||
<p class="text-lg sm:text-xl font-medium">{{
|
<div class="w-full flex items-center justify-between">
|
||||||
menuStore.formatPrice(Number(checkoutStore.shippingPrice)) }}</p>
|
<h3
|
||||||
</div>
|
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]">
|
||||||
<div class="flex items-center justify-between uppercase text-lg sm:text-xl">
|
{{ item.name }}
|
||||||
<p>{{ component.front_section_lang[0].data.total }}</p>
|
</h3>
|
||||||
|
</div>
|
||||||
|
<div class="flex w-full justify-between gap-[10px]">
|
||||||
<p
|
<p
|
||||||
class="text-accent-green-light dark:text-accent-green-dark font-inter text-xl sm: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">
|
||||||
{{ menuStore.formatPrice(Number(checkoutStore.fullPrice)) }}
|
{{ item.total_price }}
|
||||||
</p>
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col sm:flex-row items-center justify-between mt-1 gap-[55px]">
|
</div>
|
||||||
<div class="flex flex-col gap-1 text-white w-full">
|
</div>
|
||||||
<div class="flex gap-3 text-black dark:text-white items-center">
|
<div
|
||||||
<input v-model="checkoutStore.vLegal" type="checkbox" id="first" name="first" />
|
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]">
|
||||||
<!-- <label for="first" class="text-sm leading-snug">
|
<div class="space-y-5 w-full">
|
||||||
|
<h4 class="h4-uppercase-bold-inter">
|
||||||
|
{{ component.front_section_lang[0].data.account_address }}
|
||||||
|
</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>
|
||||||
|
<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>
|
||||||
|
</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 ") }}
|
{{ $t("I accept ") }}
|
||||||
<NuxtLink target="_blank"
|
<NuxtLink target="_blank"
|
||||||
:to="{ name: 'lang-info-name', params: { lang: menuStore.selectedLanguage.iso_code, name: 'legal_statement.html' } }"
|
:to="{ name: 'lang-info-name', params: { lang: menuStore.selectedLanguage.iso_code, name: 'legal_statement.html' } }"
|
||||||
@ -162,15 +175,17 @@
|
|||||||
{{ $t("the legal statement*") }}
|
{{ $t("the legal statement*") }}
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
</label> -->
|
</label> -->
|
||||||
<p class="text-sm sm:text-lg"> {{ $t("I accept ") }} {{ $t("the legal statement*") }}</p>
|
<p class="text-sm sm:text-lg">
|
||||||
</div>
|
{{ $t("I accept ") }} {{ $t("the legal statement*") }}
|
||||||
<span v-if="checkoutStore.legalValidation" class="text-xs text-red-600 ml-6">
|
</p>
|
||||||
{{ $t("You need to accept this") }}
|
</div>
|
||||||
</span>
|
<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">
|
<div class="flex gap-3 text-black dark:text-white items-center mt-2">
|
||||||
<input v-model="checkoutStore.vTerms" type="checkbox" id="second" name="second" />
|
<input id="second" v-model="checkoutStore.vTerms" type="checkbox" name="second" />
|
||||||
<!-- <label for="second" class="text-sm leading-snug">
|
<!-- <label for="second" class="text-sm leading-snug">
|
||||||
{{ $t("I accept ") }}
|
{{ $t("I accept ") }}
|
||||||
<NuxtLink target="_blank"
|
<NuxtLink target="_blank"
|
||||||
:to="{ name: 'lang-info-name', params: { lang: menuStore.selectedLanguage.iso_code, name: 'general_terms_and_conditions.html' } }"
|
:to="{ name: 'lang-info-name', params: { lang: menuStore.selectedLanguage.iso_code, name: 'general_terms_and_conditions.html' } }"
|
||||||
@ -178,83 +193,27 @@
|
|||||||
{{ $t("general terms and conditions*") }}
|
{{ $t("general terms and conditions*") }}
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
</label> -->
|
</label> -->
|
||||||
<p class="text-sm sm:text-lg"> {{ $t("I accept ") }} {{ $t("general terms and conditions*") }}
|
<p class="text-sm sm:text-lg">
|
||||||
</p>
|
{{ $t("I accept ") }} {{ $t("general terms and conditions*") }}
|
||||||
</div>
|
</p>
|
||||||
<span v-if="checkoutStore.termsValidation" class="text-xs text-red-600 ml-6">
|
</div>
|
||||||
{{ $t("You need to accept this") }}
|
<span v-if="checkoutStore.termsValidation" class="text-xs text-red-600 ml-6">
|
||||||
</span>
|
{{ $t("You need to accept this") }}
|
||||||
</div>
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<UiButtonArrow @click="checkoutStore.sendSummaryForm" type="fill" :arrow="true">
|
<UiButtonArrow type="fill" :arrow="true" @click="checkoutStore.sendSummaryForm">
|
||||||
{{ $t("Buy") }}
|
{{ $t("Buy") }}
|
||||||
</UiButtonArrow>
|
</UiButtonArrow>
|
||||||
</div>
|
</div>
|
||||||
<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">
|
</UiContainer>
|
||||||
{{ $t("summary") }}
|
|
||||||
</div>
|
|
||||||
<div class="hidden sm:block sm:px-6 sm:py-3 sm:mx-auto">
|
|
||||||
{{ $t("order_placed") }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<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">
|
|
||||||
Seznam produktů
|
|
||||||
</h4>
|
|
||||||
<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="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]">
|
|
||||||
{{ 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">
|
|
||||||
{{ item.total_price }}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="">
|
|
||||||
<div class="space-y-5">
|
|
||||||
<h4 class="h4-uppercase-bold-inter">
|
|
||||||
Adresa účtu
|
|
||||||
</h4>
|
|
||||||
<div 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>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</UiContainer>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { UCarousel } from '#components';
|
import { UCarousel } from '#components'
|
||||||
|
|
||||||
const checkoutStore = useCheckoutStore();
|
const checkoutStore = useCheckoutStore()
|
||||||
const productStore = useProductStore()
|
|
||||||
const menuStore = useMenuStore()
|
const menuStore = useMenuStore()
|
||||||
|
|
||||||
checkoutStore.getOrder()
|
checkoutStore.getOrder()
|
||||||
@ -264,30 +223,30 @@ checkoutStore.getDeliveryOptions()
|
|||||||
checkoutStore.getDefAddress()
|
checkoutStore.getDefAddress()
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
component: {
|
component: {
|
||||||
id: number
|
id: number
|
||||||
name: string
|
name: string
|
||||||
img: string[]
|
img: string[]
|
||||||
component_name: string
|
component_name: string
|
||||||
is_no_lang: boolean
|
is_no_lang: boolean
|
||||||
page_name: string
|
page_name: string
|
||||||
front_section_lang: {
|
front_section_lang: {
|
||||||
data: {
|
data: {
|
||||||
product_list: string
|
product_list: string
|
||||||
account_address: string
|
account_address: string
|
||||||
note: string
|
note: string
|
||||||
delivery_type: string
|
delivery_type: string
|
||||||
payment_method: string
|
payment_method: string
|
||||||
subtotal: string
|
subtotal: string
|
||||||
shipping_cost: string
|
shipping_cost: string
|
||||||
total: string
|
total: string
|
||||||
accept: string
|
accept: string
|
||||||
legal: string
|
legal: string
|
||||||
terms: string
|
terms: string
|
||||||
}
|
}
|
||||||
id_front_section: number
|
id_front_section: number
|
||||||
id_lang: number
|
id_lang: number
|
||||||
}[]
|
}[]
|
||||||
}
|
}
|
||||||
}>();
|
}>()
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,15 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<UiContainer v-if="!userStore.vCodeVerify"
|
<UiContainer v-if="!userStore.vCodeVerify" class="flex py-20 sm:py-14">
|
||||||
class="flex py-20 sm:py-14"
|
<div class="hidden xl:block rounded-2xl min-w-[60%] h-[830px]" :style="{
|
||||||
>
|
backgroundImage: `url('/api/public/file/${component.img[0]}_l.webp')`,
|
||||||
<div
|
backgroundSize: 'cover',
|
||||||
class="hidden xl:block rounded-2xl min-w-[60%] h-[830px]"
|
backgroundPosition: 'center',
|
||||||
:style="{
|
}" />
|
||||||
backgroundImage: `url('/api/public/file/${component.img[0]}_l.webp')`,
|
|
||||||
backgroundSize: 'cover',
|
|
||||||
backgroundPosition: 'center',
|
|
||||||
}"
|
|
||||||
/>
|
|
||||||
<div class="w-full sm:w-[80%] mx-auto my-auto xl:w-full xl:px-12">
|
<div class="w-full sm:w-[80%] mx-auto my-auto xl:w-full xl:px-12">
|
||||||
<div class="space-25-55">
|
<div class="space-25-55">
|
||||||
<div class="flex flex-wrap-reverse gap-y-4 justify-between">
|
<div class="flex flex-wrap-reverse gap-y-4 justify-between">
|
||||||
@ -18,8 +13,7 @@
|
|||||||
</h2>
|
</h2>
|
||||||
<button
|
<button
|
||||||
class="h-[40px] sm:h-[43px] px-[10px] sm:px-[17px] border border-gray dark:border-button-disabled text-gray dark:text-button-disabled hover:bg-gray transition-all hover:text-white rounded-[8px] cursor-pointer"
|
class="h-[40px] sm:h-[43px] px-[10px] sm:px-[17px] border border-gray dark:border-button-disabled text-gray dark:text-button-disabled hover:bg-gray transition-all hover:text-white rounded-[8px] cursor-pointer"
|
||||||
@click="menuStore.navigateToItem()"
|
@click="menuStore.navigateToItem()">
|
||||||
>
|
|
||||||
{{ $t("back_to_home") }}
|
{{ $t("back_to_home") }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -27,37 +21,22 @@
|
|||||||
<p class="pl-6">
|
<p class="pl-6">
|
||||||
{{ $t("email") }}
|
{{ $t("email") }}
|
||||||
</p>
|
</p>
|
||||||
<input
|
<input v-model="userStore.email" :placeholder="$t('email')" type="text"
|
||||||
v-model="userStore.email"
|
class="border-2 border-block placeholder:text-gray dark:placeholder:text-button-disabled text-bg-dark dark:text-bg-light rounded-lg px-6 h-[50px] sm:h-[67px] w-full focus:outline-none focus:ring-0 focus:border-2">
|
||||||
:placeholder="$t('email')"
|
|
||||||
type="text"
|
|
||||||
class="border-2 border-block placeholder:text-gray dark:placeholder:text-button-disabled text-bg-dark dark:text-bg-light rounded-lg px-6 h-[50px] sm:h-[67px] w-full focus:outline-none focus:ring-0 focus:border-2"
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="space-y-[15px]">
|
<div class="space-y-[15px]">
|
||||||
<p class="pl-6">
|
<p class="pl-6">
|
||||||
{{ $t("password") }}
|
{{ $t("password") }}
|
||||||
</p>
|
</p>
|
||||||
<input
|
<input v-model="userStore.password" :placeholder="$t('placeholder_password')" type="text"
|
||||||
v-model="userStore.password"
|
class="border-2 border-block placeholder:text-gray dark:placeholder:text-button-disabled text-bg-dark dark:text-bg-light rounded-lg px-6 h-[50px] sm:h-[67px] w-full focus:outline-none focus:ring-0 focus:border-2">
|
||||||
:placeholder="$t('placeholder_password')"
|
|
||||||
type="text"
|
|
||||||
class="border-2 border-block placeholder:text-gray dark:placeholder:text-button-disabled text-bg-dark dark:text-bg-light rounded-lg px-6 h-[50px] sm:h-[67px] w-full focus:outline-none focus:ring-0 focus:border-2"
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p
|
<p class="text-button hover:text-button-hover transition-all font-medium mt-[30px] cursor-pointer">
|
||||||
class="text-button hover:text-button-hover transition-all font-medium mt-[30px] cursor-pointer"
|
|
||||||
>
|
|
||||||
{{ $t("forgot_password_question") }}
|
{{ $t("forgot_password_question") }}
|
||||||
</p>
|
</p>
|
||||||
<div
|
<div class="py-[25px] sm:py-12 border-b border-gray flex justify-center w-full">
|
||||||
class="py-[25px] sm:py-12 border-b border-gray flex justify-center w-full"
|
<UiButtonArrow type="fill" :arrow="true" @click="userStore.logIn()">
|
||||||
>
|
|
||||||
<UiButtonArrow type="fill"
|
|
||||||
:arrow="true"
|
|
||||||
@click="userStore.logIn()"
|
|
||||||
>
|
|
||||||
{{
|
{{
|
||||||
$t("login")
|
$t("login")
|
||||||
}}
|
}}
|
||||||
@ -74,17 +53,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</UiContainer>
|
</UiContainer>
|
||||||
|
|
||||||
<UiContainer v-if="userStore.vCodeVerify"
|
<UiContainer v-if="userStore.vCodeVerify" class="flex py-20 sm:py-14">
|
||||||
class="flex py-20 sm:py-14"
|
<div class="hidden xl:block rounded-2xl min-w-[60%] h-[830px]" :style="{
|
||||||
>
|
backgroundImage: `url('/api/public/file/${component.img[0]}_l.webp')`,
|
||||||
<div
|
backgroundSize: 'cover',
|
||||||
class="hidden xl:block rounded-2xl min-w-[60%] h-[830px]"
|
backgroundPosition: 'center',
|
||||||
:style="{
|
}" />
|
||||||
backgroundImage: `url('/api/public/file/${component.img[0]}_l.webp')`,
|
|
||||||
backgroundSize: 'cover',
|
|
||||||
backgroundPosition: 'center',
|
|
||||||
}"
|
|
||||||
/>
|
|
||||||
<div class="w-full sm:w-[80%] mx-auto my-auto xl:w-full xl:px-12">
|
<div class="w-full sm:w-[80%] mx-auto my-auto xl:w-full xl:px-12">
|
||||||
<div class="space-25-55">
|
<div class="space-25-55">
|
||||||
<div class="flex flex-wrap-reverse gap-y-4 justify-between">
|
<div class="flex flex-wrap-reverse gap-y-4 justify-between">
|
||||||
@ -93,8 +67,7 @@
|
|||||||
</h2>
|
</h2>
|
||||||
<button
|
<button
|
||||||
class="h-[40px] sm:h-[43px] px-[10px] sm:px-[17px] border border-gray dark:border-button-disabled text-gray dark:text-button-disabled hover:bg-gray transition-all hover:text-white rounded-[8px] cursor-pointer"
|
class="h-[40px] sm:h-[43px] px-[10px] sm:px-[17px] border border-gray dark:border-button-disabled text-gray dark:text-button-disabled hover:bg-gray transition-all hover:text-white rounded-[8px] cursor-pointer"
|
||||||
@click="menuStore.navigateToItem()"
|
@click="menuStore.navigateToItem()">
|
||||||
>
|
|
||||||
{{ $t("back_to_home") }}
|
{{ $t("back_to_home") }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -108,21 +81,13 @@
|
|||||||
<p class="pl-6">
|
<p class="pl-6">
|
||||||
{{ $t("code") }}
|
{{ $t("code") }}
|
||||||
</p>
|
</p>
|
||||||
<input
|
<input v-model="userStore.vCode" :placeholder="$t('code')" type="text"
|
||||||
v-model="userStore.vCode"
|
class="border-2 border-block placeholder:text-gray dark:placeholder:text-button-disabled text-bg-dark dark:text-bg-light rounded-lg px-6 h-[50px] sm:h-[67px] w-full focus:outline-none focus:ring-0 focus:border-2">
|
||||||
:placeholder="$t('code')"
|
|
||||||
type="text"
|
|
||||||
class="border-2 border-block placeholder:text-gray dark:placeholder:text-button-disabled text-bg-dark dark:text-bg-light rounded-lg px-6 h-[50px] sm:h-[67px] w-full focus:outline-none focus:ring-0 focus:border-2"
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="py-[25px] sm:py-12 flex justify-center w-full">
|
<div class="py-[25px] sm:py-12 flex justify-center w-full">
|
||||||
<UiButtonArrow
|
<UiButtonArrow type="fill" :arrow="true" @click="userStore.sendFormCode(true)">
|
||||||
type="fill"
|
|
||||||
:arrow="true"
|
|
||||||
@click="userStore.sendFormCode(true)"
|
|
||||||
>
|
|
||||||
{{ $t("confirm") }}
|
{{ $t("confirm") }}
|
||||||
</UiButtonArrow>
|
</UiButtonArrow>
|
||||||
</div>
|
</div>
|
||||||
@ -140,7 +105,6 @@ defineProps<{
|
|||||||
is_no_lang: boolean
|
is_no_lang: boolean
|
||||||
page_name: string
|
page_name: string
|
||||||
front_section_lang: {
|
front_section_lang: {
|
||||||
data: {}
|
|
||||||
id_front_section: number
|
id_front_section: number
|
||||||
id_lang: number
|
id_lang: number
|
||||||
}[]
|
}[]
|
||||||
|
@ -1,54 +1,40 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<nuxt-link
|
<nuxt-link :to="{
|
||||||
:to="{
|
name: `id-slug___${$i18n.locale}`,
|
||||||
name: `id-slug___${$i18n.locale}`,
|
params: {
|
||||||
params: {
|
id: menuStore.getProductMenu()?.id,
|
||||||
id: menuStore.getProductMenu()?.id,
|
slug: menuStore.getProductMenu()?.front_menu_lang.at(0)?.link_rewrite,
|
||||||
slug: menuStore.getProductMenu()?.front_menu_lang.at(0)?.link_rewrite,
|
},
|
||||||
},
|
query: {
|
||||||
query: {
|
prod_id: product.id,
|
||||||
prod_id: props.product?.id,
|
name: product.link_rewrite,
|
||||||
name: props.product?.link_rewrite,
|
},
|
||||||
},
|
}">
|
||||||
}"
|
|
||||||
>
|
|
||||||
<div
|
<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]"
|
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"
|
||||||
<img
|
class="h-[95px] sm:h-[180px] md:h-[205px] rounded-[5px]" @error="handleImageError" />
|
||||||
: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
|
<div class="flex flex-col justify-between h-full w-full gap-[7px] sm:gap-[15px]">
|
||||||
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">
|
<div class="flex flex-col gap-[7px] sm:gap-[15px] w-full">
|
||||||
<h3
|
<h3
|
||||||
class="text-[10px] sm:text-base md:text-lg text-xl font-bold leading-[130%] sm:leading-[150%] text-bg-dark"
|
class="text-[10px] sm:text-base md:text-lg text-xl font-bold leading-[130%] sm:leading-[150%] text-bg-dark">
|
||||||
>
|
{{ product.name }}
|
||||||
{{ props.product?.name }}
|
|
||||||
</h3>
|
</h3>
|
||||||
<p class="text-[9px] sm:text-[12px] text-sm text-bg-dark">
|
<p class="text-[9px] sm:text-[12px] text-sm text-bg-dark">
|
||||||
{{ props.product?.tax_name }}
|
{{ product.tax_name }}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<p
|
<p
|
||||||
class="text-accent-green-light font-inter text-[12px] sm:text-[21px] md:text-2xl leading-[150%] font-bold"
|
class="text-accent-green-light font-inter text-[12px] sm:text-[21px] md:text-2xl leading-[150%] font-bold">
|
||||||
>
|
{{ product.formatted_price }}
|
||||||
{{ props.product?.formatted_price }}
|
|
||||||
</p>
|
</p>
|
||||||
<button
|
<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"
|
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.self="productStore.incrementCartItem(props.product?.id)"
|
@click.stop.prevent="productStore.incrementCartItem(product.id)">
|
||||||
>
|
<i class="uil uil-shopping-cart text-lg sm:text-2xl md:text-[31px]" />
|
||||||
<i
|
|
||||||
class="uil uil-shopping-cart text-lg sm:text-2xl md:text-[31px] cursor-pointer"
|
|
||||||
/>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -58,17 +44,22 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const props = defineProps({
|
interface Product {
|
||||||
product: Object,
|
id: number
|
||||||
})
|
name: string
|
||||||
|
link_rewrite: string
|
||||||
|
tax_name: string
|
||||||
|
formatted_price: string
|
||||||
|
cover_picture_uuid: string
|
||||||
|
}
|
||||||
|
|
||||||
|
defineProps<{ product: Product }>()
|
||||||
|
|
||||||
const productStore = useProductStore()
|
const productStore = useProductStore()
|
||||||
const menuStore = useMenuStore()
|
const menuStore = useMenuStore()
|
||||||
|
|
||||||
const isError = ref(false);
|
|
||||||
|
|
||||||
function handleImageError(event: Event) {
|
function handleImageError(event: Event) {
|
||||||
isError.value = true;
|
const img = event.target as HTMLImageElement
|
||||||
(event.target as HTMLImageElement).src = '/photo.svg';
|
img.src = '/photo.svg'
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -248,17 +248,6 @@ const goRight = () => {
|
|||||||
curImage.value = product.value.picture_uuids[0]
|
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>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -8,89 +8,50 @@
|
|||||||
<div class="xl:hidden flex items-center w-full">
|
<div class="xl:hidden flex items-center w-full">
|
||||||
<button
|
<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"
|
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
|
Otevřené kategorie a filtry
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Transition>
|
<Transition>
|
||||||
<div v-if="openCategories"
|
<div v-if="openCategories" class="min-w-[250px] px-5 sm:p-0 xl:hidden">
|
||||||
class="min-w-[250px] px-5 sm:p-0 xl:hidden"
|
<h1 class="font-bounded leading-[140%] font-bold text-[24px] mb-[25px]">
|
||||||
>
|
|
||||||
<h1
|
|
||||||
class="font-bounded leading-[140%] font-bold text-[24px] mb-[25px]"
|
|
||||||
>
|
|
||||||
{{ $t("category") }}
|
{{ $t("category") }}
|
||||||
</h1>
|
</h1>
|
||||||
<div class="flex flex-col gap-[25px]">
|
<div class="flex flex-col gap-[25px]">
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div v-if="categoriesList && categoriesList.length < 1" class="animate-pulse">
|
||||||
v-if="categoriesList && categoriesList.length < 1"
|
<div class="flex items-center justify-between mt-4 text-white rounded-lg cursor-pointer xl:pr-24">
|
||||||
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-32 h-4 bg-gray-200 rounded" />
|
||||||
<div class="w-4 h-4 bg-gray-200 rounded-full" />
|
<div class="w-4 h-4 bg-gray-200 rounded-full" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<CategoryTree
|
<CategoryTree :data="categoriesList" :active="categoryId" @change-category="changeCategory($event)" />
|
||||||
:data="categoriesList"
|
|
||||||
:active="categoryId"
|
|
||||||
@change-category="changeCategory($event)"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p
|
<p class="mb-[25px] text-lg font-extrabold text-black dark:text-white">
|
||||||
class="mb-[25px] text-lg font-extrabold text-black dark:text-white"
|
|
||||||
>
|
|
||||||
{{ $t("filtered_by") }}
|
{{ $t("filtered_by") }}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div
|
<div v-for="(item, itemIndex) in filters" :key="itemIndex" :class="[
|
||||||
v-for="(item, itemIndex) in filters"
|
'mb-[30px]',
|
||||||
:key="itemIndex"
|
visibleFeatures[item.feature] && 'border-b border-block pb-2',
|
||||||
:class="[
|
]">
|
||||||
'mb-[30px]',
|
<span class="flex justify-between items-center font-bold cursor-pointer mb-[25px] text-base"
|
||||||
visibleFeatures[item.feature] && 'border-b border-block pb-2',
|
@click="toggleFeature(item.feature)">
|
||||||
]"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="flex justify-between items-center font-bold cursor-pointer mb-[25px] text-base"
|
|
||||||
@click="toggleFeature(item.feature)"
|
|
||||||
>
|
|
||||||
{{ item.feature }}
|
{{ item.feature }}
|
||||||
<span
|
<span :class="[
|
||||||
:class="[
|
visibleFeatures[item.feature] && 'rotate-180',
|
||||||
visibleFeatures[item.feature] && 'rotate-180',
|
'transition-all',
|
||||||
'transition-all',
|
]"><i class="iconify i-lucide:chevron-down text-button shrink-0 size-6 ms-auto" /></span>
|
||||||
]"
|
|
||||||
><i
|
|
||||||
class="iconify i-lucide:chevron-down text-button shrink-0 size-6 ms-auto"
|
|
||||||
/></span>
|
|
||||||
</span>
|
</span>
|
||||||
<ul
|
<ul v-show="visibleFeatures[item.feature]" class="flex flex-col gap-5">
|
||||||
v-show="visibleFeatures[item.feature]"
|
<li v-for="filter in item.feature_values" :key="filter.value_id"
|
||||||
class="flex flex-col gap-5"
|
class="flex items-center gap-[10px] cursor-pointer">
|
||||||
>
|
<input :id="`${filter.value_id}`" v-model="selectedFilters"
|
||||||
<li
|
:value="`${filter.parent}.${filter.value_id}`" type="checkbox" class="border-button !bg-inherit">
|
||||||
v-for="filter in item.feature_values"
|
<label :for="`${filter.value_id}`"
|
||||||
:key="filter.value_id"
|
class="cursor-pointer flex items-center justify-between w-full text-base">
|
||||||
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>{{ filter.value }}</span>
|
||||||
<span>12</span>
|
<span>12</span>
|
||||||
</label>
|
</label>
|
||||||
@ -109,22 +70,13 @@
|
|||||||
</h1>
|
</h1>
|
||||||
<div class="flex flex-col gap-12">
|
<div class="flex flex-col gap-12">
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div v-if="categoriesList && categoriesList.length < 1" class="animate-pulse">
|
||||||
v-if="categoriesList && categoriesList.length < 1"
|
<div class="flex items-center justify-between mt-4 text-white rounded-lg cursor-pointer xl:pr-24">
|
||||||
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-32 h-4 bg-gray-200 rounded" />
|
||||||
<div class="w-4 h-4 bg-gray-200 rounded-full" />
|
<div class="w-4 h-4 bg-gray-200 rounded-full" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<CategoryTree
|
<CategoryTree :data="categoriesList" :active="categoryId" @change-category="changeCategory($event)" />
|
||||||
:data="categoriesList"
|
|
||||||
:active="categoryId"
|
|
||||||
@change-category="changeCategory($event)"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p class="mb-10 text-2xl font-extrabold text-black dark:text-white">
|
<p class="mb-10 text-2xl font-extrabold text-black dark:text-white">
|
||||||
@ -139,52 +91,28 @@
|
|||||||
</div>
|
</div>
|
||||||
</div> -->
|
</div> -->
|
||||||
|
|
||||||
<div
|
<div v-for="(item, itemIndex) in filters" :key="itemIndex" :class="[
|
||||||
v-for="(item, itemIndex) in filters"
|
'mb-[30px]',
|
||||||
:key="itemIndex"
|
visibleFeatures[item.feature] && 'border-b border-block pb-2',
|
||||||
:class="[
|
]">
|
||||||
'mb-[30px]',
|
<span class="flex justify-between items-center font-bold cursor-pointer mb-[25px]"
|
||||||
visibleFeatures[item.feature] && 'border-b border-block pb-2',
|
@click="toggleFeature(item.feature)">
|
||||||
]"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="flex justify-between items-center font-bold cursor-pointer mb-[25px]"
|
|
||||||
@click="toggleFeature(item.feature)"
|
|
||||||
>
|
|
||||||
{{ item.feature }}
|
{{ item.feature }}
|
||||||
<span
|
<span :class="[
|
||||||
:class="[
|
visibleFeatures[item.feature] && 'rotate-180',
|
||||||
visibleFeatures[item.feature] && 'rotate-180',
|
'transition-all',
|
||||||
'transition-all',
|
]"><i class="iconify i-lucide:chevron-down text-button shrink-0 size-6 ms-auto" /></span>
|
||||||
]"
|
|
||||||
><i
|
|
||||||
class="iconify i-lucide:chevron-down text-button shrink-0 size-6 ms-auto"
|
|
||||||
/></span>
|
|
||||||
</span>
|
</span>
|
||||||
<ul
|
<ul v-show="visibleFeatures[item.feature]" class="flex flex-col gap-5">
|
||||||
v-show="visibleFeatures[item.feature]"
|
<li v-for="filter in item.feature_values" :key="filter.value_id"
|
||||||
class="flex flex-col gap-5"
|
class="flex items-center gap-[10px] cursor-pointer">
|
||||||
>
|
|
||||||
<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}`"
|
<!-- <input :id="`${filter.value_id}`" :value="`${filter.parent}.${filter.value_id}`"
|
||||||
v-model="selectedFilters" type="checkbox" class="border-button !bg-inherit" />
|
v-model="selectedFilters" type="checkbox" class="border-button !bg-inherit" />
|
||||||
<label :for="`${filter.value_id}`" class="cursor-pointer">{{ filter.value }}</label> -->
|
<label :for="`${filter.value_id}`" class="cursor-pointer">{{ filter.value }}</label> -->
|
||||||
|
|
||||||
<input
|
<input :id="`${filter.value_id}`" v-model="selectedFilters"
|
||||||
:id="`${filter.value_id}`"
|
:value="`${filter.parent}.${filter.value_id}`" type="checkbox" class="border-button !bg-inherit">
|
||||||
v-model="selectedFilters"
|
<label :for="`${filter.value_id}`" class="cursor-pointer flex items-center justify-between w-full">
|
||||||
: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>{{ filter.value }}</span>
|
||||||
<span>12</span>
|
<span>12</span>
|
||||||
</label>
|
</label>
|
||||||
@ -197,57 +125,33 @@
|
|||||||
|
|
||||||
<div class="w-full space-y-10">
|
<div class="w-full space-y-10">
|
||||||
<!-- pop-up -->
|
<!-- pop-up -->
|
||||||
<div
|
<div v-if="isInfo"
|
||||||
v-if="isInfo"
|
class="w-full xl:w-[70%] mx-auto border-y border-block py-[15px] sm:p-[30px] flex gap-[55px] relative">
|
||||||
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"
|
||||||
<UButton
|
size="xl" icon="i-lucide-x" @click="closeElement()" />
|
||||||
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 sm:flex-row gap-[25px]">
|
||||||
<div class="flex flex-col justify-between gap-[25px]">
|
<div class="flex flex-col justify-between gap-[25px]">
|
||||||
<h4
|
<h4 class="font-inter text-lg sm:text-[24px] leading-[150%] md:leading-[120%] font-bold">
|
||||||
class="font-inter text-lg sm:text-[24px] leading-[150%] md:leading-[120%] font-bold"
|
|
||||||
>
|
|
||||||
{{ component.front_section_lang[0].data.title }}
|
{{ component.front_section_lang[0].data.title }}
|
||||||
</h4>
|
</h4>
|
||||||
<p>{{ component.front_section_lang[0].data.description }}</p>
|
<p>{{ component.front_section_lang[0].data.description }}</p>
|
||||||
</div>
|
</div>
|
||||||
<img
|
<img class="max-w-[150px] mx-auto" :src="`/api/public/file/${component.img[0]}_m.webp')`">
|
||||||
class="max-w-[150px] mx-auto"
|
|
||||||
:src="`/api/public/file/${component.img[0]}_m.webp')`"
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div v-if="products.length < 1" class="grid gap-12 pt-32 pb-16 md:grid-cols-2 2xl:grid-cols-3">
|
||||||
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" /> -->
|
<!-- <TheProductSkeleton v-for="index in 6" :key="index" /> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- products -->
|
<!-- products -->
|
||||||
<div
|
<div v-else ref="loadingElement" class="flex flex-wrap justify-center gap-5 sm:gap-10">
|
||||||
v-else
|
<Product v-for="product in products" :key="product.id" :product="product" />
|
||||||
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>
|
||||||
|
|
||||||
<div v-if="reachedEnd"
|
<div v-if="reachedEnd" class="w-full flex justify-center">
|
||||||
class="w-full flex justify-center"
|
|
||||||
>
|
|
||||||
<p>
|
<p>
|
||||||
{{ $t("FrontTranslations", "You reached end of the list.") }}
|
{{ $t("FrontTranslations", "You reached end of the list.") }}
|
||||||
</p>
|
</p>
|
||||||
@ -297,7 +201,7 @@ defineProps<{
|
|||||||
|
|
||||||
const openCategories = ref(false)
|
const openCategories = ref(false)
|
||||||
const isInfo = ref<boolean>(true)
|
const isInfo = ref<boolean>(true)
|
||||||
const selectedFilters = ref<any>([])
|
const selectedFilters = ref<string[]>([])
|
||||||
const categoryId = ref<number>(1)
|
const categoryId = ref<number>(1)
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
@ -482,7 +386,12 @@ async function loadMoreProducts() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const changeCategory = (item: any) => {
|
interface CategoryItem {
|
||||||
|
id: number
|
||||||
|
name: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const changeCategory = (item: CategoryItem) => {
|
||||||
categoryId.value = item.id
|
categoryId.value = item.id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,26 +1,25 @@
|
|||||||
import type { GenericResponse, GenericResponseItems, UserCart } from "~/types";
|
import { validation } from '../utils/validation'
|
||||||
|
import { REGEX_PHONE } from '../utils/regex'
|
||||||
|
import type { GenericResponse, GenericResponseItems, UserCart } from '~/types'
|
||||||
import type {
|
import type {
|
||||||
Address,
|
|
||||||
AddressesList,
|
AddressesList,
|
||||||
CheckoutOrder,
|
CheckoutOrder,
|
||||||
Payment,
|
Payment,
|
||||||
UserAddressOfficial,
|
UserAddressOfficial,
|
||||||
} from "~/types/checkout";
|
} from '~/types/checkout'
|
||||||
import { validation } from "../utils/validation";
|
import type { CartProduct } from '~/types/product'
|
||||||
import { REGEX_PHONE } from "../utils/regex";
|
|
||||||
import type { CartProduct } from "~/types/product";
|
|
||||||
|
|
||||||
export const useCheckoutStore = defineStore("checkoutStore", () => {
|
export const useCheckoutStore = defineStore('checkoutStore', () => {
|
||||||
const { $toast } = useNuxtApp();
|
const { $toast } = useNuxtApp()
|
||||||
const menuStore = useMenuStore();
|
const menuStore = useMenuStore()
|
||||||
|
|
||||||
const selectedIso = ref(menuStore.selectedCountry);
|
const selectedIso = ref(menuStore.selectedCountry)
|
||||||
|
|
||||||
const vLegal = ref(false);
|
const vLegal = ref(false)
|
||||||
const vTerms = ref(false);
|
const vTerms = ref(false)
|
||||||
const vNote = ref("");
|
const vNote = ref('')
|
||||||
const legalValidation = ref(false);
|
const legalValidation = ref(false)
|
||||||
const termsValidation = ref(false);
|
const termsValidation = ref(false)
|
||||||
|
|
||||||
// get address list
|
// get address list
|
||||||
const addressesList = ref<AddressesList[]>()
|
const addressesList = ref<AddressesList[]>()
|
||||||
@ -154,7 +153,7 @@ export const useCheckoutStore = defineStore("checkoutStore", () => {
|
|||||||
const phoneValidation = ref<boolean | null>(null)
|
const phoneValidation = ref<boolean | null>(null)
|
||||||
|
|
||||||
// send checkout form
|
// send checkout form
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore()
|
||||||
async function sendForm() {
|
async function sendForm() {
|
||||||
const phoneNum = vUseAccountPhoneNumber.value
|
const phoneNum = vUseAccountPhoneNumber.value
|
||||||
? accountPhoneNumber.value
|
? accountPhoneNumber.value
|
||||||
@ -197,18 +196,19 @@ export const useCheckoutStore = defineStore("checkoutStore", () => {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
console.log(res);
|
console.log(res)
|
||||||
|
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
$toast.success('Form successfully sent', {
|
$toast.success('Form successfully sent', {
|
||||||
autoClose: 5000,
|
autoClose: 5000,
|
||||||
dangerouslyHTMLString: true,
|
dangerouslyHTMLString: true,
|
||||||
});
|
})
|
||||||
menuStore.navigateToItem(
|
menuStore.navigateToItem(
|
||||||
menuStore.menuItems?.find((item) => item.id === 13)
|
menuStore.menuItems?.find(item => item.id === 13),
|
||||||
);
|
)
|
||||||
} else {
|
}
|
||||||
$toast.error("Failed to send form. Please try again.", {
|
else {
|
||||||
|
$toast.error('Failed to send form. Please try again.', {
|
||||||
autoClose: 5000,
|
autoClose: 5000,
|
||||||
dangerouslyHTMLString: true,
|
dangerouslyHTMLString: true,
|
||||||
})
|
})
|
||||||
@ -219,10 +219,6 @@ export const useCheckoutStore = defineStore("checkoutStore", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const changeActive = (item: any) => {
|
|
||||||
activeAddress.value = item
|
|
||||||
}
|
|
||||||
|
|
||||||
// get checkout
|
// get checkout
|
||||||
async function getCheckout() {
|
async function getCheckout() {
|
||||||
try {
|
try {
|
||||||
@ -279,99 +275,80 @@ export const useCheckoutStore = defineStore("checkoutStore", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get delivery options
|
// get delivery options
|
||||||
const deliveryOption = ref()
|
interface DeliveryOptionItem {
|
||||||
const currentDelivery = ref()
|
country_iso: string
|
||||||
const shippingPrice = ref()
|
country_name: string
|
||||||
|
delivery_supplier_id: number
|
||||||
|
delivery_supplier_name: string
|
||||||
|
id: number
|
||||||
|
shippment_price: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const deliveryOption = ref<DeliveryOptionItem[]>([])
|
||||||
|
const currentDelivery = ref<DeliveryOptionItem | null>(null)
|
||||||
|
const shippingPrice = ref<number>(0)
|
||||||
|
|
||||||
async function getDeliveryOptions() {
|
async function getDeliveryOptions() {
|
||||||
try {
|
try {
|
||||||
const res = await useMyFetch<
|
const { data } = await useMyFetch<GenericResponseItems<DeliveryOptionItem[]>>(
|
||||||
GenericResponseItems<object>
|
`/api/restricted/cart/checkout/delivery-options`,
|
||||||
// {
|
{
|
||||||
// items: [
|
headers: {
|
||||||
// {
|
'Content-Type': 'application/json',
|
||||||
// country_iso: string;
|
|
||||||
// country_name: string;
|
|
||||||
// delivery_supplier_id: number;
|
|
||||||
// delivery_supplier_name: string;
|
|
||||||
// id: number;
|
|
||||||
// shippment_price: string;
|
|
||||||
// }
|
|
||||||
// ];
|
|
||||||
// }
|
|
||||||
>(`/api/restricted/cart/checkout/delivery-options`, {
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
onErrorOccured: async (_, status) => {
|
|
||||||
throw createError({
|
|
||||||
statusCode: status,
|
|
||||||
statusMessage: `HTTP error: ${status}`,
|
|
||||||
})
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const data = {
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
id: 31,
|
|
||||||
shippment_price: "2",
|
|
||||||
delivery_supplier_id: 4,
|
|
||||||
delivery_supplier_name: "Personal collection",
|
|
||||||
country_iso: "pl",
|
|
||||||
country_name: "Poland",
|
|
||||||
},
|
},
|
||||||
{
|
onErrorOccured: async (_, status) => {
|
||||||
id: 34,
|
throw createError({
|
||||||
shippment_price: "20",
|
statusCode: status,
|
||||||
delivery_supplier_id: 1,
|
statusMessage: `HTTP error: ${status}`,
|
||||||
delivery_supplier_name: "Ceska Posta",
|
})
|
||||||
country_iso: "pl",
|
|
||||||
country_name: "Poland",
|
|
||||||
},
|
},
|
||||||
],
|
},
|
||||||
items_count: 2,
|
)
|
||||||
};
|
|
||||||
|
|
||||||
deliveryOption.value = data.items;
|
if (data.items && data.items.length > 0) {
|
||||||
currentDelivery.value = data.items[0];
|
deliveryOption.value = data.items
|
||||||
shippingPrice.value = data.items[0].shippment_price;
|
currentDelivery.value = data.items[0]
|
||||||
fullPrice.value = Number(fullPrice.value) + Number(shippingPrice.value);
|
shippingPrice.value = Number(data.items[0].shippment_price)
|
||||||
} catch (error) {
|
fullPrice.value += shippingPrice.value
|
||||||
console.error("getUserCart error:", error);
|
}
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.error('getDeliveryOptions error:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const setCurrentDelivery = (item: any) => {
|
const setCurrentDelivery = (item: DeliveryOptionItem) => {
|
||||||
shippingPrice.value = item.shippment_price;
|
shippingPrice.value = Number(item.shippment_price)
|
||||||
currentDelivery.value = item;
|
currentDelivery.value = item
|
||||||
fullPrice.value = Number(fullPrice.value) + Number(shippingPrice.value);
|
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() {
|
async function getDefAddress() {
|
||||||
try {
|
try {
|
||||||
const { data } = await useMyFetch<
|
const { data } = await useMyFetch<GenericResponse<{ addresses: Address[] }>>(
|
||||||
GenericResponse<{
|
`/api/public/user`,
|
||||||
addresses: [
|
{
|
||||||
{
|
headers: {
|
||||||
is_default: string
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
]
|
onErrorOccured: async (_, status) => {
|
||||||
}>
|
throw createError({
|
||||||
>(`/api/public/user`, {
|
statusCode: status,
|
||||||
headers: {
|
statusMessage: `HTTP error: ${status}`,
|
||||||
'Content-Type': 'application/json',
|
})
|
||||||
|
},
|
||||||
},
|
},
|
||||||
onErrorOccured: async (_, status) => {
|
)
|
||||||
throw createError({
|
|
||||||
statusCode: status,
|
|
||||||
statusMessage: `HTTP error: ${status}`,
|
|
||||||
})
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
defaultAddress.value = data.addresses.find(
|
defaultAddress.value = data.addresses.find(
|
||||||
(el: any) => el.is_default === true,
|
el => el.is_default === true || el.is_default === 'true',
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
@ -380,30 +357,31 @@ export const useCheckoutStore = defineStore("checkoutStore", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get bank data
|
// get bank data
|
||||||
const paymentMethods = ref([] as Payment[]);
|
const paymentMethods = ref([] as Payment[])
|
||||||
const fullAddress = ref<Address>();
|
const fullAddress = ref<Address>()
|
||||||
const currentPayment = ref<Payment | null>();
|
const currentPayment = ref<Payment | null>()
|
||||||
async function getBankAccount() {
|
async function getBankAccount() {
|
||||||
try {
|
try {
|
||||||
const { data } = await useMyFetch<GenericResponse<Payment[]>>(
|
const { data } = await useMyFetch<GenericResponse<Payment[]>>(
|
||||||
`/api/restricted/suitable-bank-accounts/${menuStore.selectedCurrency.iso_code}/${fullAddress.value?.country_iso}`,
|
`/api/restricted/suitable-bank-accounts/${menuStore.selectedCurrency.iso_code}/${fullAddress.value?.country_iso}`,
|
||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
onErrorOccured: async (_, status) => {
|
onErrorOccured: async (_, status) => {
|
||||||
throw createError({
|
throw createError({
|
||||||
statusCode: status,
|
statusCode: status,
|
||||||
statusMessage: `HTTP error: ${status}`,
|
statusMessage: `HTTP error: ${status}`,
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
)
|
||||||
|
|
||||||
paymentMethods.value = data;
|
paymentMethods.value = data
|
||||||
currentPayment.value = data[0];
|
currentPayment.value = data[0]
|
||||||
} catch (error) {
|
}
|
||||||
console.error("getUserCart error:", error);
|
catch (error) {
|
||||||
|
console.error('getUserCart error:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -414,131 +392,132 @@ export const useCheckoutStore = defineStore("checkoutStore", () => {
|
|||||||
`/api/restricted/cart/checkout/order`,
|
`/api/restricted/cart/checkout/order`,
|
||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
onErrorOccured: async (_, status) => {
|
onErrorOccured: async (_, status) => {
|
||||||
throw createError({
|
throw createError({
|
||||||
statusCode: status,
|
statusCode: status,
|
||||||
statusMessage: `HTTP error: ${status}`,
|
statusMessage: `HTTP error: ${status}`,
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
)
|
||||||
|
|
||||||
fullAddress.value = data.delivery_details.address;
|
fullAddress.value = data.delivery_details.address
|
||||||
console.log(fullAddress.value);
|
}
|
||||||
} catch (error) {
|
catch (error) {
|
||||||
console.error("getOrder error:", error);
|
console.error('getOrder error:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function setNewAddress(indexItem: number) {
|
async function setNewAddress(indexItem: number) {
|
||||||
currentPayment.value = paymentMethods.value.find(
|
currentPayment.value = paymentMethods.value.find(
|
||||||
(item, index) => indexItem === index
|
(item, index) => indexItem === index,
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// send summary form
|
// send summary form
|
||||||
async function sendSummaryForm() {
|
async function sendSummaryForm() {
|
||||||
vLegal.value
|
legalValidation.value = !vLegal.value
|
||||||
? (legalValidation.value = false)
|
termsValidation.value = !vTerms.value
|
||||||
: (legalValidation.value = true);
|
|
||||||
vTerms.value
|
|
||||||
? (termsValidation.value = false)
|
|
||||||
: (termsValidation.value = true);
|
|
||||||
if (!vTerms.value && !vLegal.value) {
|
if (!vTerms.value && !vLegal.value) {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await useMyFetch<GenericResponse<object>>(
|
await useMyFetch<GenericResponse<object>>(
|
||||||
`/api/restricted/cart/checkout/delivery`,
|
`/api/restricted/cart/checkout/delivery`,
|
||||||
{
|
{
|
||||||
method: "PUT",
|
method: 'PUT',
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
accept_general_conditions: true,
|
accept_general_conditions: true,
|
||||||
accept_long_purchase: true,
|
accept_long_purchase: true,
|
||||||
address: fullAddress.value,
|
address: fullAddress.value,
|
||||||
delivery_option_id: currentDelivery.value.id,
|
delivery_option_id: currentDelivery.value?.id,
|
||||||
note: vNote.value,
|
note: vNote.value,
|
||||||
}),
|
}),
|
||||||
onErrorOccured: async (_, status) => {
|
onErrorOccured: async (_, status) => {
|
||||||
throw createError({
|
throw createError({
|
||||||
statusCode: status,
|
statusCode: status,
|
||||||
statusMessage: `HTTP error: ${status}`,
|
statusMessage: `HTTP error: ${status}`,
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
)
|
||||||
|
|
||||||
await putCheckoutBankAccount();
|
await putCheckoutBankAccount()
|
||||||
await markOrder();
|
await markOrder()
|
||||||
await getUserCart();
|
await getUserCart()
|
||||||
} catch (error) {
|
}
|
||||||
console.error("uploadAddress error:", error);
|
catch (error) {
|
||||||
|
console.error('uploadAddress error:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// put checkout bank-account
|
// put checkout bank-account
|
||||||
async function putCheckoutBankAccount() {
|
async function putCheckoutBankAccount() {
|
||||||
try {
|
try {
|
||||||
const res = await useMyFetch<GenericResponse<object>>(
|
await useMyFetch<GenericResponse<object>>(
|
||||||
`/api/restricted/cart/checkout/bank-account/${currentPayment.value?.id}`,
|
`/api/restricted/cart/checkout/bank-account/${currentPayment.value?.id}`,
|
||||||
{
|
{
|
||||||
method: "PUT",
|
method: 'PUT',
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
onErrorOccured: async (_, status) => {
|
onErrorOccured: async (_, status) => {
|
||||||
throw createError({
|
throw createError({
|
||||||
statusCode: status,
|
statusCode: status,
|
||||||
statusMessage: `HTTP error: ${status}`,
|
statusMessage: `HTTP error: ${status}`,
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
)
|
||||||
} catch (error) {
|
}
|
||||||
console.error("uploadAddress error:", error);
|
catch (error) {
|
||||||
|
console.error('uploadAddress error:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const modalMadeOrder = ref(false);
|
const modalMadeOrder = ref(false)
|
||||||
async function markOrder() {
|
async function markOrder() {
|
||||||
try {
|
try {
|
||||||
const res = await useMyFetch<GenericResponse<object>>(
|
const res = await useMyFetch<GenericResponse<object>>(
|
||||||
`/api/restricted/cart/checkout/order`,
|
`/api/restricted/cart/checkout/order`,
|
||||||
{
|
{
|
||||||
method: "POST",
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
onErrorOccured: async (_, status) => {
|
onErrorOccured: async (_, status) => {
|
||||||
throw createError({
|
throw createError({
|
||||||
statusCode: status,
|
statusCode: status,
|
||||||
statusMessage: `HTTP error: ${status}`,
|
statusMessage: `HTTP error: ${status}`,
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
)
|
||||||
|
|
||||||
if (res.status === 200 || res.status === 201) {
|
if (res.status === 200 || res.status === 201) {
|
||||||
$toast.success("Address successfully added", {
|
$toast.success('Address successfully added', {
|
||||||
autoClose: 5000,
|
autoClose: 5000,
|
||||||
dangerouslyHTMLString: true,
|
dangerouslyHTMLString: true,
|
||||||
});
|
})
|
||||||
modalMadeOrder.value = true;
|
modalMadeOrder.value = true
|
||||||
} else {
|
}
|
||||||
$toast.error("Failed to add address. Please try again.", {
|
else {
|
||||||
|
$toast.error('Failed to add address. Please try again.', {
|
||||||
autoClose: 5000,
|
autoClose: 5000,
|
||||||
dangerouslyHTMLString: true,
|
dangerouslyHTMLString: true,
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
// window.location.href = `/golden-panel/my-purchases/${res._data?.data.id}`;
|
// window.location.href = `/golden-panel/my-purchases/${res._data?.data.id}`;
|
||||||
} catch (error) {
|
}
|
||||||
console.error("uploadAddress error:", error);
|
catch (error) {
|
||||||
|
console.error('uploadAddress error:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
@ -575,6 +554,7 @@ export const useCheckoutStore = defineStore("checkoutStore", () => {
|
|||||||
defaultAddress,
|
defaultAddress,
|
||||||
paymentMethods,
|
paymentMethods,
|
||||||
currentPayment,
|
currentPayment,
|
||||||
|
fullAddress,
|
||||||
|
|
||||||
vLegal,
|
vLegal,
|
||||||
vTerms,
|
vTerms,
|
||||||
@ -587,7 +567,6 @@ export const useCheckoutStore = defineStore("checkoutStore", () => {
|
|||||||
getCheckout,
|
getCheckout,
|
||||||
getAddressList,
|
getAddressList,
|
||||||
getUserData,
|
getUserData,
|
||||||
changeActive,
|
|
||||||
uploadAddress,
|
uploadAddress,
|
||||||
sendForm,
|
sendForm,
|
||||||
getUserCart,
|
getUserCart,
|
||||||
@ -598,5 +577,5 @@ export const useCheckoutStore = defineStore("checkoutStore", () => {
|
|||||||
getOrder,
|
getOrder,
|
||||||
setNewAddress,
|
setNewAddress,
|
||||||
sendSummaryForm,
|
sendSummaryForm,
|
||||||
};
|
}
|
||||||
});
|
})
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { useStore } from "./store";
|
import { useStore } from './store'
|
||||||
import type {
|
import type {
|
||||||
Country,
|
Country,
|
||||||
Currency,
|
Currency,
|
||||||
@ -7,78 +7,78 @@ import type {
|
|||||||
GenericResponseItems,
|
GenericResponseItems,
|
||||||
Language,
|
Language,
|
||||||
UIFrontMenu,
|
UIFrontMenu,
|
||||||
} from "~/types";
|
} from '~/types'
|
||||||
import { useMyFetch } from "#imports";
|
import { useMyFetch } from '#imports'
|
||||||
|
|
||||||
function buildTreeRecursive(
|
function buildTreeRecursive(
|
||||||
data: (FrontMenu | UIFrontMenu)[],
|
data: (FrontMenu | UIFrontMenu)[],
|
||||||
parentId: number
|
parentId: number,
|
||||||
): UIFrontMenu[] {
|
): UIFrontMenu[] {
|
||||||
const children = data.filter(
|
const children = data.filter(
|
||||||
(item): item is UIFrontMenu =>
|
(item): item is UIFrontMenu =>
|
||||||
item.id_parent === parentId && !item.is_default
|
item.id_parent === parentId && !item.is_default,
|
||||||
);
|
)
|
||||||
|
|
||||||
return children.map((item) => ({
|
return children.map(item => ({
|
||||||
...item,
|
...item,
|
||||||
children: buildTreeRecursive(data, item.id),
|
children: buildTreeRecursive(data, item.id),
|
||||||
}));
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useMenuStore = defineStore("menuStore", () => {
|
export const useMenuStore = defineStore('menuStore', () => {
|
||||||
const store = useStore();
|
const store = useStore()
|
||||||
const { $i18n } = useNuxtApp();
|
const { $i18n } = useNuxtApp()
|
||||||
// const session = useSession();
|
// const session = useSession();
|
||||||
const { $session } = useNuxtApp();
|
const { $session } = useNuxtApp()
|
||||||
const router = useRouter();
|
const router = useRouter()
|
||||||
const route = useRoute();
|
const route = useRoute()
|
||||||
|
|
||||||
const openMenu = ref(false);
|
const openMenu = ref(false)
|
||||||
const openDropDown = ref(false);
|
const openDropDown = ref(false)
|
||||||
|
|
||||||
const defaultMenu = ref();
|
const defaultMenu = ref()
|
||||||
|
|
||||||
const menu = ref([] as UIFrontMenu[]);
|
const menu = ref([] as UIFrontMenu[])
|
||||||
const menuItems = ref([] as FrontMenu[]);
|
const menuItems = ref([] as FrontMenu[])
|
||||||
|
|
||||||
// curr/country
|
// curr/country
|
||||||
const selectedCountry = ref({} as Country);
|
const selectedCountry = ref({} as Country)
|
||||||
const selectedPhoneCountry = ref({} as Country);
|
const selectedPhoneCountry = ref({} as Country)
|
||||||
const selectedCurrency = ref({} as Currency);
|
const selectedCurrency = ref({} as Currency)
|
||||||
const selectedLanguage = ref({} as Language);
|
const selectedLanguage = ref({} as Language)
|
||||||
|
|
||||||
const countries = ref([] as Country[]);
|
const countries = ref([] as Country[])
|
||||||
const currencies = ref([] as Currency[]);
|
const currencies = ref([] as Currency[])
|
||||||
const languages = ref([] as Language[]);
|
const languages = ref([] as Language[])
|
||||||
|
|
||||||
const getLocales = async () => {
|
const getLocales = async () => {
|
||||||
const { data: countriesList } = await useMyFetch<
|
const { data: countriesList } = await useMyFetch<
|
||||||
GenericResponse<Country[]>
|
GenericResponse<Country[]>
|
||||||
>(`/api/public/country/list`);
|
>(`/api/public/country/list`)
|
||||||
countries.value = countriesList;
|
countries.value = countriesList
|
||||||
selectedCountry.value = countriesList.find(
|
selectedCountry.value = countriesList.find(
|
||||||
(country) => country.iso_code === $session.currentCountryIso.value
|
country => country.iso_code === $session.currentCountryIso.value,
|
||||||
) as Country;
|
) as Country
|
||||||
selectedPhoneCountry.value = countriesList.find(
|
selectedPhoneCountry.value = countriesList.find(
|
||||||
(country) => country.iso_code === $session.currentCountryIso.value
|
country => country.iso_code === $session.currentCountryIso.value,
|
||||||
) as Country;
|
) as Country
|
||||||
|
|
||||||
const { data: currenciesList } = await useMyFetch<
|
const { data: currenciesList } = await useMyFetch<
|
||||||
GenericResponseItems<Currency[]>
|
GenericResponseItems<Currency[]>
|
||||||
>(`/api/public/currencies`);
|
>(`/api/public/currencies`)
|
||||||
currencies.value = currenciesList.items;
|
currencies.value = currenciesList.items
|
||||||
selectedCurrency.value = currenciesList.items.find(
|
selectedCurrency.value = currenciesList.items.find(
|
||||||
(currency) => currency.iso_code === $session.currentCurrencyIso.value
|
currency => currency.iso_code === $session.currentCurrencyIso.value,
|
||||||
) as Currency;
|
) as Currency
|
||||||
|
|
||||||
const { data: languagesList } = await useMyFetch<
|
const { data: languagesList } = await useMyFetch<
|
||||||
GenericResponseItems<Language[]>
|
GenericResponseItems<Language[]>
|
||||||
>(`/api/public/languages`);
|
>(`/api/public/languages`)
|
||||||
languages.value = languagesList.items;
|
languages.value = languagesList.items
|
||||||
selectedLanguage.value = languagesList.items.find(
|
selectedLanguage.value = languagesList.items.find(
|
||||||
(language) => language.iso_code === $session.currentLanguageIso.value
|
language => language.iso_code === $session.currentLanguageIso.value,
|
||||||
) as Language;
|
) as Language
|
||||||
};
|
}
|
||||||
|
|
||||||
const loadMenu = async () => {
|
const loadMenu = async () => {
|
||||||
try {
|
try {
|
||||||
@ -86,81 +86,84 @@ export const useMenuStore = defineStore("menuStore", () => {
|
|||||||
`/api/public/front/menu`,
|
`/api/public/front/menu`,
|
||||||
{
|
{
|
||||||
onErrorOccured: (err, status) => {
|
onErrorOccured: (err, status) => {
|
||||||
console.log(err, status);
|
console.log(err, status)
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
)
|
||||||
|
|
||||||
menuItems.value = data;
|
menuItems.value = data
|
||||||
|
|
||||||
const root = data.find((item) => item.is_root) as UIFrontMenu;
|
const root = data.find(item => item.is_root) as UIFrontMenu
|
||||||
defaultMenu.value = data.find((item) => item.is_default);
|
defaultMenu.value = data.find(item => item.is_default)
|
||||||
if (root) {
|
if (root) {
|
||||||
menu.value = buildTreeRecursive(data, root.id);
|
menu.value = buildTreeRecursive(data, root.id)
|
||||||
} else {
|
}
|
||||||
console.warn("Root menu item not found");
|
else {
|
||||||
menu.value = [];
|
console.warn('Root menu item not found')
|
||||||
|
menu.value = []
|
||||||
}
|
}
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
}
|
||||||
};
|
catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const navigateToItem = (item?: UIFrontMenu) => {
|
const navigateToItem = (item?: UIFrontMenu) => {
|
||||||
if (item) {
|
if (item) {
|
||||||
router.push({
|
router.push({
|
||||||
params: { slug: item.front_menu_lang[0].link_rewrite, id: item.id },
|
params: { slug: item.front_menu_lang[0].link_rewrite, id: item.id },
|
||||||
name: `id-slug___${$i18n.locale.value}`,
|
name: `id-slug___${$i18n.locale.value}`,
|
||||||
});
|
})
|
||||||
openDropDown.value = false;
|
openDropDown.value = false
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
router.push({
|
router.push({
|
||||||
params: {
|
params: {
|
||||||
slug: defaultMenu.value.front_menu_lang[0].link_rewrite,
|
slug: defaultMenu.value.front_menu_lang[0].link_rewrite,
|
||||||
id: defaultMenu.value.id,
|
id: defaultMenu.value.id,
|
||||||
},
|
},
|
||||||
name: `id-slug___${$i18n.locale.value}`,
|
name: `id-slug___${$i18n.locale.value}`,
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function navigateToShop() {
|
function navigateToShop() {
|
||||||
navigateToItem(menuItems.value?.find((item) => item.id === 5));
|
navigateToItem(menuItems.value?.find(item => item.id === 5))
|
||||||
}
|
}
|
||||||
|
|
||||||
function getProductMenu() {
|
function getProductMenu() {
|
||||||
return menuItems.value?.find((item) => item.id === 13);
|
return menuItems.value?.find(item => item.id === 14)
|
||||||
}
|
}
|
||||||
|
|
||||||
const getFirstImage = (size: "l" | "m" | "s" = "m", needbaseurl: boolean) => {
|
const getFirstImage = (size: 'l' | 'm' | 's' = 'm', needbaseurl: boolean) => {
|
||||||
const req = useRequestEvent();
|
const req = useRequestEvent()
|
||||||
const url = useRequestURL();
|
const url = useRequestURL()
|
||||||
// let img = "";
|
// let img = "";
|
||||||
const img: string[] = [];
|
const img: string[] = []
|
||||||
for (const s in store.components) {
|
for (const s in store.components) {
|
||||||
if (store.components[s].front_section.img.length === 0) continue;
|
if (store.components[s].front_section.img.length === 0) continue
|
||||||
img.push(
|
img.push(
|
||||||
`/api/public/file/${store.components[s].front_section.img[0]}_${size}.webp`
|
`/api/public/file/${store.components[s].front_section.img[0]}_${size}.webp`,
|
||||||
);
|
)
|
||||||
if (img.length > 0) break;
|
if (img.length > 0) break
|
||||||
}
|
}
|
||||||
if (img.length > 0) {
|
if (img.length > 0) {
|
||||||
if (needbaseurl) {
|
if (needbaseurl) {
|
||||||
return `${req?.headers.get("x-forwarded-proto") || url.protocol}://${
|
return `${req?.headers.get('x-forwarded-proto') || url.protocol}://${
|
||||||
req?.headers.get("x-forwarded-host") ||
|
req?.headers.get('x-forwarded-host')
|
||||||
url.host ||
|
|| url.host
|
||||||
req?.headers.get("host")
|
|| req?.headers.get('host')
|
||||||
}${img[0]}`;
|
}${img[0]}`
|
||||||
}
|
}
|
||||||
return img[0];
|
return img[0]
|
||||||
}
|
}
|
||||||
return "";
|
return ''
|
||||||
};
|
}
|
||||||
|
|
||||||
const headMeta = computed(() => {
|
const headMeta = computed(() => {
|
||||||
const item = menuItems.value?.find(
|
const item = menuItems.value?.find(
|
||||||
(item) => item.id.toString() === route.params.id
|
item => item.id.toString() === route.params.id,
|
||||||
);
|
)
|
||||||
|
|
||||||
const meta = {
|
const meta = {
|
||||||
title: item?.front_menu_lang[0].meta_title,
|
title: item?.front_menu_lang[0].meta_title,
|
||||||
@ -169,77 +172,77 @@ export const useMenuStore = defineStore("menuStore", () => {
|
|||||||
},
|
},
|
||||||
link: [
|
link: [
|
||||||
// { rel: "manifest", href: "/api/manifest.json" }
|
// { rel: "manifest", href: "/api/manifest.json" }
|
||||||
{ rel: "icon", type: "image/x-icon", href: "/favicon.png" },
|
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.png' },
|
||||||
],
|
],
|
||||||
script: [
|
script: [
|
||||||
{
|
{
|
||||||
src: "https://leiadmin.com/leitag.js?lei=894500UT83EISNNA8D04&color=dark",
|
src: 'https://leiadmin.com/leitag.js?lei=894500UT83EISNNA8D04&color=dark',
|
||||||
defer: true,
|
defer: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
meta: [
|
meta: [
|
||||||
{
|
{
|
||||||
hid: "description",
|
hid: 'description',
|
||||||
name: "description",
|
name: 'description',
|
||||||
content: item?.front_menu_lang[0].meta_description,
|
content: item?.front_menu_lang[0].meta_description,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
property: "og:title",
|
property: 'og:title',
|
||||||
content: item?.front_menu_lang[0].meta_title,
|
content: item?.front_menu_lang[0].meta_title,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
property: "og:description",
|
property: 'og:description',
|
||||||
content: item?.front_menu_lang[0].meta_description,
|
content: item?.front_menu_lang[0].meta_description,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
property: "og:image",
|
property: 'og:image',
|
||||||
content: getFirstImage("m", true),
|
content: getFirstImage('m', true),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
property: "twitter:title",
|
property: 'twitter:title',
|
||||||
content: item?.front_menu_lang[0].meta_title,
|
content: item?.front_menu_lang[0].meta_title,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
property: "twitter:description",
|
property: 'twitter:description',
|
||||||
content: item?.front_menu_lang[0].meta_description,
|
content: item?.front_menu_lang[0].meta_description,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
property: "twitter:image",
|
property: 'twitter:image',
|
||||||
content: getFirstImage("m", true),
|
content: getFirstImage('m', true),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
|
||||||
|
|
||||||
const preload = getFirstImage("l", false);
|
|
||||||
if (preload) {
|
|
||||||
meta.link.push({ rel: "preload", as: "image", href: preload } as never);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return meta;
|
const preload = getFirstImage('l', false)
|
||||||
});
|
if (preload) {
|
||||||
|
meta.link.push({ rel: 'preload', as: 'image', href: preload } as never)
|
||||||
|
}
|
||||||
|
|
||||||
|
return meta
|
||||||
|
})
|
||||||
|
|
||||||
const formatPrice = (value: number): string => {
|
const formatPrice = (value: number): string => {
|
||||||
return value.toLocaleString(selectedLanguage.value.iso_code, {
|
return value.toLocaleString(selectedLanguage.value.iso_code, {
|
||||||
minimumFractionDigits: selectedCurrency.value.precision,
|
minimumFractionDigits: selectedCurrency.value.precision,
|
||||||
maximumFractionDigits: selectedCurrency.value.precision,
|
maximumFractionDigits: selectedCurrency.value.precision,
|
||||||
currency: selectedCurrency.value.iso_code,
|
currency: selectedCurrency.value.iso_code,
|
||||||
style: "currency",
|
style: 'currency',
|
||||||
currencyDisplay: "symbol",
|
currencyDisplay: 'symbol',
|
||||||
currencySign: "accounting",
|
currencySign: 'accounting',
|
||||||
});
|
})
|
||||||
};
|
}
|
||||||
|
|
||||||
// watches
|
// watches
|
||||||
watch(
|
watch(
|
||||||
() => $session.cookieData,
|
() => $session.cookieData,
|
||||||
async () => {
|
async () => {
|
||||||
await getLocales();
|
await getLocales()
|
||||||
await loadMenu();
|
await loadMenu()
|
||||||
await store.getMinValue();
|
await store.getMinValue()
|
||||||
await store.getCalculator();
|
await store.getCalculator()
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true },
|
||||||
);
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
menu,
|
menu,
|
||||||
@ -261,5 +264,6 @@ export const useMenuStore = defineStore("menuStore", () => {
|
|||||||
navigateToItem,
|
navigateToItem,
|
||||||
getLocales,
|
getLocales,
|
||||||
getProductMenu,
|
getProductMenu,
|
||||||
};
|
formatPrice,
|
||||||
});
|
}
|
||||||
|
})
|
||||||
|
@ -1,18 +1,17 @@
|
|||||||
import { useMyFetch } from "#imports";
|
import { useMyFetch } from '#imports'
|
||||||
import type {
|
import type {
|
||||||
GenericResponse,
|
GenericResponse,
|
||||||
GenericResponseChildren,
|
GenericResponseChildren,
|
||||||
GenericResponseItems,
|
GenericResponseItems,
|
||||||
UserCart,
|
} from '~/types'
|
||||||
} from "~/types";
|
import type { Product } from '~/types/product'
|
||||||
import type { Product } from "~/types/product";
|
|
||||||
|
|
||||||
export const useProductStore = defineStore("productStore", () => {
|
export const useProductStore = defineStore('productStore', () => {
|
||||||
const { $toast } = useNuxtApp();
|
const { $toast } = useNuxtApp()
|
||||||
const productList = ref<Product[]>();
|
const productList = ref<Product[]>()
|
||||||
const modules = ref();
|
const modules = ref()
|
||||||
|
|
||||||
const checkoutStore = useCheckoutStore();
|
const checkoutStore = useCheckoutStore()
|
||||||
|
|
||||||
async function getList(count: number, categoryId = 1) {
|
async function getList(count: number, categoryId = 1) {
|
||||||
try {
|
try {
|
||||||
@ -20,21 +19,22 @@ export const useProductStore = defineStore("productStore", () => {
|
|||||||
`/api/public/products/category/${categoryId}?p=1&elems=${count}`,
|
`/api/public/products/category/${categoryId}?p=1&elems=${count}`,
|
||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
onErrorOccured: async (_, status) => {
|
onErrorOccured: async (_, status) => {
|
||||||
// await navigateTo("/error", { replace: true });
|
// await navigateTo("/error", { replace: true });
|
||||||
throw createError({
|
throw createError({
|
||||||
statusCode: status,
|
statusCode: status,
|
||||||
statusMessage: `HTTP error: ${status}`,
|
statusMessage: `HTTP error: ${status}`,
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
)
|
||||||
|
|
||||||
productList.value = data.items;
|
productList.value = data.items
|
||||||
} catch (error) {
|
}
|
||||||
console.error("getList error:", error);
|
catch (error) {
|
||||||
|
console.error('getList error:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,20 +44,21 @@ export const useProductStore = defineStore("productStore", () => {
|
|||||||
`/api/public/module/e_shop`,
|
`/api/public/module/e_shop`,
|
||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
onErrorOccured: (_, status) => {
|
onErrorOccured: (_, status) => {
|
||||||
throw new Error(`HTTP error: ${status}`);
|
throw new Error(`HTTP error: ${status}`)
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
)
|
||||||
|
|
||||||
modules.value = data.children.find(
|
modules.value = data.children.find(
|
||||||
(item: { id: number; name: string }) =>
|
(item: { id: number, name: string }) =>
|
||||||
item.name === "currency_rates_bar"
|
item.name === 'currency_rates_bar',
|
||||||
);
|
)
|
||||||
} catch (error) {
|
}
|
||||||
console.error("getList error:", error);
|
catch (error) {
|
||||||
|
console.error('getList error:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,34 +67,36 @@ export const useProductStore = defineStore("productStore", () => {
|
|||||||
const res = await useMyFetch<GenericResponse<object>>(
|
const res = await useMyFetch<GenericResponse<object>>(
|
||||||
`/api/public/user/cart/item/add/${id}/1`,
|
`/api/public/user/cart/item/add/${id}/1`,
|
||||||
{
|
{
|
||||||
method: "PUT",
|
method: 'PUT',
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
onErrorOccured: (_, status) => {
|
onErrorOccured: (_, status) => {
|
||||||
throw new Error(`HTTP error: ${status}`);
|
throw new Error(`HTTP error: ${status}`)
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
)
|
||||||
|
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
$toast.success("Item successfully added to your cart.", {
|
$toast.success('Item successfully added to your cart.', {
|
||||||
autoClose: 5000,
|
autoClose: 5000,
|
||||||
dangerouslyHTMLString: true,
|
dangerouslyHTMLString: true,
|
||||||
});
|
})
|
||||||
checkoutStore.getUserCart();
|
checkoutStore.getUserCart()
|
||||||
} else {
|
|
||||||
$toast.error("Failed to add item to cart. Please try again.", {
|
|
||||||
autoClose: 5000,
|
|
||||||
dangerouslyHTMLString: true,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
else {
|
||||||
$toast.error("An unexpected error occurred while updating your cart.", {
|
$toast.error('Failed to add item to cart. Please try again.', {
|
||||||
|
autoClose: 5000,
|
||||||
|
dangerouslyHTMLString: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
$toast.error('An unexpected error occurred while updating your cart.', {
|
||||||
autoClose: 5000,
|
autoClose: 5000,
|
||||||
dangerouslyHTMLString: true,
|
dangerouslyHTMLString: true,
|
||||||
});
|
})
|
||||||
console.error("incrementCartItem error:", error);
|
console.error('incrementCartItem error:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,34 +105,36 @@ export const useProductStore = defineStore("productStore", () => {
|
|||||||
const res = await useMyFetch<GenericResponse<object>>(
|
const res = await useMyFetch<GenericResponse<object>>(
|
||||||
`/api/public/user/cart/item/subtract/${id}/1`,
|
`/api/public/user/cart/item/subtract/${id}/1`,
|
||||||
{
|
{
|
||||||
method: "PUT",
|
method: 'PUT',
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
onErrorOccured: (_, status) => {
|
onErrorOccured: (_, status) => {
|
||||||
throw new Error(`HTTP error: ${status}`);
|
throw new Error(`HTTP error: ${status}`)
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
)
|
||||||
|
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
$toast.success("Item successfully removed from your cart.", {
|
$toast.success('Item successfully removed from your cart.', {
|
||||||
autoClose: 5000,
|
autoClose: 5000,
|
||||||
dangerouslyHTMLString: true,
|
dangerouslyHTMLString: true,
|
||||||
});
|
})
|
||||||
checkoutStore.getUserCart();
|
checkoutStore.getUserCart()
|
||||||
} else {
|
|
||||||
$toast.error("Failed to removed item from cart. Please try again.", {
|
|
||||||
autoClose: 5000,
|
|
||||||
dangerouslyHTMLString: true,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
else {
|
||||||
$toast.error("An unexpected error occurred while updating your cart.", {
|
$toast.error('Failed to removed item from cart. Please try again.', {
|
||||||
|
autoClose: 5000,
|
||||||
|
dangerouslyHTMLString: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
$toast.error('An unexpected error occurred while updating your cart.', {
|
||||||
autoClose: 5000,
|
autoClose: 5000,
|
||||||
dangerouslyHTMLString: true,
|
dangerouslyHTMLString: true,
|
||||||
});
|
})
|
||||||
console.error("decrementCartItem error:", error);
|
console.error('decrementCartItem error:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,34 +143,36 @@ export const useProductStore = defineStore("productStore", () => {
|
|||||||
const res = await useMyFetch<GenericResponse<object>>(
|
const res = await useMyFetch<GenericResponse<object>>(
|
||||||
`/api/public/user/cart/item/${id}`,
|
`/api/public/user/cart/item/${id}`,
|
||||||
{
|
{
|
||||||
method: "DELETE",
|
method: 'DELETE',
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
onErrorOccured: (_, status) => {
|
onErrorOccured: (_, status) => {
|
||||||
throw new Error(`HTTP error: ${status}`);
|
throw new Error(`HTTP error: ${status}`)
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
)
|
||||||
|
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
$toast.success("Item successfully removed from your cart.", {
|
$toast.success('Item successfully removed from your cart.', {
|
||||||
autoClose: 5000,
|
autoClose: 5000,
|
||||||
dangerouslyHTMLString: true,
|
dangerouslyHTMLString: true,
|
||||||
});
|
})
|
||||||
checkoutStore.getUserCart();
|
checkoutStore.getUserCart()
|
||||||
} else {
|
|
||||||
$toast.error("Failed to removed item from cart. Please try again.", {
|
|
||||||
autoClose: 5000,
|
|
||||||
dangerouslyHTMLString: true,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
else {
|
||||||
$toast.error("An unexpected error occurred while updating your cart.", {
|
$toast.error('Failed to removed item from cart. Please try again.', {
|
||||||
|
autoClose: 5000,
|
||||||
|
dangerouslyHTMLString: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
$toast.error('An unexpected error occurred while updating your cart.', {
|
||||||
autoClose: 5000,
|
autoClose: 5000,
|
||||||
dangerouslyHTMLString: true,
|
dangerouslyHTMLString: true,
|
||||||
});
|
})
|
||||||
console.error("deleteCartItem error:", error);
|
console.error('deleteCartItem error:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,5 +184,5 @@ export const useProductStore = defineStore("productStore", () => {
|
|||||||
incrementCartItem,
|
incrementCartItem,
|
||||||
decrementCartItem,
|
decrementCartItem,
|
||||||
deleteCartItem,
|
deleteCartItem,
|
||||||
};
|
}
|
||||||
});
|
})
|
||||||
|
@ -32,40 +32,39 @@ export interface UserAddressOfficial {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface Payment {
|
export interface Payment {
|
||||||
bank_name: string;
|
bank_name: string
|
||||||
city: string;
|
city: string
|
||||||
country_account_number: string;
|
country_account_number: string
|
||||||
country_iso: string;
|
country_iso: string
|
||||||
country_name: string;
|
country_name: string
|
||||||
currency_iso: string;
|
currency_iso: string
|
||||||
iban: string;
|
iban: string
|
||||||
id: number;
|
id: number
|
||||||
postcode: string;
|
postcode: string
|
||||||
street_and_number: string;
|
street_and_number: string
|
||||||
swift: string;
|
swift: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CheckoutOrder {
|
export interface CheckoutOrder {
|
||||||
cart_id: number;
|
cart_id: number
|
||||||
currency_iso: string;
|
currency_iso: string
|
||||||
customer_id: number;
|
customer_id: number
|
||||||
delivery_details: {
|
delivery_details: {
|
||||||
address: Address;
|
address: Address
|
||||||
contact_email: string;
|
contact_email: string
|
||||||
contact_phone_number: string;
|
contact_phone_number: string
|
||||||
delivery_option_id: number;
|
delivery_option_id: number
|
||||||
note: string;
|
}
|
||||||
};
|
payment_bank_account_id: number
|
||||||
payment_bank_account_id: number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Address {
|
export interface Address {
|
||||||
city: string;
|
city: string
|
||||||
country_iso: {
|
country_iso: {
|
||||||
str: string;
|
str: string
|
||||||
};
|
}
|
||||||
name: string;
|
name: string
|
||||||
postcode: string;
|
postcode: string
|
||||||
street: string;
|
street: string
|
||||||
surname: string;
|
surname: string
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user