Skip to content
Snippets Groups Projects
Commit bd5aa6a7 authored by Remco Tukker's avatar Remco Tukker
Browse files

handle page exit through react router properly

parent 3dd6c3e5
Branches
Tags
1 merge request!64useBlock in the survey frontend to ask users for confirmation
import React from "react";
import { unstable_useBlocker as useBlocker } from "react-router-dom";
// adapted from https://stackoverflow.com/a/75920683
// also see https://github.com/remix-run/react-router/blob/496b1fe8253643171ecca6e6a945d98386c4eb00/packages/react-router-dom/index.tsx#L1460C4-L1460C4
// for the unstable_usePrompt implementation in react router itself
// and https://claritydev.net/blog/display-warning-for-unsaved-form-data-on-page-exit for yet another example
function Prompt(props) {
const block = props.when;
const onPageExit = props.onPageExit;
// NB gives warning in the browser console but thats a bug: https://github.com/remix-run/react-router/issues/10073
// apparently the fix of that bug caused a nr of bugs again too...
useBlocker(() => {
if (block()) {
const confirmed = window.confirm(props.message);
if (confirmed) {
onPageExit();
}
return !confirmed;
}
return false;
})
return (
<div />
);
}
export default Prompt;
......@@ -6,6 +6,7 @@ import { useParams } from "react-router-dom";
import SurveyComponent from "./SurveyComponent";
import SurveyNavigationComponent from "./SurveyNavigationComponent";
import { VerificationStatus } from './Schema';
import Prompt from "./Prompt";
import "survey-core/modern.min.css";
import './survey.scss';
......@@ -29,12 +30,15 @@ function SurveyContainerComponent({ loadFrom }) {
}, []);
const pageHideListener = useCallback(() => {
if (!nren) {
return;
}
window.navigator.sendBeacon('/api/response/unlock/' + year + '/' + nren);
}, []);
const onPageExitThroughRouter = useCallback(() => {
window.navigator.sendBeacon('/api/response/unlock/' + year + '/' + nren);
removeEventListener("beforeunload", beforeUnloadListener, { capture: true });
removeEventListener("pagehide", pageHideListener);
}, []);
useEffect(() => {
async function getModel() {
const response = await fetch(loadFrom + year + (nren ? '/' + nren : ''))
......@@ -73,7 +77,6 @@ function SurveyContainerComponent({ loadFrom }) {
}
getModel().catch(error => setError('Error when loading survey: ' + error.message))
}, []);
if (!surveyModel) {
......@@ -202,6 +205,7 @@ function SurveyContainerComponent({ loadFrom }) {
return (
<Container className="survey-container">
<Toaster />
<Prompt message="Are you sure you want to leave this page? Information you've entered may not be saved." when={() => { return surveyModel.mode == 'edit' && !!nren; }} onPageExit={onPageExitThroughRouter} />
<SurveyNavigationComponent surveyModel={surveyModel} surveyActions={surveyActions} year={year} nren={nren}>
<SurveyComponent surveyModel={surveyModel} verificationStatus={verificationStatus} />
</SurveyNavigationComponent>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment