import { useEffect, useState } from "react"; import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Popover, PopoverContent, PopoverTrigger, } from "@/components/ui/popover"; import { Button } from "@/components/ui/button"; import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, } from "@/components/ui/command"; import { useInView } from "react-intersection-observer"; import { Check, ChevronsUpDown, Loader2 } from "lucide-react"; import { cn } from "@/lib/utils"; import { getAreasApi, getCitiesApi, getCoutriesApi, getStatesApi, } from "@/utils/api"; import { Textarea } from "@/components/ui/textarea"; import { t } from "@/utils"; const ManualAddress = ({ showManualAddress, setShowManualAddress, setLocation, }) => { const [CountryStore, setCountryStore] = useState({ Countries: [], SelectedCountry: {}, CountrySearch: "", currentPage: 1, hasMore: false, countryOpen: false, isLoading: false, }); const [StateStore, setStateStore] = useState({ States: [], SelectedState: {}, StateSearch: "", currentPage: 1, hasMore: false, stateOpen: false, isLoading: false, }); const [CityStore, setCityStore] = useState({ Cities: [], SelectedCity: {}, CitySearch: "", currentPage: 1, hasMore: false, isLoading: false, cityOpen: false, }); const [AreaStore, setAreaStore] = useState({ Areas: [], SelectedArea: {}, AreaSearch: "", currentPage: 1, hasMore: false, areaOpen: false, isLoading: false, }); const [Address, setAddress] = useState(""); const [fieldErrors, setFieldErrors] = useState({}); const isCountrySelected = Object.keys(CountryStore?.SelectedCountry).length > 0; // Check if areas exist for the selected city const hasAreas = AreaStore?.Areas.length > 0; // Infinite scroll refs const { ref: stateRef, inView: stateInView } = useInView(); const { ref: countryRef, inView: countryInView } = useInView(); const { ref: cityRef, inView: cityInView } = useInView(); const { ref: areaRef, inView: areaInView } = useInView(); const getCountriesData = async (search, page) => { try { setCountryStore((prev) => ({ ...prev, isLoading: true, Countries: search ? [] : prev.Countries, // Clear list if searching })); // Fetch countries const params = {}; if (search) { params.search = search; // Send only 'search' if provided } else { params.page = page; // Send only 'page' if no search } const res = await getCoutriesApi.getCoutries(params); let allCountries; if (page > 1) { allCountries = [...CountryStore?.Countries, ...res?.data?.data?.data]; } else { allCountries = res?.data?.data?.data; } setCountryStore((prev) => ({ ...prev, currentPage: res?.data?.data?.current_page, Countries: allCountries, hasMore: res?.data?.data?.current_page < res?.data?.data?.last_page ? true : false, isLoading: false, })); } catch (error) { console.error("Error fetching countries data:", error); setCountryStore((prev) => ({ ...prev, isLoading: false })); } }; const getStatesData = async (search, page) => { try { setStateStore((prev) => ({ ...prev, isLoading: true, States: search ? [] : prev.States, })); const params = { country_id: CountryStore?.SelectedCountry?.id, }; if (search) { params.search = search; // Send only 'search' if provided } else { params.page = page; // Send only 'page' if no search } const res = await getStatesApi.getStates(params); let allStates; if (page > 1) { allStates = [...StateStore?.States, ...res?.data?.data?.data]; } else { allStates = res?.data?.data?.data; } setStateStore((prev) => ({ ...prev, currentPage: res?.data?.data?.current_page, States: allStates, hasMore: res?.data?.data?.current_page < res?.data?.data?.last_page ? true : false, isLoading: false, })); } catch (error) { console.error("Error fetching states data:", error); setStateStore((prev) => ({ ...prev, isLoading: false })); return []; } }; const getCitiesData = async (search, page) => { try { setCityStore((prev) => ({ ...prev, isLoading: true, Cities: search ? [] : prev.Cities, })); const params = { state_id: StateStore?.SelectedState?.id, }; if (search) { params.search = search; // Send only 'search' if provided } else { params.page = page; // Send only 'page' if no search } const res = await getCitiesApi.getCities(params); let allCities; if (page > 1) { allCities = [...CityStore?.Cities, ...res?.data?.data?.data]; } else { allCities = res?.data?.data?.data; } setCityStore((prev) => ({ ...prev, currentPage: res?.data?.data?.current_page, Cities: allCities, hasMore: res?.data?.data?.current_page < res?.data?.data?.last_page ? true : false, isLoading: false, })); } catch (error) { console.error("Error fetching cities data:", error); setCityStore((prev) => ({ ...prev, isLoading: false })); return []; } }; const getAreaData = async (search, page) => { try { setAreaStore((prev) => ({ ...prev, isLoading: true, Areas: search ? [] : prev.Areas, })); const params = { city_id: CityStore?.SelectedCity?.id, }; if (search) { params.search = search; } else { params.page = page; } const res = await getAreasApi.getAreas(params); let allArea; if (page > 1) { allArea = [...AreaStore?.Areas, ...res?.data?.data?.data]; } else { allArea = res?.data?.data?.data; } setAreaStore((prev) => ({ ...prev, currentPage: res?.data?.data?.current_page, Areas: allArea, hasMore: res?.data?.data?.current_page < res?.data?.data?.last_page ? true : false, isLoading: false, })); } catch (error) { console.error("Error fetching areas data:", error); setAreaStore((prev) => ({ ...prev, isLoading: false })); return []; } }; useEffect(() => { const timeout = setTimeout(() => { if (showManualAddress) { getCountriesData(CountryStore?.CountrySearch, 1); } }, 500); return () => { clearTimeout(timeout); }; }, [CountryStore?.CountrySearch, showManualAddress]); useEffect(() => { if (CountryStore?.SelectedCountry?.id) { const timeout = setTimeout(() => { getStatesData(StateStore?.StateSearch, 1); }, 500); return () => { clearTimeout(timeout); }; } }, [CountryStore?.SelectedCountry?.id, StateStore?.StateSearch]); useEffect(() => { if (StateStore?.SelectedState?.id) { const timeout = setTimeout(() => { getCitiesData(CityStore?.CitySearch, 1); }, 500); return () => { clearTimeout(timeout); }; } }, [StateStore?.SelectedState?.id, CityStore?.CitySearch]); useEffect(() => { if (CityStore?.SelectedCity?.id) { const timeout = setTimeout(() => { getAreaData(AreaStore?.AreaSearch, 1); }, 500); return () => { clearTimeout(timeout); }; } }, [CityStore?.SelectedCity?.id, AreaStore?.AreaSearch]); // Trigger infinite scroll when refs come into view useEffect(() => { if (CountryStore?.hasMore && !CountryStore?.isLoading && countryInView) { getCountriesData("", CountryStore?.currentPage + 1); } }, [ countryInView, CountryStore?.hasMore, CountryStore?.isLoading, CountryStore?.currentPage, ]); useEffect(() => { if (StateStore?.hasMore && !StateStore?.isLoading && stateInView) { getStatesData("", StateStore?.currentPage + 1); } }, [ stateInView, StateStore?.hasMore, StateStore?.isLoading, StateStore?.currentPage, ]); useEffect(() => { if (CityStore?.hasMore && !CityStore?.isLoading && cityInView) { getCitiesData("", CityStore?.currentPage + 1); } }, [ cityInView, CityStore?.hasMore, CityStore?.isLoading, CityStore?.currentPage, ]); useEffect(() => { if (AreaStore?.hasMore && !AreaStore?.isLoading && areaInView) { getAreaData("", AreaStore?.currentPage + 1); } }, [ areaInView, AreaStore?.hasMore, AreaStore?.isLoading, AreaStore?.currentPage, ]); const validateFields = () => { const errors = {}; if (!CountryStore?.SelectedCountry?.name) errors.country = true; if (!StateStore?.SelectedState?.name) errors.state = true; if (!CityStore?.SelectedCity?.name) errors.city = true; if (!AreaStore?.SelectedArea?.name && !Address.trim()) errors.address = true; return errors; }; const handleCountryChange = (value) => { const Country = CountryStore?.Countries.find( (country) => country.name === value ); setCountryStore((prev) => ({ ...prev, SelectedCountry: Country, countryOpen: false, })); setStateStore({ States: [], SelectedState: {}, StateSearch: "", currentPage: 1, hasMore: false, stateOpen: false, }); setCityStore({ Cities: [], SelectedCity: {}, CitySearch: "", currentPage: 1, hasMore: false, cityOpen: false, }); setAreaStore({ Areas: [], SelectedArea: {}, AreaSearch: "", currentPage: 1, hasMore: false, areaOpen: false, }); setAddress(""); }; const handleStateChange = (value) => { const State = StateStore?.States.find((state) => state.name === value); setStateStore((prev) => ({ ...prev, SelectedState: State, stateOpen: false, })); setCityStore({ Cities: [], SelectedCity: {}, CitySearch: "", currentPage: 1, hasMore: false, cityOpen: false, }); setAreaStore({ Areas: [], SelectedArea: {}, AreaSearch: "", currentPage: 1, hasMore: false, areaOpen: false, }); setAddress(""); }; const handleCityChange = (value) => { const City = CityStore?.Cities.find((city) => city.name === value); setCityStore((prev) => ({ ...prev, SelectedCity: City, cityOpen: false, })); setAreaStore({ Areas: [], SelectedArea: {}, AreaSearch: "", currentPage: 1, hasMore: false, areaOpen: false, }); setAddress(""); }; const handleAreaChange = (value) => { const chosenArea = AreaStore?.Areas.find((item) => item.name === value); setAreaStore((prev) => ({ ...prev, SelectedArea: chosenArea, areaOpen: false, })); }; const handleSave = () => { const errors = validateFields(); setFieldErrors(errors); if (Object.keys(errors).length > 0) return; // Build address parts array and filter out empty values const addressParts = []; const addressPartsTranslated = []; if (hasAreas && AreaStore?.SelectedArea?.name) { addressParts.push(AreaStore.SelectedArea.name); addressPartsTranslated.push( AreaStore.SelectedArea.translated_name || AreaStore.SelectedArea.name ); } else if (Address.trim()) { addressParts.push(Address.trim()); addressPartsTranslated.push(Address.trim()); } if (CityStore?.SelectedCity?.name) { addressParts.push(CityStore.SelectedCity.name); addressPartsTranslated.push( CityStore.SelectedCity.translated_name || CityStore.SelectedCity.name ); } if (StateStore?.SelectedState?.name) { addressParts.push(StateStore.SelectedState.name); addressPartsTranslated.push( StateStore.SelectedState.translated_name || StateStore.SelectedState.name ); } if (CountryStore?.SelectedCountry?.name) { addressParts.push(CountryStore.SelectedCountry.name); addressPartsTranslated.push( CountryStore.SelectedCountry.translated_name || CountryStore.SelectedCountry.name ); } const formattedAddress = addressParts.join(", "); const formattedAddressTranslated = addressPartsTranslated.join(", "); const locationData = { country: CountryStore?.SelectedCountry?.name || "", state: StateStore?.SelectedState?.name || "", city: CityStore?.SelectedCity?.name || "", formattedAddress: formattedAddress, address_translated: formattedAddressTranslated, lat: CityStore?.SelectedCity?.latitude || null, long: CityStore?.SelectedCity?.longitude || null, area_id: AreaStore?.SelectedArea?.id || null, }; setLocation(locationData); setShowManualAddress(false); }; return ( {t("manuAddAddress")}
setCountryStore((prev) => ({ ...prev, countryOpen: isOpen })) } > {fieldErrors.country && ( {t("countryRequired")} )} { setCountryStore((prev) => ({ ...prev, CountrySearch: val, })); }} /> {CountryStore.isLoading ? ( ) : (

{t("noCountriesFound")}

)}
{CountryStore?.Countries?.map((country, index) => { const isLast = index === CountryStore?.Countries?.length - 1; return ( {country.translated_name || country.name} ); })} {CountryStore.isLoading && CountryStore.Countries.length > 0 && }
setStateStore((prev) => ({ ...prev, stateOpen: isOpen })) } > {fieldErrors.state && ( {t("stateRequired")} )} { setStateStore((prev) => ({ ...prev, StateSearch: val })); }} /> {StateStore.isLoading ? ( ) : (

{t("noStatesFound")}

)}
{StateStore?.States?.map((state, index) => { const isLast = index === StateStore?.States?.length - 1; return ( {state.translated_name || state.name} ); })} {StateStore.isLoading && StateStore.States.length > 0 && ( )}
setCityStore((prev) => ({ ...prev, cityOpen: isOpen })) } > {fieldErrors.city && ( {t("cityRequired")} )} { setCityStore((prev) => ({ ...prev, CitySearch: val })); }} /> {CityStore.isLoading ? ( ) : (

{t("noCitiesFound")}

)}
{CityStore?.Cities?.map((city, index) => { const isLast = index === CityStore?.Cities?.length - 1; return ( {city.translated_name || city.name} ); })} {CityStore.isLoading && CityStore.Cities.length > 0 && ( )}
{hasAreas || AreaStore?.AreaSearch ? (
setAreaStore((prev) => ({ ...prev, areaOpen: isOpen })) } > {fieldErrors.address && ( {t("areaRequired")} )} { setAreaStore((prev) => ({ ...prev, AreaSearch: val })); }} /> {AreaStore.isLoading ? ( ) : (

{t("noAreasFound")}

)}
{AreaStore?.Areas?.map((area, index) => { const isLast = index === AreaStore?.Areas?.length - 1; return ( {area.translated_name || area.name} ); })} {AreaStore.isLoading && AreaStore.Areas.length > 0 && ( )}
) : (