Restructured check email page
This commit is contained in:
1 parent
9f78173625
commit
3c8e722706
7 files changed
+184
-122
No files matched your search
@@ -1,83 +1,34 @@
|
||||
.check-email-page {
|
||||
width: var(--env-var-width-1);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
min-height: var(--env-var-height-1);
|
||||
height: var(--env-var-height-1);
|
||||
}
|
||||
.check-email-page button:not(.MuiIconButton-root) {
|
||||
height: 34px;
|
||||
border-radius: var(--env-var-radius-2);
|
||||
line-height: 0;
|
||||
}
|
||||
.check-email-page h1.MuiTypography-root {
|
||||
font-size: var(--env-var-font-size-large);
|
||||
color: var(--env-var-color-1);
|
||||
font-weight: 600;
|
||||
}
|
||||
.check-email-page p.MuiTypography-root,
|
||||
.check-email-page button,
|
||||
.check-email-page span.MuiTypography-root {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
}
|
||||
.check-email-page span.MuiTypography-root {
|
||||
font-weight: 600;
|
||||
}
|
||||
.check-email-page p.MuiTypography-root {
|
||||
color: var(--env-var-color-2);
|
||||
}
|
||||
.check-email-page button svg {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.check-email-form {
|
||||
width: var(--env-var-width-2);
|
||||
margin: 90px auto;
|
||||
}
|
||||
|
||||
.check-email-form-header {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.check-email-v-gap-large {
|
||||
height: var(--env-var-spacing-3);
|
||||
}
|
||||
|
||||
.check-email-v-gap-medium {
|
||||
height: var(--env-var-spacing-2);
|
||||
}
|
||||
|
||||
.check-email-v-gap-small {
|
||||
height: var(--env-var-spacing-1);
|
||||
}
|
||||
|
||||
.check-email-form-heading {
|
||||
font-size: var(--env-var-font-size-large);
|
||||
font-weight: 700;
|
||||
color: var(--env-var-color-1);
|
||||
}
|
||||
|
||||
.check-email-form-subheading {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
font-weight: 400;
|
||||
color: var(--env-var-color-2);
|
||||
}
|
||||
|
||||
.check-email-form-subheading span {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.check-email-body {
|
||||
margin-top: 65px;
|
||||
width: var(--env-var-width-2);
|
||||
}
|
||||
|
||||
.check-email-resend {
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
font-weight: 400;
|
||||
color: var(--env-var-color-2);
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.check-email-resend span {
|
||||
font-weight: 700;
|
||||
color: var(--env-var-color-3);
|
||||
}
|
||||
|
||||
.check-email-back-button {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.check-email-back-button-img {
|
||||
width: var(--env-var-img-width-1);
|
||||
height: var(--env-var-img-width-1);
|
||||
margin-right: 5px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.check-email-back-button-text {
|
||||
height: var(--env-var-img-width-1);
|
||||
font-size: var(--env-var-font-size-medium);
|
||||
font-weight: 500;
|
||||
color: var(--env-var-color-2);
|
||||
align-items: center;
|
||||
}
|
||||
@@ -1,56 +1,143 @@
|
||||
import BackgroundPattern from "../../Components/BackgroundPattern/BackgroundPattern";
|
||||
import "./index.css";
|
||||
import React from "react";
|
||||
import EmailIcon from "../../assets/Images/email.png";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import EmailIcon from "../../assets/icons/email.svg?react";
|
||||
import Button from "../../Components/Button";
|
||||
import LeftArrow from "../../assets/Images/arrow-left.png";
|
||||
import ArrowBackRoundedIcon from "@mui/icons-material/ArrowBackRounded";
|
||||
import { Stack, Typography } from "@mui/material";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { useNavigate } from "react-router";
|
||||
import { createToast } from "../../Utils/toastUtils";
|
||||
import { forgotPassword } from "../../Features/Auth/authSlice";
|
||||
|
||||
const CheckEmail = () => {
|
||||
const theme = useTheme();
|
||||
const navigate = useNavigate();
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const [email, setEmail] = useState();
|
||||
const [disabled, setDisabled] = useState(false);
|
||||
useEffect(() => {
|
||||
setEmail(sessionStorage.getItem("email"));
|
||||
}, []);
|
||||
|
||||
// TODO - fix
|
||||
const openMail = () => {
|
||||
window.location.href = "mailto:";
|
||||
};
|
||||
|
||||
const toastFail = [
|
||||
{
|
||||
variant: "info",
|
||||
body: "Email not found.",
|
||||
hasIcon: false,
|
||||
},
|
||||
{
|
||||
variant: "info",
|
||||
body: "Redirecting in 3...",
|
||||
hasIcon: false,
|
||||
},
|
||||
{
|
||||
variant: "info",
|
||||
body: "Redirecting in 2...",
|
||||
hasIcon: false,
|
||||
},
|
||||
{
|
||||
variant: "info",
|
||||
body: "Redirecting in 1...",
|
||||
hasIcon: false,
|
||||
},
|
||||
];
|
||||
|
||||
const resendToken = async () => {
|
||||
setDisabled(true); // prevent resent button from being spammed
|
||||
if (!email) {
|
||||
let index = 0;
|
||||
const interval = setInterval(() => {
|
||||
if (index < toastFail.length) {
|
||||
createToast(toastFail[index]);
|
||||
index++;
|
||||
} else {
|
||||
clearInterval(interval);
|
||||
navigate("/forgot-password");
|
||||
}
|
||||
}, 1000);
|
||||
} else {
|
||||
const form = { email: email };
|
||||
const action = await dispatch(forgotPassword(form));
|
||||
if (action.payload.success) {
|
||||
createToast({
|
||||
variant: "info",
|
||||
body: `Instructions sent to ${form.email}.`,
|
||||
hasIcon: false,
|
||||
});
|
||||
setDisabled(false);
|
||||
} else {
|
||||
if (action.payload) {
|
||||
// dispatch errors
|
||||
createToast({
|
||||
variant: "info",
|
||||
body: action.payload.msg,
|
||||
hasIcon: false,
|
||||
});
|
||||
} else {
|
||||
// unknown errors
|
||||
createToast({
|
||||
variant: "info",
|
||||
body: "Unknown error.",
|
||||
hasIcon: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="check-email-page">
|
||||
<BackgroundPattern />
|
||||
<div className="check-email-form">
|
||||
<div className="check-email-form-header">
|
||||
<img
|
||||
className="check-email-form-header-logo"
|
||||
src={EmailIcon}
|
||||
alt="EmailIcon"
|
||||
/>
|
||||
<div className="check-email-v-gap-medium"></div>
|
||||
<div className="check-email-form-heading">Check your email</div>
|
||||
<div className="check-email-v-gap-small"></div>
|
||||
<div className="check-email-form-subheading">
|
||||
We sent a password reset link to <span>username@email.com</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="check-email-v-gap-large"></div>
|
||||
<div className="check-email-body">
|
||||
<form className="check-email-form">
|
||||
<Stack direction="column" alignItems="center" gap={theme.gap.small}>
|
||||
<EmailIcon alt="EmailIcon" style={{ fill: "white" }} />
|
||||
<Typography component="h1" sx={{ mt: theme.gap.ml }}>
|
||||
Check your email
|
||||
</Typography>
|
||||
<Typography sx={{ width: "max-content" }}>
|
||||
We sent a password reset link to{" "}
|
||||
<Typography component="span">
|
||||
{email || "username@email.com"}
|
||||
</Typography>
|
||||
</Typography>
|
||||
</Stack>
|
||||
<Stack gap={theme.gap.ml} sx={{ mt: `calc(${theme.gap.ml}*2)` }}>
|
||||
<Button level="primary" label="Open email app" onClick={openMail} />
|
||||
<Typography sx={{ alignSelf: "center", mb: theme.gap.medium }}>
|
||||
Didn't receive the email?{" "}
|
||||
<Typography
|
||||
component="span"
|
||||
onClick={resendToken}
|
||||
sx={{
|
||||
color: theme.palette.primary.main,
|
||||
letterSpacing: "-0.1px",
|
||||
userSelect: "none",
|
||||
pointerEvents: disabled ? "none" : "auto",
|
||||
cursor: disabled ? "default" : "pointer",
|
||||
opacity: disabled ? 0.5 : 1,
|
||||
}}
|
||||
>
|
||||
Click to resend
|
||||
</Typography>
|
||||
</Typography>
|
||||
|
||||
<Button
|
||||
level="primary"
|
||||
label="Open email app"
|
||||
sx={{
|
||||
width: "100%",
|
||||
fontSize: "13px",
|
||||
fontWeight: "200",
|
||||
height: "44px",
|
||||
}}
|
||||
level="tertiary"
|
||||
label="Back to log in"
|
||||
img={<ArrowBackRoundedIcon />}
|
||||
sx={{ alignSelf: "center", width: "fit-content" }}
|
||||
onClick={() => navigate("/login")}
|
||||
/>
|
||||
</div>
|
||||
<div className="check-email-v-gap-large"></div>
|
||||
<div className="check-email-resend">
|
||||
Didn’t receive the email?
|
||||
<span> Click to resend</span>
|
||||
</div>
|
||||
<div className="check-email-v-gap-large"></div>
|
||||
<div className="check-email-back-button">
|
||||
<img
|
||||
className="check-email-back-button-img"
|
||||
src={LeftArrow}
|
||||
alt="LeftArrow"
|
||||
/>
|
||||
<div className="check-email-back-button-text">Back to log in</div>
|
||||
</div>
|
||||
</div>
|
||||
</Stack>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -50,6 +50,7 @@ const ForgotPassword = () => {
|
||||
} else {
|
||||
const action = await dispatch(forgotPassword(form));
|
||||
if (action.payload.success) {
|
||||
sessionStorage.setItem("email", form.email);
|
||||
navigate("/check-email");
|
||||
createToast({
|
||||
variant: "info",
|
||||
@@ -100,7 +101,7 @@ const ForgotPassword = () => {
|
||||
return (
|
||||
<div className="forgot-password-page">
|
||||
<BackgroundPattern></BackgroundPattern>
|
||||
<form className="forgot-password-form">
|
||||
<form className="forgot-password-form" onSubmit={handleSubmit}>
|
||||
<Stack direction="column" alignItems="center" gap={theme.gap.small}>
|
||||
<Logomark alt="Logomark" style={{ fill: "white" }} />
|
||||
<Typography component="h1" sx={{ mt: theme.gap.ml }}>
|
||||
|
||||
@@ -173,7 +173,9 @@ const Login = () => {
|
||||
}
|
||||
label="Remember me"
|
||||
/>
|
||||
<span>Forgot password</span>
|
||||
<span onClick={() => navigate("/forgot-password")}>
|
||||
Forgot password
|
||||
</span>
|
||||
</Stack>
|
||||
</Stack>
|
||||
<Stack gap={theme.gap.ml} mt={theme.gap.large}>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.7 KiB |
@@ -0,0 +1,18 @@
|
||||
<svg width="60" height="60" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g filter="url(#filter0_d_137_18989)">
|
||||
<path d="M2.5 13C2.5 6.64873 7.64873 1.5 14 1.5H46C52.3513 1.5 57.5 6.64873 57.5 13V45C57.5 51.3513 52.3513 56.5 46 56.5H14C7.64873 56.5 2.5 51.3513 2.5 45V13Z" stroke="#EAECF0" shape-rendering="crispEdges"/>
|
||||
<path d="M18.3333 23.1667L27.859 29.8347C28.6304 30.3746 29.016 30.6446 29.4356 30.7492C29.8061 30.8416 30.1937 30.8416 30.5643 30.7492C30.9838 30.6446 31.3695 30.3746 32.1408 29.8347L41.6666 23.1667M23.9333 38.3333H36.0666C38.0268 38.3333 39.0069 38.3333 39.7556 37.9519C40.4141 37.6163 40.9496 37.0809 41.2851 36.4223C41.6666 35.6736 41.6666 34.6935 41.6666 32.7333V25.2667C41.6666 23.3065 41.6666 22.3264 41.2851 21.5777C40.9496 20.9191 40.4141 20.3837 39.7556 20.0481C39.0069 19.6667 38.0268 19.6667 36.0666 19.6667H23.9333C21.9731 19.6667 20.993 19.6667 20.2443 20.0481C19.5857 20.3837 19.0503 20.9191 18.7147 21.5777C18.3333 22.3264 18.3333 23.3065 18.3333 25.2667V32.7333C18.3333 34.6935 18.3333 35.6736 18.7147 36.4223C19.0503 37.0809 19.5857 37.6163 20.2443 37.9519C20.993 38.3333 21.9731 38.3333 23.9333 38.3333Z" stroke="#344054" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_d_137_18989" x="0" y="0" width="60" height="60" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="1"/>
|
||||
<feGaussianBlur stdDeviation="1"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.0627451 0 0 0 0 0.0941176 0 0 0 0 0.156863 0 0 0 0.05 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_137_18989"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_137_18989" result="shape"/>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
@@ -47,7 +47,7 @@
|
||||
--env-var-color-27: #fecf60;
|
||||
--lighter-env-var-color-27: rgba(254, 207, 96, 0.1);
|
||||
--env-var-color-28: #f79009;
|
||||
--env-var-color-29: #D0D5DD;
|
||||
--env-var-color-29: #d0d5dd;
|
||||
|
||||
--env-var-radius-1: 4px;
|
||||
--env-var-radius-2: 8px;
|
||||
@@ -128,11 +128,14 @@ button:focus-visible {
|
||||
.Toastify__toast-container {
|
||||
width: auto;
|
||||
}
|
||||
.Toastify__toast-body .alert{
|
||||
min-width: 150px;
|
||||
}
|
||||
.Toastify [class^="Toastify__toast"] {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
.Toastify__toast{
|
||||
.Toastify__toast {
|
||||
min-height: 0;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user