Ignore:
Timestamp:
06/17/24 21:59:14 (3 months ago)
Author:
223021 <daniel.ilievski.2@…>
Branches:
main
Children:
08f82ec
Parents:
b248810
Message:

Added an edit profile page for both job seekers and recruiters, where they can upload profile pictures/company logos and edit their profile data. Added profile page specifically for recruiters. Refactored existing code.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • jobvista-frontend/src/views/applications/ApplicationsByJobAd.js

    rb248810 rbefb988  
    1 import {useDispatch} from "react-redux";
     1import {useDispatch, useSelector} from "react-redux";
    22import {useEffect, useState} from "react";
    33import {useParams} from "react-router";
    44import {ApplicationActions} from "../../redux/actions/applicationActions";
    5 import {ViewApplicationDetails} from "./ViewApplicationDetails";
     5import {ApplicationDetailsModal} from "./ApplicationDetailsModal";
    66import "./Applications.css"
    77import Select from "react-select";
     8import {sortElementsBy} from "../../utils/utils";
     9import {JobSeekerActions} from "../../redux/actions/JobSeekerActions";
     10import {notifyAppStatusUpdate} from "../../utils/toastUtils";
    811
    912export const ApplicationsByJobAd = () => {
     
    1114    const dispatch = useDispatch();
    1215    let {advertisement_id} = useParams();
     16
    1317    const [applicationsByJobAd, setApplicationsByJobAd] = useState([]);
     18    let applicationsByJobAdState = useSelector(state => state.appl.applicationsByJobAdId)
     19    const [dispatched, setDispatched] = useState(false);
     20
     21    const [profilePics, setProfilePics] = useState({});
     22    let profilePicsState = useSelector(state => state.images.profilePictures)
     23    const [profilePicsDispatched, setProfilePicsDispatched] = useState(false);
     24
    1425    const [jobAdTitle, setJobAdTitle] = useState("");
    1526
    1627    useEffect(() => {
    17         dispatch(ApplicationActions.fetchApplicationsByJobAdId(advertisement_id, (success, reponse) => {
    18             if (success && reponse.data.length > 0) {
    19                 setApplicationsByJobAd(reponse.data)
    20                 setJobAdTitle(reponse.data[0].jobAdTitle)
     28        if(!dispatched && (applicationsByJobAdState.length === 0 || applicationsByJobAdState.length === 1)) {
     29            dispatch(ApplicationActions.fetchApplicationsByJobAdId(advertisement_id, (success, reponse) => {
     30                if (success && reponse.data.length > 0) {
     31                    setApplicationsByJobAd(sortElementsBy(reponse.data, "submittedOn"))
     32                    setJobAdTitle(reponse.data[0].jobAdTitle)
     33                }
     34                setDispatched(true)
     35                console.log("Fetch applications by job ad GET")
     36            }))
     37        } else {
     38            setApplicationsByJobAd(sortElementsBy(applicationsByJobAdState, "submittedOn"));
     39            if(applicationsByJobAdState.length > 0) {
     40                setJobAdTitle(applicationsByJobAdState[0].jobAdTitle)
     41            }
     42
     43        }
     44
     45    }, [applicationsByJobAdState])
     46
     47    useEffect(() => {
     48        if(dispatched && !profilePicsDispatched) {
     49            applicationsByJobAd.forEach(app => {
     50                if(app.jobSeekerId && !profilePics[app.jobSeekerId]) {
     51                    fetchProfilePic(app.jobSeekerId)
     52                }
     53            })
     54            setProfilePicsDispatched(true);
     55            console.log("Fetch all profile pics GET")
     56        } else if(profilePicsDispatched) {
     57            setProfilePics(profilePicsState)
     58            console.log("Fetch all profile pics STATE")
     59        }
     60    }, [dispatched])
     61
     62    const fetchProfilePic = (jobSeekerId) => {
     63        dispatch(JobSeekerActions.downloadProfilePic(jobSeekerId, (success, response) => {
     64            if(success) {
     65                setProfilePics(prevState => ({...prevState, [jobSeekerId]: response}))
    2166            }
    2267        }))
    23     }, [])
     68    }
     69
    2470
    2571    const options = [
     
    3783        dispatch(ApplicationActions.updateApplicationStatus(id, selectedOption.value, (success, response) => {
    3884            if(success) {
    39                 console.log("Status updated.")
     85                // console.log("Status updated.")
     86                notifyAppStatusUpdate()
    4087            }
    4188        }))
     
    4390
    4491
    45     return (<div className="applications-container">
     92    return (<div className="custom-container">
    4693        <div className="application-title">
    4794            {jobAdTitle ?
    48                 <h1>Applications for <span>{jobAdTitle}</span></h1> :
     95                <h3>Applications for <b>{jobAdTitle}</b></h3> :
    4996                <h1></h1>
    5097            }
    51 
    5298        </div>
    5399
    54100        {applicationsByJobAd && applicationsByJobAd.map((application, index) => (
    55101            <div className="application-card">
    56                 <div className="left-box">
     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">
    57111                    <span>Submitted on <b>{new Date(application.submittedOn).toLocaleString('default', {
    58112                        day: 'numeric',
     
    60114                        year: 'numeric'
    61115                    })}</b></span>
    62                     <br/><br/>
    63116                    <div className="contact-info">
    64117                        <div className="contact-item">
    65118                            <i className="fa-solid fa-user"></i> <span>{application.jobSeekerName}</span>
    66                         </div>
    67                         <div className="contact-item">
     119                        </div> <div className="contact-item">
    68120                            <i className="fa-solid fa-envelope"></i> <span>{application.jobSeekerEmail}</span>
    69                         </div>
    70                         <div className="contact-item">
     121                        </div> <div className="contact-item">
    71122                            <i className="fa-solid fa-phone"></i> <span>{application.jobSeekerPhoneNumber}</span>
    72123                        </div>
     
    74125                </div>
    75126
    76                 <div className="right-box">
    77                     <ViewApplicationDetails application={application}/>
     127                <div className="app-status">
     128                    <ApplicationDetailsModal application={application}/>
    78129                    <div className="select">
    79130                        <Select options={options}  onChange={(selectedOption) => handleChangeStatus(selectedOption, application.id)} defaultValue={handleDefaultStatus(application.status)}/>
Note: See TracChangeset for help on using the changeset viewer.