import { SuppliersListDocument, NearestSuppliersDocument } from '~/composables/graphql/public/geo-generated' const PAGE_SIZE = 24 // Shared state across list and map views const items = ref([]) const total = ref(0) const isLoading = ref(false) const isLoadingMore = ref(false) const isInitialized = ref(false) const filterProductUuid = ref(null) const filterBounds = ref<{ west: number; south: number; east: number; north: number } | null>(null) export function useCatalogSuppliers() { const { execute } = useGraphQL() const itemsWithCoords = computed(() => items.value.filter(s => s.latitude && s.longitude) ) const canLoadMore = computed(() => items.value.length < total.value) const fetchPage = async (offset: number, replace = false) => { if (replace) isLoading.value = true try { // If filtering by product, use nearestSuppliers with global search // (center point 0,0 with very large radius to cover entire globe) if (filterProductUuid.value) { const data = await execute( NearestSuppliersDocument, { lat: 0, lon: 0, radius: 20000, // 20000 km radius covers entire Earth productUuid: filterProductUuid.value, limit: 500 // Increased limit for global search }, 'public', 'geo' ) items.value = data?.nearestSuppliers || [] total.value = items.value.length isInitialized.value = true return } // Default: fetch all suppliers from GEO (graph-based) const data = await execute( SuppliersListDocument, { limit: PAGE_SIZE, offset, ...(filterBounds.value && { west: filterBounds.value.west, south: filterBounds.value.south, east: filterBounds.value.east, north: filterBounds.value.north }) }, 'public', 'geo' ) const next = data?.suppliersList || [] items.value = replace ? next : items.value.concat(next) // suppliersList doesn't return total count, estimate from fetched items if (replace) { total.value = next.length < PAGE_SIZE ? next.length : next.length + PAGE_SIZE } else if (next.length < PAGE_SIZE) { total.value = items.value.length } isInitialized.value = true } finally { isLoading.value = false } } const loadMore = async () => { if (isLoadingMore.value) return isLoadingMore.value = true try { await fetchPage(items.value.length) } finally { isLoadingMore.value = false } } // Initialize data if not already loaded const init = async () => { if (!isInitialized.value && items.value.length === 0) { await fetchPage(0, true) } } const setProductFilter = (uuid: string | null) => { if (filterProductUuid.value === uuid) return // Early return if unchanged filterProductUuid.value = uuid if (isInitialized.value) { fetchPage(0, true) } } const setBoundsFilter = (bounds: { west: number; south: number; east: number; north: number } | null) => { // Early return if bounds haven't changed const prev = filterBounds.value const same = prev === bounds || ( prev && bounds && prev.west === bounds.west && prev.south === bounds.south && prev.east === bounds.east && prev.north === bounds.north ) if (same) return filterBounds.value = bounds if (isInitialized.value) { fetchPage(0, true) } } return { items, total, isLoading, isLoadingMore, itemsWithCoords, canLoadMore, fetchPage, loadMore, init, setProductFilter, setBoundsFilter } }