Files
thrilltrack-explorer/src/hooks/useAutocompleteData.ts
2025-10-21 18:53:17 +00:00

306 lines
8.3 KiB
TypeScript

import { useState, useEffect } from 'react';
import { supabase } from '@/integrations/supabase/client';
import { ComboboxOption } from '@/components/ui/combobox';
import { toast } from 'sonner';
import { logger } from '@/lib/logger';
import { getErrorMessage } from '@/lib/errorHandler';
export function useCountries() {
const [countries, setCountries] = useState<ComboboxOption[]>([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
async function fetchCountries() {
setLoading(true);
try {
const { data, error } = await supabase
.from('locations')
.select('country')
.not('country', 'is', null);
if (error) throw error;
const uniqueCountries = Array.from(
new Set(data?.map(item => item.country) || [])
).sort();
setCountries(
uniqueCountries.map(country => ({
label: country,
value: country.toLowerCase().replace(/\s+/g, '_')
}))
);
} catch (error: unknown) {
const errorMsg = getErrorMessage(error);
logger.error('Failed to fetch countries', { error: errorMsg });
toast.error('Failed to load countries', {
description: 'Please refresh the page and try again.',
});
setCountries([]);
} finally {
setLoading(false);
}
}
fetchCountries();
}, []);
return { countries, loading };
}
export function useStatesProvinces(country?: string) {
const [statesProvinces, setStatesProvinces] = useState<ComboboxOption[]>([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
if (!country) {
setStatesProvinces([]);
return;
}
async function fetchStatesProvinces() {
setLoading(true);
try {
const { data, error } = await supabase
.from('locations')
.select('state_province')
.eq('country', country)
.not('state_province', 'is', null);
if (error) throw error;
const uniqueStates = Array.from(
new Set(data?.map(item => item.state_province) || [])
).sort();
setStatesProvinces(
uniqueStates.map(state => ({
label: state,
value: state.toLowerCase().replace(/\s+/g, '_')
}))
);
} catch (error: unknown) {
const errorMsg = getErrorMessage(error);
logger.error('Failed to fetch states/provinces', { country, error: errorMsg });
toast.error('Failed to load states/provinces', {
description: 'Please refresh the page and try again.',
});
setStatesProvinces([]);
} finally {
setLoading(false);
}
}
fetchStatesProvinces();
}, [country]);
return { statesProvinces, loading };
}
export function useManufacturers() {
const [manufacturers, setManufacturers] = useState<ComboboxOption[]>([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
async function fetchManufacturers() {
setLoading(true);
try {
const { data, error } = await supabase
.from('companies')
.select('id, name')
.eq('company_type', 'manufacturer')
.order('name');
if (error) throw error;
setManufacturers(
(data || []).map(company => ({
label: company.name,
value: company.id
}))
);
} catch (error: unknown) {
const errorMsg = getErrorMessage(error);
logger.error('Failed to fetch manufacturers', { error: errorMsg });
toast.error('Failed to load manufacturers', {
description: 'Please refresh the page and try again.',
});
setManufacturers([]);
} finally {
setLoading(false);
}
}
fetchManufacturers();
}, []);
return { manufacturers, loading };
}
export function useRideModels(manufacturerId?: string) {
const [rideModels, setRideModels] = useState<ComboboxOption[]>([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
if (!manufacturerId) {
setRideModels([]);
return;
}
async function fetchRideModels() {
setLoading(true);
try {
const { data, error } = await supabase
.from('ride_models')
.select('id, name')
.eq('manufacturer_id', manufacturerId)
.order('name');
if (error) throw error;
setRideModels(
(data || []).map(model => ({
label: model.name,
value: model.id
}))
);
} catch (error: unknown) {
const errorMsg = getErrorMessage(error);
logger.error('Failed to fetch ride models', { manufacturerId, error: errorMsg });
toast.error('Failed to load ride models', {
description: 'Please refresh the page and try again.',
});
setRideModels([]);
} finally {
setLoading(false);
}
}
fetchRideModels();
}, [manufacturerId]);
return { rideModels, loading };
}
export function useCompanyHeadquarters() {
const [headquarters, setHeadquarters] = useState<ComboboxOption[]>([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
async function fetchHeadquarters() {
setLoading(true);
try {
const { data, error } = await supabase
.from('companies')
.select('headquarters_location')
.not('headquarters_location', 'is', null);
if (error) throw error;
const uniqueHeadquarters = Array.from(
new Set(data?.map(item => item.headquarters_location) || [])
).sort();
setHeadquarters(
uniqueHeadquarters.map(hq => ({
label: hq,
value: hq.toLowerCase().replace(/\s+/g, '_')
}))
);
} catch (error: unknown) {
const errorMsg = getErrorMessage(error);
logger.error('Failed to fetch headquarters', { error: errorMsg });
toast.error('Failed to load headquarters', {
description: 'Please refresh the page and try again.',
});
setHeadquarters([]);
} finally {
setLoading(false);
}
}
fetchHeadquarters();
}, []);
return { headquarters, loading };
}
export function useOperators() {
const [operators, setOperators] = useState<ComboboxOption[]>([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
async function fetchOperators() {
setLoading(true);
try {
const { data, error } = await supabase
.from('companies')
.select('id, name')
.eq('company_type', 'operator')
.order('name');
if (error) throw error;
setOperators(
(data || []).map(company => ({
label: company.name,
value: company.id
}))
);
} catch (error: unknown) {
const errorMsg = getErrorMessage(error);
logger.error('Failed to fetch operators', { error: errorMsg });
toast.error('Failed to load operators', {
description: 'Please refresh the page and try again.',
});
setOperators([]);
} finally {
setLoading(false);
}
}
fetchOperators();
}, []);
return { operators, loading };
}
export function usePropertyOwners() {
const [propertyOwners, setPropertyOwners] = useState<ComboboxOption[]>([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
async function fetchPropertyOwners() {
setLoading(true);
try {
const { data, error } = await supabase
.from('companies')
.select('id, name')
.eq('company_type', 'property_owner')
.order('name');
if (error) throw error;
setPropertyOwners(
(data || []).map(company => ({
label: company.name,
value: company.id
}))
);
} catch (error: unknown) {
const errorMsg = getErrorMessage(error);
logger.error('Failed to fetch property owners', { error: errorMsg });
toast.error('Failed to load property owners', {
description: 'Please refresh the page and try again.',
});
setPropertyOwners([]);
} finally {
setLoading(false);
}
}
fetchPropertyOwners();
}, []);
return { propertyOwners, loading };
}