109 lines
3.0 KiB
TypeScript
109 lines
3.0 KiB
TypeScript
import { ref } from 'vue'
|
|
import { useRouter } from 'vue-router'
|
|
import { useCartStore } from '@/stores/customer/cart'
|
|
import { useCustomerProductStore } from '@/stores/customer/customer-product'
|
|
import { useToast } from '@nuxt/ui/runtime/composables/useToast.js'
|
|
import { useFetchJson } from '@/composable/useFetchJson'
|
|
|
|
export interface SearchProductParams {
|
|
query: string
|
|
searchByReference?: boolean
|
|
}
|
|
|
|
export function useProductSearchApi() {
|
|
const router = useRouter()
|
|
const cartStore = useCartStore()
|
|
const customerProductStore = useCustomerProductStore()
|
|
const toast = useToast()
|
|
|
|
const searchQuery = ref('')
|
|
const products = ref<any[]>([])
|
|
const loading = ref(false)
|
|
const error = ref<string | null>(null)
|
|
const searchByReference = ref(false)
|
|
|
|
const selectedCount = ref({
|
|
product_id: null as number | null,
|
|
count: 0
|
|
})
|
|
|
|
async function fetchProducts() {
|
|
if (!searchQuery.value.trim()) {
|
|
products.value = []
|
|
return
|
|
}
|
|
|
|
loading.value = true
|
|
error.value = null
|
|
|
|
try {
|
|
let query = ''
|
|
|
|
if (searchByReference.value) {
|
|
query = `reference_eq=${searchQuery.value.trim()}`
|
|
} else {
|
|
query = `name=~${searchQuery.value.trim()}`
|
|
}
|
|
|
|
const result = await useFetchJson(
|
|
`/api/v1/restricted/product/list?elems=30&${query}`
|
|
)
|
|
|
|
products.value = result.items || []
|
|
} catch (e) {
|
|
error.value = 'Failed to load products'
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
async function addToCart(product_id: number) {
|
|
if (!cartStore.activeCartId) {
|
|
toast.add({
|
|
title: "No cart selected",
|
|
description: "Please select a cart before adding products",
|
|
icon: "i-heroicons-exclamation-triangle",
|
|
duration: 5000
|
|
})
|
|
return
|
|
}
|
|
|
|
const count = selectedCount.value.count || 1
|
|
await cartStore.addProduct(product_id, count)
|
|
|
|
toast.add({
|
|
title: "Product added to cart",
|
|
description: `Quantity: ${count}`,
|
|
icon: "i-heroicons-check-circle",
|
|
duration: 5000
|
|
})
|
|
}
|
|
|
|
function goToProduct(productId: number) {
|
|
router.push({
|
|
name: 'customer-product-details',
|
|
params: { product_id: productId }
|
|
})
|
|
}
|
|
|
|
function getSortIcon(field: string, sortValue: [string | undefined, string | undefined]): string {
|
|
if (sortValue[0] === field) {
|
|
if (sortValue[1] === 'asc') return 'i-lucide-arrow-up-narrow-wide'
|
|
if (sortValue[1] === 'desc') return 'i-lucide-arrow-down-wide-narrow'
|
|
}
|
|
return 'i-lucide-arrow-up-down'
|
|
}
|
|
|
|
return {
|
|
searchQuery,
|
|
products,
|
|
loading,
|
|
error,
|
|
searchByReference,
|
|
selectedCount,
|
|
fetchProducts,
|
|
addToCart,
|
|
goToProduct,
|
|
getSortIcon
|
|
}
|
|
} |