Confirm email

The confirm email page like the reset password page is only accessed via a link sent to the user in an email. This link contains a token which we need to send to the backend thereby proving the user has access to the email address. It is therefore a fairly simple page that sends data and then redirects the user to the homepage.

To make the experience better for the user we'll display a progress element to indicate that something is happening whilst the request to the backend is made. The following should be added to frontend/src/pages/ConfirmEmail.tsx,

import Box from "@material-ui/core/Box";
import LinearProgress from "@material-ui/core/LinearProgress";
import axios from "axios";
import React, { useContext } from "react";
import { useTranslation } from "react-i18next";
import { useParams } from "react-router";
import { Redirect } from "react-router-dom";

import { useQuery } from "src/query";
import { ToastContext } from "src/ToastContext";

interface IParams {
  token?: string;
}

const ConfirmEmail = () => {
  const { t } = useTranslation();
  const { addToast } = useContext(ToastContext);
  const params = useParams<IParams>();
  const token = params.token ?? "";
  const { isLoading } = useQuery(
    "Email",
    async () => {
      await axios.put("/members/email/", { token });
    },
    {
      onError: (error) => {
        if (error.response?.status === 400) {
          if (error.response.data.code === "TOKEN_INVALID") {
            addToast({ category: "error", message: t("generic.invalidToken") });
          } else if (error.response.data.code === "TOKEN_EXPIRED") {
            addToast({ category: "error", message: t("generic.expiredToken") });
          }
        } else {
          addToast({ category: "error", message: t("generic.tryAgainError") });
        }
      },
      onSuccess: () => {
        addToast({ category: "success", message: t("generic.thanks") });
      },
    },
  );

  if (isLoading) {
    return (
      <Box mt={4}>
        <LinearProgress />
      </Box>
    );
  } else {
    return <Redirect to="/" />;
  }
};

export default ConfirmEmail;

Then we can add the page to the routing by adding the following to frontend/src/Router.tsx,

import ConfirmEmail from "src/pages/ConfirmEmail";
...

const Router = () => (
  <BrowserRouter>
    ...
    <Route exact={true} path="/confirm-email/:token/">
      <ConfirmEmail />
    </Route>
  </BrowserRouter>
);