1
1
import { Button } from '@blueprintjs/core'
2
2
3
- import { requestRegister } from 'apis/auth'
4
- import { FC } from 'react'
3
+ import { reqeustRegistrationToken , requestRegister } from 'apis/auth'
4
+ import { FC , useEffect , useState } from 'react'
5
5
import { useForm } from 'react-hook-form'
6
6
7
7
import { AppToaster } from 'components/Toaster'
8
8
import { NetworkError } from 'utils/fetcher'
9
+ import { REGEX_EMAIL } from 'utils/regexes'
9
10
import { wrapErrorMessage } from 'utils/wrapErrorMessage'
10
11
11
12
import {
12
13
AuthFormEmailField ,
13
14
AuthFormPasswordField ,
14
15
AuthFormUsernameField ,
16
+ AuthRegistrationTokenField ,
15
17
} from './AuthFormShared'
16
18
17
19
export interface RegisterFormValues {
18
20
email : string
19
21
password : string
20
22
username : string
23
+ registrationToken : string
21
24
}
22
25
23
26
export const RegisterPanel : FC < {
@@ -27,20 +30,60 @@ export const RegisterPanel: FC<{
27
30
control,
28
31
handleSubmit,
29
32
formState : { errors, isValid, isDirty, isSubmitting } ,
33
+ getValues,
30
34
} = useForm < RegisterFormValues > ( )
31
-
35
+ const [ isSendEmailButtonDisabled , setSendEmailButtonDisabled ] =
36
+ useState ( false )
37
+ const [ countdown , setCountdown ] = useState ( 60 )
32
38
const onSubmit = async ( val : RegisterFormValues ) => {
33
39
await wrapErrorMessage (
34
40
( e : NetworkError ) => `注册失败:${ e . message } ` ,
35
- requestRegister ( val . email , val . username , val . password ) ,
41
+ requestRegister (
42
+ val . email ,
43
+ val . registrationToken ,
44
+ val . username ,
45
+ val . password ,
46
+ ) ,
36
47
)
37
48
AppToaster . show ( {
38
49
intent : 'success' ,
39
- message : `已向注册邮箱发送验证邮件,请使用邮件内的验证链接进行验证 ` ,
50
+ message : `注册成功 ` ,
40
51
} )
41
52
onComplete ( )
42
53
}
54
+ const handleCountdownTick = ( ) => {
55
+ setCountdown ( ( prevCountdown ) => prevCountdown - 1 )
56
+ }
57
+ useEffect ( ( ) => {
58
+ let countdownInterval
59
+ if ( countdown <= 0 ) {
60
+ setCountdown ( 60 )
61
+ setSendEmailButtonDisabled ( false )
62
+ } else if ( isSendEmailButtonDisabled ) {
63
+ countdownInterval = setInterval ( handleCountdownTick , 1000 )
64
+ }
65
+ return ( ) => clearInterval ( countdownInterval )
66
+ } , [ isSendEmailButtonDisabled , countdown ] )
43
67
68
+ const onEmailSubmit = async ( ) => {
69
+ const val = getValues ( )
70
+ if ( ! REGEX_EMAIL . test ( val . email ) ) {
71
+ AppToaster . show ( {
72
+ intent : 'danger' ,
73
+ message : `邮箱输入为空或格式错误,请重新输入` ,
74
+ } )
75
+ return
76
+ }
77
+ await wrapErrorMessage (
78
+ ( e : NetworkError ) => `发送失败:${ e . message } ` ,
79
+ reqeustRegistrationToken ( val . email ) ,
80
+ )
81
+ AppToaster . show ( {
82
+ intent : 'success' ,
83
+ message : `邮件发送成功` ,
84
+ } )
85
+ setSendEmailButtonDisabled ( true )
86
+ }
44
87
return (
45
88
< form onSubmit = { handleSubmit ( onSubmit ) } >
46
89
< AuthFormEmailField
@@ -49,6 +92,26 @@ export const RegisterPanel: FC<{
49
92
error = { errors . email }
50
93
field = "email"
51
94
/>
95
+ < div className = "mt-6 flex justify-end" >
96
+ < Button
97
+ disabled = {
98
+ ( ! isValid && ! isDirty ) || isSubmitting || isSendEmailButtonDisabled
99
+ }
100
+ intent = "primary"
101
+ type = "button"
102
+ icon = "envelope"
103
+ className = "self-stretch"
104
+ onClick = { onEmailSubmit }
105
+ >
106
+ { isSendEmailButtonDisabled ? `${ countdown } 秒再试` : '发送验证码' }
107
+ </ Button >
108
+ </ div >
109
+ < AuthRegistrationTokenField
110
+ register
111
+ control = { control }
112
+ error = { errors . registrationToken }
113
+ field = "registrationToken"
114
+ />
52
115
53
116
< AuthFormUsernameField
54
117
control = { control }
0 commit comments