fix: attendance clock-in button stuck when geolocation fails or hangs
handlePunch set submitting=true before calling geolocation, but the error callback never reset it. When geolocation was denied or timed out: - Error alert showed - GPS confirm modal opened - Button stayed disabled showing "Zpracovávám..." - User thought it was stuck; no server request appeared to happen Also added a 12s safety timeout fallback because some browsers silently hang on getCurrentPosition without calling either callback. Fix: call setSubmitting(false) in the error callback and clear the safety timeout in both success and error paths. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -186,7 +186,18 @@ export default function Attendance() {
|
|||||||
setSubmitting(true);
|
setSubmitting(true);
|
||||||
latestActionRef.current = action;
|
latestActionRef.current = action;
|
||||||
|
|
||||||
|
// Safety timeout: if geolocation hangs silently (some browsers ignore
|
||||||
|
// the timeout option), reset the button so the user isn't stuck.
|
||||||
|
const safetyTimeout = setTimeout(() => {
|
||||||
|
if (mountedRef.current) {
|
||||||
|
setSubmitting(false);
|
||||||
|
alert.error("Vypršel časový limit pro získání polohy");
|
||||||
|
setGpsConfirm({ isOpen: true, action });
|
||||||
|
}
|
||||||
|
}, 12000);
|
||||||
|
|
||||||
if (!navigator.geolocation) {
|
if (!navigator.geolocation) {
|
||||||
|
clearTimeout(safetyTimeout);
|
||||||
alert.warning("GPS není dostupná");
|
alert.warning("GPS není dostupná");
|
||||||
submitPunch(action, {});
|
submitPunch(action, {});
|
||||||
return;
|
return;
|
||||||
@@ -194,6 +205,7 @@ export default function Attendance() {
|
|||||||
|
|
||||||
navigator.geolocation.getCurrentPosition(
|
navigator.geolocation.getCurrentPosition(
|
||||||
(position) => {
|
(position) => {
|
||||||
|
clearTimeout(safetyTimeout);
|
||||||
if (!mountedRef.current) return;
|
if (!mountedRef.current) return;
|
||||||
const { latitude, longitude, accuracy } = position.coords;
|
const { latitude, longitude, accuracy } = position.coords;
|
||||||
submitPunch(action, { latitude, longitude, accuracy, address: "" });
|
submitPunch(action, { latitude, longitude, accuracy, address: "" });
|
||||||
@@ -228,6 +240,7 @@ export default function Attendance() {
|
|||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
},
|
},
|
||||||
(geoError) => {
|
(geoError) => {
|
||||||
|
clearTimeout(safetyTimeout);
|
||||||
if (!mountedRef.current) return;
|
if (!mountedRef.current) return;
|
||||||
let errorMsg = "Nepodařilo se získat polohu";
|
let errorMsg = "Nepodařilo se získat polohu";
|
||||||
if (geoError.code === geoError.PERMISSION_DENIED) {
|
if (geoError.code === geoError.PERMISSION_DENIED) {
|
||||||
@@ -236,6 +249,7 @@ export default function Attendance() {
|
|||||||
errorMsg = "Vypršel časový limit";
|
errorMsg = "Vypršel časový limit";
|
||||||
}
|
}
|
||||||
alert.error(errorMsg);
|
alert.error(errorMsg);
|
||||||
|
setSubmitting(false);
|
||||||
setGpsConfirm({ isOpen: true, action });
|
setGpsConfirm({ isOpen: true, action });
|
||||||
},
|
},
|
||||||
{ enableHighAccuracy: true, timeout: 10000, maximumAge: 60000 },
|
{ enableHighAccuracy: true, timeout: 10000, maximumAge: 60000 },
|
||||||
|
|||||||
Reference in New Issue
Block a user