1
1
import { FC , useContext , useState } from 'react'
2
2
import { SWRResponse } from 'swr'
3
3
import { bind , isEmpty } from 'lodash'
4
+ import { toast } from 'react-toastify'
4
5
import classNames from 'classnames'
5
6
6
7
import { profileContext , ProfileContextData } from '~/libs/core'
7
- import { Button , InputDatePicker , InputMultiselectOption ,
8
+ import { Button , IconSolid , InputDatePicker , InputMultiselectOption ,
8
9
InputRadio , InputSelect , InputText , InputTextarea } from '~/libs/ui'
9
10
import { InputSkillSelector } from '~/libs/shared'
10
11
11
- import { useFetchProjects } from '../../services/projects'
12
+ import { saveCopilotRequest , useFetchProjects } from '../../services/projects'
12
13
import { ProjectTypes } from '../../constants'
13
14
import { Project } from '../../models/Project'
14
15
@@ -47,6 +48,11 @@ const CopilotRequestForm: FC<{}> = () => {
47
48
...prevFormValues ,
48
49
paymentType : t ,
49
50
} ) )
51
+ setFormErrors ( ( prevFormErrors : any ) => {
52
+ const updatedErrors = { ...prevFormErrors }
53
+ delete updatedErrors . paymentType
54
+ return updatedErrors
55
+ } )
50
56
setPaymentType ( t )
51
57
}
52
58
@@ -72,6 +78,24 @@ const CopilotRequestForm: FC<{}> = () => {
72
78
...oldFormValues ,
73
79
[ key ] : value ,
74
80
} )
81
+
82
+ // Clear specific field error
83
+ setFormErrors ( ( prevFormErrors : any ) => {
84
+ const updatedErrors = { ...prevFormErrors }
85
+ let errorKey : string
86
+ switch ( key ) {
87
+ case 'copilotUsername' :
88
+ errorKey = 'existingCopilot'
89
+ break
90
+ default :
91
+ errorKey = key
92
+ break
93
+ }
94
+
95
+ // Remove the error from the updatedErrors object
96
+ delete updatedErrors [ errorKey ]
97
+ return updatedErrors
98
+ } )
75
99
setIsFormChanged ( true )
76
100
}
77
101
@@ -85,22 +109,44 @@ const CopilotRequestForm: FC<{}> = () => {
85
109
...prevFormValues ,
86
110
skills : updatedSkills ,
87
111
} ) )
112
+
113
+ setFormErrors ( ( prevFormErrors : any ) => {
114
+ const updatedErrors = { ...prevFormErrors }
115
+ delete updatedErrors . skills
116
+ return updatedErrors
117
+ } )
88
118
setIsFormChanged ( true )
89
119
}
90
120
91
121
function handleFormAction ( ) : void {
92
122
const updatedFormErrors : { [ key : string ] : string } = { }
93
123
94
124
if ( ! formValues . projectId ) {
95
- updatedFormErrors . project = 'Project is required'
125
+ updatedFormErrors . projectId = 'Project is required'
126
+ }
127
+
128
+ if ( ! existingCopilot ) {
129
+ updatedFormErrors . existingCopilot = 'Selection is required'
130
+ }
131
+
132
+ if ( ! formValues . complexity ) {
133
+ updatedFormErrors . complexity = 'Selection is required'
134
+ }
135
+
136
+ if ( ! formValues . requiresCommunicatn ) {
137
+ updatedFormErrors . requiresCommunicatn = 'Selection is required'
138
+ }
139
+
140
+ if ( ! formValues . paymentType ) {
141
+ updatedFormErrors . paymentType = 'Selection is required'
96
142
}
97
143
98
144
if ( ! formValues . projectType ) {
99
145
updatedFormErrors . projectType = 'Selecting project type is required'
100
146
}
101
147
102
- if ( ! formValues . projectOverview ) {
103
- updatedFormErrors . projectOverview = 'Providing a project overview is required'
148
+ if ( ! formValues . overview ) {
149
+ updatedFormErrors . overview = 'Providing a project overview is required'
104
150
}
105
151
106
152
if ( ! formValues . skills ) {
@@ -124,7 +170,19 @@ const CopilotRequestForm: FC<{}> = () => {
124
170
}
125
171
126
172
if ( isEmpty ( updatedFormErrors ) ) {
127
- // call the API to update the trait based on action type
173
+ saveCopilotRequest ( formValues )
174
+ . then ( ( ) => {
175
+ toast . success ( 'Subscription updated successfully' )
176
+ // Reset form after successful submission
177
+ setFormValues ( { } )
178
+ setIsFormChanged ( false )
179
+ setFormErrors ( { } )
180
+ setExistingCopilot ( '' )
181
+ setPaymentType ( '' )
182
+ } )
183
+ . catch ( ( ) => {
184
+ toast . error ( 'Error updating subscription' )
185
+ } )
128
186
}
129
187
130
188
setFormErrors ( updatedFormErrors )
@@ -152,7 +210,7 @@ const CopilotRequestForm: FC<{}> = () => {
152
210
label = 'Project'
153
211
placeholder = 'Select the project you wish to request a copilot for'
154
212
dirty
155
- error = { formErrors . project }
213
+ error = { formErrors . projectId }
156
214
/>
157
215
< p className = { styles . formRow } >
158
216
Are you already working with a copilot that you'd love to work with on this project
@@ -198,6 +256,12 @@ const CopilotRequestForm: FC<{}> = () => {
198
256
</ div >
199
257
)
200
258
}
259
+ { formErrors . existingCopilot && (
260
+ < p className = { styles . error } >
261
+ < IconSolid . ExclamationIcon />
262
+ { formErrors . existingCopilot }
263
+ </ p >
264
+ ) }
201
265
202
266
< p className = { styles . formRow } > What type of project are you working on?</ p >
203
267
< InputSelect
@@ -252,6 +316,12 @@ const CopilotRequestForm: FC<{}> = () => {
252
316
noCaps
253
317
leftAlignText
254
318
/>
319
+ { formErrors . complexity && (
320
+ < p className = { styles . error } >
321
+ < IconSolid . ExclamationIcon />
322
+ { formErrors . complexity }
323
+ </ p >
324
+ ) }
255
325
</ div >
256
326
< p className = { styles . formRow } >
257
327
Please provide an overview of the project the copilot will undertake
@@ -263,11 +333,11 @@ const CopilotRequestForm: FC<{}> = () => {
263
333
type of work and project which is to be undertaken.'
264
334
value = { formValues . overview }
265
335
onChange = { bind ( handleFormValueChange , this , 'overview' ) }
266
- error = { formErrors . projectOverview }
267
- tabIndex = { 0 }
336
+ error = { formErrors . overview }
337
+ dirty
268
338
/>
269
339
< p className = { styles . formRow } > Any specific skills or technology requirements that come to mind?</ p >
270
- < div className = { styles . skillsWrapper } >
340
+ < div className = { formErrors . skills ? styles . skillsError : styles . skillsWrapper } >
271
341
< InputSkillSelector
272
342
placeholder = 'Enter skills you are searching for...'
273
343
useWrapper = { false }
@@ -276,6 +346,12 @@ const CopilotRequestForm: FC<{}> = () => {
276
346
onChange = { handleSkillsChange }
277
347
/>
278
348
</ div >
349
+ { formErrors . skills && (
350
+ < p className = { styles . error } >
351
+ < IconSolid . ExclamationIcon />
352
+ { formErrors . skills }
353
+ </ p >
354
+ ) }
279
355
< p className = { styles . formRow } > What's the planned start date for the copilot?</ p >
280
356
< InputDatePicker
281
357
label = 'Copilot Start Date'
@@ -344,6 +420,12 @@ const CopilotRequestForm: FC<{}> = () => {
344
420
onChange = { bind ( handleFormValueChange , this , 'requiresCommunicatn' ) }
345
421
/>
346
422
</ div >
423
+ { formErrors . requiresCommunicatn && (
424
+ < p className = { styles . error } >
425
+ < IconSolid . ExclamationIcon />
426
+ { formErrors . requiresCommunicatn }
427
+ </ p >
428
+ ) }
347
429
< p className = { styles . formRow } > Will this role be standard payments or something else?</ p >
348
430
< div className = { styles . formRadioBtn } >
349
431
< InputRadio
@@ -377,6 +459,12 @@ const CopilotRequestForm: FC<{}> = () => {
377
459
/>
378
460
) }
379
461
</ div >
462
+ { formErrors . paymentType && (
463
+ < p className = { styles . error } >
464
+ < IconSolid . ExclamationIcon />
465
+ { formErrors . paymentType }
466
+ </ p >
467
+ ) }
380
468
< Button
381
469
primary
382
470
size = 'lg'
0 commit comments