Fix: Implement location data storage fix

This commit is contained in:
gpt-engineer-app[bot]
2025-10-03 15:08:31 +00:00
parent 4493b0824e
commit 404444d5b4
4 changed files with 123 additions and 62 deletions

View File

@@ -23,7 +23,6 @@ interface LocationResult {
}
interface SelectedLocation {
id?: string;
name: string;
city?: string;
state_province?: string;
@@ -32,6 +31,7 @@ interface SelectedLocation {
latitude: number;
longitude: number;
timezone?: string;
display_name: string; // Full OSM display name for reference
}
interface LocationSearchProps {
@@ -61,11 +61,10 @@ export function LocationSearch({ onLocationSelect, initialLocationId, className
.from('locations')
.select('*')
.eq('id', locationId)
.single();
.maybeSingle();
if (data && !error) {
setSelectedLocation({
id: data.id,
name: data.name,
city: data.city || undefined,
state_province: data.state_province || undefined,
@@ -74,6 +73,7 @@ export function LocationSearch({ onLocationSelect, initialLocationId, className
latitude: parseFloat(data.latitude?.toString() || '0'),
longitude: parseFloat(data.longitude?.toString() || '0'),
timezone: data.timezone || undefined,
display_name: data.name, // Use name as display for existing locations
});
}
};
@@ -94,12 +94,30 @@ export function LocationSearch({ onLocationSelect, initialLocationId, className
},
}
);
// Check if response is OK and content-type is JSON
if (!response.ok) {
console.error('OpenStreetMap API error:', response.status);
setResults([]);
setShowResults(false);
return;
}
const contentType = response.headers.get('content-type');
if (!contentType || !contentType.includes('application/json')) {
console.error('Invalid response format from OpenStreetMap');
setResults([]);
setShowResults(false);
return;
}
const data = await response.json();
setResults(data);
setShowResults(true);
} catch (error) {
console.error('Error searching locations:', error);
setResults([]);
setShowResults(false);
} finally {
setIsSearching(false);
}
@@ -123,61 +141,18 @@ export function LocationSearch({ onLocationSelect, initialLocationId, className
? `${city}, ${result.address.state || ''} ${result.address.country}`.trim()
: result.display_name;
// Check if location exists in database
const { data: existingLocation } = await supabase
.from('locations')
.select('*')
.eq('latitude', latitude)
.eq('longitude', longitude)
.maybeSingle();
let locationData: SelectedLocation;
if (existingLocation) {
locationData = {
id: existingLocation.id,
name: existingLocation.name,
city: existingLocation.city || undefined,
state_province: existingLocation.state_province || undefined,
country: existingLocation.country,
postal_code: existingLocation.postal_code || undefined,
latitude: parseFloat(existingLocation.latitude?.toString() || '0'),
longitude: parseFloat(existingLocation.longitude?.toString() || '0'),
timezone: existingLocation.timezone || undefined,
};
} else {
// Create new location
const { data: newLocation, error } = await supabase
.from('locations')
.insert({
name: locationName,
city: city || null,
state_province: result.address.state || null,
country: result.address.country || '',
postal_code: result.address.postcode || null,
latitude,
longitude,
})
.select()
.single();
if (error || !newLocation) {
console.error('Error creating location:', error);
return;
}
locationData = {
id: newLocation.id,
name: newLocation.name,
city: newLocation.city || undefined,
state_province: newLocation.state_province || undefined,
country: newLocation.country,
postal_code: newLocation.postal_code || undefined,
latitude: parseFloat(newLocation.latitude?.toString() || '0'),
longitude: parseFloat(newLocation.longitude?.toString() || '0'),
timezone: newLocation.timezone || undefined,
};
}
// Build location data object (no database operations)
const locationData: SelectedLocation = {
name: locationName,
city: city || undefined,
state_province: result.address.state || undefined,
country: result.address.country || '',
postal_code: result.address.postcode || undefined,
latitude,
longitude,
timezone: undefined, // Will be set by server during approval if needed
display_name: result.display_name,
};
setSelectedLocation(locationData);
setSearchQuery('');

View File

@@ -28,6 +28,17 @@ const parkSchema = z.object({
status: z.string().min(1, 'Status is required'),
opening_date: z.string().optional(),
closing_date: z.string().optional(),
location: z.object({
name: z.string(),
city: z.string().optional(),
state_province: z.string().optional(),
country: z.string(),
postal_code: z.string().optional(),
latitude: z.number(),
longitude: z.number(),
timezone: z.string().optional(),
display_name: z.string(),
}).optional(),
location_id: z.string().uuid().optional(),
website_url: z.string().url().optional().or(z.literal('')),
phone: z.string().optional(),
@@ -289,12 +300,12 @@ export function ParkForm({ onSubmit, onCancel, initialData, isEditing = false }:
<Label>Location</Label>
<LocationSearch
onLocationSelect={(location) => {
setValue('location_id', location.id);
setValue('location', location);
}}
initialLocationId={watch('location_id')}
/>
<p className="text-sm text-muted-foreground">
Search for the park's location using OpenStreetMap
Search for the park's location using OpenStreetMap. Location will be created when submission is approved.
</p>
</div>