11import type { ReactElement } from 'react' ;
22import React , { useCallback } from 'react' ;
3- import { Controller , useFormContext } from 'react-hook-form' ;
3+ import { Controller , useFieldArray , useFormContext } from 'react-hook-form' ;
44import { TextField } from '../../../fields/TextField' ;
55import Textarea from '../../../fields/Textarea' ;
66import {
@@ -14,6 +14,12 @@ import type { TLocation } from '../../../../graphql/autocomplete';
1414import { LocationDataset } from '../../../../graphql/autocomplete' ;
1515import type { Opportunity } from '../../../../features/opportunity/types' ;
1616import type { OpportunitySideBySideEditFormData } from '../hooks/useOpportunityEditForm' ;
17+ import { Button , ButtonSize , ButtonVariant } from '../../../buttons/Button' ;
18+ import { PlusIcon } from '../../../icons/Plus' ;
19+ import { TrashIcon } from '../../../icons/Trash' ;
20+ import { IconSize } from '../../../Icon' ;
21+ import { LocationType } from '../../../../features/opportunity/protobuf/util' ;
22+ import { Radio } from '../../../fields/Radio' ;
1723
1824export interface RoleInfoSectionProps {
1925 opportunity : Opportunity ;
@@ -26,13 +32,24 @@ export function RoleInfoSection({
2632 register,
2733 control,
2834 setValue,
35+ watch,
2936 formState : { errors } ,
3037 } = useFormContext < OpportunitySideBySideEditFormData > ( ) ;
3138
39+ const { fields, append, remove } = useFieldArray ( {
40+ control,
41+ name : 'locations' ,
42+ } ) ;
43+
3244 const handleLocationSelect = useCallback (
33- ( location : TLocation | null ) => {
45+ ( location : TLocation | null , index : number ) => {
46+ setValue (
47+ `locations.${ index } .externalLocationId` ,
48+ location ?. id || undefined ,
49+ { shouldDirty : true } ,
50+ ) ;
3451 setValue (
35- ' locationData' ,
52+ `locations. ${ index } . locationData` ,
3653 location
3754 ? {
3855 id : location . id ,
@@ -47,6 +64,25 @@ export function RoleInfoSection({
4764 [ setValue ] ,
4865 ) ;
4966
67+ const locationType = watch ( 'locationType' ) ;
68+
69+ const locationTypeOptions = [
70+ { label : 'Remote' , value : `${ LocationType . REMOTE } ` } ,
71+ { label : 'Hybrid' , value : `${ LocationType . HYBRID } ` } ,
72+ { label : 'On-site' , value : `${ LocationType . OFFICE } ` } ,
73+ ] ;
74+
75+ const handleAddLocation = useCallback ( ( ) => {
76+ append ( { } ) ;
77+ } , [ append ] ) ;
78+
79+ const handleRemoveLocation = useCallback (
80+ ( index : number ) => {
81+ remove ( index ) ;
82+ } ,
83+ [ remove ] ,
84+ ) ;
85+
5086 return (
5187 < div className = "flex flex-col gap-4" >
5288 < div data-field-key = "title" >
@@ -110,24 +146,63 @@ export function RoleInfoSection({
110146 />
111147 </ div >
112148
113- < div data-field-key = "location" >
114- < ProfileLocation
115- locationName = "externalLocationId"
116- typeName = "locationType"
117- dataset = { LocationDataset . Internal }
118- defaultValue = {
119- opportunity ?. locations ?. [ 0 ] ?. location
120- ? {
121- id : '' ,
122- city : opportunity . locations [ 0 ] . location . city ,
123- country : opportunity . locations [ 0 ] . location . country || '' ,
124- subdivision : opportunity . locations [ 0 ] . location . subdivision ,
125- type : opportunity . locations [ 0 ] . type ,
126- }
127- : undefined
149+ < div data-field-key = "locations" className = "flex flex-col gap-3" >
150+ < Typography bold type = { TypographyType . Caption1 } >
151+ Locations
152+ </ Typography >
153+ < Radio
154+ name = "locationType"
155+ options = { locationTypeOptions }
156+ value = { `${ locationType } ` }
157+ onChange = { ( val ) =>
158+ setValue ( 'locationType' , Number ( val ) , { shouldDirty : true } )
128159 }
129- onLocationSelect = { handleLocationSelect }
160+ className = { { container : '!flex-row' } }
130161 />
162+ { fields . map ( ( field , index ) => (
163+ < div key = { field . id } className = "flex items-start gap-2" >
164+ < div className = "flex-1" >
165+ < ProfileLocation
166+ locationName = { `locations.${ index } .externalLocationId` }
167+ dataset = { LocationDataset . Internal }
168+ defaultValue = {
169+ opportunity ?. locations ?. [ index ] ?. location
170+ ? {
171+ id : '' ,
172+ city : opportunity . locations [ index ] . location . city ,
173+ country :
174+ opportunity . locations [ index ] . location . country || '' ,
175+ subdivision :
176+ opportunity . locations [ index ] . location . subdivision ,
177+ }
178+ : undefined
179+ }
180+ onLocationSelect = { ( location ) =>
181+ handleLocationSelect ( location , index )
182+ }
183+ />
184+ </ div >
185+ { fields . length > 1 && (
186+ < Button
187+ type = "button"
188+ variant = { ButtonVariant . Tertiary }
189+ size = { ButtonSize . Small }
190+ icon = { < TrashIcon size = { IconSize . Small } /> }
191+ onClick = { ( ) => handleRemoveLocation ( index ) }
192+ className = "mt-6"
193+ />
194+ ) }
195+ </ div >
196+ ) ) }
197+ < Button
198+ type = "button"
199+ variant = { ButtonVariant . Secondary }
200+ size = { ButtonSize . Small }
201+ icon = { < PlusIcon size = { IconSize . Small } /> }
202+ onClick = { handleAddLocation }
203+ >
204+ Add location
205+ </ Button >
131206 </ div >
132207 </ div >
133208 ) ;
0 commit comments