Skip to content

Commit 50ea26a

Browse files
committed
feat(web): confirmation-page-ui
1 parent 143d33f commit 50ea26a

File tree

3 files changed

+126
-45
lines changed

3 files changed

+126
-45
lines changed
Lines changed: 15 additions & 0 deletions
Loading

web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ const StyledHourglassIcon = styled(HourglassIcon)`
3737
`;
3838

3939
const StyledButton = styled(Button)`
40+
display: inline-block;
4041
background-color: transparent;
4142
padding: 0;
4243
.button-text {
@@ -84,7 +85,8 @@ const EmailVerificationInfo: React.FC<IEmailInfo> = ({ toggleIsSettingsOpen }) =
8485
<InfoInnerContainer>
8586
<InfoTitle>Email Verification Pending</InfoTitle>
8687
<InfoSubtitle>
87-
We have sent you a confirmation email. <StyledButton text="Resend email" onClick={resendEmail} />
88+
We sent you a verification email. Please, verify it.
89+
<br /> Didn’t receive the email? <StyledButton text="Resend it" onClick={resendEmail} />
8890
</InfoSubtitle>
8991
</InfoInnerContainer>
9092
</InfoContainer>

web/src/pages/Settings/EmailConfirmation/index.tsx

Lines changed: 108 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
import React, { useCallback, useEffect, useMemo, useState } from "react";
2-
import styled, { css } from "styled-components";
1+
import React, { useEffect, useMemo, useState } from "react";
2+
import styled, { css, useTheme } from "styled-components";
33

44
import { useNavigate, useSearchParams } from "react-router-dom";
55
import { isAddress } from "viem";
66

77
import { Button } from "@kleros/ui-components-library";
88

9-
import ThreePnksIcon from "svgs/styled/three-pnks.svg";
9+
import CheckIcon from "svgs/icons/check-circle-outline.svg";
10+
import WarningIcon from "svgs/icons/warning-outline.svg";
11+
import InvalidIcon from "svgs/label-icons/minus-circle.svg";
1012

1113
import { useAtlasProvider } from "context/AtlasProvider";
1214

@@ -16,44 +18,84 @@ import Loader from "components/Loader";
1618

1719
const Container = styled.div`
1820
display: flex;
19-
justify-content: center;
2021
width: 100%;
22+
gap: 48px 16px;
2123
flex-direction: column;
22-
gap: 16px;
23-
position: relative;
24+
justify-content: center;
25+
align-items: center;
26+
margin-top: 80px;
2427
${landscapeStyle(
2528
() => css`
26-
margin-top: 48px;
29+
flex-direction: row;
30+
justify-content: space-between;
2731
`
2832
)}
2933
`;
3034

31-
const Header = styled.h1`
32-
color: ${({ theme }) => theme.secondaryPurple};
35+
const InfoWrapper = styled.div`
36+
display: flex;
37+
flex-direction: column;
38+
gap: 32px;
39+
align-items: center;
40+
flex: 1;
41+
${landscapeStyle(
42+
() => css`
43+
align-items: start;
44+
`
45+
)}
3346
`;
3447

35-
const Subtitle = styled.h3``;
48+
const textCss = css`
49+
margin: 0;
50+
text-align: center;
51+
${landscapeStyle(
52+
() => css`
53+
text-align: left;
54+
`
55+
)}
56+
`;
3657

37-
const ThreePnksIconContainer = styled.div`
38-
display: flex;
39-
width: 100%;
40-
position: absolute;
41-
right: 0;
42-
top: 0;
43-
justify-content: end;
58+
const Header = styled.h1<{ fontColor: string }>`
59+
${textCss}
60+
${({ fontColor }) =>
61+
css`
62+
color: ${fontColor};
63+
`};
64+
`;
65+
66+
const Subtitle = styled.h3`
67+
${textCss}
4468
`;
4569

46-
const StyledThreePnksIcon = styled(ThreePnksIcon)`
47-
width: 200px;
48-
height: 200px;
70+
const HeaderIconContainer = styled.div<{ iconColor: string }>`
71+
svg {
72+
width: 64px;
73+
height: 64px;
74+
${({ iconColor }) =>
75+
css`
76+
path {
77+
fill: ${iconColor};
78+
}
79+
`}
80+
}
81+
`;
82+
83+
const IconContainer = styled.div`
84+
svg {
85+
width: 250px;
86+
height: 250px;
87+
path {
88+
fill: ${({ theme }) => theme.whiteBackground};
89+
}
90+
}
4991
`;
5092

