source: jobvista-frontend/src/views/job_advertisements/JobAdvertisements.js@ 28b3398

main
Last change on this file since 28b3398 was 28b3398, checked in by 223021 <daniel.ilievski.2@…>, 3 weeks ago

Implemented job application functionality, added job advertisement filtering and replaced text areas with editors

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