All files / app/features/auth/deletion DeleteAccount.tsx

0% Statements 0/26
0% Branches 0/5
0% Functions 0/4
0% Lines 0/26

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125                                                                                                                                                                                                                                                         
import { Typography, useMediaQuery, useTheme } from "@material-ui/core";
import Alert from "components/Alert";
import Button from "components/Button";
import TextField from "components/TextField";
import { Empty } from "google-protobuf/google/protobuf/empty_pb";
import { RpcError } from "grpc-web";
import { Trans, useTranslation } from "i18n";
import { AUTH, GLOBAL } from "i18n/namespaces";
import { useForm } from "react-hook-form";
import { useMutation } from "react-query";
import { service } from "service";
import { lowercaseAndTrimField } from "utils/validation";
 
import useChangeDetailsFormStyles from "../useChangeDetailsFormStyles";
 
interface DeleteAccountForm {
  confirmUsername: string;
  reason?: string;
}
 
interface DeleteAccountProps {
  username: string;
  className?: string;
}
 
export default function DeleteAccount({
  className,
  username,
}: DeleteAccountProps) {
  const { t } = useTranslation([AUTH, GLOBAL]);
  const formClasses = useChangeDetailsFormStyles();
  const theme = useTheme();
  const isMdOrWider = useMediaQuery(theme.breakpoints.up("md"));
 
  const {
    handleSubmit,
    register,
    reset: resetForm,
  } = useForm<DeleteAccountForm>();
  const onSubmit = handleSubmit((data) => {
    deleteAccount(data);
  });
 
  const {
    error: deleteAccountError,
    isLoading: isDeleteAccountLoading,
    isSuccess: isDeleteAccountSuccess,
    mutate: deleteAccount,
  } = useMutation<Empty, RpcError, DeleteAccountForm>(
    ({ confirmUsername, reason }) => {
      const confirm =
        lowercaseAndTrimField(confirmUsername) ===
        lowercaseAndTrimField(username);
      Iif (!confirm) {
        throw Error(t("auth:delete_account.request.username_mismatch"));
      }
      return service.account.deleteAccount(confirm, reason);
    },
    {
      onSuccess: () => {
        resetForm();
      },
    }
  );
 
  return (
    <div className={className}>
      <Typography variant="h2">
        {t("auth:delete_account.request.title")}
      </Typography>
      <>
        <Typography variant="body1">
          {t("auth:delete_account.request.description")}
        </Typography>
        {deleteAccountError && (
          <Alert severity="error">{deleteAccountError.message}</Alert>
        )}
        {isDeleteAccountSuccess && (
          <Alert severity="success">
            {t("auth:delete_account.request.success_message")}
          </Alert>
        )}
        <form className={formClasses.form} onSubmit={onSubmit}>
          <Typography variant="subtitle1">
            <Trans
              t={t}
              i18nKey="auth:delete_account.request.confirm_username_explanation"
            >
              Your username is <strong>{{ username }}</strong>, please type it
              in below to confirm account deletion.
            </Trans>
          </Typography>
          <TextField
            id="confirmUsername"
            inputRef={register({ required: true })}
            label={t("auth:delete_account.request.confirm_username_label")}
            name="confirmUsername"
            fullWidth={!isMdOrWider}
          />
          <Typography variant="subtitle1">
            {t("auth:delete_account.request.reason_explanation")}
          </Typography>
          <TextField
            id="reason"
            inputRef={register()}
            label={t("auth:delete_account.request.reason_label")}
            name="reason"
            minRows={4}
            maxRows={6}
            multiline
            fullWidth
          />
          <Button
            fullWidth={!isMdOrWider}
            loading={isDeleteAccountLoading}
            type="submit"
          >
            {t("global:submit")}
          </Button>
        </form>
      </>
    </div>
  );
}