diff --git a/src/components/ui/combobox.tsx b/src/components/ui/combobox.tsx
new file mode 100644
index 00000000..9a80a32d
--- /dev/null
+++ b/src/components/ui/combobox.tsx
@@ -0,0 +1,96 @@
+import * as React from "react";
+import { Check, ChevronsUpDown } from "lucide-react";
+import { cn } from "@/lib/utils";
+import { Button } from "@/components/ui/button";
+import {
+ Command,
+ CommandEmpty,
+ CommandGroup,
+ CommandInput,
+ CommandItem,
+ CommandList,
+} from "@/components/ui/command";
+import {
+ Popover,
+ PopoverContent,
+ PopoverTrigger,
+} from "@/components/ui/popover";
+
+export interface ComboboxOption {
+ label: string;
+ value: string;
+}
+
+interface ComboboxProps {
+ options: ComboboxOption[];
+ value?: string;
+ onValueChange?: (value: string) => void;
+ placeholder?: string;
+ searchPlaceholder?: string;
+ emptyText?: string;
+ disabled?: boolean;
+ className?: string;
+ loading?: boolean;
+}
+
+export function Combobox({
+ options,
+ value,
+ onValueChange,
+ placeholder = "Select option...",
+ searchPlaceholder = "Search...",
+ emptyText = "No options found.",
+ disabled = false,
+ className,
+ loading = false,
+}: ComboboxProps) {
+ const [open, setOpen] = React.useState(false);
+
+ const selectedOption = options.find((option) => option.value === value);
+
+ return (
+
+
+
+
+
+
+
+
+ {loading ? "Loading..." : emptyText}
+
+ {options.map((option) => (
+ {
+ const newValue = currentValue === value ? "" : currentValue;
+ onValueChange?.(newValue);
+ setOpen(false);
+ }}
+ >
+
+ {option.label}
+
+ ))}
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/hooks/useAutocompleteData.ts b/src/hooks/useAutocompleteData.ts
new file mode 100644
index 00000000..4b93e874
--- /dev/null
+++ b/src/hooks/useAutocompleteData.ts
@@ -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
([]);
+ 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([]);
+ 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([]);
+ 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([]);
+ 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 };
+}
\ No newline at end of file