Send another code working

This commit is contained in:
Maxime Lalo 2023-11-29 16:47:38 +01:00
parent 07313fba82
commit 7e7725c8ff
4 changed files with 87 additions and 5 deletions

View File

@ -94,4 +94,14 @@ export default class Auth extends BaseApiService {
return Promise.reject(err); return Promise.reject(err);
} }
} }
public async sendAnotherCode(body: IMailVerifyParams): Promise<IMailVerifyReturn> {
const url = new URL(this.baseURl.concat("/send-another-code"));
try {
return this.postRequest<IMailVerifyReturn>(url, body);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
} }

View File

@ -21,4 +21,24 @@
margin-top: 32px; margin-top: 32px;
} }
} }
.ask-another-code {
margin-top: 48px;
display: flex;
flex-direction: column;
gap: 16px;
align-items: flex-start;
.new-code-button {
&[data-disabled="true"] {
opacity: 0.5;
cursor: not-allowed;
}
}
.new-code-timer {
display: flex;
gap: 6px;
align-items: center;
}
}
} }

View File

@ -1,6 +1,6 @@
import React from "react"; import React, { useEffect } from "react";
import classes from "./classes.module.scss"; import classes from "./classes.module.scss";
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography"; import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
import Form from "@Front/Components/DesignSystem/Form"; import Form from "@Front/Components/DesignSystem/Form";
import TextField from "@Front/Components/DesignSystem/Form/TextField"; import TextField from "@Front/Components/DesignSystem/Form/TextField";
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button"; import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
@ -9,15 +9,37 @@ type IProps = {
onSubmit: (e: React.FormEvent<HTMLFormElement> | null, values: { [key: string]: string }) => void; onSubmit: (e: React.FormEvent<HTMLFormElement> | null, values: { [key: string]: string }) => void;
validationErrors: ValidationError[]; validationErrors: ValidationError[];
partialPhoneNumber: string; partialPhoneNumber: string;
onSendAnotherCode: () => void;
}; };
export default function StepTotp(props: IProps) { export default function StepTotp(props: IProps) {
const { onSubmit, validationErrors, partialPhoneNumber } = props; const { onSubmit, validationErrors, partialPhoneNumber, onSendAnotherCode } = props;
const [disableNewCodeButton, setDisableNewCodeButton] = React.useState(true);
const [secondsBeforeNewCode, setSecondsBeforeNewCode] = React.useState(30);
useEffect(() => {
const interval = setInterval(() => {
if (secondsBeforeNewCode > 0) {
setSecondsBeforeNewCode(secondsBeforeNewCode - 1);
} else {
setDisableNewCodeButton(false);
}
}, 1000);
return () => clearInterval(interval);
}, [secondsBeforeNewCode]);
const sendAnotherCode = () => {
onSendAnotherCode();
setDisableNewCodeButton(true);
setSecondsBeforeNewCode(30);
};
return ( return (
<div className={classes["root"]}> <div className={classes["root"]}>
<Typography typo={ITypo.H1}> <Typography typo={ITypo.H1}>
<div className={classes["title"]}>Votre code a é envoyé par SMS au ** ** ** {partialPhoneNumber}</div> <div className={classes["title"]}>
Votre code a é envoyé par SMS au ** ** ** {partialPhoneNumber.replace(/(.{2})/g, "$1 ")}
</div>
</Typography> </Typography>
<Form className={classes["form"]} onSubmit={onSubmit}> <Form className={classes["form"]} onSubmit={onSubmit}>
<TextField <TextField
@ -29,6 +51,23 @@ export default function StepTotp(props: IProps) {
Suivant Suivant
</Button> </Button>
</Form> </Form>
<div className={classes["ask-another-code"]}>
<Typography typo={ITypo.P_16}>Vous n'avez rien reçu ?</Typography>
<Button
variant={EButtonVariant.LINE}
disabled={disableNewCodeButton}
onClick={sendAnotherCode}
data-disabled={disableNewCodeButton.toString()}
className={classes["new-code-button"]}>
Envoyer un nouveau code
</Button>
<Typography typo={ITypo.P_SB_16} className={classes["new-code-timer"]}>
Redemandez un code dans
<Typography typo={ITypo.P_16} color={ITypoColor.PINK_FLASH}>
00:{secondsBeforeNewCode < 10 ? `0${secondsBeforeNewCode}` : secondsBeforeNewCode}
</Typography>
</Typography>
</div>
</div> </div>
); );
} }

View File

@ -177,12 +177,25 @@ export default function Login() {
} }
}, [email]); }, [email]);
const onSendAnotherCode = useCallback(async () => {
try {
await Auth.getInstance().sendAnotherCode({ email });
} catch (error: any) {
return;
}
}, [email]);
return ( return (
<DefaultDoubleSidePage title={"Login"} image={LandingImage}> <DefaultDoubleSidePage title={"Login"} image={LandingImage}>
<div className={classes["root"]}> <div className={classes["root"]}>
{step === LoginStep.EMAIL && <StepEmail onSubmit={onEmailFormSubmit} validationErrors={validationErrors} />} {step === LoginStep.EMAIL && <StepEmail onSubmit={onEmailFormSubmit} validationErrors={validationErrors} />}
{step === LoginStep.TOTP && ( {step === LoginStep.TOTP && (
<StepTotp onSubmit={onSmsCodeSubmit} validationErrors={validationErrors} partialPhoneNumber={partialPhoneNumber} /> <StepTotp
onSubmit={onSmsCodeSubmit}
validationErrors={validationErrors}
partialPhoneNumber={partialPhoneNumber}
onSendAnotherCode={onSendAnotherCode}
/>
)} )}
{step === LoginStep.PASSWORD && ( {step === LoginStep.PASSWORD && (
<StepPassword <StepPassword