@@ -12,6 +12,7 @@ import {
1212} from 'react'
1313import { useLocation , useNavigate , useParams } from 'react-router-dom'
1414import { mutate } from 'swr'
15+ import { toast } from 'react-toastify'
1516import moment from 'moment'
1617
1718import {
@@ -28,6 +29,7 @@ import { textFormatDateLocaleShortString } from '~/libs/shared'
2829
2930import { CopilotApplication } from '../../models/CopilotApplication'
3031import {
32+ cancelCopilotOpportunity ,
3133 copilotBaseUrl ,
3234 CopilotOpportunityResponse ,
3335 useCopilotApplications ,
@@ -104,7 +106,7 @@ const CopilotOpportunityDetails: FC<{}> = () => {
104106
105107 const onApplied : ( ) => void = useCallback ( ( ) => {
106108 mutate ( `${ copilotBaseUrl } /copilots/opportunity/${ opportunityId } /applications` )
107- mutate ( `${ copilotBaseUrl } /copilots /opportunity/${ opportunityId } ` )
109+ mutate ( `${ copilotBaseUrl } /copilot /opportunity/${ opportunityId } ` )
108110 } , [ ] )
109111
110112 const onCloseApplyModal : ( ) => void = useCallback ( ( ) => {
@@ -120,11 +122,26 @@ const CopilotOpportunityDetails: FC<{}> = () => {
120122 )
121123 }
122124
125+ async function cancelCopilotOpportunityHandler ( ) : Promise < void > {
126+ if ( opportunityId ) {
127+ await cancelCopilotOpportunity ( opportunityId )
128+ mutate ( `${ copilotBaseUrl } /copilots/opportunity/${ opportunityId } /applications` )
129+ mutate ( `${ copilotBaseUrl } /copilot/opportunity/${ opportunityId } ` )
130+ toast . success ( 'Canceled copilot opportunity successfully' )
131+ }
132+
133+ }
134+
123135 const applyCopilotOpportunityButton : ButtonProps = {
124136 label : 'Apply as Copilot' ,
125137 onClick : ( ) => setShowApplyOpportunityModal ( true ) ,
126138 }
127139
140+ const cancelCopilotOpportunityButton : ButtonProps = {
141+ label : 'Cancel opportunity' ,
142+ onClick : cancelCopilotOpportunityHandler ,
143+ }
144+
128145 const application = copilotApplications && copilotApplications [ 0 ]
129146
130147 const getOpportunityType = ( type : string ) : ProjectType => {
@@ -152,6 +169,10 @@ const CopilotOpportunityDetails: FC<{}> = () => {
152169 && opportunity ?. status === 'active'
153170 && opportunity ?. canApplyAsCopilot ? applyCopilotOpportunityButton : undefined
154171 }
172+ secondaryButtonConfig = {
173+ opportunity ?. status === 'active'
174+ && isAdminOrPM ? cancelCopilotOpportunityButton : undefined
175+ }
155176 infoComponent = { ( isCopilot && ! ( copilotApplications
156177 && copilotApplications . length === 0
157178 ) && opportunity ?. status === 'active' && ! ! application ) && (
@@ -171,98 +192,101 @@ const CopilotOpportunityDetails: FC<{}> = () => {
171192 { isValidating && ! showNotFound && (
172193 < LoadingSpinner />
173194 ) }
174- < h1 className = { styles . header } >
175- { opportunity ?. projectName }
176- </ h1 >
177- < div className = { styles . infoRow } >
178- < div className = { styles . infoColumn } >
179- < IconOutline . ClipboardCheckIcon className = { styles . icon } />
180- < div className = { styles . infoText } >
181- < span className = { styles . infoHeading } > Status</ span >
182- < span className = { styles . infoValue } > { opportunity ?. status } </ span >
195+ < div className = { styles . wrapper } >
196+ < h1 className = { styles . header } >
197+ { opportunity ?. projectName }
198+ </ h1 >
199+ < div className = { styles . infoRow } >
200+ < div className = { styles . infoColumn } >
201+ < IconOutline . ClipboardCheckIcon className = { styles . icon } />
202+ < div className = { styles . infoText } >
203+ < span className = { styles . infoHeading } > Status</ span >
204+ < span className = { styles . infoValue } > { opportunity ?. status } </ span >
205+ </ div >
183206 </ div >
184- </ div >
185- < div className = { styles . infoColumn } >
186- < IconOutline . PlayIcon className = { styles . icon } />
187- < div className = { styles . infoText } >
188- < span className = { styles . infoHeading } > Start Date</ span >
189- < span className = { styles . infoValue } >
190- { moment ( opportunity ?. startDate )
191- . format ( 'MMM D, YYYY' ) }
207+ < div className = { styles . infoColumn } >
208+ < IconOutline . PlayIcon className = { styles . icon } />
209+ < div className = { styles . infoText } >
210+ < span className = { styles . infoHeading } > Start Date</ span >
211+ < span className = { styles . infoValue } >
212+ { moment ( opportunity ?. startDate )
213+ . format ( 'MMM D, YYYY' ) }
192214
193- </ span >
215+ </ span >
216+ </ div >
194217 </ div >
195- </ div >
196- < div className = { styles . infoColumn } >
197- < IconOutline . CalendarIcon className = { styles . icon } / >
198- < div className = { styles . infoText } >
199- < span className = { styles . infoHeading } > Duration </ span >
200- < span className = { styles . infoValue } >
201- { opportunity ?. numWeeks }
202- { ' ' }
203- weeks
204- </ span >
218+ < div className = { styles . infoColumn } >
219+ < IconOutline . CalendarIcon className = { styles . icon } / >
220+ < div className = { styles . infoText } >
221+ < span className = { styles . infoHeading } > Duration </ span >
222+ < span className = { styles . infoValue } >
223+ { opportunity ?. numWeeks }
224+ { ' ' }
225+ weeks
226+ </ span >
227+ </ div >
205228 </ div >
206- </ div >
207- < div className = { styles . infoColumn } >
208- < IconOutline . ClockIcon className = { styles . icon } / >
209- < div className = { styles . infoText } >
210- < span className = { styles . infoHeading } > Hours </ span >
211- < span className = { styles . infoValue } >
212- { opportunity ?. numHoursPerWeek }
213- { ' ' }
214- hours/week
215- </ span >
229+ < div className = { styles . infoColumn } >
230+ < IconOutline . ClockIcon className = { styles . icon } / >
231+ < div className = { styles . infoText } >
232+ < span className = { styles . infoHeading } > Hours </ span >
233+ < span className = { styles . infoValue } >
234+ { opportunity ?. numHoursPerWeek }
235+ { ' ' }
236+ hours/week
237+ </ span >
238+ </ div >
216239 </ div >
217- </ div >
218- < div className = { styles . infoColumn } >
219- < IconOutline . CogIcon className = { styles . icon } / >
220- < div className = { styles . infoText } >
221- < span className = { styles . infoHeading } > Type </ span >
222- < span
223- className = { styles . infoValue }
224- >
225- { opportunity ?. type && getOpportunityType ( opportunity ?. type ) }
226- </ span >
240+ < div className = { styles . infoColumn } >
241+ < IconOutline . CogIcon className = { styles . icon } / >
242+ < div className = { styles . infoText } >
243+ < span className = { styles . infoHeading } > Type </ span >
244+ < span
245+ className = { styles . infoValue }
246+ >
247+ { opportunity ?. type && getOpportunityType ( opportunity ?. type ) }
248+ </ span >
249+ </ div >
227250 </ div >
228- </ div >
229- < div className = { styles . infoColumn } >
230- < IconOutline . GlobeAltIcon className = { styles . icon } / >
231- < div className = { styles . infoText } >
232- < span className = { styles . infoHeading } > Working Hours </ span >
233- < span className = { styles . infoValue } > { opportunity ?. tzRestrictions } </ span >
251+ < div className = { styles . infoColumn } >
252+ < IconOutline . GlobeAltIcon className = { styles . icon } / >
253+ < div className = { styles . infoText } >
254+ < span className = { styles . infoHeading } > Working Hours </ span >
255+ < span className = { styles . infoValue } > { opportunity ?. tzRestrictions } </ span >
256+ </ div >
234257 </ div >
235258 </ div >
236- </ div >
237- {
238- initialized && (
239- < TabsNavbar
240- defaultActive = { activeTab }
241- onChange = { handleTabChange }
242- tabs = { getCopilotDetailsTabsConfig ( isAdminOrPM ) }
259+ {
260+ initialized && (
261+ < TabsNavbar
262+ defaultActive = { activeTab }
263+ onChange = { handleTabChange }
264+ tabs = { getCopilotDetailsTabsConfig ( isAdminOrPM ) }
265+ />
266+ )
267+ }
268+ { activeTab === CopilotDetailsTabViews . details && < OpportunityDetails opportunity = { opportunity } /> }
269+ { activeTab === CopilotDetailsTabViews . applications && isAdminOrPM && opportunity && (
270+ < CopilotApplications
271+ copilotApplications = { copilotApplications }
272+ opportunity = { opportunity }
273+ members = { members }
243274 />
244- )
245- }
246- { activeTab === CopilotDetailsTabViews . details && < OpportunityDetails opportunity = { opportunity } /> }
247- { activeTab === CopilotDetailsTabViews . applications && isAdminOrPM && opportunity && (
248- < CopilotApplications
249- copilotApplications = { copilotApplications }
250- opportunity = { opportunity }
251- members = { members }
252- />
253- ) }
275+ ) }
276+
277+ {
278+ showApplyOpportunityModal
279+ && opportunity && (
280+ < ApplyOpportunityModal
281+ copilotOpportunityId = { opportunity ?. id }
282+ onClose = { onCloseApplyModal }
283+ projectName = { opportunity ?. projectName }
284+ onApplied = { onApplied }
285+ />
286+ )
287+ }
288+ </ div >
254289
255- {
256- showApplyOpportunityModal
257- && opportunity && (
258- < ApplyOpportunityModal
259- copilotOpportunityId = { opportunity ?. id }
260- onClose = { onCloseApplyModal }
261- projectName = { opportunity ?. projectName }
262- onApplied = { onApplied }
263- />
264- )
265- }
266290 </ ContentLayout >
267291 )
268292}
0 commit comments