130 lines
3.5 KiB
TypeScript
130 lines
3.5 KiB
TypeScript
import {
|
|
Alert,
|
|
Box,
|
|
Button,
|
|
CircularProgress,
|
|
TextField,
|
|
Typography,
|
|
} from "@mui/material";
|
|
import React from "react";
|
|
import { useLocation } from "react-router-dom";
|
|
import { AuthApi, CheckResetTokenResponse } from "../../api/AuthApi";
|
|
import { ServerApi } from "../../api/ServerApi";
|
|
import { AsyncWidget } from "../../widgets/AsyncWidget";
|
|
import { AuthSingleMessage } from "../../widgets/AuthSingleMessage";
|
|
import { PasswordInput } from "../../widgets/PasswordInput";
|
|
|
|
export function ResetPasswordRoute(): React.ReactElement {
|
|
const [error, setError] = React.useState<string | null>(null);
|
|
const [loading, setLoading] = React.useState(false);
|
|
const [success, setSuccess] = React.useState(false);
|
|
|
|
const [password, setPassword] = React.useState("");
|
|
const [confirmPassword, setConfirmPassword] = React.useState("");
|
|
|
|
const { hash } = useLocation();
|
|
const token = hash.substring(1);
|
|
|
|
const [info, setInfo] = React.useState<null | CheckResetTokenResponse>(null);
|
|
|
|
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(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 (
|
|
<AsyncWidget
|
|
loadKey={token}
|
|
load={async () => setInfo(await AuthApi.CheckResetPasswordToken(token))}
|
|
errMsg="Echec de validation du jeton de réinitialisation de mot de passe !"
|
|
build={() => (
|
|
<>
|
|
{error && (
|
|
<Alert style={{ width: "100%" }} severity="error">
|
|
{error}
|
|
</Alert>
|
|
)}
|
|
|
|
<Typography
|
|
component="h2"
|
|
variant="body1"
|
|
style={{ marginBottom: "15px" }}
|
|
>
|
|
Bonjour {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>
|
|
</>
|
|
)}
|
|
/>
|
|
);
|
|
}
|