5193
const EmailConfirmation: React.FC = () => {
94+
const theme = useTheme();
5295
const { confirmEmail } = useAtlasProvider();
5396

5497
const [isConfirming, setIsConfirming] = useState(false);
5598
const [isConfirmed, setIsConfirmed] = useState(false);
56-
const [isTokenExpired, setIsTokenExpired] = useState(false);
5799
const [isTokenInvalid, setIsTokenInvalid] = useState(false);
58100
const [isError, setIsError] = useState(false);
59101
const [searchParams, _] = useSearchParams();
@@ -69,47 +111,69 @@ const EmailConfirmation: React.FC = () => {
69111
confirmEmail({ address, token })
70112
.then((res) => {
71113
setIsConfirmed(res.isConfirmed);
72-
setIsTokenExpired(res.isTokenExpired);
73114
setIsTokenInvalid(res.isTokenInvalid);
74115
setIsError(res.isError);
75116
})
76117
.finally(() => setIsConfirming(false));
77118
}
78119
}, [address, token, confirmEmail]);
79120

80-
const [headerMsg, subtitleMsg, buttonMsg] = useMemo(() => {
121+
const [headerMsg, subtitleMsg, buttonMsg, buttonTo, Icon, color] = useMemo(() => {
81122
if (!address || !isAddress(address) || !token || isTokenInvalid)
82-
return ["Invalid Link!", "Oops, seems like you followed an invalid link.", "Contact Support"];
83-
else if (isError) return ["Verification Failed", "Oops, could not verify your email.", "Contact Support"];
123+
return [
124+
"Invalid Link!",
125+
"Oops, seems like you followed an invalid link.",
126+
"Contact Support",
127+
"/",
128+
InvalidIcon,
129+
theme.primaryText,
130+
];
131+
else if (isError)
132+
return [
133+
"Something went wrong",
134+
"Oops, seems like something went wrong in our systems",
135+
"Contact Support",
136+
"/",
137+
WarningIcon,
138+
theme.error,
139+
];
84140
else if (isConfirmed)
85-
return ["Verification Successful 🎉", "Hooray! , your email has been verified.", "Go to dashboard"];
86-
else if (isTokenExpired)
87141
return [
88-
"Link Expired",
89-
"Oops, seems like this email verification link has expired. \n No worries we can send the link again.",
90-
"Generate new link",
142+
"Congratulations! Your email has been verified!",
143+
"We'll remind you when your actions are required on Court, and send you notifications on key moments to help you achieve the best of Kleros.",
144+
"Let's start!",
145+
"/",
146+
CheckIcon,
147+
theme.success,
91148
];
92-
else return ["Something went wrong", "Oops, seems like something went wrong in our systems", "Contact Support"];
93-
}, [address, token, isError, isConfirmed, isTokenExpired, isTokenInvalid]);
94-
95-
const handleButtonClick = useCallback(() => {
96-
// TODO: send to support?
97-
if (!address || !isAddress(address) || !token || isError) return navigate("/");
98-
navigate("/#notifications");
99-
}, [address, token, isError, navigate]);
149+
else
150+
return [
151+
"Verification link expired...",
152+
"Oops, the email verification link has expired. No worries! Go to settings and click on Resend it to receive another verification email.",
153+
"Open Settings",
154+
"/#notifications",
155+
WarningIcon,
156+
theme.warning,
157+
];
158+
}, [address, token, isError, isConfirmed, isTokenInvalid, theme]);
100159

101160
return (
102161
<Container>
103-
<ThreePnksIconContainer>
104-
<StyledThreePnksIcon />
105-
</ThreePnksIconContainer>
106162
{isConfirming ? (
107163
<Loader width={"148px"} height={"148px"} />
108164
) : (
109165
<>
110-
<Header>{headerMsg}</Header>
111-
<Subtitle>{subtitleMsg}</Subtitle>
112-
<Button text={buttonMsg} onClick={handleButtonClick} />
166+
<InfoWrapper>
167+
<HeaderIconContainer iconColor={color}>
168+
<Icon />
169+
</HeaderIconContainer>
170+
<Header fontColor={color}>{headerMsg}</Header>
171+
<Subtitle>{subtitleMsg}</Subtitle>
172+
<Button text={buttonMsg} onClick={() => navigate(buttonTo)} />
173+
</InfoWrapper>
174+
<IconContainer>
175+
<Icon />
176+
</IconContainer>
113177
</>
114178
)}
115179
</Container>

0 commit comments

Comments
 (0)