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" ;
3
3
4
4
import { useNavigate , useSearchParams } from "react-router-dom" ;
5
5
import { isAddress } from "viem" ;
6
6
7
7
import { Button } from "@kleros/ui-components-library" ;
8
8
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" ;
10
12
11
13
import { useAtlasProvider } from "context/AtlasProvider" ;
12
14
@@ -16,44 +18,84 @@ import Loader from "components/Loader";
16
18
17
19
const Container = styled . div `
18
20
display: flex;
19
- justify-content: center;
20
21
width: 100%;
22
+ gap: 48px 16px;
21
23
flex-direction: column;
22
- gap: 16px;
23
- position: relative;
24
+ justify-content: center;
25
+ align-items: center;
26
+ margin-top: 80px;
24
27
${ landscapeStyle (
25
28
( ) => css `
26
- margin-top: 48px;
29
+ flex-direction: row;
30
+ justify-content: space-between;
27
31
`
28
32
) }
29
33
` ;
30
34
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
+ ) }
33
46
` ;
34
47
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
+ ` ;
36
57
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 }
44
68
` ;
45
69
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
+ }
49
91
` ;
50
92
51
93
const EmailConfirmation : React . FC = ( ) => {
94
+ const theme = useTheme ( ) ;
52
95
const { confirmEmail } = useAtlasProvider ( ) ;
53
96
54
97
const [ isConfirming , setIsConfirming ] = useState ( false ) ;
55
98
const [ isConfirmed , setIsConfirmed ] = useState ( false ) ;
56
- const [ isTokenExpired , setIsTokenExpired ] = useState ( false ) ;
57
99
const [ isTokenInvalid , setIsTokenInvalid ] = useState ( false ) ;
58
100
const [ isError , setIsError ] = useState ( false ) ;
59
101
const [ searchParams , _ ] = useSearchParams ( ) ;
@@ -69,47 +111,69 @@ const EmailConfirmation: React.FC = () => {
69
111
confirmEmail ( { address, token } )
70
112
. then ( ( res ) => {
71
113
setIsConfirmed ( res . isConfirmed ) ;
72
- setIsTokenExpired ( res . isTokenExpired ) ;
73
114
setIsTokenInvalid ( res . isTokenInvalid ) ;
74
115
setIsError ( res . isError ) ;
75
116
} )
76
117
. finally ( ( ) => setIsConfirming ( false ) ) ;
77
118
}
78
119
} , [ address , token , confirmEmail ] ) ;
79
120
80
- const [ headerMsg , subtitleMsg , buttonMsg ] = useMemo ( ( ) => {
121
+ const [ headerMsg , subtitleMsg , buttonMsg , buttonTo , Icon , color ] = useMemo ( ( ) => {
81
122
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
+ ] ;
84
140
else if ( isConfirmed )
85
- return [ "Verification Successful 🎉" , "Hooray! , your email has been verified." , "Go to dashboard" ] ;
86
- else if ( isTokenExpired )
87
141
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 ,
91
148
] ;
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 ] ) ;
100
159
101
160
return (
102
161
< Container >
103
- < ThreePnksIconContainer >
104
- < StyledThreePnksIcon />
105
- </ ThreePnksIconContainer >
106
162
{ isConfirming ? (
107
163
< Loader width = { "148px" } height = { "148px" } />
108
164
) : (
109
165
< >
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 >
113
177
</ >
114
178
) }
115
179
</ Container >
0 commit comments