11/* eslint-disable complexity */
2- import { Dispatch , FC , MutableRefObject , SetStateAction , useRef , useState } from 'react'
2+ import { ChangeEvent , Dispatch , FC , MutableRefObject , SetStateAction , useEffect , useRef , useState } from 'react'
33import { bind , sortBy , trim } from 'lodash'
44import { toast } from 'react-toastify'
55import classNames from 'classnames'
66
7- import { BaseModal , Button , IconOutline , InputDatePicker , InputSelect , InputText } from '~/libs/ui'
7+ import { BaseModal , Button , IconOutline , InputDatePicker , InputSelect , InputText , InputTextarea } from '~/libs/ui'
88import {
99 updateDeleteOrCreateMemberTraitAsync ,
1010 UserProfile , UserTrait ,
1111 UserTraitCategoryNames ,
1212 UserTraitIds ,
1313} from '~/libs/core'
14- import { getIndustryOptionLabel , getIndustryOptionValue , INDUSTRIES_OPTIONS } from '~/libs/shared'
14+ import { getIndustryOptionLabel , getIndustryOptionValue , INDUSTRIES_OPTIONS , InputSkillSelector } from '~/libs/shared'
15+ import { fetchSkillsByIds } from '~/libs/shared/lib/services/standard-skills'
1516
1617import { WorkExpirenceCard } from '../WorkExpirenceCard'
1718
@@ -32,10 +33,10 @@ const ModifyWorkExpirenceModal: FC<ModifyWorkExpirenceModalProps> = (props: Modi
3233 = useState < boolean > ( props . workExpirence ?. length === 0 || false )
3334
3435 const [ formValues , setFormValues ] : [
35- { [ key : string ] : string | boolean | Date | undefined } ,
36- Dispatch < SetStateAction < { [ key : string ] : string | boolean | Date | undefined } > >
36+ { [ key : string ] : string | boolean | Date | any [ ] | undefined } ,
37+ Dispatch < SetStateAction < { [ key : string ] : string | boolean | Date | any [ ] | undefined } > >
3738 ]
38- = useState < { [ key : string ] : string | boolean | Date | undefined } > ( { } )
39+ = useState < { [ key : string ] : string | boolean | Date | any [ ] | undefined } > ( { } )
3940
4041 const [ formErrors , setFormErrors ] : [
4142 { [ key : string ] : string } ,
@@ -56,6 +57,86 @@ const ModifyWorkExpirenceModal: FC<ModifyWorkExpirenceModalProps> = (props: Modi
5657 ]
5758 = useState < UserTrait [ ] | undefined > ( props . workExpirence )
5859
60+ const [ skillNamesMap , setSkillNamesMap ] = useState < Record < string , string > > ( { } )
61+ const [ loadingSkills , setLoadingSkills ] = useState < boolean > ( false )
62+ const fetchedSkillIdsRef = useRef < Set < string > > ( new Set ( ) )
63+
64+ useEffect ( ( ) => {
65+ if ( ! workExpirence ) {
66+ setLoadingSkills ( false )
67+ return
68+ }
69+
70+ const allSkillIds = new Set < string > ( )
71+ workExpirence . forEach ( ( work : UserTrait ) => {
72+ if ( work . associatedSkills && Array . isArray ( work . associatedSkills ) ) {
73+ work . associatedSkills . forEach ( ( skillId : string ) => {
74+ if ( skillId && typeof skillId === 'string' ) {
75+ allSkillIds . add ( skillId )
76+ }
77+ } )
78+ }
79+ } )
80+
81+ if ( allSkillIds . size > 0 ) {
82+ const skillIdsToFetch = Array . from ( allSkillIds )
83+ . filter ( id => ! fetchedSkillIdsRef . current . has ( id ) )
84+
85+ if ( skillIdsToFetch . length > 0 ) {
86+ setLoadingSkills ( true )
87+ skillIdsToFetch . forEach ( id => fetchedSkillIdsRef . current . add ( id ) )
88+
89+ fetchSkillsByIds ( skillIdsToFetch )
90+ . then ( skills => {
91+ setSkillNamesMap ( prevMap => {
92+ const newMap : Record < string , string > = { ...prevMap }
93+ skills . forEach ( skill => {
94+ if ( skill . id && skill . name ) {
95+ newMap [ skill . id ] = skill . name
96+ }
97+ } )
98+ skillIdsToFetch . forEach ( skillId => {
99+ if ( ! newMap [ skillId ] ) {
100+ newMap [ skillId ] = skillId
101+ }
102+ } )
103+ return newMap
104+ } )
105+ } )
106+ . catch ( ( ) => {
107+ setSkillNamesMap ( prevMap => {
108+ const fallbackMap : Record < string , string > = { ...prevMap }
109+ skillIdsToFetch . forEach ( skillId => {
110+ if ( ! fallbackMap [ skillId ] ) {
111+ fallbackMap [ skillId ] = skillId
112+ }
113+ } )
114+ return fallbackMap
115+ } )
116+ } )
117+ . finally ( ( ) => {
118+ setLoadingSkills ( false )
119+ } )
120+ } else {
121+ setLoadingSkills ( false )
122+ }
123+ } else {
124+ // No skills to fetch
125+ setLoadingSkills ( false )
126+ }
127+ } , [ workExpirence ] )
128+
129+ const areSkillsLoaded = ( work : UserTrait ) : boolean => {
130+ if ( ! work . associatedSkills || ! Array . isArray ( work . associatedSkills ) || work . associatedSkills . length === 0 ) {
131+ return true
132+ }
133+
134+ return work . associatedSkills . every ( ( skillId : string ) => {
135+ const skillName = skillNamesMap [ skillId ]
136+ return skillName && skillName !== skillId
137+ } )
138+ }
139+
59140 const industryOptions : any = sortBy ( INDUSTRIES_OPTIONS )
60141 . map ( v => ( {
61142 label : getIndustryOptionLabel ( v ) ,
@@ -89,13 +170,16 @@ const ModifyWorkExpirenceModal: FC<ModifyWorkExpirenceModalProps> = (props: Modi
89170 } )
90171 }
91172
92- function handleFormValueChange ( key : string , event : React . ChangeEvent < HTMLInputElement > ) : void {
173+ function handleFormValueChange (
174+ key : string ,
175+ event : React . ChangeEvent < HTMLInputElement | HTMLTextAreaElement > ,
176+ ) : void {
93177 let value : string | boolean | Date | undefined
94178 const oldFormValues = { ...formValues }
95179
96180 switch ( key ) {
97181 case 'currentlyWorking' :
98- value = event . target . checked
182+ value = ( event . target as HTMLInputElement ) . checked
99183 if ( value ) {
100184 oldFormValues . endDate = undefined
101185 }
@@ -116,6 +200,17 @@ const ModifyWorkExpirenceModal: FC<ModifyWorkExpirenceModalProps> = (props: Modi
116200 } )
117201 }
118202
203+ function handleSkillsChange ( event : ChangeEvent < HTMLInputElement > ) : void {
204+ const selectedSkills = ( event . target as any ) . value || [ ]
205+ setFormValues ( {
206+ ...formValues ,
207+ associatedSkills : selectedSkills . map ( ( skill : any ) => ( {
208+ id : skill . value || skill . id ,
209+ name : skill . label || skill . name ,
210+ } ) ) ,
211+ } )
212+ }
213+
119214 function resetForm ( ) : void {
120215 setFormValues ( { } )
121216 setFormErrors ( { } )
@@ -173,9 +268,10 @@ const ModifyWorkExpirenceModal: FC<ModifyWorkExpirenceModalProps> = (props: Modi
173268 : undefined
174269
175270 const updatedWorkExpirence : UserTrait = {
176- cityTown : formValues . city ,
271+ associatedSkills : ( formValues . associatedSkills as any [ ] ) ?. map ( ( s : any ) => s . id || s ) || [ ] ,
177272 company : companyName ,
178273 companyName,
274+ description : ( formValues . description as string ) || undefined ,
179275 endDate : endDateIso ,
180276 industry : formValues . industry ,
181277 position : formValues . position ,
@@ -200,20 +296,41 @@ const ModifyWorkExpirenceModal: FC<ModifyWorkExpirenceModalProps> = (props: Modi
200296 resetForm ( )
201297 }
202298
203- function handleWorkExpirenceEdit ( indx : number ) : void {
299+ async function handleWorkExpirenceEdit ( indx : number ) : Promise < void > {
204300 const work : UserTrait = workExpirence ? workExpirence [ indx ] : { }
205301
206302 setEditedItemIndex ( indx )
207303
304+ let associatedSkills : any [ ] = [ ]
305+ if ( work . associatedSkills && Array . isArray ( work . associatedSkills ) && work . associatedSkills . length > 0 ) {
306+ try {
307+ const skills = await fetchSkillsByIds (
308+ work . associatedSkills . filter ( ( id ) : id is string => typeof id === 'string' ) ,
309+ )
310+ const skillsMap = new Map ( skills . map ( s => [ s . id , s . name ] ) )
311+
312+ associatedSkills = work . associatedSkills . map ( ( skillId : string ) => ( {
313+ id : skillId ,
314+ name : skillsMap . get ( skillId ) || '' ,
315+ } ) )
316+ } catch {
317+ associatedSkills = work . associatedSkills . map ( ( skillId : string ) => ( {
318+ id : skillId ,
319+ name : skillNamesMap [ skillId ] || '' ,
320+ } ) )
321+ }
322+ }
323+
208324 setFormValues ( {
209- city : work . cityTown || work . city ,
210- company : work . company || work . companyName ,
211- currentlyWorking : work . working ,
325+ associatedSkills,
326+ company : ( work . company || work . companyName || '' ) as string ,
327+ currentlyWorking : work . working || false ,
328+ description : work . description || '' ,
212329 endDate : work . timePeriodTo
213330 ? new Date ( work . timePeriodTo )
214331 : ( work . endDate ? new Date ( work . endDate ) : undefined ) ,
215- industry : work . industry ,
216- position : work . position ,
332+ industry : work . industry || '' ,
333+ position : ( work . position || '' ) as string ,
217334 startDate : work . timePeriodFrom
218335 ? new Date ( work . timePeriodFrom )
219336 : ( work . startDate ? new Date ( work . startDate ) : undefined ) ,
@@ -241,6 +358,7 @@ const ModifyWorkExpirenceModal: FC<ModifyWorkExpirenceModalProps> = (props: Modi
241358 }
242359 }
243360
361+ console . log ( formValues , 'formValues' )
244362 return (
245363 < BaseModal
246364 onClose = { props . onClose }
@@ -286,7 +404,12 @@ const ModifyWorkExpirenceModal: FC<ModifyWorkExpirenceModalProps> = (props: Modi
286404 className = { styles . workExpirenceCardWrap }
287405 key = { uniqueKey || `${ work . position } -${ indx } ` }
288406 >
289- < WorkExpirenceCard work = { work } isModalView />
407+ < WorkExpirenceCard
408+ work = { work }
409+ isModalView
410+ skillNamesMap = { skillNamesMap }
411+ showSkills = { ! loadingSkills && areSkillsLoaded ( work ) }
412+ />
290413 < div className = { styles . actionElements } >
291414 < Button
292415 className = { styles . ctaBtn }
@@ -320,6 +443,7 @@ const ModifyWorkExpirenceModal: FC<ModifyWorkExpirenceModalProps> = (props: Modi
320443 placeholder = 'Enter a company'
321444 dirty
322445 tabIndex = { 0 }
446+ forceUpdateValue
323447 type = 'text'
324448 onChange = { bind ( handleFormValueChange , this , 'company' ) }
325449 value = { formValues . company as string }
@@ -332,6 +456,7 @@ const ModifyWorkExpirenceModal: FC<ModifyWorkExpirenceModalProps> = (props: Modi
332456 dirty
333457 tabIndex = { 0 }
334458 type = 'text'
459+ forceUpdateValue
335460 onChange = { bind ( handleFormValueChange , this , 'position' ) }
336461 value = { formValues . position as string }
337462 />
@@ -376,6 +501,23 @@ const ModifyWorkExpirenceModal: FC<ModifyWorkExpirenceModalProps> = (props: Modi
376501 onChange = { bind ( handleFormValueChange , this , 'currentlyWorking' ) }
377502 checked = { formValues . currentlyWorking as boolean }
378503 />
504+ < InputTextarea
505+ name = 'description'
506+ label = 'Description'
507+ placeholder = 'Describe your role and achievements at this company'
508+ dirty
509+ tabIndex = { 0 }
510+ onChange = { bind ( handleFormValueChange , this , 'description' ) }
511+ value = { formValues . description as string }
512+ rows = { 4 }
513+ />
514+ < InputSkillSelector
515+ label = 'Associated Skills'
516+ placeholder = 'Type to search and add skills...'
517+ value = { formValues . associatedSkills as any [ ] }
518+ onChange = { handleSkillsChange }
519+ loading = { false }
520+ />
379521 </ form >
380522 ) : (
381523 < Button
0 commit comments