Compare commits
2 Commits
main
...
img_button
Author | SHA1 | Date | |
---|---|---|---|
c18497b3fa | |||
bf317d2e34 |
@ -18,7 +18,7 @@
|
||||
<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`"
|
||||
<img :src="`https://www.yourgold.cz/api/public/file/${item.picture_uuid}.webp`"
|
||||
alt="" class="max-w-full max-h-full object-contain">
|
||||
</div>
|
||||
|
||||
@ -66,14 +66,10 @@
|
||||
</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))
|
||||
}
|
||||
menuStore.navigateToItem(menuStore.menuItems?.find((item) => item.id === 12))
|
||||
openCart = false
|
||||
}" class="w-full" type="fill" :arrow="true" :full="true">{{ userStore.isLogged ?
|
||||
$t('to_checkout') : $t('login') }}
|
||||
}" class="w-full" type="fill" :arrow="true" :full="true">{{
|
||||
$t('to_checkout') }}
|
||||
</UiButtonArrow>
|
||||
</div>
|
||||
<div v-else
|
||||
@ -96,7 +92,6 @@ const productStore = useProductStore()
|
||||
const openCart = ref(false);
|
||||
|
||||
const menuStore = useMenuStore()
|
||||
const userStore = useUserStore()
|
||||
|
||||
const dropdownRef = ref(null);
|
||||
onClickOutside(dropdownRef, () => {
|
||||
|
@ -4,7 +4,7 @@
|
||||
<div class="w-full border-b border-border">
|
||||
<UiContainer class="relative">
|
||||
<div class="hidden h-[120px] w-full items-center gap-[145px] xl:flex">
|
||||
<ul class="flex items-center justify-between gap-5 whitespace-nowrap w-full">
|
||||
<ul class="flex items-center justify-between whitespace-nowrap w-full">
|
||||
<li v-for="(item, index) in menuStore.menu" @click="menuStore.navigateToItem(item)" :key="item.id"
|
||||
:class="['hover:text-accent-green-light dark:hover:text-accent-green-dark cursor-pointer text-lg transition-all text-inter',
|
||||
route.params.id == item.id.toString() ? 'text-accent-green-light dark:text-accent-green-dark font-bold underline' : false]">
|
||||
@ -18,12 +18,13 @@
|
||||
</ClientOnly>
|
||||
<div class="w-full flex items-center justify-between">
|
||||
<div class="flex items-center gap-[30px]">
|
||||
<div>
|
||||
<div>
|
||||
<i v-if="!userStore.isLogged"
|
||||
@click="menuStore.navigateToItem(menuStore.menuItems?.find((item) => item.id === 11))"
|
||||
class="uil uil-user text-[31px] cursor-pointer"></i>
|
||||
<div v-else class="py-[6px] px-3 border border-block rounded-sm">
|
||||
{{ userStore.user }}
|
||||
<!-- {{ userStore.user }} -->
|
||||
Arina Yakovenko
|
||||
</div>
|
||||
</div>
|
||||
<CartPopup />
|
||||
@ -34,7 +35,7 @@
|
||||
</div>
|
||||
<ThemeSwitcher />
|
||||
<button @click="menuStore.navigateToShop" :class="[
|
||||
'cursor-pointer transition-all text-inter whitespace-nowrap',
|
||||
'cursor-pointer transition-all text-inter',
|
||||
route.params.id == '5'
|
||||
? 'text-accent-green-light dark:text-accent-green-dark font-bold pb-1 border-b-2'
|
||||
: 'hover:bg-button-hover bg-button text-white font-medium rounded-xl px-6 py-3'
|
||||
@ -56,14 +57,7 @@
|
||||
</ClientOnly>
|
||||
<div class="flex items-center gap-6">
|
||||
<div class="flex items-center gap-[30px]">
|
||||
<div>
|
||||
<i v-if="!userStore.isLogged"
|
||||
@click="menuStore.navigateToItem(menuStore.menuItems?.find((item) => item.id === 11))"
|
||||
class="uil uil-user text-[31px] cursor-pointer"></i>
|
||||
<div v-else class="py-[6px] px-3 border border-block rounded-sm">
|
||||
{{ userStore.user }}
|
||||
</div>
|
||||
</div>
|
||||
<i class="uil uil-user text-[31px] cursor-pointer"></i>
|
||||
<CartPopup />
|
||||
</div>
|
||||
<div class="flex">
|
||||
@ -109,14 +103,7 @@
|
||||
</ClientOnly>
|
||||
<div class="flex items-center gap-6">
|
||||
<div class="flex items-center gap-[30px]">
|
||||
<div>
|
||||
<i v-if="!userStore.isLogged"
|
||||
@click="menuStore.navigateToItem(menuStore.menuItems?.find((item) => item.id === 11))"
|
||||
class="uil uil-user text-[31px] cursor-pointer"></i>
|
||||
<div v-else class="py-[6px] px-3 border border-block rounded-sm">
|
||||
{{ userStore.user }}
|
||||
</div>
|
||||
</div>
|
||||
<i class="uil uil-user text-[31px] cursor-pointer"></i>
|
||||
<CartPopup />
|
||||
</div>
|
||||
<i variant="subtle" block class="uil uil-apps text-[30px] cursor-pointer" @click="open = !open"></i>
|
||||
@ -178,10 +165,6 @@
|
||||
@click="menuStore.navigateToItem()" />
|
||||
</ClientOnly>
|
||||
<div class="flex items-center gap-6">
|
||||
<div>
|
||||
<i @click="!userStore.isLogged && menuStore.navigateToItem(menuStore.menuItems?.find((item) => item.id === 11))"
|
||||
class="uil uil-user text-[30px] cursor-pointer"></i>
|
||||
</div>
|
||||
<CartPopup />
|
||||
<i variant="subtle" block class="uil uil-apps text-[30px] cursor-pointer" @click="open = !open"></i>
|
||||
</div>
|
||||
|
6
components/section/ChackoutSummary.vue
Normal file
6
components/section/ChackoutSummary.vue
Normal file
@ -0,0 +1,6 @@
|
||||
<template>
|
||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Modi perspiciatis adipisci quam odio natus odit excepturi
|
||||
eveniet vitae. Fugit dicta officiis quos quia debitis perspiciatis porro ducimus earum placeat sunt?
|
||||
</template>
|
||||
|
||||
<script lang="ts"></script>
|
@ -1,47 +1,49 @@
|
||||
<template>
|
||||
<UiContainer>
|
||||
<div class="xl:w-[85%] mx-auto">
|
||||
<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">
|
||||
<div class="sm:px-6 sm:py-3 mx-auto">
|
||||
{{ $t("login") }}
|
||||
</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("address") }}
|
||||
</div>
|
||||
<div class="sm:px-6 sm:py-3 mx-auto">
|
||||
{{ $t("summary") }}
|
||||
</div>
|
||||
<div class="hidden sm:block sm:px-6 sm:py-3 sm:mx-auto">
|
||||
{{ $t("order_placed") }}
|
||||
<div class="w-[85%] mx-auto">
|
||||
<div v-if="userStore.isLogged" class="space-25-55">
|
||||
|
||||
<div class="w-full flex items-center justify-center">
|
||||
<div class="flex justify-between">
|
||||
<div class="flex items-center gap-[25px] text-gray dark:text-button-disabled">
|
||||
<div class="px-6 py-3 mx-auto">
|
||||
{{ $t("login") }}
|
||||
</div>
|
||||
<div
|
||||
class="cursor-pointer transition-all text-inter hover:bg-button-hover bg-button text-white font-medium rounded-xl px-6 py-3">
|
||||
{{ $t("address") }}
|
||||
</div>
|
||||
<div class="px-6 py-3 mx-auto">
|
||||
{{ $t("summary") }}
|
||||
</div>
|
||||
<div class="px-6 py-3 mx-auto">
|
||||
{{ $t("order_placed") }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="space-y-[25px] sm:space-y-[30px]">
|
||||
<div class="space-y-[30px]">
|
||||
<h2 class="h2-bold-bounded">
|
||||
{{ $t("Account address") }}
|
||||
</h2>
|
||||
<div class="flex flex-col gap-[30px] sm:flex-row">
|
||||
<div class="flex flex-col sm:w-1/2 gap-[25px] sm:gap-[30px]">
|
||||
<div class="flex flex-col gap-[30px] xl:flex-row">
|
||||
<div class="flex flex-col w-1/2 gap-[30px]">
|
||||
<CheckoutInput v-model="checkoutStore.userName" :id="1" disabled>{{ $t("first_name")
|
||||
}} </CheckoutInput>
|
||||
}} </CheckoutInput>
|
||||
<CheckoutInput v-model="checkoutStore.lastName" :id="2" disabled>{{ $t("surname")
|
||||
}} </CheckoutInput>
|
||||
}} </CheckoutInput>
|
||||
<CheckoutInput v-model="checkoutStore.address" :id="3" disabled>{{ $t("address")
|
||||
}} </CheckoutInput>
|
||||
}} </CheckoutInput>
|
||||
<CheckoutInput v-model="checkoutStore.postCode" :id="4" disabled>{{ $t("post_code")
|
||||
}} </CheckoutInput>
|
||||
}} </CheckoutInput>
|
||||
</div>
|
||||
<div class="flex flex-col sm:w-1/2 gap-[30px]">
|
||||
<div class="flex flex-col w-1/2 gap-[30px]">
|
||||
<CheckoutInput v-model="checkoutStore.city" :id="5" disabled>{{ $t("city")
|
||||
}} </CheckoutInput>
|
||||
}} </CheckoutInput>
|
||||
<CheckoutInput v-model="checkoutStore.country" :id="6" disabled>{{ $t("country")
|
||||
}} </CheckoutInput>
|
||||
}} </CheckoutInput>
|
||||
<CheckoutInput v-model="checkoutStore.accountPhoneNumber" :id="7" disabled>{{ $t("phone")
|
||||
}} </CheckoutInput>
|
||||
}} </CheckoutInput>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -49,27 +51,23 @@
|
||||
<h2 class="h2-bold-bounded">
|
||||
{{ $t("Shipping details") }}
|
||||
</h2>
|
||||
<div class="flex flex-col gap-2">
|
||||
<div
|
||||
:class="['flex items-center gap-[10px] relative border border-block rounded-lg h-[50px] sm:h-[67px] w-full', checkoutStore.vUseAccountPhoneNumber && 'px-6']">
|
||||
<div class="flex items-center gap-5 sm:gap-[25px]"
|
||||
v-if="!checkoutStore.vUseAccountPhoneNumber">
|
||||
<div class="relative border border-block rounded-lg px-6 h-[67px] w-full">
|
||||
<div class="flex items-center gap-[10px]">
|
||||
<div class="flex items-center gap-[25px]" v-if="!checkoutStore.vUseAccountPhoneNumber">
|
||||
<div class="flex flex-col items-start gap-[25px]">
|
||||
<div ref="dropdownIsoRef"
|
||||
class="pl-5 sm:pl-[25px] relative w-full ring-0 cursor-pointer focus:ring-0 outline-none focus-visible:ring-0">
|
||||
class="pl-[25px] relative w-full ring-0 cursor-pointer focus:ring-0 outline-none focus-visible:ring-0">
|
||||
<div class="p-0" @click="dropIso = !dropIso">
|
||||
<div
|
||||
class="flex items-center gap-2 text-base sm:text-xl font-medium uppercase text-text-light dark:text-text-dark">
|
||||
<p class="hidden sm:block">{{ checkoutStore.selectedIso.name }}</p>
|
||||
<p class="sm:hidden">{{ checkoutStore.selectedIso.iso_code }}</p>
|
||||
<span> <i
|
||||
class="flex items-center gap-2 text-xl font-medium uppercase text-text-light dark:text-text-dark">
|
||||
{{ checkoutStore.selectedIso.name }} <span> <i
|
||||
class="uil uil-angle-down text-2xl font-light cursor-pointer"></i></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="dropIso"
|
||||
class="absolute w-[130px] sm:w-full mt-2 left-0 bg-bg-light dark:bg-bg-dark rounded-[5px] data-highlighted:not-data-disabled:before:bg-button/50 ring-0 cursor-pointer focus:ring-0 outline-none focus-visible:ring-0 border border-button py-[10px] px-[5px]">
|
||||
<div class="overflow-auto h-[200px] w-full overflow-x-hidden">
|
||||
class="absolute w-full mt-2 left-0 bg-bg-light dark:bg-bg-dark rounded-[5px] data-highlighted:not-data-disabled:before:bg-button/50 ring-0 cursor-pointer focus:ring-0 outline-none focus-visible:ring-0 border border-button py-[10px] px-[5px]">
|
||||
<div class="overflow-auto h-[200px] w-full">
|
||||
<p @click="() => { checkoutStore.selectedIso = item; dropIso = false; checkoutStore.changePrefix(item.call_prefix as string) }"
|
||||
class="w-full hover:bg-block dark:hover:bg-button pl-2 py-2 text-base text-text-light dark:text-text-dark rounded-[5px]"
|
||||
v-for="item in menuStore.countries" :key="item.iso_code">
|
||||
@ -79,24 +77,23 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-sm sm:text-xl border-r pr-[10px] border-block">{{
|
||||
checkoutStore.currentPrefix }}</p>
|
||||
<p class="text-xl">{{ checkoutStore.currentPrefix }}</p>
|
||||
</div>
|
||||
<input id="phone"
|
||||
<input
|
||||
:value="checkoutStore.vUseAccountPhoneNumber ? checkoutStore.accountPhoneNumber : checkoutStore.phoneNumber"
|
||||
:disabled="checkoutStore.vUseAccountPhoneNumber" @input="(e) => {
|
||||
if (!checkoutStore.vUseAccountPhoneNumber) {
|
||||
checkoutStore.phoneNumber = (e.target as HTMLInputElement).value;
|
||||
}
|
||||
}" type="tel" placeholder="123 xxxx xxx"
|
||||
class="placeholder:text-sm sm:placeholder:text-xl placeholder:text-gray placeholder:uppercase dark:placeholder:text-bg-light rounded-lg h-[50px] sm:h-[67px] w-full focus:outline-none focus:ring-0 focus:border-0" />
|
||||
class="placeholder:text-xl placeholder:text-gray placeholder:uppercase dark:placeholder:text-bg-light rounded-lg h-[67px] w-full focus:outline-none focus:ring-0 focus:border-0" />
|
||||
</div>
|
||||
<p v-if="checkoutStore.phoneValidation === false && !checkoutStore.vUseAccountPhoneNumber"
|
||||
class="text-red-500">Invalid phone number</p>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2">
|
||||
<input id="checkbox" @change="(event: Event) => {
|
||||
<input @change="(event: Event) => {
|
||||
const target = event.target as HTMLInputElement
|
||||
target.checked ? checkoutStore.vUseAccountPhoneNumber = true : checkoutStore.vUseAccountPhoneNumber = false
|
||||
checkoutStore.phoneValidation = null
|
||||
@ -104,24 +101,23 @@
|
||||
<p>{{ $t('use_account_phone') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="space-y-[30px] h-full">
|
||||
<div class="space-y-[30px]">
|
||||
<h2 class="h2-bold-bounded">
|
||||
{{ $t("Select delivery address") }}
|
||||
</h2>
|
||||
<div
|
||||
class="flex flex-col md:flex-row items-center justify-center gap-[10px] sm:gap-[25px] md:h-[225px]">
|
||||
<div class="w-full sm:w-[500px] flex flex-col gap-4 h-full">
|
||||
<div class="flex items-center justify-center gap-[25px] h-[225px]">
|
||||
<div class="w-[500px] flex flex-col gap-4 h-full">
|
||||
<div v-for="(item, index) in checkoutStore.addressesList" :key="index"
|
||||
:class="['flex min-h-[200px] md:h-full flex-col py-[15px] px-[25px] gap-[15px] rounded-lg border-2', checkoutStore.activeAddress === item ? 'border-button' : 'border-block']">
|
||||
:class="['flex h-full flex-col py-[15px] px-[25px] gap-[15px] rounded-lg border-2', checkoutStore.activeAddress === item ? 'border-button' : 'border-block']">
|
||||
<div
|
||||
:class="['flex flex-col justify-between gap-[10px] h-full', checkoutStore.activeAddress !== item && 'text-gray dark:text-button-disabled']">
|
||||
:class="['flex flex-col justify-between mt-1 h-full', checkoutStore.activeAddress !== item && 'text-gray dark:text-button-disabled']">
|
||||
<span>{{ item.address.name }} {{ item.address.surname }}</span>
|
||||
<span>{{ item.address.street }}</span>
|
||||
<span>{{ item.address.postcode }} {{ item.address.city }}</span>
|
||||
<span>{{ item.address.country_iso }}</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 border-t pt-[15px] border-block">
|
||||
<input id="checkbox" :checked="checkoutStore.activeAddress ? true : false" @change="(event: Event) => {
|
||||
<input :checked="checkoutStore.activeAddress ? true : false" @change="(event: Event) => {
|
||||
const target = event.target as HTMLInputElement
|
||||
target.checked ? checkoutStore.activeAddress = item : checkoutStore.activeAddress = null;
|
||||
checkoutStore.isOpen = false;
|
||||
@ -135,7 +131,7 @@
|
||||
checkoutStore.isOpen = !checkoutStore.isOpen
|
||||
checkoutStore.activeAddress = null
|
||||
}"
|
||||
:class="['cursor-pointer w-full sm:w-[500px] py-[15px] px-[25px] rounded-lg border-2 flex flex-col items-center justify-center min-h-[200px] md:h-full', checkoutStore.isOpen ? 'border-button text-button' : 'text-gray border-block ']">
|
||||
:class="['cursor-pointer w-[500px] py-[15px] px-[25px] rounded-lg border-2 flex flex-col items-center justify-center h-full', checkoutStore.isOpen ? 'border-button text-button' : 'text-gray border-block ']">
|
||||
<h4
|
||||
:class="['font-inter text-base leading-[150%] uppercase text-[16px] sm:text-[20px] border-b', checkoutStore.isOpen ? 'border-button' : 'border-gray']">
|
||||
{{ $t("add_new_address") }}
|
||||
@ -146,7 +142,7 @@
|
||||
<div v-if="checkoutStore.isOpen"
|
||||
class="flex flex-col items-center gap-[30px] justify-center w-full">
|
||||
<div class="flex flex-col gap-[30px] xl:flex-row w-full">
|
||||
<div class="flex flex-col sm:w-1/2 gap-[25px] sm:gap-[30px]">
|
||||
<div class="flex flex-col w-1/2 gap-[30px]">
|
||||
<CheckoutInput v-model="checkoutStore.vNewAddressName" :placeholder="$t('first_name')"
|
||||
:id="8">{{ $t("first_name") }}
|
||||
</CheckoutInput>
|
||||
@ -157,7 +153,7 @@
|
||||
:id="10">{{ $t("city") }}
|
||||
</CheckoutInput>
|
||||
</div>
|
||||
<div class="flex flex-col sm:w-1/2 gap-[25px] sm:gap-[30px]">
|
||||
<div class="flex flex-col w-1/2 gap-[30px]">
|
||||
<CheckoutInput v-model="checkoutStore.vNewAddressSurname" :placeholder="$t('surname')"
|
||||
:id="11">{{ $t("surname") }}
|
||||
</CheckoutInput>
|
||||
@ -167,10 +163,10 @@
|
||||
</p>
|
||||
<div ref="dropdownCountryRef"
|
||||
class="relative w-full ring-0 cursor-pointer focus:ring-0 outline-none focus-visible:ring-0">
|
||||
<div class="border border-block placeholder:text-gray dark:placeholder:text-button-disabled rounded-lg px-6 h-[50px] sm:h-[67px] w-full focus:outline-none focus:ring-0 focus:border-2 flex items-center justify-start"
|
||||
<div class="border border-block placeholder:text-gray dark:placeholder:text-button-disabled rounded-lg px-6 h-[67px] w-full focus:outline-none focus:ring-0 focus:border-2 flex items-center justify-start"
|
||||
@click="dropCountry = !dropCountry">
|
||||
<div
|
||||
class="flex items-center gap-2 text-base sm:text-xl font-medium uppercase text-text-light dark:text-text-dark">
|
||||
class="flex items-center gap-2 text-xl font-medium uppercase text-text-light dark:text-text-dark">
|
||||
{{ checkoutStore.vNewAddressCountry ?
|
||||
checkoutStore.vNewAddressCountry.name : '-' }} <span> <i
|
||||
class="uil uil-angle-down text-2xl font-light cursor-pointer"></i></span>
|
||||
@ -230,6 +226,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { LazyColorScheme } from '#components';
|
||||
import CheckoutInput from '../ui/CheckoutInput.vue';
|
||||
import { onClickOutside } from "@vueuse/core";
|
||||
|
||||
|
@ -1,223 +0,0 @@
|
||||
<template>
|
||||
<UiContainer>
|
||||
<div class="xl:w-[85%] mx-auto space-25-55">
|
||||
<div class="space-25-55">
|
||||
<div class="w-full flex items-center sm:justify-center">
|
||||
<div
|
||||
class="flex items-center justify-between sm:justify-center sm:gap-[25px] text-gray dark:text-button-disabled w-full sm:w-auto">
|
||||
<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-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">
|
||||
<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="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>
|
||||
</UiContainer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { UCarousel } from '#components';
|
||||
|
||||
const checkoutStore = useCheckoutStore();
|
||||
const productStore = useProductStore()
|
||||
const menuStore = useMenuStore()
|
||||
|
||||
checkoutStore.getOrder()
|
||||
checkoutStore.getBankAccount()
|
||||
checkoutStore.getUserCart()
|
||||
checkoutStore.getDeliveryOptions()
|
||||
checkoutStore.getDefAddress()
|
||||
|
||||
defineProps<{
|
||||
component: {
|
||||
id: number
|
||||
name: string
|
||||
img: string[]
|
||||
component_name: string
|
||||
is_no_lang: boolean
|
||||
page_name: string
|
||||
front_section_lang: {
|
||||
data: {
|
||||
product_list: string
|
||||
account_address: string
|
||||
note: string
|
||||
delivery_type: string
|
||||
payment_method: string
|
||||
subtotal: string
|
||||
shipping_cost: string
|
||||
total: string
|
||||
accept: string
|
||||
legal: string
|
||||
terms: string
|
||||
}
|
||||
id_front_section: number
|
||||
id_lang: number
|
||||
}[]
|
||||
}
|
||||
}>();
|
||||
</script>
|
@ -3,19 +3,12 @@
|
||||
<UiContainer class="flex flex-col gap-24">
|
||||
<div
|
||||
class="grid grid-cols-1 md:grid-cols-2 gap-[75px] xl:gap-0 xl:grid-cols-none xl:grid-flow-col auto-cols-max justify-between">
|
||||
<div>
|
||||
<div v-for="(item, key) in contact" :key="key" class="flex flex-col gap-[25px] sm:gap-8 max-w-[280px]">
|
||||
<h3 v-if="key == 'header'" class="h4-uppercase-bold-inter">{{ item }}</h3>
|
||||
<div v-else class="transition-all text-inter">{{ item }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-for="(section, index) in docs" :key="index" class="flex flex-col gap-[25px] sm:gap-8 max-w-[280px]">
|
||||
<h3 class="h4-uppercase-bold-inter">{{ section.translation }}</h3>
|
||||
<div v-for="(item, key) in section.data" :key="key">
|
||||
<div class="cursor-pointer hover:text-text-light/80 dark:hover:text-text-dark/70 transition-all text-inter">
|
||||
<a target="_blank" :href="`/api/public/document/${item.name}`">{{ item.translation }}</a>
|
||||
</div>
|
||||
<div v-for="(item, index) in component.front_section_lang[0].data" :key="index"
|
||||
class="flex flex-col gap-[25px] sm:gap-8 max-w-[280px]">
|
||||
<h3 class="h4-uppercase-bold-inter">{{ item.title }}</h3>
|
||||
<div class="cursor-pointer hover:text-text-light/80 dark:hover:text-text-dark/70 transition-all text-inter"
|
||||
v-for="(el, indexEl) in item.children" :key="indexEl">
|
||||
{{ el.title }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -29,17 +22,38 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { GenericResponse, Footer } from '~/types';
|
||||
defineProps<{
|
||||
component: {
|
||||
id: number
|
||||
name: string
|
||||
img: string[]
|
||||
component_name: string
|
||||
is_no_lang: boolean
|
||||
page_name: string
|
||||
front_section_lang: {
|
||||
data: {
|
||||
title: string
|
||||
children: {
|
||||
title: string
|
||||
value: 'email' | 'address' | 'certificate' | 'document' | 'form' | 'info'
|
||||
link?: string
|
||||
}[]
|
||||
}[]
|
||||
id_front_section: number
|
||||
id_lang: number
|
||||
}[]
|
||||
}
|
||||
}>();
|
||||
|
||||
const menuStore = useMenuStore();
|
||||
const colorMode = useColorMode();
|
||||
|
||||
const { data } = await useMyFetch<GenericResponse<Footer>>('/api/public/front/footer', {});
|
||||
|
||||
|
||||
const contact = ref(data.data.contact)
|
||||
const docs = ref(data.data.docs)
|
||||
|
||||
|
||||
const isDark = computed(() => colorMode.value === "dark");
|
||||
const isDark = computed({
|
||||
get() {
|
||||
return colorMode.value === "dark";
|
||||
},
|
||||
set(_isDark) {
|
||||
colorMode.preference = _isDark ? "dark" : "light";
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
@ -28,7 +28,7 @@
|
||||
]">
|
||||
<div v-for="(item, index) in productStore.productList" :key="index"
|
||||
class="w-[200px] sm:w-[260px] md:w-[290px] sm:py-5 sm:px-[15px] py-[15px] px-[10px] bg-block rounded-2xl flex flex-col items-center gap-5 sm:gap-7">
|
||||
<img :src="`/api/public/file/${item.cover_picture_uuid}.webp`" alt="pics"
|
||||
<img :src="`https://www.yourgold.cz/api/public/file/${item.cover_picture_uuid}.webp`" alt="pics"
|
||||
class="max-h-[150px] sm:max-h-[180px] md:max-h-[205px]" />
|
||||
<div class="flex flex-col justify-between h-full">
|
||||
<div class="flex flex-col gap-[10px] sm:gap-[15px] w-full">
|
||||
|
@ -7,7 +7,7 @@
|
||||
<!-- product -->
|
||||
<div v-for="(item, index) in productStore.productList" :key="index"
|
||||
class="w-[200px] sm:w-[260px] md:w-[290px] sm:py-5 sm:px-[15px] py-[15px] px-[10px] bg-block rounded-2xl flex flex-col items-center gap-5 sm:gap-7">
|
||||
<img :src="`/api/public/file/${item.cover_picture_uuid}.webp`" alt="pics"
|
||||
<img :src="`https://www.yourgold.cz/api/public/file/${item.cover_picture_uuid}.webp`" alt="pics"
|
||||
class="max-h-[150px] sm:max-h-[180px] md:max-h-[205px]" />
|
||||
<div class="flex flex-col justify-between h-full">
|
||||
<div class="flex flex-col gap-[10px] sm:gap-[15px] w-full">
|
||||
|
@ -1,10 +1,9 @@
|
||||
<template>
|
||||
<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]">
|
||||
<img :src="`/api/public/file/${props.product?.cover_picture_uuid}.webp`" alt="Product Image" :class="[
|
||||
'h-[95px] sm:min-h-[180px] md:min-h-[205px] rounded-[5px]',
|
||||
isError ? 'max-w-[50%]' : ''
|
||||
]" @error="handleImageError" />
|
||||
<img :src="`https://www.yourgold.cz/api/public/file/${props.product?.cover_picture_uuid}.webp`" alt="Product Image"
|
||||
class="h-[95px] sm:h-[180px] md:h-[205px] rounded-[5px]"
|
||||
onerror="this.onerror=null; this.src='/photo.svg';" />
|
||||
|
||||
<div class="flex flex-col justify-between h-full w-full gap-[7px] sSm:gap-[15px]">
|
||||
<div class="flex flex-col gap-[7px] sm:gap-[15px] w-full">
|
||||
@ -34,11 +33,4 @@ const props = defineProps({
|
||||
});
|
||||
|
||||
const productStore = useProductStore()
|
||||
|
||||
const isError = ref(false);
|
||||
|
||||
function handleImageError(event: Event) {
|
||||
isError.value = true;
|
||||
(event.target as HTMLImageElement).src = '/photo.svg';
|
||||
}
|
||||
</script>
|
||||
|
@ -7,19 +7,19 @@
|
||||
}" />
|
||||
<div class="w-full sm:w-[80%] mx-auto my-auto xl:w-full xl:px-12 ">
|
||||
<div class="space-25-55">
|
||||
<div class="flex flex-wrap-reverse gap-y-4 justify-between">
|
||||
<div class="flex justify-between">
|
||||
<h2 class="h2-bold-bounded">{{ $t('sign_up') }}</h2>
|
||||
<button @click="menuStore.navigateToItem()"
|
||||
<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">{{
|
||||
$t('back_to_home') }}</button>
|
||||
</div>
|
||||
<div class="space-y-[25px] sm:space-y-[30px]">
|
||||
<p>{{ $t('current_information') }}</p>
|
||||
<p>Obecné informace</p>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-[30px]">
|
||||
<div class="space-y-[15px]">
|
||||
<p class="pl-6">{{ $t('first_name') }}</p>
|
||||
<input :placeholder="$t('first_name')" type="text"
|
||||
class="text-sm sm:text-xl border 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" />
|
||||
class="text-sm sm:text-xl 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 class="space-y-[15px]">
|
||||
<p class="pl-6">{{ $t('last_name') }}</p>
|
||||
@ -29,7 +29,7 @@
|
||||
<div class="space-y-[15px]">
|
||||
<p class="pl-6">{{ $t('email') }}</p>
|
||||
<input :placeholder="$t('email')" type="text"
|
||||
class="text-sm sm:text-xl border 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" />
|
||||
class="text-sm sm:text-xl 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 class="space-y-[15px]" ref="dropdownRef">
|
||||
<p class="pl-6">{{ $t('phone') }}</p>
|
||||
@ -48,7 +48,7 @@
|
||||
</div>
|
||||
|
||||
<div v-if="dropCountry"
|
||||
class="mt-2 absolute bg-bg-light dark:bg-bg-dark rounded-[5px] ring-0 cursor-pointer w-[130px] sm:w-full border border-button py-[10px] px-[5px] overflow-hidden">
|
||||
class="mt-2 absolute bg-bg-light dark:bg-bg-dark rounded-[5px] ring-0 cursor-pointer w-full border border-button py-[10px] px-[5px] overflow-hidden">
|
||||
<div class="overflow-y-auto h-[200px] w-full">
|
||||
<p v-for="item in menuStore.countries" :key="item.iso_code"
|
||||
@click="() => { menuStore.selectedPhoneCountry = item; dropCountry = false }"
|
||||
@ -61,15 +61,14 @@
|
||||
|
||||
</div>
|
||||
<p class="text-sm sm:text-xl font-normal">{{ menuStore.selectedPhoneCountry.call_prefix
|
||||
}}</p>
|
||||
<input id="phone" :placeholder="$t('phone')" type="text"
|
||||
}}</p>
|
||||
<input :placeholder="$t('phone')" type="text"
|
||||
class="text-sm sm:text-xl placeholder:text-gray dark:placeholder:text-button-disabled text-bg-dark dark:text-bg-light px-6 h-[50px] sm:h-[67px] w-full focus:outline-none focus:ring-0" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="space-y-[15px]">
|
||||
<p class="pl-6">{{ $t('account_type') }}</p>
|
||||
<USelect v-model="selectedType"
|
||||
:items="component.front_section_lang && component.front_section_lang[0].data.account_types"
|
||||
<USelect v-model="selectedType" :items="component.front_section_lang[0].data.account_types"
|
||||
value-key="name" :searchable="false" :ui="{
|
||||
base: 'bg-inherit ring-0 cursor-pointer w-auto focus:ring-0 outline-none focus-visible:ring-0 h-[50px] sm:h-[67px] w-full p-0',
|
||||
trailing: 'hidden w-full',
|
||||
@ -84,9 +83,7 @@
|
||||
<div
|
||||
class="flex items-center justify-between gap-2 uppercase text-sm sm:text-xl border-2 border-block placeholder:text-gray dark:placeholder:text-button-disabled text-bg-dark dark:text-bg-light rounded-lg px-6 w-full h-[50px] sm:h-[67px]">
|
||||
<p class="truncate whitespace-nowrap">
|
||||
{{component.front_section_lang &&
|
||||
component.front_section_lang[0].data.account_types.find((item) => item.name
|
||||
=== modelValue)?.name}}
|
||||
{{ component.front_section_lang[0].data.account_types.find((item) => item.name === modelValue)?.name }}
|
||||
</p>
|
||||
<span> <i
|
||||
class="uil uil-angle-down text-2xl font-light cursor-pointer"></i></span>
|
||||
@ -112,15 +109,14 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="py-[25px] sm:py-12 border-b border-gray flex justify-center w-full">
|
||||
<UiButtonArrow type="fill" :arrow="true">{{ $t('sign_up') }}</UiButtonArrow>
|
||||
<UiButtonArrow type="fill" :arrow="true">{{ $t('login') }}</UiButtonArrow>
|
||||
</div>
|
||||
<div class="mt-[25px] sm:mt-[30px] w-full flex justify-center gap-3">
|
||||
<p class="cursor-pointer hover:underline transition-all">{{
|
||||
$t('is_account')
|
||||
}}</p>
|
||||
<p @click="menuStore.navigateToItem(menuStore.menuItems?.find((item) => item.id === 11))"
|
||||
class="text-button cursor-pointer hover:text-button-hover">{{
|
||||
$t('login')
|
||||
}}</p>
|
||||
<p class="text-button cursor-pointer hover:text-button-hover">{{
|
||||
$t('login')
|
||||
}}</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -154,9 +150,7 @@ const menuStore = useMenuStore()
|
||||
const dropdownRef = ref(null);
|
||||
const dropCountry = ref()
|
||||
|
||||
const selectedType = ref()
|
||||
if (props.component.front_section_lang)
|
||||
selectedType.value = props.component.front_section_lang[0].data.account_types[0].name
|
||||
const selectedType = ref(props.component.front_section_lang[0].data.account_types[0].name)
|
||||
|
||||
onClickOutside(dropdownRef, () => {
|
||||
dropCountry.value = false
|
||||
|
@ -9,7 +9,7 @@
|
||||
:placeholder="placeholder" :disabled="disabled"
|
||||
@input="$emit('update:modelValue', ($event.target as HTMLInputElement).value)"
|
||||
@focus="$emit('focus')" @blur="$emit('blur')"
|
||||
class="border border-block placeholder:text-gray dark:placeholder:text-button-disabled rounded-lg px-6 h-[50px] sm:h-[67px] w-full focus:outline-none focus:ring-0 focus:border-2" />
|
||||
class="border border-block placeholder:text-gray dark:placeholder:text-button-disabled rounded-lg px-6 h-[67px] w-full focus:outline-none focus:ring-0 focus:border-2" />
|
||||
<i v-if="disabled"
|
||||
class="uil uil-lock-alt text-[22px] absolute right-6 top-1/2 -translate-y-1/2 text-gray" />
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
<svg width="76" height="53" viewBox="0 0 76 53" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M76 49.8V2C76 0.9 75.1 0 74 0H2C0.9 0 0 0.9 0 2V50C0 52.5 3.3 52 2 52H74C77 52 75.6 47.4 76 49.8ZM6 48L28 19.3L46.4 43.4L49.9 48H6ZM55 48L50.5 42.2L58 32.4L69.9 48H55ZM72 44L59.6 27.8C58.8 26.7 57.2 26.7 56.4 27.8L48 38.8L29.6 14.8C28.8 13.7 27.2 13.7 26.4 14.8L4 44.1V4H72V44ZM49 10C45.1 10 42 13.1 42 17C42 20.9 45.1 24 49 24C52.9 24 56 20.9 56 17C56 13.1 52.8 10 49 10ZM49 20C47.4 20 46 18.7 46 17C46 15.3 47.3 14 49 14C50.7 14 52 15.3 52 17C52 18.7 50.6 20 49 20Z" fill="#525252"/>
|
||||
<path d="M76 49.8V2C76 0.9 75.1 0 74 0H2C0.9 0 0 0.9 0 2V50C0 52.5 3.3 52 2 52H74C77 52 75.6 47.4 76 49.8ZM6 48L28 19.3L46.4 43.4L49.9 48H6ZM55 48L50.5 42.2L58 32.4L69.9 48H55ZM72 44L59.6 27.8C58.8 26.7 57.2 26.7 56.4 27.8L48 38.8L29.6 14.8C28.8 13.7 27.2 13.7 26.4 14.8L4 44.1V4H72V44ZM49 10C45.1 10 42 13.1 42 17C42 20.9 45.1 24 49 24C52.9 24 56 20.9 56 17C56 13.1 52.8 10 49 10ZM49 20C47.4 20 46 18.7 46 17C46 15.3 47.3 14 49 14C50.7 14 52 15.3 52 17C52 18.7 50.6 20 49 20Z" fill="#004F3D"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 598 B After Width: | Height: | Size: 598 B |
@ -1,26 +1,13 @@
|
||||
import type { GenericResponse, GenericResponseItems, UserCart } from "~/types";
|
||||
import type {
|
||||
Address,
|
||||
AddressesList,
|
||||
CheckoutOrder,
|
||||
Payment,
|
||||
UserAddressOfficial,
|
||||
} from "~/types/checkout";
|
||||
import type { GenericResponse } from "~/types";
|
||||
import type { AddressesList, UserAddressOfficial } from "~/types/checkout";
|
||||
import { validation } from "../utils/validation";
|
||||
import { REGEX_PHONE } from "../utils/regex";
|
||||
import type { CartProduct } from "~/types/product";
|
||||
|
||||
export const useCheckoutStore = defineStore("checkoutStore", () => {
|
||||
const { $toast } = useNuxtApp();
|
||||
const menuStore = useMenuStore();
|
||||
const selectedIso = ref(menuStore.selectedCountry);
|
||||
|
||||
const vLegal = ref(false);
|
||||
const vTerms = ref(false);
|
||||
const vNote = ref("");
|
||||
const legalValidation = ref(false);
|
||||
const termsValidation = ref(false);
|
||||
|
||||
// get address list
|
||||
const addressesList = ref<AddressesList[]>();
|
||||
const activeAddress = ref<AddressesList | null>();
|
||||
@ -148,8 +135,8 @@ export const useCheckoutStore = defineStore("checkoutStore", () => {
|
||||
};
|
||||
const phoneValidation = ref<boolean | null>(null);
|
||||
|
||||
// send checkout form
|
||||
const userStore = useUserStore();
|
||||
// send form
|
||||
async function sendForm() {
|
||||
let phoneNum = vUseAccountPhoneNumber.value
|
||||
? accountPhoneNumber.value
|
||||
@ -197,9 +184,7 @@ export const useCheckoutStore = defineStore("checkoutStore", () => {
|
||||
autoClose: 5000,
|
||||
dangerouslyHTMLString: true,
|
||||
});
|
||||
menuStore.navigateToItem(
|
||||
menuStore.menuItems?.find((item) => item.id === 13)
|
||||
);
|
||||
// redirectToSummary();
|
||||
} else {
|
||||
$toast.error("Failed to send form. Please try again.", {
|
||||
autoClose: 5000,
|
||||
@ -215,7 +200,6 @@ export const useCheckoutStore = defineStore("checkoutStore", () => {
|
||||
activeAddress.value = item;
|
||||
};
|
||||
|
||||
// get checkout
|
||||
async function getCheckout() {
|
||||
try {
|
||||
const res = await useMyFetch<GenericResponse<object>>(
|
||||
@ -238,267 +222,6 @@ export const useCheckoutStore = defineStore("checkoutStore", () => {
|
||||
}
|
||||
}
|
||||
|
||||
// get user cart
|
||||
const products = ref<CartProduct[]>();
|
||||
const fullPrice = ref();
|
||||
const fullProductsPrice = ref();
|
||||
async function getUserCart() {
|
||||
try {
|
||||
const { data } = await useMyFetch<GenericResponse<UserCart>>(
|
||||
`/api/public/user/cart`,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
onErrorOccured: async (_, status) => {
|
||||
throw createError({
|
||||
statusCode: status,
|
||||
statusMessage: `HTTP error: ${status}`,
|
||||
});
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
products.value = data.cart_items;
|
||||
fullPrice.value = data.total_value;
|
||||
fullProductsPrice.value = data.total_value;
|
||||
fullPrice.value = Number(fullPrice.value) + Number(shippingPrice.value);
|
||||
} catch (error) {
|
||||
console.error("getUserCart error:", error);
|
||||
}
|
||||
}
|
||||
|
||||
// get delivery options
|
||||
const deliveryOption = ref();
|
||||
const currentDelivery = ref();
|
||||
const shippingPrice = ref();
|
||||
async function getDeliveryOptions() {
|
||||
try {
|
||||
const res = await useMyFetch<
|
||||
GenericResponseItems<object>
|
||||
// {
|
||||
// items: [
|
||||
// {
|
||||
// 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",
|
||||
},
|
||||
{
|
||||
id: 34,
|
||||
shippment_price: "20",
|
||||
delivery_supplier_id: 1,
|
||||
delivery_supplier_name: "Ceska Posta",
|
||||
country_iso: "pl",
|
||||
country_name: "Poland",
|
||||
},
|
||||
],
|
||||
items_count: 2,
|
||||
};
|
||||
|
||||
deliveryOption.value = data.items;
|
||||
currentDelivery.value = data.items[0];
|
||||
shippingPrice.value = data.items[0].shippment_price;
|
||||
fullPrice.value = Number(fullPrice.value) + Number(shippingPrice.value);
|
||||
} catch (error) {
|
||||
console.error("getUserCart error:", error);
|
||||
}
|
||||
}
|
||||
|
||||
const setCurrentDelivery = (item: any) => {
|
||||
shippingPrice.value = item.shippment_price;
|
||||
currentDelivery.value = item;
|
||||
fullPrice.value = Number(fullPrice.value) + Number(shippingPrice.value);
|
||||
};
|
||||
|
||||
const defaultAddress = ref();
|
||||
async function getDefAddress() {
|
||||
try {
|
||||
const { data } = await useMyFetch<
|
||||
GenericResponse<{
|
||||
addresses: [
|
||||
{
|
||||
is_default: string;
|
||||
}
|
||||
];
|
||||
}>
|
||||
>(`/api/public/user`, {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
onErrorOccured: async (_, status) => {
|
||||
throw createError({
|
||||
statusCode: status,
|
||||
statusMessage: `HTTP error: ${status}`,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
defaultAddress.value = data.addresses.find(
|
||||
(el: any) => el.is_default === true
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("getUserCart error:", error);
|
||||
}
|
||||
}
|
||||
|
||||
// get bank data
|
||||
const paymentMethods = ref([] as Payment[]);
|
||||
const fullAddress = ref<Address>();
|
||||
const currentPayment = ref<Payment | null>(null);
|
||||
async function getBankAccount() {
|
||||
try {
|
||||
const { data } = await useMyFetch<GenericResponse<Payment[]>>(
|
||||
`/api/restricted/suitable-bank-accounts/${menuStore.selectedCurrency.iso_code}/${fullAddress.value?.country_iso}`,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
onErrorOccured: async (_, status) => {
|
||||
throw createError({
|
||||
statusCode: status,
|
||||
statusMessage: `HTTP error: ${status}`,
|
||||
});
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
paymentMethods.value = data;
|
||||
currentPayment.value = data[0];
|
||||
} catch (error) {
|
||||
console.error("getUserCart error:", error);
|
||||
}
|
||||
}
|
||||
|
||||
// get order (summary)
|
||||
async function getOrder() {
|
||||
try {
|
||||
const { data } = await useMyFetch<GenericResponse<CheckoutOrder>>(
|
||||
`/api/restricted/cart/checkout/order`,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
onErrorOccured: async (_, status) => {
|
||||
throw createError({
|
||||
statusCode: status,
|
||||
statusMessage: `HTTP error: ${status}`,
|
||||
});
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
fullAddress.value = data.delivery_details.address;
|
||||
console.log(fullAddress.value);
|
||||
} catch (error) {
|
||||
console.error("getOrder error:", error);
|
||||
}
|
||||
}
|
||||
|
||||
async function setNewAddress(index: number) {
|
||||
currentPayment.value = paymentMethods.value.find(
|
||||
(item, index) => index === index
|
||||
);
|
||||
}
|
||||
|
||||
// send summary form
|
||||
async function sendSummaryForm() {
|
||||
vLegal.value
|
||||
? (legalValidation.value = false)
|
||||
: (legalValidation.value = true);
|
||||
vTerms.value
|
||||
? (termsValidation.value = false)
|
||||
: (termsValidation.value = true);
|
||||
// if (vTerms.value && vLegal.value) {
|
||||
// isModalOpen.value = true;
|
||||
// }
|
||||
|
||||
try {
|
||||
const res = await useMyFetch<GenericResponse<object>>(
|
||||
`/api/restricted/cart/checkout/delivery`,
|
||||
{
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
accept_general_conditions: true,
|
||||
accept_long_purchase: true,
|
||||
address: fullAddress.value,
|
||||
delivery_option_id: currentDelivery.value.id,
|
||||
note: vNote.value,
|
||||
}),
|
||||
onErrorOccured: async (_, status) => {
|
||||
throw createError({
|
||||
statusCode: status,
|
||||
statusMessage: `HTTP error: ${status}`,
|
||||
});
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
putCheckoutBankAccount();
|
||||
} catch (error) {
|
||||
console.error("uploadAddress error:", error);
|
||||
}
|
||||
}
|
||||
|
||||
// put checkout bank-account
|
||||
async function putCheckoutBankAccount() {
|
||||
try {
|
||||
const res = await useMyFetch<GenericResponse<object>>(
|
||||
`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,
|
||||
statusMessage: `HTTP error: ${status}`,
|
||||
});
|
||||
},
|
||||
}
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("uploadAddress error:", error);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
addressesList,
|
||||
activeAddress,
|
||||
@ -524,22 +247,6 @@ export const useCheckoutStore = defineStore("checkoutStore", () => {
|
||||
vNewAddressCity,
|
||||
vNewAddressCountry,
|
||||
|
||||
products,
|
||||
fullPrice,
|
||||
fullProductsPrice,
|
||||
deliveryOption,
|
||||
currentDelivery,
|
||||
shippingPrice,
|
||||
defaultAddress,
|
||||
paymentMethods,
|
||||
currentPayment,
|
||||
|
||||
vLegal,
|
||||
vTerms,
|
||||
vNote,
|
||||
legalValidation,
|
||||
termsValidation,
|
||||
|
||||
changePrefix,
|
||||
getCheckout,
|
||||
getAddressList,
|
||||
@ -547,12 +254,5 @@ export const useCheckoutStore = defineStore("checkoutStore", () => {
|
||||
changeActive,
|
||||
uploadAddress,
|
||||
sendForm,
|
||||
getUserCart,
|
||||
getDeliveryOptions,
|
||||
getDefAddress,
|
||||
setCurrentDelivery,
|
||||
getBankAccount,
|
||||
getOrder,
|
||||
setNewAddress,
|
||||
};
|
||||
});
|
||||
|
@ -11,6 +11,7 @@ import { useStore } from "./store";
|
||||
import { useMyFetch } from "#imports";
|
||||
// import { useSession } from "~/plugins/01_i18n";
|
||||
|
||||
|
||||
function buildTreeRecursive(
|
||||
data: (FrontMenu | UIFrontMenu)[],
|
||||
parentId: number
|
||||
@ -39,50 +40,42 @@ export const useMenuStore = defineStore("menuStore", () => {
|
||||
|
||||
const defaultMenu = ref();
|
||||
|
||||
|
||||
const menu = ref([] as UIFrontMenu[]);
|
||||
const menuItems = ref([] as FrontMenu[]);
|
||||
|
||||
|
||||
// curr/country
|
||||
const selectedCountry = ref({} as Country);
|
||||
const selectedPhoneCountry = ref({} as Country);
|
||||
const selectedCurrency = ref({} as Currency);
|
||||
const selectedLanguage = ref({} as Language);
|
||||
|
||||
|
||||
const countries = ref([] as Country[]);
|
||||
const currencies = ref([] as Currency[]);
|
||||
const languages = ref([] as Language[]);
|
||||
|
||||
const getLocales = async () => {
|
||||
const { data: countriesList } = await useMyFetch<
|
||||
GenericResponse<Country[]>
|
||||
>(`/api/public/country/list`);
|
||||
const { data: countriesList } = await useMyFetch<GenericResponse<Country[]>>(`/api/public/country/list`);
|
||||
countries.value = countriesList;
|
||||
selectedCountry.value = countriesList.find(
|
||||
(country) => country.iso_code === $session.currentCountryIso.value
|
||||
) as Country;
|
||||
selectedPhoneCountry.value = countriesList.find(
|
||||
(country) => country.iso_code === $session.currentCountryIso.value
|
||||
) as Country;
|
||||
selectedCountry.value = countriesList.find((country) => country.iso_code === $session.currentCountryIso.value) as Country;
|
||||
selectedPhoneCountry.value = countriesList.find((country) => country.iso_code === $session.currentCountryIso.value) as Country;
|
||||
|
||||
const { data: currenciesList } = await useMyFetch<
|
||||
GenericResponseItems<Currency[]>
|
||||
>(`/api/public/currencies`);
|
||||
|
||||
const { data: currenciesList } = await useMyFetch<GenericResponseItems<Currency[]>>(`/api/public/currencies`)
|
||||
currencies.value = currenciesList.items;
|
||||
selectedCurrency.value = currenciesList.items.find(
|
||||
(currency) => currency.iso_code === $session.currentCurrencyIso.value
|
||||
) as Currency;
|
||||
selectedCurrency.value = currenciesList.items.find((currency) => currency.iso_code === $session.currentCurrencyIso.value) as Currency;
|
||||
|
||||
const { data: languagesList } = await useMyFetch<
|
||||
GenericResponseItems<Language[]>
|
||||
>(`/api/public/languages`);
|
||||
const { data: languagesList } = await useMyFetch<GenericResponseItems<Language[]>>(`/api/public/languages`)
|
||||
languages.value = languagesList.items;
|
||||
selectedLanguage.value = languagesList.items.find(
|
||||
(language) => language.iso_code === $session.currentLanguageIso.value
|
||||
) as Language;
|
||||
selectedLanguage.value = languagesList.items.find((language) => language.iso_code === $session.currentLanguageIso.value) as Language;
|
||||
};
|
||||
|
||||
|
||||
const loadMenu = async () => {
|
||||
try {
|
||||
|
||||
const { data } = await useMyFetch<GenericResponse<FrontMenu[]>>(
|
||||
`/api/public/front/menu`,
|
||||
{
|
||||
@ -107,6 +100,7 @@ export const useMenuStore = defineStore("menuStore", () => {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const navigateToItem = (item?: UIFrontMenu) => {
|
||||
if (item) {
|
||||
router.push({
|
||||
@ -133,21 +127,15 @@ export const useMenuStore = defineStore("menuStore", () => {
|
||||
const req = useRequestEvent();
|
||||
const url = useRequestURL();
|
||||
// let img = "";
|
||||
const img: string[] = [];
|
||||
const img: string[] = []
|
||||
for (const s in store.components) {
|
||||
if (store.components[s].front_section.img.length === 0) continue;
|
||||
img.push(
|
||||
`/api/public/file/${store.components[s].front_section.img[0]}_${size}.webp`
|
||||
);
|
||||
if (img.length > 0) break;
|
||||
img.push(`/api/public/file/${store.components[s].front_section.img[0]}_${size}.webp`)
|
||||
if (img.length > 0) break;;
|
||||
}
|
||||
if (img.length > 0) {
|
||||
if (needbaseurl) {
|
||||
return `${req?.headers.get("x-forwarded-proto") || url.protocol}://${
|
||||
req?.headers.get("x-forwarded-host") ||
|
||||
url.host ||
|
||||
req?.headers.get("host")
|
||||
}${img[0]}`;
|
||||
return `${req?.headers.get("x-forwarded-proto") || url.protocol}://${req?.headers.get("x-forwarded-host") || url.host || req?.headers.get("host")}${img[0]}`;
|
||||
}
|
||||
return img[0];
|
||||
}
|
||||
@ -167,9 +155,6 @@ export const useMenuStore = defineStore("menuStore", () => {
|
||||
link: [
|
||||
// { rel: "manifest", href: "/api/manifest.json" }
|
||||
],
|
||||
script:[
|
||||
{src:"https://leiadmin.com/leitag.js?lei=894500UT83EISNNA8D04&color=dark"}
|
||||
],
|
||||
meta: [
|
||||
{
|
||||
hid: "description",
|
||||
@ -209,30 +194,16 @@ export const useMenuStore = defineStore("menuStore", () => {
|
||||
}
|
||||
|
||||
return meta;
|
||||
|
||||
});
|
||||
|
||||
const formatPrice = (value: number): string => {
|
||||
return value.toLocaleString(selectedLanguage.value.iso_code, {
|
||||
minimumFractionDigits: selectedCurrency.value.precision,
|
||||
maximumFractionDigits: selectedCurrency.value.precision,
|
||||
currency: selectedCurrency.value.iso_code,
|
||||
style: "currency",
|
||||
currencyDisplay: "symbol",
|
||||
currencySign: "accounting",
|
||||
});
|
||||
};
|
||||
|
||||
// watches
|
||||
watch(
|
||||
() => $session.cookieData,
|
||||
async () => {
|
||||
await getLocales();
|
||||
await loadMenu();
|
||||
await store.getMinValue();
|
||||
await store.getCalculator();
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
watch(() => $session.cookieData, async () => {
|
||||
await getLocales();
|
||||
await loadMenu();
|
||||
await store.getMinValue();
|
||||
await store.getCalculator();
|
||||
}, { deep: true });
|
||||
|
||||
return {
|
||||
menu,
|
||||
@ -248,11 +219,9 @@ export const useMenuStore = defineStore("menuStore", () => {
|
||||
selectedLanguage,
|
||||
defaultMenu,
|
||||
headMeta,
|
||||
|
||||
navigateToShop,
|
||||
loadMenu,
|
||||
navigateToItem,
|
||||
getLocales,
|
||||
formatPrice,
|
||||
};
|
||||
});
|
||||
|
@ -30,42 +30,3 @@ export interface UserAddressOfficial {
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export interface Payment {
|
||||
bank_name: string;
|
||||
city: string;
|
||||
country_account_number: string;
|
||||
country_iso: string;
|
||||
country_name: string;
|
||||
currency_iso: string;
|
||||
iban: string;
|
||||
id: number;
|
||||
postcode: string;
|
||||
street_and_number: string;
|
||||
swift: string;
|
||||
}
|
||||
|
||||
export interface CheckoutOrder {
|
||||
cart_id: number;
|
||||
currency_iso: string;
|
||||
customer_id: number;
|
||||
delivery_details: {
|
||||
address: Address;
|
||||
contact_email: string;
|
||||
contact_phone_number: string;
|
||||
delivery_option_id: number;
|
||||
note: string;
|
||||
};
|
||||
payment_bank_account_id: number;
|
||||
}
|
||||
|
||||
export interface Address {
|
||||
city: string;
|
||||
country_iso: {
|
||||
str: string;
|
||||
};
|
||||
name: string;
|
||||
postcode: string;
|
||||
street: string;
|
||||
surname: string;
|
||||
}
|
||||
|
@ -1,26 +0,0 @@
|
||||
export interface Footer {
|
||||
data: {
|
||||
contact: Contact
|
||||
docs: FooterDoc[]
|
||||
}
|
||||
id: number
|
||||
name: string
|
||||
}
|
||||
|
||||
export interface Contact {
|
||||
header: string
|
||||
ownerAddress: string
|
||||
ownerMail: string
|
||||
}
|
||||
|
||||
export interface FooterDoc {
|
||||
footer_section: string
|
||||
translation: string
|
||||
data: FooterPdf[]
|
||||
}
|
||||
|
||||
export interface FooterPdf {
|
||||
name: string
|
||||
translation: string
|
||||
guest_avaliable: boolean
|
||||
}
|
@ -126,4 +126,3 @@ export type {
|
||||
} from "./planPrediction";
|
||||
export type { Product } from "./product";
|
||||
export type { FrontMenu, FrontMenuLang, UIFrontMenu } from "./frontMenu";
|
||||
export type {Contact, Footer, FooterDoc, FooterPdf} from './footer'
|
@ -11,22 +11,3 @@ export interface Product {
|
||||
applied_tax_rate: number;
|
||||
tax_name: string;
|
||||
}
|
||||
|
||||
export interface CartProduct {
|
||||
cart_item_id: number;
|
||||
link_rewrite: string;
|
||||
name: string;
|
||||
picture_uuid: string;
|
||||
product_id: number;
|
||||
quantity: number;
|
||||
single_item_price: number;
|
||||
total_price: number;
|
||||
}
|
||||
|
||||
export interface UserCart {
|
||||
cart_items: CartProduct[];
|
||||
checkout_in_progress: boolean;
|
||||
currency_iso: string;
|
||||
id: number;
|
||||
total_value: number;
|
||||
}
|
||||
|
Reference in New Issue
Block a user