conflicts

This commit is contained in:
2025-07-03 13:24:45 +02:00
parent 5d59059474
commit e935e9f911
5 changed files with 332 additions and 239 deletions

View File

@ -1,17 +1,90 @@
<template>
<div ref="dropdownRef">
<div class="relative cursor-pointer"
@click="openCart = !openCart"
>
<i class="uil uil-shopping-cart text-[31px]" />
<div @click="openCart = !openCart" class="relative cursor-pointer">
<i class="uil uil-shopping-cart text-[31px]"></i>
<div v-if="checkoutStore.products && checkoutStore.products.length > 0"
class="w-[15px] h-[15px] rounded-full bg-accent-green-light dark:bg-accent-green-light text-white flex items-center justify-center text-[9px] absolute top-1 right-0">
{{ checkoutStore.products.length }}</div>
</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
v-if="
productStore.cart.cart_items
&& productStore.cart.cart_items.length > 0
"
class="w-[15px] h-[15px] rounded-full bg-accent-green-light dark:bg-accent-green-light text-white flex items-center justify-center text-[9px] absolute top-1 right-0"
>
{{ productStore.cart.cart_items.length }}
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
@ -155,7 +228,8 @@
import { onClickOutside } from '@vueuse/core'
const productStore = useProductStore()
const openCart = ref(false)
const checkoutStore = useCheckoutStore()
const openCart = ref(false);
const menuStore = useMenuStore()
const userStore = useUserStore()

View File

