248 lines
7.0 KiB
TypeScript
248 lines
7.0 KiB
TypeScript
import { defineStore } from 'pinia'
|
|
import { ref, computed } from 'vue'
|
|
import { useFetchJson } from '@/composable/useFetchJson'
|
|
|
|
export interface Cart {
|
|
id: number
|
|
name: string
|
|
items: any[]
|
|
}
|
|
|
|
export interface Address {
|
|
id: number
|
|
country_id: number
|
|
customer_id: number
|
|
address_info: Record<string, string>
|
|
}
|
|
|
|
export type AddressTemplate = Record<string, string>
|
|
|
|
export const useCartStore = defineStore('cart', () => {
|
|
const carts = ref<Cart[]>([])
|
|
const activeCartId = ref<number | null>(null)
|
|
const error = ref<string | null>(null)
|
|
|
|
const addresses = ref<Address[]>([])
|
|
const addressLoading = ref(false)
|
|
const addressError = ref<string | null>(null)
|
|
const addressSearchQuery = ref('')
|
|
const addressCurrentPage = ref(1)
|
|
const addressPageSize = 20
|
|
const addressTotalCount = ref(0)
|
|
|
|
function transformAddressResponse(address: any): Address {
|
|
const info = address.address_info || address.addressInfo || {}
|
|
|
|
return {
|
|
id: address.id ?? 0,
|
|
country_id: address.country_id ?? address.countryId ?? 1,
|
|
customer_id: address.customer_id ?? address.customerId ?? 0,
|
|
address_info: info as Record<string, string>
|
|
}
|
|
}
|
|
|
|
async function fetchAddresses() {
|
|
addressLoading.value = true
|
|
addressError.value = null
|
|
|
|
try {
|
|
const queryParam = addressSearchQuery.value ? `&query=${encodeURIComponent(addressSearchQuery.value)}` : ''
|
|
const response = await useFetchJson<Address[]>(`/api/v1/restricted/addresses/retrieve-addresses?page=${addressCurrentPage.value}&elems=${addressPageSize}${queryParam}`)
|
|
addresses.value = response.items || []
|
|
addressTotalCount.value = response.count ?? addresses.value.length
|
|
} catch (error: unknown) {
|
|
addressError.value = error instanceof Error ? error.message : 'Failed to load addresses'
|
|
} finally {
|
|
addressLoading.value = false
|
|
}
|
|
}
|
|
|
|
async function addAddress(countryId: number, formData: AddressTemplate): Promise<Address | null> {
|
|
addressLoading.value = true
|
|
addressError.value = null
|
|
|
|
try {
|
|
const response = await useFetchJson<any>(`/api/v1/restricted/addresses/add-new-address?country_id=${countryId}`, {
|
|
method: 'POST',
|
|
body: JSON.stringify(formData)
|
|
})
|
|
|
|
await fetchAddresses()
|
|
return transformAddressResponse(response.items ?? response)
|
|
} catch (error: unknown) {
|
|
addressError.value = error instanceof Error ? error.message : 'Failed to create address'
|
|
return null
|
|
} finally {
|
|
addressLoading.value = false
|
|
}
|
|
}
|
|
|
|
async function getAddressTemplate(countryId: number): Promise<AddressTemplate> {
|
|
const response = await useFetchJson<any>(`/api/v1/restricted/addresses/get-template?country_id=${countryId}`)
|
|
return response.items ?? {}
|
|
}
|
|
|
|
async function updateAddress(id: number, countryId: number, formData: AddressTemplate): Promise<boolean> {
|
|
addressLoading.value = true
|
|
addressError.value = null
|
|
|
|
try {
|
|
await useFetchJson<any>(`/api/v1/restricted/addresses/modify-address?country_id=${countryId}&address_id=${id}`, {
|
|
method: 'POST',
|
|
body: JSON.stringify(formData)
|
|
})
|
|
|
|
await fetchAddresses()
|
|
return true
|
|
} catch (error: unknown) {
|
|
addressError.value = error instanceof Error ? error.message : 'Failed to update address'
|
|
return false
|
|
} finally {
|
|
addressLoading.value = false
|
|
}
|
|
}
|
|
|
|
async function deleteAddress(id: number): Promise<boolean> {
|
|
addressLoading.value = true
|
|
addressError.value = null
|
|
|
|
try {
|
|
await useFetchJson<any>(`/api/v1/restricted/addresses/delete-address?address_id=${id}`, {
|
|
method: 'DELETE'
|
|
})
|
|
|
|
await fetchAddresses()
|
|
return true
|
|
} catch (error: unknown) {
|
|
addressError.value = error instanceof Error ? error.message : 'Failed to delete address'
|
|
return false
|
|
} finally {
|
|
addressLoading.value = false
|
|
}
|
|
}
|
|
|
|
const totalAddressItems = computed(() => addressTotalCount.value || addresses.value.length)
|
|
const totalAddressPages = computed(() => Math.ceil(totalAddressItems.value / addressPageSize))
|
|
|
|
const paginatedAddresses = computed(() => addresses.value)
|
|
|
|
function setAddressPage(page: number) {
|
|
addressCurrentPage.value = page
|
|
return fetchAddresses()
|
|
}
|
|
|
|
function setAddressSearchQuery(query: string) {
|
|
addressSearchQuery.value = query
|
|
addressCurrentPage.value = 1
|
|
return fetchAddresses()
|
|
}
|
|
|
|
|
|
function initMockData() {
|
|
items.value = [
|
|
{ id: 1, productId: 101, name: 'Premium Widget Pro', product_number: 'NC209/7000', image: '/img/product-1.jpg', price: 129.99, quantity: 2 },
|
|
{ id: 2, productId: 102, name: 'Ultra Gadget X', product_number: 'NC234/6453', image: '/img/product-2.jpg', price: 89.50, quantity: 1 },
|
|
{ id: 3, productId: 103, name: 'Mega Tool Set', product_number: 'NC324/9030', image: '/img/product-3.jpg', price: 249.00, quantity: 3 }
|
|
]
|
|
}
|
|
|
|
async function addNewCart(name: string) {
|
|
try {
|
|
error.value = null
|
|
|
|
const url = `/api/v1/restricted/carts/add-new-cart`
|
|
const response = await useFetchJson<ApiResponse>(url)
|
|
|
|
const newCart: Cart = {
|
|
id: response.items.cart_id,
|
|
name: response.items.name,
|
|
items: []
|
|
}
|
|
|
|
carts.value.push(newCart)
|
|
activeCartId.value = newCart.id
|
|
|
|
return newCart
|
|
} catch (e: any) {
|
|
error.value = e?.message ?? 'Error creating cart'
|
|
}
|
|
}
|
|
|
|
const route = useRoute()
|
|
const amount = ref<number>(1);
|
|
const errorMessage = ref('');
|
|
|
|
async function addProduct(product_id: number, count: number) {
|
|
if (!activeCartId.value) {
|
|
errorMessage.value = 'No active cart selected'
|
|
return
|
|
}
|
|
|
|
try {
|
|
const res = await useFetchJson<ApiResponse>(
|
|
`/api/v1/restricted/carts/add-product-to-cart?cart_id=${activeCartId.value}&product_id=${product_id}&amount=${count}`
|
|
)
|
|
|
|
console.log('fsdfsdfdsfdsfs', res)
|
|
} catch (e: any) {
|
|
errorMessage.value = e?.message ?? 'Error adding product'
|
|
}
|
|
}
|
|
|
|
function setActiveCart(id: number | null) {
|
|
activeCartId.value = id
|
|
|
|
if (id) {
|
|
localStorage.setItem('activeCartId', String(id))
|
|
} else {
|
|
localStorage.removeItem('activeCartId')
|
|
}
|
|
}
|
|
|
|
function initCart() {
|
|
const saved = localStorage.getItem('activeCartId')
|
|
|
|
if (saved) {
|
|
activeCartId.value = Number(saved)
|
|
}
|
|
}
|
|
|
|
const activeCart = computed(() => {
|
|
return carts.value.find(c => c.cart_id === activeCartId.value)
|
|
})
|
|
|
|
return {
|
|
items,
|
|
selectedAddressId,
|
|
selectedDeliveryMethodId,
|
|
shippingCost,
|
|
vatRate,
|
|
deliveryMethods,
|
|
productsTotal,
|
|
vatAmount,
|
|
orderTotal,
|
|
itemCount,
|
|
deleteProduct,
|
|
updateQuantity,
|
|
removeItem,
|
|
clearCart,
|
|
setSelectedAddress,
|
|
setDeliveryMethod,
|
|
addresses,
|
|
addressLoading,
|
|
addressError,
|
|
addressSearchQuery,
|
|
addressCurrentPage,
|
|
addressPageSize,
|
|
paginatedAddresses,
|
|
totalAddressItems,
|
|
totalAddressPages,
|
|
fetchAddresses,
|
|
addAddress,
|
|
updateAddress,
|
|
deleteAddress,
|
|
setAddressPage,
|
|
setAddressSearchQuery,
|
|
getAddressTemplate
|
|
}
|
|
}) |