Skip to content

Commit e3f4bf9

Browse files
author
himaniraghav3
committed
Integrate save request API
1 parent c4999cf commit e3f4bf9

File tree

4 files changed

+148
-11
lines changed

4 files changed

+148
-11
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { UserSkill } from '~/libs/core'
2+
3+
import { ProjectType } from '../constants'
4+
5+
export interface CopilotRequest {
6+
projectId: string,
7+
projectType: ProjectType,
8+
complexity: 'high' | 'medium' | 'low',
9+
copilotUsername: string,
10+
numHoursPerWeek: number,
11+
numWeeks: number,
12+
overview: string,
13+
paymentType: string,
14+
requiresCommunicatn: 'yes' | 'no',
15+
skills: UserSkill[],
16+
startDate: Date,
17+
tzRestrictions: 'yes' | 'no',
18+
}

src/apps/copilots/src/pages/copilot-request-form/index.tsx

Lines changed: 98 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import { FC, useContext, useState } from 'react'
22
import { SWRResponse } from 'swr'
33
import { bind, isEmpty } from 'lodash'
4+
import { toast } from 'react-toastify'
45
import classNames from 'classnames'
56

67
import { profileContext, ProfileContextData } from '~/libs/core'
7-
import { Button, InputDatePicker, InputMultiselectOption,
8+
import { Button, IconSolid, InputDatePicker, InputMultiselectOption,
89
InputRadio, InputSelect, InputText, InputTextarea } from '~/libs/ui'
910
import { InputSkillSelector } from '~/libs/shared'
1011

11-
import { useFetchProjects } from '../../services/projects'
12+
import { saveCopilotRequest, useFetchProjects } from '../../services/projects'
1213
import { ProjectTypes } from '../../constants'
1314
import { Project } from '../../models/Project'
1415

@@ -47,6 +48,11 @@ const CopilotRequestForm: FC<{}> = () => {
4748
...prevFormValues,
4849
paymentType: t,
4950
}))
51+
setFormErrors((prevFormErrors: any) => {
52+
const updatedErrors = { ...prevFormErrors }
53+
delete updatedErrors.paymentType
54+
return updatedErrors
55+
})
5056
setPaymentType(t)
5157
}
5258

@@ -72,6 +78,24 @@ const CopilotRequestForm: FC<{}> = () => {
7278
...oldFormValues,
7379
[key]: value,
7480
})
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+
})
7599
setIsFormChanged(true)
76100
}
77101

@@ -85,22 +109,44 @@ const CopilotRequestForm: FC<{}> = () => {
85109
...prevFormValues,
86110
skills: updatedSkills,
87111
}))
112+
113+
setFormErrors((prevFormErrors: any) => {
114+
const updatedErrors = { ...prevFormErrors }
115+
delete updatedErrors.skills
116+
return updatedErrors
117+
})
88118
setIsFormChanged(true)
89119
}
90120

91121
function handleFormAction(): void {
92122
const updatedFormErrors: { [key: string]: string } = {}
93123

94124
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'
96142
}
97143

98144
if (!formValues.projectType) {
99145
updatedFormErrors.projectType = 'Selecting project type is required'
100146
}
101147

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'
104150
}
105151

106152
if (!formValues.skills) {
@@ -124,7 +170,19 @@ const CopilotRequestForm: FC<{}> = () => {
124170
}
125171

126172
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+
})
128186
}
129187

130188
setFormErrors(updatedFormErrors)
@@ -152,7 +210,7 @@ const CopilotRequestForm: FC<{}> = () => {
152210
label='Project'
153211
placeholder='Select the project you wish to request a copilot for'
154212
dirty
155-
error={formErrors.project}
213+
error={formErrors.projectId}
156214
/>
157215
<p className={styles.formRow}>
158216
Are you already working with a copilot that you&apos;d love to work with on this project
@@ -198,6 +256,12 @@ const CopilotRequestForm: FC<{}> = () => {
198256
</div>
199257
)
200258
}
259+
{formErrors.existingCopilot && (
260+
<p className={styles.error}>
261+
<IconSolid.ExclamationIcon />
262+
{formErrors.existingCopilot}
263+
</p>
264+
)}
201265

