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

384 lines
10 KiB
TypeScript

import { validation } from '../utils/validation'
import { REGEX_PHONE } from '../utils/regex'
import type { GenericResponse, GenericResponseItems, UserCart } from '~/types'
import type { AddressesList, 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 showSummary = 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)
const userStore = useUserStore()
// send form
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}`,
})
},
},
)
if (res.status === 200) {
$toast.success('Form successfully sent', {
autoClose: 5000,
dangerouslyHTMLString: true,
})
// redirectToSummary();
showSummary.value = true
}
else {
$toast.error('Failed to send form. Please try again.', {
autoClose: 5000,
dangerouslyHTMLString: true,
})
}
}
catch (error) {
console.error('uploadAddress error:', error)
}
}
const changeActive = (item: AddressesList) => {
activeAddress.value = item
}
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)
}
}
type DeliveryOption = {
country_iso: string
country_name: string
delivery_supplier_id: number
delivery_supplier_name: string
id: number
shippment_price: string
}
// get delivery options
const deliveryOption = ref()
const currentDelivery = ref()
const shippingPrice = ref()
async function getDeliveryOptions() {
try {
const { data } = await useMyFetch<
GenericResponseItems<DeliveryOption[]>
>(`/api/restricted/cart/checkout/delivery-options`, {
headers: {
'Content-Type': 'application/json',
},
onErrorOccured: async (_, status) => {
throw createError({
statusCode: status,
statusMessage: `HTTP error: ${status}`,
})
},
})
console.log(data)
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 defaultAddress = ref()
async function getDefAddress() {
try {
const { data } = await useMyFetch<
GenericResponse<{
addresses: [
{
is_default: boolean
},
]
}>
>(`/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: { is_default: boolean }) => el.is_default === true,
)
}
catch (error) {
console.error('getUserCart error:', error)
}
}
return {
addressesList,
activeAddress,
isOpen,
selectedIso,
phoneValidation,
userName,
lastName,
address,
postCode,
city,
country,
phoneNumber,
accountPhoneNumber,
vUseAccountPhoneNumber,
currentPrefix,
vNewAddressName,
vNewAddressSurname,
vNewAddressAddress,
vNewAddressCode,
vNewAddressCity,
vNewAddressCountry,
showSummary,
products,
fullPrice,
fullProductsPrice,
deliveryOption,
currentDelivery,
shippingPrice,
defaultAddress,
changePrefix,
getCheckout,
getAddressList,
getUserData,
changeActive,
uploadAddress,
sendForm,
getUserCart,
getDeliveryOptions,
getDefAddress,
}
})