Files
your-gold/components/section/CheckoutMain.vue
2025-07-03 11:13:42 +02:00

465 lines
18 KiB
Vue

<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>
</div>
</div>
<div class="space-y-[25px] sm: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]">
<CheckoutInput :id="1"
v-model="checkoutStore.userName"
disabled
>
{{ $t("first_name") }}
</CheckoutInput>
<CheckoutInput :id="2"
v-model="checkoutStore.lastName"
disabled
>
{{ $t("surname") }}
</CheckoutInput>
<CheckoutInput :id="3"
v-model="checkoutStore.address"
disabled
>
{{ $t("address") }}
</CheckoutInput>
<CheckoutInput :id="4"
v-model="checkoutStore.postCode"
disabled
>
{{ $t("post_code") }}
</CheckoutInput>
</div>
<div class="flex flex-col sm:w-1/2 gap-[30px]">
<CheckoutInput :id="5"
v-model="checkoutStore.city"
disabled
>
{{ $t("city") }}
</CheckoutInput>
<CheckoutInput :id="6"
v-model="checkoutStore.country"
disabled
>
{{ $t("country") }}
</CheckoutInput>
<CheckoutInput
:id="7"
v-model="checkoutStore.accountPhoneNumber"
disabled
>
{{ $t("phone") }}
</CheckoutInput>
</div>
</div>
</div>
<div class="space-y-[30px]">
<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
v-if="!checkoutStore.vUseAccountPhoneNumber"
class="flex items-center gap-5 sm:gap-[25px]"
>
<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"
>
<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="uil uil-angle-down text-2xl font-light cursor-pointer"
/></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"
>
<p
v-for="item in menuStore.countries"
:key="item.iso_code"
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]"
@click="
() => {
checkoutStore.selectedIso = item;
dropIso = false;
checkoutStore.changePrefix(
item.call_prefix as string,
);
}
"
>
{{ item?.name }}
</p>
</div>
</div>
</div>
</div>
<p class="text-sm sm:text-xl border-r pr-[10px] border-block">
{{ checkoutStore.currentPrefix }}
</p>
</div>
<input
id="phone"
:value="
checkoutStore.vUseAccountPhoneNumber
? checkoutStore.accountPhoneNumber
: checkoutStore.phoneNumber
"
:disabled="checkoutStore.vUseAccountPhoneNumber"
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"
@input="
(e) => {
if (!checkoutStore.vUseAccountPhoneNumber) {
checkoutStore.phoneNumber = (
e.target as HTMLInputElement
).value;
}
}
"
>
</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"
type="checkbox"
class="border border-button !bg-inherit"
@change="
(event: Event) => {
const target = event.target as HTMLInputElement;
target.checked
? (checkoutStore.vUseAccountPhoneNumber = true)
: (checkoutStore.vUseAccountPhoneNumber = false);
checkoutStore.phoneValidation = null;
}
"
>
<p>{{ $t("use_account_phone") }}</p>
</div>
</div>
<div class="space-y-[30px] h-full">
<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
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',
]"
>
<div
:class="[
'flex flex-col justify-between gap-[10px] 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"
type="checkbox"
class="border border-button !bg-inherit"
@change="
(event: Event) => {
const target = event.target as HTMLInputElement;
target.checked
? (checkoutStore.activeAddress = item)
: (checkoutStore.activeAddress = null);
checkoutStore.isOpen = false;
}
"
>
<p>{{ $t("choose_default_address") }}</p>
</div>
</div>
</div>
<p class="uppercase">
{{ $t("or") }}
</p>
<div
: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 ',
]"
@click="
() => {
checkoutStore.isOpen = !checkoutStore.isOpen;
checkoutStore.activeAddress = null;
}
"
>
<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") }}
</h4>
</div>
</div>
<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]">
<CheckoutInput
:id="8"
v-model="checkoutStore.vNewAddressName"
:placeholder="$t('first_name')"
>
{{ $t("first_name") }}
</CheckoutInput>
<CheckoutInput
:id="9"
v-model="checkoutStore.vNewAddressAddress"
:placeholder="$t('address')"
>
{{ $t("address") }}
</CheckoutInput>
<CheckoutInput
:id="10"
v-model="checkoutStore.vNewAddressCity"
:placeholder="$t('city')"
>
{{ $t("city") }}
</CheckoutInput>
</div>
<div class="flex flex-col sm:w-1/2 gap-[25px] sm:gap-[30px]">
<CheckoutInput
:id="11"
v-model="checkoutStore.vNewAddressSurname"
:placeholder="$t('surname')"
>
{{ $t("surname") }}
</CheckoutInput>
<div class="space-y-[15px]">
<p class="pl-6">
{{ $t("country") }}
</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"
@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"
>
{{
checkoutStore.vNewAddressCountry
? checkoutStore.vNewAddressCountry.name
: "-"
}}
<span>
<i
class="uil uil-angle-down text-2xl font-light cursor-pointer"
/></span>
</div>
</div>
<div
v-if="dropCountry"
class="absolute z-50 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
v-for="item in menuStore.countries"
:key="item.iso_code"
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]"
@click="
() => {
checkoutStore.vNewAddressCountry = item;
dropCountry = false;
}
"
>
{{ item?.name }}
</p>
</div>
</div>
</div>
</div>
<CheckoutInput
:id="13"
v-model="checkoutStore.vNewAddressCode"
:placeholder="$t('post_code')"
>
{{ $t("post_code") }}
</CheckoutInput>
</div>
</div>
<div>
<span v-if="addressValidation === false"
class="text-red"
>
{{ $t("Remember to select a shipping address") }}</span>
<div
class="group flex cursor-pointer items-center justify-start gap-2 whitespace-nowrap"
>
<button
:class="[
'h-[40px] cursor-pointer min-w-40 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="checkoutStore.uploadAddress()"
>
{{ $t("add_new_address") }}
</button>
</div>
</div>
</div>
</div>
<div class="flex justify-center">
<div
class="group flex cursor-pointer items-center justify-start gap-2 whitespace-nowrap"
>
<button
:disabled="!checkoutStore.activeAddress"
:class="[
'h-[40px] cursor-pointer min-w-40 rounded-[10px] px-[22px] transition-all sm:h-[50px] md:h-[65px] md:rounded-[15px] md:px-[42px]',
checkoutStore.activeAddress
? 'bg-button text-text-dark group-hover:bg-button-hover'
: ' bg-button-disabled text-gray',
]"
@click="checkoutStore.sendForm()"
>
{{ $t("continue") }}
</button>
<div
:class="[
'flex h-[40px] w-[40px] items-center justify-center rounded-[10px] p-2.5 transition-all sm:h-[50px] sm:w-[50px] md:h-[65px] md:w-[65px] md:rounded-[15px]',
checkoutStore.activeAddress
? 'bg-button text-text-dark group-hover:bg-button-hover'
: ' bg-button-disabled text-gray',
]"
>
<svg
class=""
width=" 26"
height="26"
viewBox="0 0 26 26"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M25.1274 1.87258C25.1274 1.3203 24.6797 0.872582 24.1274 0.872584L15.1274 0.872583C14.5751 0.872583 14.1274 1.3203 14.1274 1.87258C14.1274 2.42487 14.5751 2.87258 15.1274 2.87258L23.1274 2.87258L23.1274 10.8726C23.1274 11.4249 23.5751 11.8726 24.1274 11.8726C24.6797 11.8726 25.1274 11.4249 25.1274 10.8726L25.1274 1.87258ZM1.5 24.5L2.20711 25.2071L24.8345 2.57969L24.1274 1.87258L23.4203 1.16548L0.792893 23.7929L1.5 24.5Z"
fill="currentColor"
/>
</svg>
</div>
</div>
</div>
</div>
</div>
</UiContainer>
</template>
<script setup lang="ts">
import { onClickOutside } from '@vueuse/core'
import CheckoutInput from '../ui/CheckoutInput.vue'
const checkoutStore = useCheckoutStore()
const menuStore = useMenuStore()
const dropIso = ref(false)
const dropCountry = ref(false)
const addressValidation = ref<null | boolean>(null)
const dropdownIsoRef = ref(null)
const dropdownCountryRef = ref(null)
onClickOutside(dropdownIsoRef, () => {
dropIso.value = false
})
onClickOutside(dropdownCountryRef, () => {
dropCountry.value = false
})
checkoutStore.getCheckout()
checkoutStore.getAddressList()
checkoutStore.getUserData()
</script>