Legend:
- Unmodified
- Added
- Removed
-
jobvista-frontend/src/views/applications/ApplicationsByJobAd.js
r0f0add0 r4d97b63 25 25 const [jobAdTitle, setJobAdTitle] = useState(""); 26 26 27 const [changedApplications, setChangedApplications] = useState({}); 28 27 29 useEffect(() => { 28 if(!dispatched && (applicationsByJobAdState.length === 0 || applicationsByJobAdState.length === 1)) {30 if(!dispatched) { 29 31 dispatch(ApplicationActions.fetchApplicationsByJobAdId(advertisement_id, (success, reponse) => { 30 32 if (success && reponse.data.length > 0) { … … 60 62 }, [dispatched]) 61 63 64 62 65 const fetchProfilePic = (jobSeekerId) => { 63 66 dispatch(JobSeekerActions.downloadProfilePic(jobSeekerId, (success, response) => { … … 67 70 })) 68 71 } 69 70 72 71 73 const options = [ … … 76 78 ]; 77 79 80 const [selectedFilter, setSelectedFilter] = useState('All'); 81 82 const filters = [ 83 { value: 'ALL', label: 'All', icon: 'fa-folder-open' }, 84 { value: 'PROPOSED', label: 'Proposed', icon: 'fa-paper-plane' }, 85 { value: 'UNDER_REVIEW', label: 'Under Review', icon: 'fa-file-pen' }, 86 { value: 'ACCEPTED', label: 'Accepted', icon: 'fa-user-check' }, 87 { value: 'DENIED', label: 'Denied', icon: 'fa-user-slash' }, 88 ]; 89 90 const filterApplicationsByJobAdvertisement = (filter) => { 91 dispatch(ApplicationActions.filterApplicationsByJobAdId(advertisement_id, filter, (success, response) => { 92 if(success) { 93 //notify 94 } 95 })) 96 } 97 78 98 let handleDefaultStatus = (status) => { 79 99 return options.find(option => option.value === status); 80 100 } 81 101 82 let handleChangeStatus = (selectedOption, id) => { 83 dispatch(ApplicationActions.updateApplicationStatus(id, selectedOption.value, (success, response) => { 102 let handleStatusChange = (selectedOption, id) => { 103 104 const currentApplication = applicationsByJobAd.find(app => app.id === id); 105 106 setChangedApplications(prevState => ({ 107 ...prevState, 108 [id]: { 109 ...prevState[id], 110 response: (selectedOption.value === "ACCEPTED" || selectedOption.value === "DENIED") ? (prevState[id]?.response || currentApplication.response || "") : "", 111 status: selectedOption.value 112 } 113 })) 114 115 setApplicationsByJobAd(prevState => ( 116 prevState.map(application => 117 application.id === id ? {...application, status: selectedOption.value} : application) 118 )) 119 120 const responseTextarea = document.getElementById(`response-${id}`); 121 if (responseTextarea) { 122 responseTextarea.value = ""; 123 } 124 125 /* dispatch(ApplicationActions.updateApplicationStatus(id, selectedOption.value, (success, response) => { 84 126 if(success) { 85 // console.log("Status updated.")86 127 notifyAppStatusUpdate() 87 128 } 88 })) 89 } 129 }))*/ 130 } 131 132 let handleResponseChange = (e, id) => { 133 134 const currentApplication = applicationsByJobAd.find(app => app.id === id); 135 136 setChangedApplications(prevState => ({ 137 ...prevState, 138 [id]: { 139 ...prevState[id], 140 response: e.target.value, 141 status: prevState[id]?.status || currentApplication.status, 142 } 143 } 144 )) 145 } 146 147 const handleSaveChanges = () => { 148 console.log(changedApplications) 149 const changes = Object.entries(changedApplications).map( 150 ([applicationId, change]) => ({ 151 id: applicationId, 152 status: change.status, 153 response: change.response, 154 }) 155 ); 156 console.log(changes) 157 158 if(changes.length === 0) { 159 return; 160 } 161 162 dispatch(ApplicationActions.updateApplications(changes, (success, response) => { 163 if(success) { 164 setChangedApplications({}); 165 notifyAppStatusUpdate() 166 //notify change success 167 } 168 })) 169 170 171 } 172 173 const isChangedApplication = (id) => { 174 return changedApplications && Object.keys(changedApplications).includes(id.toString()); 175 }; 90 176 91 177 … … 98 184 </div> 99 185 186 <div className="row"> 187 <div className="col-md-6 application-filters-wrap"> 188 <div className="application-filters d-inline-flex flex-row justify-content-start"> 189 { 190 filters.map(filter => ( 191 <span 192 key={filter.label} 193 className={selectedFilter === filter.label ? "selected" : ""} 194 onClick={() => { 195 setSelectedFilter(filter.label) 196 filterApplicationsByJobAdvertisement(filter.value) 197 setChangedApplications({}); 198 }} 199 ><i className={`fa-solid ${filter.icon}`}></i> {filter.label}</span> 200 )) 201 } 202 </div> 203 204 </div> 205 <div className="col-md-6 d-inline-flex flex-row justify-content-end"> 206 <button onClick={handleSaveChanges} 207 className={`blue-submit-button ${Object.keys(changedApplications).length === 0 ? 'disabled' : ''}`} 208 disabled={Object.keys(changedApplications).length === 0} 209 >Submit Changes</button> 210 </div> 211 </div> 212 213 214 100 215 {applicationsByJobAd && applicationsByJobAd.map((application, index) => ( 101 <div className="application-card"> 102 <div className="app-job-seeker-pic"> 103 <img 104 // loading gif 105 src={profilePicsState[application.jobSeekerId]} 106 alt="" 107 width={75} height={75} 108 /> 109 </div> 110 <div className="app-info"> 111 <span>Submitted on <b>{new Date(application.submittedOn).toLocaleString('default', { 112 day: 'numeric', 113 month: 'long', 114 year: 'numeric' 115 })}</b></span> 116 <div className="contact-info"> 117 <div className="contact-item"> 118 <i className="fa-solid fa-user"></i> <span>{application.jobSeekerName}</span> 119 </div> <div className="contact-item"> 120 <i className="fa-solid fa-envelope"></i> <span>{application.jobSeekerEmail}</span> 121 </div> <div className="contact-item"> 122 <i className="fa-solid fa-phone"></i> <span>{application.jobSeekerPhoneNumber}</span> 216 <div 217 key={application.id} 218 className={`application-card-wrapper ${(application.status !== "PROPOSED" ) ? 'expanded' : ''}`} 219 > 220 221 <div className={`application-card ${changedApplications[application.id] ? 'changed' : ''}`}> 222 <div className="app-job-seeker-pic"> 223 <img 224 src={profilePicsState[application.jobSeekerId]} 225 alt="" 226 width={75} height={75} 227 /> 228 </div> 229 <div className="app-info"> 230 <span>Submitted on <b>{new Date(application.submittedOn).toLocaleString('default', { 231 day: 'numeric', 232 month: 'long', 233 year: 'numeric' 234 })}</b></span> 235 <div className="contact-info"> 236 <div className="contact-item"> 237 <i className="fa-solid fa-user"></i> <span>{application.jobSeekerName}</span> 238 </div> 239 <div className="contact-item"> 240 <i className="fa-solid fa-envelope"></i> <span>{application.jobSeekerEmail}</span> 241 </div> 242 <div className="contact-item"> 243 <i className="fa-solid fa-phone"></i> <span>{application.jobSeekerPhoneNumber}</span> 244 </div> 245 </div> 246 </div> 247 248 <div className="app-status"> 249 <ApplicationDetailsModal application={application} /> 250 <div className="select"> 251 <Select options={options} onChange={(selectedOption) => handleStatusChange(selectedOption, application.id)} defaultValue={handleDefaultStatus(application.status)} /> 123 252 </div> 124 253 </div> 125 254 </div> 126 255 127 <div className="app-status"> 128 <ApplicationDetailsModal application={application}/> 129 <div className="select"> 130 <Select options={options} onChange={(selectedOption) => handleChangeStatus(selectedOption, application.id)} defaultValue={handleDefaultStatus(application.status)}/> 131 </div> 132 256 <div className="expand-section"> 257 <textarea 258 id={`response-${application.id}`} 259 placeholder={application.status === "UNDER_REVIEW" ? "Request additional documents..." :"Write your response..."} 260 defaultValue={application.response} 261 onChange={(e) => handleResponseChange(e, application.id)} 262 /> 133 263 </div> 134 264 </div> 135 ))} 265 ))} 266 136 267 137 268 </div>)
Note:
See TracChangeset
for help on using the changeset viewer.