1
- import { useMemo } from 'react'
1
+ import { useEffect , useMemo , useState } from 'react'
2
2
import { useForm } from 'react-hook-form'
3
3
4
4
import { Button , Card , Fieldset , FormWrapper , Input , Message , MessageTheme , StyledLink } from '@/components'
5
5
import { Floating1ColumnLayout , TranslationStore } from '@/views'
6
6
import { zodResolver } from '@hookform/resolvers/zod'
7
+ import { makeValidationUtils } from '@utils/validation'
7
8
import { z } from 'zod'
8
9
9
10
import { Agreements } from './components/agreements'
@@ -16,27 +17,49 @@ interface SignInPageProps {
16
17
error ?: string
17
18
}
18
19
19
- const makeSignInSchema = ( t : TranslationStore [ 't' ] ) =>
20
- z . object ( {
21
- email : z . string ( ) . trim ( ) . nonempty ( t ( 'views:signIn.validation.emailNoEmpty' , 'Field can’t be blank' ) ) ,
22
- password : z . string ( ) . nonempty ( t ( 'views:signIn.validation.passwordNoEmpty' , 'Password can’t be blank' ) )
20
+ const makeSignInSchema = ( t : TranslationStore [ 't' ] ) => {
21
+ const { required } = makeValidationUtils ( t )
22
+
23
+ return z . object ( {
24
+ email : z
25
+ . string ( )
26
+ . trim ( )
27
+ . nonempty ( required ( t ( 'views:signIn.emailTitle' ) ) ) ,
28
+ password : z . string ( ) . nonempty ( required ( t ( 'views:signIn.passwordTitle' ) ) )
23
29
} )
30
+ }
24
31
25
32
export type SignInData = z . infer < ReturnType < typeof makeSignInSchema > >
26
33
27
34
export function SignInPage ( { handleSignIn, useTranslationStore, isLoading, error } : SignInPageProps ) {
35
+ const [ serverError , setServerError ] = useState < string | null > ( null )
36
+
28
37
const { t } = useTranslationStore ( )
29
38
const {
30
39
register,
31
40
handleSubmit,
32
41
formState : { errors }
33
42
} = useForm < SignInData > ( {
43
+ mode : 'onChange' ,
34
44
resolver : zodResolver ( makeSignInSchema ( t ) )
35
45
} )
36
46
37
- const errorMessage = useMemo ( ( ) => ( error ?. includes ( 'Not Found' ) ? 'Please check your details' : error ) , [ error ] )
47
+ const errorMessage = useMemo (
48
+ ( ) => ( error ?. includes ( 'Not Found' ) ? t ( 'views:signIn.checkDetails' , 'Please check your details' ) : error ) ,
49
+ [ error , t ]
50
+ )
51
+
52
+ const handleInputChange = async ( ) => {
53
+ if ( ! serverError ) return
54
+ setServerError ( null )
55
+ }
56
+
57
+ useEffect ( ( ) => {
58
+ if ( ! error ) return
59
+ setServerError ( error )
60
+ } , [ error ] )
38
61
39
- const hasError = Object . keys ( errors ) . length > 0 || ! ! error
62
+ const hasError = Object . keys ( errors ) . length > 0 || ! ! serverError
40
63
41
64
return (
42
65
< Floating1ColumnLayout
@@ -65,14 +88,14 @@ export function SignInPage({ handleSignIn, useTranslationStore, isLoading, error
65
88
label = { t ( 'views:signIn.emailTitle' , 'Username/Email' ) }
66
89
placeholder = { t ( 'views:signIn.emailDescription' , 'Your email' ) }
67
90
size = "md"
68
- { ...register ( 'email' ) }
91
+ { ...register ( 'email' , { onChange : handleInputChange } ) }
69
92
error = { errors . email ?. message ?. toString ( ) }
70
93
autoFocus
71
94
/>
72
95
< Input
73
96
id = "password"
74
97
type = "password"
75
- { ...register ( 'password' ) }
98
+ { ...register ( 'password' , { onChange : handleInputChange } ) }
76
99
label = { t ( 'views:signIn.passwordTitle' , 'Password' ) }
77
100
placeholder = { t ( 'views:signIn.passwordDescription' , 'Password' ) }
78
101
size = "md"
0 commit comments