11import {
2+ use ,
3+ useCallback ,
4+ useMemo ,
5+ } from 'react' ;
6+ import {
7+ BlockLoading ,
28 Button ,
39 Container ,
410 Description ,
@@ -13,17 +19,39 @@ import {
1319 createSubmitHandler ,
1420 getErrorObject ,
1521 type ObjectSchema ,
22+ removeNull ,
1623 requiredStringCondition ,
1724 useForm ,
1825} from '@togglecorp/toggle-form' ;
26+ import { gql } from 'urql' ;
1927
28+ import UserContext from '#contexts/UserContext' ;
29+ import { useLoginMutation } from '#generated/types/graphql' ;
30+ import useAlert from '#hooks/useAlert' ;
31+ import useRouting from '#hooks/useRouting' ;
2032import BackGroundImage from '#resources/image/loginbackground.jpg' ;
2133import Logo from '#resources/image/logo.png' ;
34+ import { errorMessage } from '#utils/common' ;
2235
2336import styles from './styles.module.css' ;
2437
38+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
39+ const LOGIN_MUTATION = gql `
40+ mutation Login($email: String!, $password: String!) {
41+ login(email: $email, password: $password) {
42+ email
43+ fullName
44+ id
45+ createdAt
46+ isActive
47+ mfaEnabled
48+ role
49+ }
50+ }
51+ ` ;
52+
2553interface FormFields {
26- username ?: string ;
54+ email ?: string ;
2755 password ?: string ;
2856}
2957type FormSchema = ObjectSchema < FormFields > ;
@@ -34,7 +62,7 @@ const defaultFormValue: FormFields = {
3462
3563const formSchema : FormSchema = {
3664 fields : ( ) : FormSchemaFields => ( {
37- username : {
65+ email : {
3866 required : true ,
3967 requiredValidation : requiredStringCondition ,
4068 } ,
@@ -46,24 +74,71 @@ const formSchema: FormSchema = {
4674} ;
4775
4876function Login ( ) {
77+ const { setUser } = use ( UserContext ) ;
78+ const navigate = useRouting ( ) ;
79+ const alert = useAlert ( ) ;
80+
4981 const {
50- value : formValue ,
82+ value,
5183 error : formError ,
5284 setFieldValue,
5385 setError,
5486 validate,
5587 } = useForm ( formSchema , { value : defaultFormValue } ) ;
5688
57- const fieldError = getErrorObject ( formError ) ;
89+ const error = getErrorObject ( formError ) ;
90+
91+ const [ { fetching : loginPending } , triggerLogin ] = useLoginMutation ( ) ;
92+
93+ const handleMutation = useCallback ( async ( mutationData : FormFields ) => {
94+ try {
95+ const { data, error : apiError } = await triggerLogin ( {
96+ email : mutationData . email ?? '' ,
97+ password : mutationData . password ?? '' ,
98+ } ) ;
99+
100+ if ( apiError ) {
101+ alert . show ( 'Incorrect username/password' , {
102+ variant : 'danger' ,
103+ } ) ;
104+ return ;
105+ }
58106
59- // TODO: Implement actual login logic
60- const login = ( ) => { } ;
107+ const loginResponse = data ?. login ;
61108
62- const handleFormSubmit = ( ) => createSubmitHandler (
109+ if ( ! loginResponse ) {
110+ alert . show ( errorMessage , {
111+ variant : 'danger' ,
112+ } ) ;
113+ return ;
114+ }
115+
116+ setUser ( removeNull ( loginResponse ) ) ;
117+
118+ alert . show ( 'Login successful!' , { variant : 'success' } ) ;
119+ navigate ( 'home' ) ;
120+ } catch {
121+ alert . show ( errorMessage , {
122+ variant : 'danger' ,
123+ } ) ;
124+ }
125+ } , [ alert , navigate , setUser , triggerLogin ] ) ;
126+
127+ const handleFormSubmit = useMemo ( ( ) => createSubmitHandler (
63128 validate ,
64129 setError ,
65- login ,
66- ) ;
130+ handleMutation ,
131+ ) , [ validate , setError , handleMutation ] ) ;
132+
133+ if ( loginPending ) {
134+ return (
135+ < BlockLoading
136+ withoutBorder
137+ compact
138+ message = "Loading"
139+ />
140+ ) ;
141+ }
67142
68143 return (
69144 < ListView
@@ -75,7 +150,7 @@ function Login() {
75150 src = { BackGroundImage }
76151 className = { styles . image }
77152 />
78- < form onSubmit = { handleFormSubmit } >
153+ < form >
79154 < Container
80155 spacing = "4xl"
81156 withCenteredContent
@@ -116,20 +191,22 @@ function Login() {
116191 spacing = "lg"
117192 >
118193 < TextInput
119- name = "username "
194+ name = "email "
120195 label = "Email/Username"
121- value = { formValue . username }
196+ value = { value . email }
122197 onChange = { setFieldValue }
123- error = { fieldError ?. username }
198+ error = { error ?. email }
124199 withAsterisk
200+ disabled = { loginPending }
125201 autoFocus
126202 />
127203 < PasswordInput
128204 name = "password"
129205 label = "Password"
130- value = { formValue . password }
206+ value = { value . password }
131207 onChange = { setFieldValue }
132- error = { fieldError ?. password }
208+ error = { error ?. password }
209+ disabled = { loginPending }
133210 withAsterisk
134211 />
135212 </ ListView >
@@ -140,8 +217,9 @@ function Login() {
140217 >
141218 < Button
142219 name = { undefined }
143- type = "submit"
144220 styleVariant = "filled"
221+ onClick = { handleFormSubmit }
222+ disabled = { loginPending }
145223 >
146224 Login
147225 </ Button >
0 commit comments