@ -374,13 +374,14 @@ import CartPopup from './CartPopup.vue'
import CountryCurrencySelector from './CountryCurrencySelector.vue'
import LangSwitcher from './LangSwitcher.vue'
const menuStore = useMenuStore()
const userStore = useUserStore()
const productStore = useProductStore()
const open = ref(false)
const colorMode = useColorMode()
const menuStore = useMenuStore();
const checkoutStore = useCheckoutStore();
productStore.getCart()
checkoutStore.getUserCart()
const route = useRoute()
const isDark = computed({

View File

@ -1,18 +1,211 @@
<template>
<UiContainer>
<UiContainer v-if="checkoutStore.modalMadeOrder">
<NuxtLink to="/" class="mt-6 text-blue-500 underline" @click="checkoutStore.modalMadeOrder = false">Go back home
</NuxtLink>
</UiContainer>
<UiContainer v-else>
<div class="xl:w-[85%] mx-auto space-25-55">
<div class="space-25-55">
<div class="w-full flex items-center sm:justify-center">
<div
class="flex items-center justify-between sm:justify-center sm:gap-[25px] text-gray dark:text-button-disabled w-full sm:w-auto"
>
class="flex items-center justify-between sm:justify-center sm:gap-[25px] text-gray dark:text-button-disabled w-full sm:w-auto">
<div class="sm:px-6 sm:py-3 mx-auto">
{{ $t("login") }}
</div>
<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 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 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 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 v-model="checkoutStore.vLegal" type="checkbox" id="first" name="first" />
<!-- <label for="first" class="text-sm leading-snug">
{{ $t("I accept ") }}
<NuxtLink target="_blank"
:to="{ name: 'lang-info-name', params: { lang: menuStore.selectedLanguage.iso_code, name: 'legal_statement.html' } }"
class="underline cursor-pointer">
{{ $t("the legal statement*") }}
</NuxtLink>
</label> -->
<p class="text-sm sm:text-lg"> {{ $t("I accept ") }} {{ $t("the legal statement*") }}</p>
</div>
<span v-if="checkoutStore.legalValidation" class="text-xs text-red-600 ml-6">
{{ $t("You need to accept this") }}
</span>
<div class="flex gap-3 text-black dark:text-white items-center mt-2">
<input v-model="checkoutStore.vTerms" type="checkbox" id="second" name="second" />
<!-- <label for="second" class="text-sm leading-snug">
{{ $t("I accept ") }}
<NuxtLink target="_blank"
:to="{ name: 'lang-info-name', params: { lang: menuStore.selectedLanguage.iso_code, name: 'general_terms_and_conditions.html' } }"
class="underline cursor-pointer">
{{ $t("general terms and conditions*") }}
</NuxtLink>
</label> -->
<p class="text-sm sm:text-lg"> {{ $t("I accept ") }} {{ $t("general terms and conditions*") }}
</p>
</div>
<span v-if="checkoutStore.termsValidation" class="text-xs text-red-600 ml-6">
{{ $t("You need to accept this") }}
</span>
</div>
<UiButtonArrow @click="checkoutStore.sendSummaryForm" type="fill" :arrow="true">
{{ $t("Buy") }}
</UiButtonArrow>
</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 class="grid grid-cols-3 gap-[30px]">
<div class="col-start-1 col-end-3 space-y-5">
<h4 class="h4-uppercase-bold-inter">{{ component.front_section_lang[0].data.product_list }}</h4>
<div class="border-2 border-block rounded-[15px] p-[50px] space-25-55">
<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]">
@ -38,193 +231,12 @@
</div>
</div>
</div>
<div class="flex 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-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-3 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-3 space-y-5">
<h4 class="h4-uppercase-bold-inter">Typ doručení</h4>
<div class="border-2 border-block rounded-[15px] p-[50px] space-y-[25px] 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-[12px] 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-[15px] flex-1 flex flex-col gap-1 text-xl overflow-auto">
<UCarousel :prevIcon="'i-lucide-chevron-left'" :nextIcon="'i-lucide-chevron-right'" :ui="{
viewport: 'h-full',
container: 'h-full',
item: 'h-full',
prev: 'ring-0 text-button disable:text-block p-0 ring-inset ring-accented bg-inherit disabled:bg-inherit',
next: '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 max-w-full mx-10 h-full">
<template #default="{ item }">
<div class="flex flex-col items-start justify-between h-full">
<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] text-xl">
<div class="flex items-center justify-between">
<p>{{ component.front_section_lang[0].data.subtotal }}</p>
<p>5,043.18</p>
</div>
<div class="flex items-center justify-between">
<p>{{ component.front_section_lang[0].data.shipping_cost }}</p>
<p>5,043.18</p>
</div>
<div class="flex items-center justify-between uppercase">
<p>{{ component.front_section_lang[0].data.total }}</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">
5,043.18
</p>
</div>
</div>
<div class="flex justify-between mt-1">
<div class="flex flex-col gap-1 text-white w-full">
<div class="flex gap-3 text-black dark:text-white items-center">
<input v-model="checkoutStore.vLegal" type="checkbox" id="first" name="first" />
<!-- <label for="first" class="text-sm leading-snug">
{{ $t("I accept ") }}
<NuxtLink target="_blank"
:to="{ name: 'lang-info-name', params: { lang: menuStore.selectedLanguage.iso_code, name: 'legal_statement.html' } }"
class="underline cursor-pointer">
{{ $t("the legal statement*") }}
</NuxtLink>
</label> -->
<p class="text-lg"> {{ $t("I accept ") }} {{ $t("the legal statement*") }}</p>
</div>
<span v-if="checkoutStore.legalValidation" class="text-xs text-red-600 ml-6">
{{ $t("You need to accept this") }}
</span>
<div class="flex gap-3 text-black dark:text-white items-center mt-2">
<input v-model="checkoutStore.vTerms" type="checkbox" id="second" name="second" />
<!-- <label for="second" class="text-sm leading-snug">
{{ $t("I accept ") }}
<NuxtLink target="_blank"
:to="{ name: 'lang-info-name', params: { lang: menuStore.selectedLanguage.iso_code, name: 'general_terms_and_conditions.html' } }"
class="underline cursor-pointer">
{{ $t("general terms and conditions*") }}
</NuxtLink>
</label> -->
<p class="text-lg"> {{ $t("I accept ") }} {{ $t("general terms and conditions*") }}</p>
</div>
<span v-if="checkoutStore.termsValidation" class="text-xs text-red-600 ml-6">
{{ $t("You need to accept this") }}
</span>
</div>
<UiButtonArrow type="fill" :arrow="true">
{{ $t("Buy") }}
</UiButtonArrow>
</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 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"
>
<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>

View File

