582 lines
15 KiB
TypeScript
582 lines
15 KiB
TypeScript
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<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)
|
|
}
|
|
}
|
|
|
|
// 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
|
|
interface DeliveryOptionItem {
|
|
country_iso: string
|
|
country_name: string
|
|
delivery_supplier_id: number
|
|
delivery_supplier_name: string
|
|
id: number
|
|
shippment_price: string
|
|
}
|
|
|
|
const deliveryOption = ref<DeliveryOptionItem[]>([])
|
|
const currentDelivery = ref<DeliveryOptionItem | null>(null)
|
|
const shippingPrice = ref<number>(0)
|
|
|
|
async function getDeliveryOptions() {
|
|
try {
|
|
const { data } = await useMyFetch<GenericResponseItems<DeliveryOptionItem[]>>(
|
|
`/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<Address | undefined>()
|
|
|
|
async function getDefAddress() {
|
|
try {
|
|
const { data } = await useMyFetch<GenericResponse<{ addresses: Address[] }>>(
|
|
`/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<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
|
|
}
|
|
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<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 {
|
|
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,
|
|
fullAddress,
|
|
|
|
vLegal,
|
|
vTerms,
|
|
vNote,
|
|
legalValidation,
|
|
termsValidation,
|
|
modalMadeOrder,
|
|
|
|
changePrefix,
|
|
getCheckout,
|
|
getAddressList,
|
|
getUserData,
|
|
uploadAddress,
|
|
sendForm,
|
|
getUserCart,
|
|
getDeliveryOptions,
|
|
getDefAddress,
|
|
setCurrentDelivery,
|
|
getBankAccount,
|
|
getOrder,
|
|
setNewAddress,
|
|
sendSummaryForm,
|
|
}
|
|
})
|