1

I have a timeout dialog that I want to render in various components when a token expires at X minutes (I have hardcoded the times for now). Material-UI Dialog is being used for the dialog pop up. I have two timeouts set, one at 29min:30sec for a warning message and 30min will force the logout.

I have looked at the following example for ideas.

const AlertDialog = props => {
  const [warningTimeout, setWarningTimeout] = useState(1770000);
  const [limitTimeout, setLimitTimeout] = useState(1800000);
  const [open, setOpen] = useState(true);

  const handleContinue = () => {
    //this will make an api call to refresh the token, where we must update the context with the new token
    setOpen(false);
  };

  const handleLogout = () => {
    //this will destroy the session, clear localstorage
  };

  const warn = () => {
    console.log("Warning, 30 minutes has past");
  };
  const logout = () => {
    console.log("You have been logged out");
  };

  const setTimeouts = () => {
    const warnTimeout = setTimeout(warn, warningTimeout);
    const logoutTimeout = setTimeout(logout, limitTimeout);
  };

  useEffect(() => {
    setTimeouts();
  });

  return (
    <div>
      <Dialog
        disableBackdropClick
        disableEscapeKeyDown
        open={open}
        aria-labelledby="alert-dialog-title"
        aria-describedby="alert-dialog-description"
      >
        <DialogTitle id="alert-dialog-title">{"Session Timeout"}</DialogTitle>
        <DialogContent>
          <DialogContentText id="alert-dialog-description">
            If you wish to continue the current session please press continue.
            You have 30 seconds to decide or you will be logged out.
          </DialogContentText>
        </DialogContent>
        <DialogActions>
          <Button onClick={handleLogout} color="primary">
            Logout
          </Button>
          <Button onClick={handleContinue} color="primary" autoFocus>
            Continue
          </Button>
        </DialogActions>
      </Dialog>
    </div>
  );
};

export default AlertDialog;

The project has protected routes so they look like this. I want to pass this alert dialog to all the <AdminPrivateRoute>'s

const Routes = () => (
  <UserProvider>
    <TokenProvider>
      <Router>
        <Switch>
          <Route exact path="/" component={LoginForm} />
          <AdminPrivateRoute path="/dashboard" component={Dashboard} />
          <AdminPrivateRoute path="/secondary-page" component={SecondaryPage} />
        </Switch>
      </Router>
    </TokenProvider>
  </UserProvider>
);

Is wrapping the above components with alert dialog a viable option? <AdminPrivateRoute path="/dashbaord" component={AlertDialog(Dashboard)} /> Is there a better approach?

Codesandbox for reference, you can use any credentials to log in.

DJ2
  • 1,721
  • 3
  • 34
  • 74

1 Answers1

0

Placing the <AlertDialog /> component outside the <Switch /> seems to do the trick.

const Routes = () => (
  <Router>
    <AlertDialog />
    <Switch>
      <Route exact path="/" component={LoginForm} />
      <AdminPrivateRoute path="/dashboard" component={Dashboard} />
    </Switch>
  </Router>
);
DJ2
  • 1,721
  • 3
  • 34
  • 74