import type { GenericResponse, GenericResponseItems, UserCart } from "~/types"; import type { Address, AddressesList, CheckoutOrder, Payment, 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(); 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() { let 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}`, }); }, } ); 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); } } const changeActive = (item: any) => { activeAddress.value = item; }; // get checkout async function getCheckout() { try { const res = 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 const deliveryOption = ref(); const currentDelivery = ref(); const shippingPrice = ref(); async function getDeliveryOptions() { try { const res = await useMyFetch< GenericResponseItems // { // 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
(); const currentPayment = ref(null); 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; 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>( `/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>( `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, 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, vLegal, vTerms, vNote, legalValidation, termsValidation, changePrefix, getCheckout, getAddressList, getUserData, changeActive, uploadAddress, sendForm, getUserCart, getDeliveryOptions, getDefAddress, setCurrentDelivery, getBankAccount, getOrder, setNewAddress, }; });