fixing bugs with item notification radius

This commit is contained in:
jackiettran
2025-11-20 15:01:15 -05:00
parent 413ac6b6e2
commit 83872fe039
11 changed files with 842 additions and 680 deletions

View File

@@ -6,6 +6,10 @@ import {
} from "../services/geocodingService";
import AddressAutocomplete from "./AddressAutocomplete";
import { PlaceDetails } from "../services/placesService";
import {
useAddressAutocomplete,
usStates,
} from "../hooks/useAddressAutocomplete";
interface LocationFormData {
address1: string;
@@ -29,123 +33,14 @@ interface LocationFormProps {
onAddressSelect: (addressId: string) => void;
formatAddressDisplay: (address: Address) => string;
onCoordinatesChange?: (latitude: number, longitude: number) => void;
onGeocodeRef?: (geocodeFunction: () => Promise<boolean>) => void;
onGeocodeRef?: (
geocodeFunction: () => Promise<{
latitude: number;
longitude: number;
} | null>
) => void;
}
// State constants - moved to top to avoid hoisting issues
const usStates = [
"Alabama",
"Alaska",
"Arizona",
"Arkansas",
"California",
"Colorado",
"Connecticut",
"Delaware",
"Florida",
"Georgia",
"Hawaii",
"Idaho",
"Illinois",
"Indiana",
"Iowa",
"Kansas",
"Kentucky",
"Louisiana",
"Maine",
"Maryland",
"Massachusetts",
"Michigan",
"Minnesota",
"Mississippi",
"Missouri",
"Montana",
"Nebraska",
"Nevada",
"New Hampshire",
"New Jersey",
"New Mexico",
"New York",
"North Carolina",
"North Dakota",
"Ohio",
"Oklahoma",
"Oregon",
"Pennsylvania",
"Rhode Island",
"South Carolina",
"South Dakota",
"Tennessee",
"Texas",
"Utah",
"Vermont",
"Virginia",
"Washington",
"West Virginia",
"Wisconsin",
"Wyoming",
];
// State code to full name mapping for Google Places API integration
const stateCodeToName: { [key: string]: string } = {
AL: "Alabama",
AK: "Alaska",
AZ: "Arizona",
AR: "Arkansas",
CA: "California",
CO: "Colorado",
CT: "Connecticut",
DE: "Delaware",
FL: "Florida",
GA: "Georgia",
HI: "Hawaii",
ID: "Idaho",
IL: "Illinois",
IN: "Indiana",
IA: "Iowa",
KS: "Kansas",
KY: "Kentucky",
LA: "Louisiana",
ME: "Maine",
MD: "Maryland",
MA: "Massachusetts",
MI: "Michigan",
MN: "Minnesota",
MS: "Mississippi",
MO: "Missouri",
MT: "Montana",
NE: "Nebraska",
NV: "Nevada",
NH: "New Hampshire",
NJ: "New Jersey",
NM: "New Mexico",
NY: "New York",
NC: "North Carolina",
ND: "North Dakota",
OH: "Ohio",
OK: "Oklahoma",
OR: "Oregon",
PA: "Pennsylvania",
RI: "Rhode Island",
SC: "South Carolina",
SD: "South Dakota",
TN: "Tennessee",
TX: "Texas",
UT: "Utah",
VT: "Vermont",
VA: "Virginia",
WA: "Washington",
WV: "West Virginia",
WI: "Wisconsin",
WY: "Wyoming",
DC: "District of Columbia",
PR: "Puerto Rico",
VI: "Virgin Islands",
AS: "American Samoa",
GU: "Guam",
MP: "Northern Mariana Islands",
};
const LocationForm: React.FC<LocationFormProps> = ({
data,
userAddresses,
@@ -164,11 +59,13 @@ const LocationForm: React.FC<LocationFormProps> = ({
// Debounced geocoding function
const geocodeAddress = useCallback(
async (addressData: LocationFormData) => {
async (
addressData: LocationFormData
): Promise<{ latitude: number; longitude: number } | null> => {
if (
!geocodingService.isAddressComplete(addressData as AddressComponents)
) {
return;
return null;
}
setGeocoding(true);
@@ -182,6 +79,7 @@ const LocationForm: React.FC<LocationFormProps> = ({
if ("error" in result) {
setGeocodeError(result.details || result.error);
return null;
} else {
setGeocodeSuccess(true);
if (onCoordinatesChange) {
@@ -189,9 +87,13 @@ const LocationForm: React.FC<LocationFormProps> = ({
}
// Clear success message after 3 seconds
setTimeout(() => setGeocodeSuccess(false), 3000);
// Return the coordinates
return { latitude: result.latitude, longitude: result.longitude };
}
} catch (error) {
setGeocodeError("Failed to geocode address");
return null;
} finally {
setGeocoding(false);
}
@@ -202,10 +104,10 @@ const LocationForm: React.FC<LocationFormProps> = ({
// Expose geocoding function to parent components
const triggerGeocoding = useCallback(async () => {
if (data.address1 && data.city && data.state && data.zipCode) {
await geocodeAddress(data);
return true; // Successfully triggered
const coordinates = await geocodeAddress(data);
return coordinates; // Return coordinates directly from geocoding
}
return false; // Incomplete address
return null; // Incomplete address
}, [data, geocodeAddress]);
// Pass geocoding function to parent component
@@ -215,16 +117,19 @@ const LocationForm: React.FC<LocationFormProps> = ({
}
}, [onGeocodeRef, triggerGeocoding]);
// Use address autocomplete hook
const { parsePlace } = useAddressAutocomplete();
// Handle place selection from autocomplete
const handlePlaceSelect = useCallback(
(place: PlaceDetails) => {
try {
const addressComponents = place.addressComponents;
const parsedAddress = parsePlace(place);
// Build address1 from street number and route
const streetNumber = addressComponents.streetNumber || "";
const route = addressComponents.route || "";
const address1 = `${streetNumber} ${route}`.trim();
if (!parsedAddress) {
setPlacesApiError(true);
return;
}
// Create synthetic events to update form data
const createSyntheticEvent = (name: string, value: string) =>
@@ -237,52 +142,15 @@ const LocationForm: React.FC<LocationFormProps> = ({
} as React.ChangeEvent<HTMLInputElement>);
// Update all address fields
onChange(
createSyntheticEvent("address1", address1 || place.formattedAddress)
);
if (addressComponents.locality) {
onChange(createSyntheticEvent("city", addressComponents.locality));
}
if (addressComponents.administrativeAreaLevel1) {
// Convert state code to full name using mapping, with fallback to long name or original code
const stateCode = addressComponents.administrativeAreaLevel1;
const stateName =
stateCodeToName[stateCode] ||
addressComponents.administrativeAreaLevel1Long ||
stateCode;
// Only set the state if it exists in our dropdown options
if (usStates.includes(stateName)) {
onChange(createSyntheticEvent("state", stateName));
} else {
console.warn(
`State not found in dropdown options: ${stateName} (code: ${stateCode})`
);
}
}
if (addressComponents.postalCode) {
onChange(
createSyntheticEvent("zipCode", addressComponents.postalCode)
);
}
if (addressComponents.country) {
onChange(createSyntheticEvent("country", addressComponents.country));
}
onChange(createSyntheticEvent("address1", parsedAddress.address1));
onChange(createSyntheticEvent("city", parsedAddress.city));
onChange(createSyntheticEvent("state", parsedAddress.state));
onChange(createSyntheticEvent("zipCode", parsedAddress.zipCode));
onChange(createSyntheticEvent("country", parsedAddress.country));
// Set coordinates immediately
if (
onCoordinatesChange &&
place.geometry.latitude &&
place.geometry.longitude
) {
onCoordinatesChange(
place.geometry.latitude,
place.geometry.longitude
);
if (onCoordinatesChange) {
onCoordinatesChange(parsedAddress.latitude, parsedAddress.longitude);
}
// Clear any previous geocoding messages
@@ -295,7 +163,7 @@ const LocationForm: React.FC<LocationFormProps> = ({
setPlacesApiError(true);
}
},
[onChange, onCoordinatesChange]
[onChange, onCoordinatesChange, parsePlace]
);
// Handle Places API errors