Files
thrilltrack-explorer/src-old/hooks/useAutocompleteData.ts

346 lines
9.0 KiB
TypeScript

import { useState, useEffect } from 'react';
import { supabase } from '@/lib/supabaseClient';
import { ComboboxOption } from '@/components/ui/combobox';
import { toast } from 'sonner';
import { handleNonCriticalError } 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) {
handleNonCriticalError(error, { action: 'Fetch countries' });
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).filter((s): s is string => s != null) || [])
).sort();
setStatesProvinces(
uniqueStates.map(state => ({
label: state,
value: state.toLowerCase().replace(/\s+/g, '_')
}))
);
} catch (error: unknown) {
handleNonCriticalError(error, {
action: 'Fetch states/provinces',
metadata: { country },
});
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) {
handleNonCriticalError(error, { action: 'Fetch manufacturers' });
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) {
handleNonCriticalError(error, {
action: 'Fetch ride models',
metadata: { manufacturerId },
});
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).filter((hq): hq is string => hq != null) || [])
).sort();
setHeadquarters(
uniqueHeadquarters.map(hq => ({
label: hq,
value: hq.toLowerCase().replace(/\s+/g, '_')
}))
);
} catch (error: unknown) {
handleNonCriticalError(error, { action: 'Fetch headquarters' });
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) {
handleNonCriticalError(error, { action: 'Fetch operators' });
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) {
handleNonCriticalError(error, { action: 'Fetch property owners' });
toast.error('Failed to load property owners', {
description: 'Please refresh the page and try again.',
});
setPropertyOwners([]);
} finally {
setLoading(false);
}
}
fetchPropertyOwners();
}, []);
return { propertyOwners, loading };
}
/**
* Hook to fetch all parks for autocomplete
* Returns parks as combobox options
*/
export function useParks() {
const [parks, setParks] = useState<ComboboxOption[]>([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
async function fetchParks() {
setLoading(true);
try {
const { data, error } = await supabase
.from('parks')
.select('id, name, slug')
.order('name');
if (error) throw error;
setParks(
(data || []).map(park => ({
label: park.name,
value: park.id
}))
);
} catch (error: unknown) {
handleNonCriticalError(error, { action: 'Fetch parks' });
toast.error('Failed to load parks', {
description: 'Please refresh the page and try again.',
});
setParks([]);
} finally {
setLoading(false);
}
}
fetchParks();
}, []);
return { parks, loading };
}