diff --git a/frontend/src/components/notes/NoteForm.tsx b/frontend/src/components/notes/NoteForm.tsx index b599e0f..1f86648 100644 --- a/frontend/src/components/notes/NoteForm.tsx +++ b/frontend/src/components/notes/NoteForm.tsx @@ -30,6 +30,8 @@ export default function NoteForm({ initialValues, onSubmit, onCancel, submitLabe const [gpsLat, setGpsLat] = useState(initialValues?.gps_lat ?? undefined) const [gpsLon, setGpsLon] = useState(initialValues?.gps_lon ?? undefined) const [gpsLoading, setGpsLoading] = useState(false) + const [gpsError, setGpsError] = useState(null) + const [gpsManual, setGpsManual] = useState(false) const [saving, setSaving] = useState(false) const [error, setError] = useState(null) const contentRef = useRef(null) @@ -39,19 +41,37 @@ export default function NoteForm({ initialValues, onSubmit, onCancel, submitLabe } function handleGps() { - if (!navigator.geolocation) return + setGpsError(null) + if (!navigator.geolocation) { + setGpsError('GPS non disponible (HTTPS requis hors localhost)') + setGpsManual(true) + return + } setGpsLoading(true) navigator.geolocation.getCurrentPosition( pos => { setGpsLat(pos.coords.latitude) setGpsLon(pos.coords.longitude) setGpsLoading(false) + setGpsManual(false) + }, + err => { + setGpsLoading(false) + if (err.code === 1) setGpsError('Permission refusée') + else if (err.code === 2) setGpsError('Position indisponible — saisie manuelle ?') + else setGpsError('Délai dépassé — saisie manuelle ?') + setGpsManual(true) }, - () => setGpsLoading(false), { timeout: 8000 }, ) } + function handleManualCoord(field: 'lat' | 'lon', val: string) { + const n = parseFloat(val.replace(',', '.')) + if (field === 'lat') setGpsLat(isNaN(n) ? undefined : n) + else setGpsLon(isNaN(n) ? undefined : n) + } + async function handleSubmit() { if (!content.trim()) return setSaving(true) @@ -112,36 +132,57 @@ export default function NoteForm({ initialValues, onSubmit, onCancel, submitLabe {/* GPS */} -
- - {gpsLat && ( - <> - - {gpsLat.toFixed(5)}, {gpsLon?.toFixed(5)} - - - +
+
+ + {gpsLat != null && ( + <> + + {gpsLat.toFixed(5)}, {gpsLon?.toFixed(5)} + + + + )} +
+ + {gpsError && ( + + {gpsError} + + )} + + {gpsManual && gpsLat == null && ( +
+ handleManualCoord('lat', e.target.value)} + /> + handleManualCoord('lon', e.target.value)} + /> +
)}
diff --git a/frontend/src/components/todos/TodoForm.tsx b/frontend/src/components/todos/TodoForm.tsx index 54be8f5..9d8ad65 100644 --- a/frontend/src/components/todos/TodoForm.tsx +++ b/frontend/src/components/todos/TodoForm.tsx @@ -69,6 +69,8 @@ export default function TodoForm({ onSubmit, onCancel, initialValues, submitLabe const [photoPath, setPhotoPath] = useState(initialValues?.photo_path ?? undefined) const [photoLoading, setPhotoLoading] = useState(false) const [gpsLoading, setGpsLoading] = useState(false) + const [gpsError, setGpsError] = useState(null) + const [gpsManual, setGpsManual] = useState(false) const [loading, setLoading] = useState(false) const fileRef = useRef(null) @@ -109,18 +111,37 @@ export default function TodoForm({ onSubmit, onCancel, initialValues, submitLabe }, []) function handleGps() { - if (!navigator.geolocation) return + setGpsError(null) + if (!navigator.geolocation) { + setGpsError('GPS non disponible (HTTPS requis hors localhost)') + setGpsManual(true) + return + } setGpsLoading(true) navigator.geolocation.getCurrentPosition( pos => { setGpsLat(pos.coords.latitude) setGpsLng(pos.coords.longitude) setGpsLoading(false) + setGpsManual(false) }, - () => setGpsLoading(false) + err => { + setGpsLoading(false) + if (err.code === 1) setGpsError('Permission refusée') + else if (err.code === 2) setGpsError('Position indisponible — saisie manuelle ?') + else setGpsError('Délai dépassé — saisie manuelle ?') + setGpsManual(true) + }, + { timeout: 8000 }, ) } + function handleManualCoord(field: 'lat' | 'lng', val: string) { + const n = parseFloat(val.replace(',', '.')) + if (field === 'lat') setGpsLat(isNaN(n) ? undefined : n) + else setGpsLng(isNaN(n) ? undefined : n) + } + async function handleSubmit(e: React.FormEvent) { e.preventDefault() if (!title.trim()) return @@ -296,7 +317,7 @@ export default function TodoForm({ onSubmit, onCancel, initialValues, submitLabe
{/* Boutons */}