Files
your-gold/stores/checkoutStore.ts
2025-07-03 13:24:45 +02:00

603 lines
16 KiB
TypeScript

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<AddressesList[]>()
const activeAddress = ref<AddressesList | null>()
async function getAddressList() {
try {
const { data } = await useMyFetch<GenericResponse<AddressesList[]>>(
`/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<GenericResponse<UserAddressOfficial>>(
`/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<boolean>(false)
async function uploadAddress() {
try {
const res = await useMyFetch<GenericResponse<object>>(
`/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<string | number>(
menuStore.selectedCountry.call_prefix,
)
const changePrefix = (item: string) => {
currentPrefix.value = item
}
const phoneValidation = ref<boolean | null>(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<GenericResponse<object>>(
`/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)
}
}
const changeActive = (item: any) => {
activeAddress.value = item
}
// get checkout
async function getCheckout() {
try {
await useMyFetch<GenericResponse<object>>(
`/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<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>();
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(indexItem: number) {
currentPayment.value = paymentMethods.value.find(
(item, index) => indexItem === 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) {
return;
}
try {
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}`,
});
},
}
);
await putCheckoutBankAccount();
await markOrder();
await getUserCart();
} catch (error) {
console.error("uploadAddress error:", error);
}
}
// put checkout bank-account
async function putCheckoutBankAccount() {
try {
const res = await useMyFetch<GenericResponse<object>>(
`/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<GenericResponse<object>>(
`/api/restricted/cart/checkout/order`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
onErrorOccured: async (_, status) => {
throw createError({
statusCode: status,
statusMessage: `HTTP error: ${status}`,
});
},
}
);
if (res.status === 200 || res.status === 201) {
$toast.success("Address successfully added", {
autoClose: 5000,
dangerouslyHTMLString: true,
});
modalMadeOrder.value = true;
} else {
$toast.error("Failed to add address. Please try again.", {
autoClose: 5000,
dangerouslyHTMLString: true,
});
}
// window.location.href = `/golden-panel/my-purchases/${res._data?.data.id}`;
} catch (error) {
console.error("uploadAddress error:", error);
}
}
return {
addressesList,
activeAddress,
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,
modalMadeOrder,
changePrefix,
getCheckout,
getAddressList,
getUserData,
changeActive,
uploadAddress,
sendForm,
getUserCart,
getDeliveryOptions,
getDefAddress,
setCurrentDelivery,
getBankAccount,
getOrder,
setNewAddress,
sendSummaryForm,
};
});