202266
<p className={styles.formRow}>What type of project are you working on?</p>
203267
<InputSelect
@@ -252,6 +316,12 @@ const CopilotRequestForm: FC<{}> = () => {
252316
noCaps
253317
leftAlignText
254318
/>
319+
{formErrors.complexity && (
320+
<p className={styles.error}>
321+
<IconSolid.ExclamationIcon />
322+
{formErrors.complexity}
323+
</p>
324+
)}
255325
</div>
256326
<p className={styles.formRow}>
257327
Please provide an overview of the project the copilot will undertake
@@ -263,11 +333,11 @@ const CopilotRequestForm: FC<{}> = () => {
263333
type of work and project which is to be undertaken.'
264334
value={formValues.overview}
265335
onChange={bind(handleFormValueChange, this, 'overview')}
266-
error={formErrors.projectOverview}
267-
tabIndex={0}
336+
error={formErrors.overview}
337+
dirty
268338
/>
269339
<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}>
271341
<InputSkillSelector
272342
placeholder='Enter skills you are searching for...'
273343
useWrapper={false}
@@ -276,6 +346,12 @@ const CopilotRequestForm: FC<{}> = () => {
276346
onChange={handleSkillsChange}
277347
/>
278348
</div>
349+
{formErrors.skills && (
350+
<p className={styles.error}>
351+
<IconSolid.ExclamationIcon />
352+
{formErrors.skills}
353+
</p>
354+
)}
279355
<p className={styles.formRow}>What&apos;s the planned start date for the copilot?</p>
280356
<InputDatePicker
281357
label='Copilot Start Date'
@@ -344,6 +420,12 @@ const CopilotRequestForm: FC<{}> = () => {
344420
onChange={bind(handleFormValueChange, this, 'requiresCommunicatn')}
345421
/>
346422
</div>
423+
{formErrors.requiresCommunicatn && (
424+
<p className={styles.error}>
425+
<IconSolid.ExclamationIcon />
426+
{formErrors.requiresCommunicatn}
427+
</p>
428+
)}
347429
<p className={styles.formRow}>Will this role be standard payments or something else?</p>
348430
<div className={styles.formRadioBtn}>
349431
<InputRadio
@@ -377,6 +459,12 @@ const CopilotRequestForm: FC<{}> = () => {
377459
/>
378460
)}
379461
</div>
462+
{formErrors.paymentType && (
463+
<p className={styles.error}>
464+
<IconSolid.ExclamationIcon />
465+
{formErrors.paymentType}
466+
</p>
467+
)}
380468
<Button
381469
primary
382470
size='lg'

src/apps/copilots/src/pages/copilot-request-form/styles.module.scss

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
@import '@libs/ui/styles/includes';
2+
13
$gradient: linear-gradient(
24
to top right, // This approximates the diagonal direction
35
#086093, // Start color
@@ -50,4 +52,22 @@ $gradient: linear-gradient(
5052
border: 1px solid #aaaaaa;
5153
border-radius: 0.375rem;
5254
}
55+
56+
.skillsError {
57+
border: 2px solid $red-100;
58+
border-radius: 0.375rem;
59+
}
60+
61+
.error {
62+
font-size: 11px;
63+
display: flex;
64+
align-items: center;
65+
color: $red-100;
66+
67+
svg {
68+
@include icon-md;
69+
fill: $red-100;
70+
margin-right: $sp-1;
71+
}
72+
}
5373
}

src/apps/copilots/src/services/projects.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import useSWR, { SWRResponse } from 'swr'
22

3-
import { xhrGetAsync } from '~/libs/core'
3+
import { xhrGetAsync, xhrPostAsync } from '~/libs/core'
44
import { EnvironmentConfig } from '~/config'
55

66
import { Project } from '../models/Project'
7+
import { CopilotRequest } from '../models/CopilotRequest'
78

89
const baseUrl = `${EnvironmentConfig.API.V5}/projects`
910

@@ -14,3 +15,13 @@ export const useFetchProjects = (): SWRResponse<Project[]> => {
1415
})
1516
return response
1617
}
18+
19+
export const saveCopilotRequest = (request: CopilotRequest)
20+
: Promise<CopilotRequest> => {
21+
const url = `${baseUrl}/${request.projectId}/copilots/request`
22+
const requestData = {
23+
data: request,
24+
}
25+
26+
return xhrPostAsync(url, requestData)
27+
}

0 commit comments

Comments
 (0)