source: jobvista-frontend/src/views/job_advertisements/RecruiterWorkspace.js@ befb988

main
Last change on this file since befb988 was befb988, checked in by 223021 <daniel.ilievski.2@…>, 5 months ago

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.

  • Property mode set to 100644
File size: 7.3 KB
RevLine 
[19398ad]1import {AddJobAdModal} from "./AddJobAdModal";
2
3import "./JobAdvertisements.css"
[befb988]4import "../shared_css/Random.css"
5
[19398ad]6import {useDispatch, useSelector} from "react-redux";
7import {useEffect, useState} from "react";
8import {JobAdvertisementActions} from "../../redux/actions/jobAdvertisementActions";
[b248810]9import {formatRelativeTime, sortElementsBy} from "../../utils/utils";
[28b3398]10import {dataRangeOptions, industryOptions, industryOptionsFilter, sortOptions} from "../selectOptions";
[19398ad]11import Select from "react-select";
12import {DeleteJobAdModal} from "./DeleteJobAdModal";
13import {EditJobAdModal} from "./EditJobAdModal";
14import {Link} from "react-router-dom";
15import JobType from "../../enumerations/JobType";
[befb988]16import {RecruiterActions} from "../../redux/actions/recruiterActions";
17
[19398ad]18
[befb988]19export const Workspace = (props) => {
[19398ad]20
21 const dispatch = useDispatch();
[befb988]22 const [dispatched, setDispatched] = useState(false)
23
[19398ad]24 const auth = useSelector(state => (state.auth.currentUser))
[befb988]25
26 const [jobAdvertisementsByRecruiter, setJobAdvertisementsByRecruiter] = useState([]);
[19398ad]27 let jobAdvertisementsByRecruiterState = useSelector(state => (state.jobAd.jobAdvertisementsByRecruiter))
28
[befb988]29 const [recruiterDetails, setRecruiterDetails] = useState(null);
30
[28b3398]31 const [selectedSortOrder, setSelectedSortOrder] = useState("date_newest");
32 const [selectedIndustry, setSelectedIndustry] = useState("all");
[19398ad]33 const [searchTerm, setSearchTerm] = useState("");
34
[befb988]35 const [activeJobListingsCount, setActiveJobListingsCount] = useState(0);
[19398ad]36
37 useEffect(() => {
38 if (auth) {
[befb988]39 dispatch(RecruiterActions.fetchRecruiterEditDetailsById(auth.id, (success, response) => {
40 if (success) {
41 setRecruiterDetails(response.data)
42 }
43 }))
[19398ad]44 }
45 }, [auth]);
46
[befb988]47
[19398ad]48 useEffect(() => {
49 if (!dispatched && jobAdvertisementsByRecruiterState.length === 0) {
[befb988]50 dispatch(JobAdvertisementActions.fetchJobAdvertisementsByRecruiter(auth.id, (success, response) => {
[19398ad]51 if (success && response.data.length > 0) {
[b248810]52 setJobAdvertisementsByRecruiter(sortElementsBy(response.data))
[19398ad]53 }
54 console.log("Fetch job advertisements by recruiter GET")
55 }))
56 setDispatched(true);
57
58 } else {
59 setJobAdvertisementsByRecruiter(jobAdvertisementsByRecruiterState)
60 console.log("Fetch job advertisements by recruiter STATE")
[befb988]61
62 setActiveJobListingsCount(countActiveJobListings(jobAdvertisementsByRecruiterState));
[19398ad]63 }
[befb988]64
[19398ad]65 }, [jobAdvertisementsByRecruiterState])
66
[28b3398]67 let filterJobAdvertisements = () => {
[befb988]68 JobAdvertisementActions.filterJobAdvertisementsByRecruiter({
69 searchTerm: searchTerm, industry: selectedIndustry, sortOrder: selectedSortOrder
70 }, (success, response) => {
71 if (success) {
72 setJobAdvertisementsByRecruiter(response.data);
[28b3398]73 }
[befb988]74 })
[28b3398]75 }
76
[befb988]77 function countActiveJobListings(jobAds) {
78 if (jobAds.length > 0) {
79 const activeJobListings = jobAds.filter(job => job.active)
80 return activeJobListings.length;
81 }
82 return 0;
83 }
84
85 return (<div className="container">
86
87 {/*<div className="line-separator"></div>*/}
88
89 <div className="filter-container">
[19398ad]90 <div className="row">
[befb988]91 <div className="col-md-12 filter-box">
[28b3398]92 <div className="search-container">
93 <i className="fa-solid fa-magnifying-glass search-icon"></i>
[19398ad]94 <input
95 className="search-input"
96 type="text"
97 placeholder="Search job advertisement by title..."
[28b3398]98 value={searchTerm}
99 onChange={event => setSearchTerm(event.target.value)}
[19398ad]100 />
101 </div>
102 <div className="sort-section item">
103 <Select
[28b3398]104 defaultValue={{value: "all", label: "All industries"}}
105 value={selectedIndustry.value}
106 onChange={option => setSelectedIndustry(option.value)}
107 options={industryOptionsFilter}
[19398ad]108 className="sort-range sort"
109 />
110 </div>
[28b3398]111 <div className="sort-section item">
[19398ad]112 <Select
[28b3398]113 defaultValue={{value: "newest", label: "Date (Newest First)"}}
114 value={selectedSortOrder.value}
115 onChange={option => setSelectedSortOrder(option.value)}
116 options={sortOptions}
117 className="sort-range sort"
[19398ad]118 />
119 </div>
[befb988]120 <button onClick={filterJobAdvertisements} className="blue-submit-button">Find jobs</button>
[19398ad]121 </div>
122 </div>
123 </div>
[befb988]124 <div className="row row-cols-1 row-cols-md-5 g-3">
[28b3398]125 <AddJobAdModal/>
[19398ad]126
[befb988]127 {jobAdvertisementsByRecruiter && jobAdvertisementsByRecruiter.map((jobAd, index) => (
128 <div key={index} className="col">
129 <div className="custom-card">
130 <div className="card-head">
131 <span className="hourly-salary"><b>${jobAd.startingSalary}/hr</b></span>
132 <span
133 className="job-type"> {jobAd.jobType === JobType.JOB ? "Job" : "Internship"}</span>
134 {!jobAd.active && <span className="expired">Expired</span>}
135 <div className="card-management-btns">
136 <DeleteJobAdModal props={jobAd}/>
137 <EditJobAdModal props={jobAd}/>
[19398ad]138 </div>
[befb988]139 </div>
140 <div className="card-body">
141 <h5 className="card-title">{jobAd.title}</h5>
142 <span>{jobAd.industry} • <span style={{
143 color: "black", fontWeight: "bold"
144 }}>{formatRelativeTime(jobAd.postedOn)}</span></span>
145 <div className="card-info">
[28b3398]146 <span><i className="fa-solid fa-building"
147 style={{color: "#000000"}}></i> Company: <span style={{
[befb988]148 color: "black", fontWeight: "bold"
[28b3398]149 }}>{jobAd.recruiterName}</span></span> <br/>
[befb988]150 </div>
[19398ad]151
[befb988]152 <div className="aligned">
153 <Link to={`/job-management-hub/applications/${jobAd.id}`}
154 className="card-button solo">View applications</Link>
[19398ad]155 </div>
[befb988]156
[19398ad]157 </div>
158 </div>
[befb988]159 </div>))}
[19398ad]160 </div>
161 </div>
[befb988]162
163
[19398ad]164 )
165}
Note: See TracBrowser for help on using the repository browser.