import { validation } from '../utils/validation' import { REGEX_PHONE } from '../utils/regex' import type { GenericResponse, GenericResponseItems, UserCart } from '~/types' import type { AddressesList, CheckoutOrder, Payment, UserAddressOfficial, } from '~/types/checkout' import type { 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() const activeAddress = ref() async function getAddressList() { try { const { data } = await useMyFetch>( `/api/restricted/user/addresses`, { headers: { 'Content-Type': 'application/json', }, onErrorOccured: async (_, status) => { throw createError({ statusCode: status, statusMessage: `HTTP error: ${status}`, }) }, }, ) addressesList.value = data activeAddress.value = addressesList.value[0] } catch (error) { console.error('restrictedAddress error:', error) } } // get user data const userName = ref('') const lastName = ref('') const address = ref('') const postCode = ref('') const city = ref('') const country = ref('') const phoneNumber = ref('') const accountPhoneNumber = ref('') async function getUserData() { try { const { data } = await useMyFetch>( `/api/restricted/user/address/official`, { headers: { 'Content-Type': 'application/json', }, onErrorOccured: async (_, status) => { throw createError({ statusCode: status, statusMessage: `HTTP error: ${status}`, }) }, }, ) userName.value = data.address.name lastName.value = data.address.surname address.value = data.address.street postCode.value = data.address.postcode city.value = data.address.city country.value = data.address.country.country_lang[0].name } catch (error) { console.error('getUserData error:', error) } } // upload new address const vNewAddressName = ref('') const vNewAddressSurname = ref('') const vNewAddressAddress = ref('') const vNewAddressCode = ref('') const vNewAddressCity = ref('') const vNewAddressCountry = ref() const vUseAccountPhoneNumber = ref(false) const isOpen = ref(false) async function uploadAddress() { try { const res = await useMyFetch>( `/api/restricted/user/address`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ address: { city: vNewAddressCity.value, country_iso: vNewAddressCountry.value.iso_code, name: vNewAddressName.value, postcode: vNewAddressCode.value, street: vNewAddressAddress.value, surname: vNewAddressSurname.value, }, }), onErrorOccured: async (_, status) => { throw createError({ statusCode: status, statusMessage: `HTTP error: ${status}`, }) }, }, ) if (res.status === 200) { $toast.success('Address successfully added', { autoClose: 5000, dangerouslyHTMLString: true, }) isOpen.value = false getAddressList() } else { $toast.error('Failed to add address. Please try again.', { autoClose: 5000, dangerouslyHTMLString: true, }) } } catch (error) { console.error('uploadAddress error:', error) } } const currentPrefix = ref( menuStore.selectedCountry.call_prefix, ) const changePrefix = (item: string) => { currentPrefix.value = item } const phoneValidation = ref(null) // send checkout form const userStore = useUserStore() async function sendForm() { const phoneNum = vUseAccountPhoneNumber.value ? accountPhoneNumber.value : `${currentPrefix.value}${phoneNumber.value}`.replaceAll(' ', '').trim() // if (vUseAccountPhoneNumber.value) { // phoneNum = phoneNumber.value; // } phoneValidation.value = validation(phoneNum, 1, 49, REGEX_PHONE) if (!phoneValidation.value && !vUseAccountPhoneNumber.value) { return } try { const res = await useMyFetch>( `/api/restricted/cart/checkout/delivery`, { method: 'PUT', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ address: { city: activeAddress.value?.address.city, country_iso: activeAddress.value?.address.country_iso, name: activeAddress.value?.address.name, postcode: activeAddress.value?.address.postcode, street: activeAddress.value?.address.street, surname: activeAddress.value?.address.surname, }, phone_number: phoneNum, email: userStore.fullUserData?.email, }), onErrorOccured: async (_, status) => { throw createError({ statusCode: status, statusMessage: `HTTP error: ${status}`, }) }, }, ) console.log(res) if (res.status === 200) { $toast.success('Form successfully sent', { autoClose: 5000, dangerouslyHTMLString: true, }) menuStore.navigateToItem( menuStore.menuItems?.find(item => item.id === 13), ) } else { $toast.error('Failed to send form. Please try again.', { autoClose: 5000, dangerouslyHTMLString: true, }) } } catch (error) { console.error('uploadAddress error:', error) } } // get checkout async function getCheckout() { try { await useMyFetch>( `/api/restricted/cart/checkout`, { method: 'PUT', headers: { 'Content-Type': 'application/json', }, onErrorOccured: async (_, status) => { throw createError({ statusCode: status, statusMessage: `HTTP error: ${status}`, }) }, }, ) } catch (error) { console.error('uploadAddress error:', error) } } // get user cart const products = ref() const fullPrice = ref() const fullProductsPrice = ref() async function getUserCart() { try { const { data } = await useMyFetch>( `/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 interface DeliveryOptionItem { country_iso: string country_name: string delivery_supplier_id: number delivery_supplier_name: string id: number shippment_price: string } const deliveryOption = ref([]) const currentDelivery = ref(null) const shippingPrice = ref(0) async function getDeliveryOptions() { try { const { data } = await useMyFetch>( `/api/restricted/cart/checkout/delivery-options`, { headers: { 'Content-Type': 'application/json', }, onErrorOccured: async (_, status) => { throw createError({ statusCode: status, statusMessage: `HTTP error: ${status}`, }) }, }, ) if (data.items && data.items.length > 0) { deliveryOption.value = data.items currentDelivery.value = data.items[0] shippingPrice.value = Number(data.items[0].shippment_price) fullPrice.value += shippingPrice.value } } catch (error) { console.error('getDeliveryOptions error:', error) } } const setCurrentDelivery = (item: DeliveryOptionItem) => { shippingPrice.value = Number(item.shippment_price) currentDelivery.value = item fullPrice.value = Number(fullPrice.value) + Number(shippingPrice.value) } interface Address { is_default: boolean | string country_iso: string } const defaultAddress = ref
() async function getDefAddress() { try { const { data } = await useMyFetch>( `/api/public/user`, { headers: { 'Content-Type': 'application/json', }, onErrorOccured: async (_, status) => { throw createError({ statusCode: status, statusMessage: `HTTP error: ${status}`, }) }, }, ) defaultAddress.value = data.addresses.find( el => el.is_default === true || el.is_default === 'true', ) } catch (error) { console.error('getUserCart error:', error) } } // get bank data const paymentMethods = ref([] as Payment[]) const fullAddress = ref
() const currentPayment = ref() async function getBankAccount() { try { const { data } = await useMyFetch>( `/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>( `/api/restricted/cart/checkout/order`, { headers: { 'Content-Type': 'application/json', }, onErrorOccured: async (_, status) => { throw createError({ statusCode: status, statusMessage: `HTTP error: ${status}`, }) }, }, ) fullAddress.value = data.delivery_details.address } catch (error) { console.error('getOrder error:', error) } } async function setNewAddress(indexItem: number) { currentPayment.value = paymentMethods.value.find( (item, index) => indexItem === index, ) } // send summary form async function sendSummaryForm() { legalValidation.value = !vLegal.value termsValidation.value = !vTerms.value if (!vTerms.value && !vLegal.value) { return } try { await useMyFetch>( `/api/restricted/cart/checkout/delivery`, { method: 'PUT', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ accept_general_conditions: true, accept_long_purchase: true, address: fullAddress.value, delivery_option_id: currentDelivery.value?.id, note: vNote.value, }), onErrorOccured: async (_, status) => { throw createError({ statusCode: status, statusMessage: `HTTP error: ${status}`, }) }, }, ) await putCheckoutBankAccount() await markOrder() await getUserCart() } catch (error) { console.error('uploadAddress error:', error) } } // put checkout bank-account async function putCheckoutBankAccount() { try { await useMyFetch>( `/api/restricted/cart/checkout/bank-account/${currentPayment.value?.id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json', }, onErrorOccured: async (_, status) => { throw createError({ statusCode: status, statusMessage: `HTTP error: ${status}`, }) }, }, ) } catch (error) { console.error('uploadAddress error:', error) } } const modalMadeOrder = ref(false) async function markOrder() { try { const res = await useMyFetch>( `/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, isOpen, selectedIso, phoneValidation, userName, lastName, address, postCode, city, country, phoneNumber, accountPhoneNumber, vUseAccountPhoneNumber, currentPrefix, vNewAddressName, vNewAddressSurname, vNewAddressAddress, vNewAddressCode, vNewAddressCity, vNewAddressCountry, products, fullPrice, fullProductsPrice, deliveryOption, currentDelivery, shippingPrice, defaultAddress, paymentMethods, currentPayment, fullAddress, vLegal, vTerms, vNote, legalValidation, termsValidation, modalMadeOrder, changePrefix, getCheckout, getAddressList, getUserData, uploadAddress, sendForm, getUserCart, getDeliveryOptions, getDefAddress, setCurrentDelivery, getBankAccount, getOrder, setNewAddress, sendSummaryForm, } })