interface AirportResult { iata: string name: string city_name: string country_code: string country_name: string lat: number | null lon: number | null } export function useLocations() { const supabase = useSupabaseClient() const airports = ref([]) const loaded = ref(false) async function loadAirports() { if (loaded.value) return const { data } = await supabase .from('airports') .select('iata, name, city_name, country_code, country_name, lat, lon') .order('iata') .limit(10000) if (data && data.length > 0) { airports.value = data as AirportResult[] loaded.value = true } else { // Fallback: fetch from Flightics API and cache in Supabase await syncLocations() } } async function syncLocations() { try { const data = await $fetch('/api/sync/locations', { method: 'POST' }) if (data?.count) { // Reload from Supabase after sync const { data: fresh } = await supabase .from('airports') .select('iata, name, city_name, country_code, country_name, lat, lon') .order('iata') airports.value = (fresh as AirportResult[]) || [] loaded.value = true } } catch { // Silently fail, user can retry } } function normalize(s: string): string { return s.normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase() } function searchAirports(query: string): AirportResult[] { if (!query || query.length < 2) return [] const q = normalize(query) return airports.value .filter(a => normalize(a.iata).includes(q) || normalize(a.name).includes(q) || normalize(a.city_name || '').includes(q) ) .slice(0, 20) } return { airports, loaded, loadAirports, searchAirports, syncLocations } }