Make meeting point coordinates optional on tour creation
- Latitude/longitude fields are now optional for local/national tours - If provided, both must be filled and valid; otherwise geohash and coords tags are omitted from the published event - Updated input placeholders and added helper text clarifying coordinates are optional Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
This commit is contained in:
parent
8abdb25593
commit
ede0440244
1 changed files with 25 additions and 18 deletions
|
|
@ -441,19 +441,20 @@ export default function CreateTourPage() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Coordinates required only for local/national tours
|
// Coordinates are optional. If one is provided, both must be provided and valid.
|
||||||
if ((tourCategory === 'local' || tourCategory === 'national') && (!meetingLat || !meetingLng)) {
|
|
||||||
toast({
|
|
||||||
title: 'Meeting point coordinates required',
|
|
||||||
description: 'Please enter coordinates or use your current location.',
|
|
||||||
variant: 'destructive',
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let lat = 0;
|
let lat = 0;
|
||||||
let lng = 0;
|
let lng = 0;
|
||||||
if (tourCategory === 'local' || tourCategory === 'national') {
|
let hasCoords = false;
|
||||||
|
if ((tourCategory === 'local' || tourCategory === 'national') && (meetingLat || meetingLng)) {
|
||||||
|
if (!meetingLat || !meetingLng) {
|
||||||
|
toast({
|
||||||
|
title: 'Incomplete coordinates',
|
||||||
|
description: 'Please enter both latitude and longitude, or leave both empty.',
|
||||||
|
variant: 'destructive',
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
lat = parseFloat(meetingLat);
|
lat = parseFloat(meetingLat);
|
||||||
lng = parseFloat(meetingLng);
|
lng = parseFloat(meetingLng);
|
||||||
|
|
||||||
|
|
@ -465,6 +466,8 @@ export default function CreateTourPage() {
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasCoords = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Spot types required only for non-destruction tours
|
// Spot types required only for non-destruction tours
|
||||||
|
|
@ -509,7 +512,7 @@ export default function CreateTourPage() {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Generate low-precision geohash for city-level location (4 chars = ~39km)
|
// Generate low-precision geohash for city-level location (4 chars = ~39km)
|
||||||
const geohash = ngeohash.encode(lat, lng, 4);
|
const geohash = hasCoords ? ngeohash.encode(lat, lng, 4) : '';
|
||||||
|
|
||||||
// Create unique identifier
|
// Create unique identifier
|
||||||
const identifier = title
|
const identifier = title
|
||||||
|
|
@ -528,10 +531,13 @@ export default function CreateTourPage() {
|
||||||
|
|
||||||
// Location/geohash only for local/national tours
|
// Location/geohash only for local/national tours
|
||||||
if (tourCategory === 'local' || tourCategory === 'national') {
|
if (tourCategory === 'local' || tourCategory === 'national') {
|
||||||
tags.push(['g', geohash]);
|
|
||||||
tags.push(['location', location.trim()]);
|
tags.push(['location', location.trim()]);
|
||||||
tags.push(['meeting-point', meetingPoint.trim()]);
|
tags.push(['meeting-point', meetingPoint.trim()]);
|
||||||
tags.push(['meeting-point-coords', lat.toString(), lng.toString()]);
|
// Coordinates are optional - only include when provided
|
||||||
|
if (hasCoords) {
|
||||||
|
tags.push(['g', geohash]);
|
||||||
|
tags.push(['meeting-point-coords', lat.toString(), lng.toString()]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Duration - store in appropriate unit
|
// Duration - store in appropriate unit
|
||||||
|
|
@ -1022,23 +1028,24 @@ export default function CreateTourPage() {
|
||||||
<div className="grid grid-cols-2 gap-4 mt-3">
|
<div className="grid grid-cols-2 gap-4 mt-3">
|
||||||
<div>
|
<div>
|
||||||
<Input
|
<Input
|
||||||
placeholder="Latitude"
|
placeholder="Latitude (optional)"
|
||||||
value={meetingLat}
|
value={meetingLat}
|
||||||
onChange={(e) => setMeetingLat(e.target.value)}
|
onChange={(e) => setMeetingLat(e.target.value)}
|
||||||
className="bg-black border-cyan-500/30"
|
className="bg-black border-cyan-500/30"
|
||||||
required
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Input
|
<Input
|
||||||
placeholder="Longitude"
|
placeholder="Longitude (optional)"
|
||||||
value={meetingLng}
|
value={meetingLng}
|
||||||
onChange={(e) => setMeetingLng(e.target.value)}
|
onChange={(e) => setMeetingLng(e.target.value)}
|
||||||
className="bg-black border-cyan-500/30"
|
className="bg-black border-cyan-500/30"
|
||||||
required
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<p className="text-[11px] text-gray-500 mt-1">
|
||||||
|
Coordinates are optional. Add them to pin your meeting point on the map.
|
||||||
|
</p>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue