GeneIT/geneit_app/src/routes/auth/ResetPasswordRoute.tsx

159 lines
3.9 KiB
TypeScript
Raw Normal View History

2023-06-12 19:10:31 +02:00
import {
Alert,
Box,
Button,
CircularProgress,
TextField,
Typography,
} from "@mui/material";
import React, { useEffect, useRef, useState } from "react";
2023-06-12 16:25:38 +02:00
import { useLocation } from "react-router-dom";
import { AuthApi, CheckResetTokenResponse } from "../../api/AuthApi";
2023-06-12 19:10:31 +02:00
import { PasswordInput } from "../../widgets/PasswordInput";
import { AuthSingleMessage } from "../../widgets/AuthSingleMessage";
import { ServerApi } from "../../api/ServerApi";
2023-06-12 16:25:38 +02:00
export function ResetPasswordRoute(): React.ReactElement {
const [error, setError] = React.useState<string | null>(null);
const { hash } = useLocation();
const token = hash.substring(1);
2023-06-12 19:10:31 +02:00
const [info, setInfo] = React.useState<null | CheckResetTokenResponse>(null);
2023-06-12 16:25:38 +02:00
const checkedToken = useRef<null | string>(null);
useEffect(() => {
(async () => {
if (token === checkedToken.current) return;
checkedToken.current = token;
try {
setError(null);
2023-06-12 19:10:31 +02:00
const info = await AuthApi.CheckResetPasswordToken(token);
setInfo(info);
2023-06-12 16:25:38 +02:00
} catch (e) {
console.error(e);
setError(
"Echec de validation du jeton de réinitialisation de mot de passe!"
);
}
})();
});
if (error)
return (
<Alert style={{ width: "100%" }} severity="error">
{error}
</Alert>
);
if (info === null)
return (
<>
<CircularProgress />
</>
);
2023-06-12 19:10:31 +02:00
return <ResetPasswordForm token={token} info={info} />;
2023-06-12 16:25:38 +02:00
}
function ResetPasswordForm(p: {
token: string;
info: CheckResetTokenResponse;
}): React.ReactElement {
2023-06-12 19:10:31 +02:00
const [error, setError] = React.useState<string | null>(null);
const [loading, setLoading] = React.useState(false);
const [success, setSuccess] = React.useState(false);
const [password, setPassword] = useState("");
const [confirmPassword, setConfirmPassword] = useState("");
const canSubmit =
ServerApi.CheckPassword(password) === null && password === confirmPassword;
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
if (!canSubmit) return;
setLoading(true);
try {
await AuthApi.ResetPassword(p.token, password);
setSuccess(true);
} catch (e) {
console.error(e);
setError("Echec de la réinitialisation du mot de passe !");
}
setLoading(false);
};
if (loading)
return (
<>
<CircularProgress />
</>
);
if (success)
return (
<AuthSingleMessage message="Mot de passe réinitialisé avec succès. Vous pouvez dès à présent l'utiliser pour accéder à votre compte." />
);
return (
<>
{error && (
<Alert style={{ width: "100%" }} severity="error">
{error}
</Alert>
)}
<Typography
component="h2"
variant="body1"
style={{ marginBottom: "15px" }}
>
Bonjour {p.info.name}, veuillez définir votre nouveau mot de passe :
</Typography>
<Box component="form" noValidate onSubmit={handleSubmit} sx={{ mt: 1 }}>
<PasswordInput
label="Nouveau mot de passe"
value={password}
onChange={(n) => {
setPassword(n);
}}
/>
<TextField
margin="normal"
required
fullWidth
error={password !== confirmPassword}
helperText={
password !== confirmPassword
? "Les mots de passe saisis ne correspondent pas !"
: null
}
value={confirmPassword}
onChange={(e) => setConfirmPassword(e.target.value)}
label="Confirmer le mot de passe"
type="password"
id="password"
autoComplete="current-password"
/>
<Button
type="submit"
fullWidth
variant="contained"
sx={{ mt: 3, mb: 2 }}
disabled={!canSubmit}
>
Valider
</Button>
</Box>
</>
);
2023-06-12 16:25:38 +02:00
}