feat: Implement Combobox component and Autocomplete for Country

This commit is contained in:
gpt-engineer-app[bot]
2025-09-29 15:58:09 +00:00
parent 29f687b29e
commit 8b33a0d925
3 changed files with 301 additions and 13 deletions

View File

@@ -0,0 +1,162 @@
import { useState, useEffect } from 'react';
import { supabase } from '@/integrations/supabase/client';
import { ComboboxOption } from '@/components/ui/combobox';
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) {
console.error('Error fetching countries:', error);
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) {
console.error('Error fetching states/provinces:', error);
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('name')
.eq('company_type', 'manufacturer')
.order('name');
if (error) throw error;
setManufacturers(
(data || []).map(company => ({
label: company.name,
value: company.name.toLowerCase().replace(/\s+/g, '_')
}))
);
} catch (error) {
console.error('Error fetching manufacturers:', error);
setManufacturers([]);
} finally {
setLoading(false);
}
}
fetchManufacturers();
}, []);
return { manufacturers, 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) {
console.error('Error fetching headquarters:', error);
setHeadquarters([]);
} finally {
setLoading(false);
}
}
fetchHeadquarters();
}, []);
return { headquarters, loading };
}