@ -13,6 +13,7 @@ import type { CartProduct } from "~/types/product";
export const useCheckoutStore = defineStore("checkoutStore", () => {
const { $toast } = useNuxtApp();
const menuStore = useMenuStore();
const selectedIso = ref(menuStore.selectedCountry);
const vLegal = ref(false);
@ -196,6 +197,8 @@ export const useCheckoutStore = defineStore("checkoutStore", () => {
},
)
console.log(res);
if (res.status === 200) {
$toast.success('Form successfully sent', {
autoClose: 5000,
@ -379,7 +382,7 @@ export const useCheckoutStore = defineStore("checkoutStore", () => {
// get bank data
const paymentMethods = ref([] as Payment[]);
const fullAddress = ref<Address>();
const currentPayment = ref<Payment | null>(null);
const currentPayment = ref<Payment | null>();
async function getBankAccount() {
try {
const { data } = await useMyFetch<GenericResponse<Payment[]>>(
@ -429,9 +432,9 @@ export const useCheckoutStore = defineStore("checkoutStore", () => {
}
}
async function setNewAddress(index: number) {
async function setNewAddress(indexItem: number) {
currentPayment.value = paymentMethods.value.find(
(item, index) => index === index
(item, index) => indexItem === index
);
}
@ -443,12 +446,12 @@ export const useCheckoutStore = defineStore("checkoutStore", () => {
vTerms.value
? (termsValidation.value = false)
: (termsValidation.value = true);
// if (vTerms.value && vLegal.value) {
// isModalOpen.value = true;
// }
if (!vTerms.value && !vLegal.value) {
return;
}
try {
const res = await useMyFetch<GenericResponse<object>>(
await useMyFetch<GenericResponse<object>>(
`/api/restricted/cart/checkout/delivery`,
{
method: "PUT",
@ -471,7 +474,9 @@ export const useCheckoutStore = defineStore("checkoutStore", () => {
}
);
putCheckoutBankAccount();
await putCheckoutBankAccount();
await markOrder();
await getUserCart();
} catch (error) {
console.error("uploadAddress error:", error);
}
@ -481,19 +486,12 @@ export const useCheckoutStore = defineStore("checkoutStore", () => {
async function putCheckoutBankAccount() {
try {
const res = await useMyFetch<GenericResponse<object>>(
`restricted/cart/checkout/bank-account/${currentPayment.value?.id}`,
`/api/restricted/cart/checkout/bank-account/${currentPayment.value?.id}`,
{
method: "PUT",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
accept_general_conditions: true,
accept_long_purchase: true,
address: fullAddress.value,
delivery_option_id: currentDelivery.value.id,
note: vNote.value,
}),
onErrorOccured: async (_, status) => {
throw createError({
statusCode: status,
@ -507,6 +505,42 @@ export const useCheckoutStore = defineStore("checkoutStore", () => {
}
}
const modalMadeOrder = ref(false);
async function markOrder() {
try {
const res = await useMyFetch<GenericResponse<object>>(
`/api/restricted/cart/checkout/order`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
onErrorOccured: async (_, status) => {
throw createError({
statusCode: status,
statusMessage: `HTTP error: ${status}`,
});
},
}
);
if (res.status === 200 || res.status === 201) {
$toast.success("Address successfully added", {
autoClose: 5000,
dangerouslyHTMLString: true,
});
modalMadeOrder.value = true;
} else {
$toast.error("Failed to add address. Please try again.", {
autoClose: 5000,
dangerouslyHTMLString: true,
});
}
// window.location.href = `/golden-panel/my-purchases/${res._data?.data.id}`;
} catch (error) {
console.error("uploadAddress error:", error);
}
}
return {
addressesList,
activeAddress,
@ -547,6 +581,7 @@ export const useCheckoutStore = defineStore("checkoutStore", () => {
vNote,
legalValidation,
termsValidation,
modalMadeOrder,
changePrefix,
getCheckout,
@ -562,5 +597,6 @@ export const useCheckoutStore = defineStore("checkoutStore", () => {
getBankAccount,
getOrder,
setNewAddress,
sendSummaryForm,
};
});

View File

@ -1,16 +1,18 @@
import { useMyFetch } from '#imports'
import { useMyFetch } from "#imports";
import type {
GenericResponse,
GenericResponseChildren,
GenericResponseItems,
UserCart,
} from '~/types'
import type { Product } from '~/types/product'
} from "~/types";
import type { Product } from "~/types/product";
export const useProductStore = defineStore('productStore', () => {
const { $toast } = useNuxtApp()
const productList = ref<Product[]>()
const modules = ref()
export const useProductStore = defineStore("productStore", () => {
const { $toast } = useNuxtApp();
const productList = ref<Product[]>();
const modules = ref();
const checkoutStore = useCheckoutStore();
async function getList(count: number, categoryId = 1) {
try {
@ -18,22 +20,21 @@ export const useProductStore = defineStore('productStore', () => {
`/api/public/products/category/${categoryId}?p=1&elems=${count}`,
{
headers: {
'Content-Type': 'application/json',
"Content-Type": "application/json",
},
onErrorOccured: async (_, status) => {
// await navigateTo("/error", { replace: true });
throw createError({
statusCode: status,
statusMessage: `HTTP error: ${status}`,
})
});
},
},
)
productList.value = data.items
}
catch (error) {
console.error('getList error:', error)
);
productList.value = data.items;
} catch (error) {
console.error("getList error:", error);
}
}
@ -43,21 +44,20 @@ export const useProductStore = defineStore('productStore', () => {
`/api/public/module/e_shop`,
{
headers: {
'Content-Type': 'application/json',
"Content-Type": "application/json",
},
onErrorOccured: (_, status) => {
throw new Error(`HTTP error: ${status}`)
throw new Error(`HTTP error: ${status}`);
},
},
)
}
);
modules.value = data.children.find(
(item: { id: number, name: string }) =>
item.name === 'currency_rates_bar',
)
}
catch (error) {
console.error('getList error:', error)
(item: { id: number; name: string }) =>
item.name === "currency_rates_bar"
);
} catch (error) {
console.error("getList error:", error);
}
}
@ -66,36 +66,34 @@ export const useProductStore = defineStore('productStore', () => {
const res = await useMyFetch<GenericResponse<object>>(
`/api/public/user/cart/item/add/${id}/1`,
{
method: 'PUT',
method: "PUT",
headers: {
'Content-Type': 'application/json',
"Content-Type": "application/json",
},
onErrorOccured: (_, status) => {
throw new Error(`HTTP error: ${status}`)
throw new Error(`HTTP error: ${status}`);
},
},
)
}
);
if (res.status === 200) {
$toast.success('Item successfully added to your cart.', {
$toast.success("Item successfully added to your cart.", {
autoClose: 5000,
dangerouslyHTMLString: true,
})
getCart()
}
else {
$toast.error('Failed to add item to cart. Please try again.', {
});
checkoutStore.getUserCart();
} else {
$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.', {
} catch (error) {
$toast.error("An unexpected error occurred while updating your cart.", {
autoClose: 5000,
dangerouslyHTMLString: true,
})
console.error('incrementCartItem error:', error)
});
console.error("incrementCartItem error:", error);
}
}
@ -104,36 +102,34 @@ export const useProductStore = defineStore('productStore', () => {
const res = await useMyFetch<GenericResponse<object>>(
`/api/public/user/cart/item/subtract/${id}/1`,
{
method: 'PUT',
method: "PUT",
headers: {
'Content-Type': 'application/json',
"Content-Type": "application/json",
},
onErrorOccured: (_, status) => {
throw new Error(`HTTP error: ${status}`)
throw new Error(`HTTP error: ${status}`);
},
},
)
}
);
if (res.status === 200) {
$toast.success('Item successfully removed from your cart.', {
$toast.success("Item successfully removed from your cart.", {
autoClose: 5000,
dangerouslyHTMLString: true,
})
getCart()
}
else {
$toast.error('Failed to removed item from cart. Please try again.', {
});
checkoutStore.getUserCart();
} else {
$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.', {
} catch (error) {
$toast.error("An unexpected error occurred while updating your cart.", {
autoClose: 5000,
dangerouslyHTMLString: true,
})
console.error('decrementCartItem error:', error)
});
console.error("decrementCartItem error:", error);
}
}
@ -142,70 +138,44 @@ export const useProductStore = defineStore('productStore', () => {
const res = await useMyFetch<GenericResponse<object>>(
`/api/public/user/cart/item/${id}`,
{
method: 'DELETE',
method: "DELETE",
headers: {
'Content-Type': 'application/json',
"Content-Type": "application/json",
},
onErrorOccured: (_, status) => {
throw new Error(`HTTP error: ${status}`)
throw new Error(`HTTP error: ${status}`);
},
},
)
}
);
if (res.status === 200) {
$toast.success('Item successfully removed from your cart.', {
$toast.success("Item successfully removed from your cart.", {
autoClose: 5000,
dangerouslyHTMLString: true,
})
getCart()
}
else {
$toast.error('Failed to removed item from cart. Please try again.', {
});
checkoutStore.getUserCart();
} else {
$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.', {
} catch (error) {
$toast.error("An unexpected error occurred while updating your cart.", {
autoClose: 5000,
dangerouslyHTMLString: true,
})
console.error('deleteCartItem error:', error)
}
}
const cart = ref({} as UserCart)
async function getCart() {
try {
const { data } = await useMyFetch<GenericResponse<UserCart>>(
`/api/public/user/cart`,
{
headers: {
'Content-Type': 'application/json',
},
onErrorOccured: (_, status) => {
throw new Error(`HTTP error: ${status}`)
},
},
)
cart.value = data
}
catch (error) {
console.error('getList error:', error)
});
console.error("deleteCartItem error:", error);
}
}
return {
productList,
modules,
cart,
getList,
getModules,
incrementCartItem,
decrementCartItem,
deleteCartItem,
getCart,
}
})
};
});