| import React, { useState } from "react"; | |||||
| import React, { useEffect, useState } from "react"; | |||||
| import PropType from "prop-types"; | import PropType from "prop-types"; | ||||
| import Box from "@mui/material/Box"; | import Box from "@mui/material/Box"; | ||||
| import Drawer from "@mui/material/Drawer"; | import Drawer from "@mui/material/Drawer"; | ||||
| import Slider from "@mui/material/Slider"; | import Slider from "@mui/material/Slider"; | ||||
| import filterIcon from "../../assets/images/filter_vector.png"; | import filterIcon from "../../assets/images/filter_vector.png"; | ||||
| import x from "../../assets/images/x.png"; | import x from "../../assets/images/x.png"; | ||||
| import { filterCandidates } from "../../store/actions/candidates/candidatesActions"; | |||||
| import { | |||||
| filterCandidates, | |||||
| fetchAdsCandidates | |||||
| } from "../../store/actions/candidates/candidatesActions"; | |||||
| import { useDispatch } from "react-redux"; | import { useDispatch } from "react-redux"; | ||||
| import { formatDateInput } from "../../util/helpers/dateHelpers"; | import { formatDateInput } from "../../util/helpers/dateHelpers"; | ||||
| import { changeIsCheckedValue,resetIsCheckedValue } from "../../store/actions/technologies/technologiesActions"; | |||||
| const CandidateFilters = ({ open, handleClose,pageSize,currentPage }) => { | |||||
| const CandidateFilters = ({ | |||||
| open, | |||||
| handleClose, | |||||
| pageSize, | |||||
| currentPage, | |||||
| isTableView, | |||||
| technologies, | |||||
| }) => { | |||||
| const dispatch = useDispatch(); | const dispatch = useDispatch(); | ||||
| const [sliderValue, setSliderValue] = useState([0, 0]); | const [sliderValue, setSliderValue] = useState([0, 0]); | ||||
| const [startingDate,setStartingDate] = useState('') | |||||
| const [endingDate,setEndingDate] = useState('') | |||||
| const [technologies, setTechnologies] = useState([ | |||||
| { name: "react", isChecked: false }, | |||||
| { name: "angular", isChecked: false }, | |||||
| { name: "sql", isChecked: false }, | |||||
| { name: "nodejs", isChecked: false }, | |||||
| { name: ".net", isChecked: false }, | |||||
| { name: "git", isChecked: false }, | |||||
| { name: "html/css", isChecked: false }, | |||||
| { name: "vanillaJS", isChecked: false }, | |||||
| ]); | |||||
| const [startingDate, setStartingDate] = useState(""); | |||||
| const [endingDate, setEndingDate] = useState(""); | |||||
| const [typesOfEmployments, setTypesOfEmployments] = useState([ | const [typesOfEmployments, setTypesOfEmployments] = useState([ | ||||
| { name: "Posao", isChecked: true }, | |||||
| { name: "Posao", isChecked: false }, | |||||
| { name: "Intership", isChecked: false }, | { name: "Intership", isChecked: false }, | ||||
| ]); | ]); | ||||
| const [isInitial, setIsInitial] = useState(true) | |||||
| useEffect(() => { | |||||
| console.log(isTableView); | |||||
| }, [isTableView]); | |||||
| const handleSliderChange = (_, newValue) => { | const handleSliderChange = (_, newValue) => { | ||||
| setSliderValue(newValue); | setSliderValue(newValue); | ||||
| }; | }; | ||||
| const updateState = (name, value) => { | |||||
| const newState = technologies.map((obj) => { | |||||
| if (obj.name === name) { | |||||
| return { ...obj, isChecked: value }; | |||||
| } | |||||
| return obj; | |||||
| }); | |||||
| setTechnologies(newState); | |||||
| const resetFilters = () => { | |||||
| setTypesOfEmployments([ | |||||
| { name: "Posao", isChecked: false }, | |||||
| { name: "Intership", isChecked: false }, | |||||
| ]); | |||||
| setSliderValue([0,0]) | |||||
| setEndingDate("") | |||||
| setStartingDate("") | |||||
| }; | }; | ||||
| useEffect(() => { | |||||
| if(isInitial) { | |||||
| setIsInitial(false) | |||||
| return; | |||||
| } | |||||
| dispatch(resetIsCheckedValue()) | |||||
| resetFilters(); | |||||
| }, [isTableView]) | |||||
| const updateTypeState = (name, value) => { | const updateTypeState = (name, value) => { | ||||
| const newState = typesOfEmployments.map((obj) => { | const newState = typesOfEmployments.map((obj) => { | ||||
| if (obj.name === name) { | if (obj.name === name) { | ||||
| setTypesOfEmployments(newState); | setTypesOfEmployments(newState); | ||||
| }; | }; | ||||
| const handleTechologiesChange = (event) => { | |||||
| updateState(event.target.name, event.target.checked); | |||||
| const handleTechologiesChange = (e) => { | |||||
| const { name } = e.target; | |||||
| dispatch(changeIsCheckedValue(name)); | |||||
| }; | }; | ||||
| const getSelectedEmploymentType = () => { | const getSelectedEmploymentType = () => { | ||||
| return typesOfEmployments.filter((e) => e.isChecked === true); | return typesOfEmployments.filter((e) => e.isChecked === true); | ||||
| }; | }; | ||||
| const getSelectedTechnologies = () => { | |||||
| let k = technologies.filter(t => t.isChecked === true) | |||||
| let n = [] | |||||
| k.forEach(technology => { | |||||
| n.push(technology.name) | |||||
| }); | |||||
| return n; | |||||
| } | |||||
| const handleChangeTypeOfEmployment = (name) => { | const handleChangeTypeOfEmployment = (name) => { | ||||
| updateTypeState(name, true); | updateTypeState(name, true); | ||||
| }; | }; | ||||
| const handleApiResponseSuccess = () => { | const handleApiResponseSuccess = () => { | ||||
| handleClose() | |||||
| handleClose(); | |||||
| }; | |||||
| const isThereSelectedFilter = () => { | |||||
| let tech = technologies.filter(t => t.isChecked === true); | |||||
| if(tech.length > 0){ | |||||
| return true; | |||||
| } | |||||
| let k = typesOfEmployments.filter(te => te.isChecked === true) | |||||
| if(k.length > 0){ | |||||
| return true | |||||
| } | |||||
| if(sliderValue[0] !== 0 || sliderValue[1] !== 0) { | |||||
| return true | |||||
| } | |||||
| if(startingDate !== "" || endingDate !== ""){ | |||||
| return true; | |||||
| } | |||||
| return false | |||||
| } | } | ||||
| const fiterItems = () => { | const fiterItems = () => { | ||||
| const tech = technologies | |||||
| .filter((tech) => tech.isChecked === true) | |||||
| .map((tech) => tech.name); | |||||
| const selectedEmploymentType = getSelectedEmploymentType(); | |||||
| isTableView ? | |||||
| dispatch( | dispatch( | ||||
| filterCandidates({ | filterCandidates({ | ||||
| pageSize, | pageSize, | ||||
| currentPage, | currentPage, | ||||
| minExperience: sliderValue[0], | minExperience: sliderValue[0], | ||||
| maxExperience: sliderValue[1], | maxExperience: sliderValue[1], | ||||
| employmentType: getSelectedEmploymentType()[0].name, | |||||
| minDateOfApplication:startingDate, | |||||
| maxDateOfApplication:endingDate, | |||||
| technologies:getSelectedTechnologies(), | |||||
| handleApiResponseSuccess | |||||
| employmentType:selectedEmploymentType.length === 0 ? "" : selectedEmploymentType[0].name, | |||||
| minDateOfApplication: startingDate, | |||||
| maxDateOfApplication: endingDate, | |||||
| technologies: tech, | |||||
| handleApiResponseSuccess, | |||||
| }) | |||||
| ) : | |||||
| dispatch( | |||||
| fetchAdsCandidates({ | |||||
| pageSize, | |||||
| currentPage, | |||||
| minExperience: sliderValue[0], | |||||
| maxExperience: sliderValue[1], | |||||
| employmentType:selectedEmploymentType.length === 0 ? "" : selectedEmploymentType[0].name, | |||||
| minDateOfApplication: startingDate, | |||||
| maxDateOfApplication: endingDate, | |||||
| technologies: tech, | |||||
| handleApiResponseSuccess, | |||||
| }) | }) | ||||
| ); | ); | ||||
| }; | }; | ||||
| const handleChangeStartingDate = (event) => { | const handleChangeStartingDate = (event) => { | ||||
| console.log(event) | |||||
| setStartingDate(event.target.value) | |||||
| } | |||||
| console.log(event); | |||||
| setStartingDate(event.target.value); | |||||
| }; | |||||
| const handleChangeEndingDate = (event) => { | const handleChangeEndingDate = (event) => { | ||||
| console.log(event) | |||||
| setEndingDate(event.target.value) | |||||
| } | |||||
| console.log(event); | |||||
| setEndingDate(event.target.value); | |||||
| }; | |||||
| const getDayBeforeToday = (date = new Date()) => { | const getDayBeforeToday = (date = new Date()) => { | ||||
| const previous = new Date(date.getTime()); | const previous = new Date(date.getTime()); | ||||
| previous.setDate(date.getDate() - 1); | previous.setDate(date.getDate() - 1); | ||||
| return previous; | return previous; | ||||
| } | |||||
| }; | |||||
| const list = () => ( | const list = () => ( | ||||
| <Box | <Box | ||||
| <p>Datum prijave</p> | <p>Datum prijave</p> | ||||
| <div className="filter-date-container"> | <div className="filter-date-container"> | ||||
| <p>Od</p> | <p>Od</p> | ||||
| <input type="date" id="start" max={formatDateInput(getDayBeforeToday())} value={startingDate} onChange={handleChangeStartingDate}/> | |||||
| <input | |||||
| type="date" | |||||
| id="start" | |||||
| max={formatDateInput(getDayBeforeToday())} | |||||
| value={startingDate} | |||||
| onChange={handleChangeStartingDate} | |||||
| /> | |||||
| </div> | </div> | ||||
| <div className="filter-date-container"> | <div className="filter-date-container"> | ||||
| <p>Do</p> | <p>Do</p> | ||||
| <input type="date" id="start" max={ formatDateInput(new Date())} value={endingDate} onChange={handleChangeEndingDate}/> | |||||
| <input | |||||
| type="date" | |||||
| id="start" | |||||
| max={formatDateInput(new Date())} | |||||
| value={endingDate} | |||||
| onChange={handleChangeEndingDate} | |||||
| /> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div className="ad-filters-search" style={{ marginTop: "45px" }}> | <div className="ad-filters-search" style={{ marginTop: "45px" }}> | ||||
| <button className="c-btn c-btn--primary" onClick={fiterItems}> | |||||
| <button className="c-btn c-btn--primary" onClick={fiterItems} disabled={!isThereSelectedFilter()}> | |||||
| Pretrazi | Pretrazi | ||||
| </button> | </button> | ||||
| </div> | </div> | ||||
| open: PropType.any, | open: PropType.any, | ||||
| handleClose: PropType.func, | handleClose: PropType.func, | ||||
| candidates: PropType.array, | candidates: PropType.array, | ||||
| currentPage:PropType.number, | |||||
| pageSize:PropType.number | |||||
| currentPage: PropType.number, | |||||
| pageSize: PropType.number, | |||||
| isTableView: PropType.bool, | |||||
| technologies: PropType.array, | |||||
| }; | }; | ||||
| export default CandidateFilters; | export default CandidateFilters; |
| export const BACKSPACE_KEYCODE = 8; | export const BACKSPACE_KEYCODE = 8; | ||||
| export const TAB_KEYCODE = 9; | export const TAB_KEYCODE = 9; | ||||
| export const PAGE_SIZE_CANDIDATES = 6; | |||||
| export const PAGE_SIZE_CANDIDATES = 2; |
| import { fetchCandidate } from "../../store/actions/candidate/candidateActions"; | import { fetchCandidate } from "../../store/actions/candidate/candidateActions"; | ||||
| import { useMediaQuery } from "@mui/material"; | import { useMediaQuery } from "@mui/material"; | ||||
| import { useTheme } from "@mui/system"; | import { useTheme } from "@mui/system"; | ||||
| import CandidateAd from '../../components/Candidates/CandidateAd'; | |||||
| import CandidateAd from "../../components/Candidates/CandidateAd"; | |||||
| import Slider from "react-slick"; | import Slider from "react-slick"; | ||||
| import arrow_left from "../../assets/images/arrow_left.png"; | import arrow_left from "../../assets/images/arrow_left.png"; | ||||
| import arrow_right from "../../assets/images/arrow_right.png"; | import arrow_right from "../../assets/images/arrow_right.png"; | ||||
| import { ADS_PAGE } from "../../constants/pages"; | |||||
| import { ADS_PAGE, CANDIDATES_PAGE } from "../../constants/pages"; | |||||
| import PropTypes from "prop-types"; | import PropTypes from "prop-types"; | ||||
| import { deleteCandidate } from "../../request/candidatesRequest"; | |||||
| import { deleteCandidate } from "../../store/actions/candidate/candidateActions"; | |||||
| import ConfirmDialog from "../../components/MUI/ConfirmDialog"; | |||||
| import deleteIcon from "../../assets/images/delete.png"; | |||||
| const CandidateDetailsPage = ({history}) => { | |||||
| const CandidateDetailsPage = ({ history }) => { | |||||
| const dispatch = useDispatch(); | const dispatch = useDispatch(); | ||||
| const { users } = useSelector((s) => s.users); | const { users } = useSelector((s) => s.users); | ||||
| const { user } = useSelector((s) => s.user); | const { user } = useSelector((s) => s.user); | ||||
| const theme = useTheme(); | const theme = useTheme(); | ||||
| const matches = useMediaQuery(theme.breakpoints.down("680")); | const matches = useMediaQuery(theme.breakpoints.down("680")); | ||||
| const adsSliderRef = useRef(); | const adsSliderRef = useRef(); | ||||
| const [showDelete, setDelete] = useState(false); | |||||
| useEffect(() => { | useEffect(() => { | ||||
| dispatch(fetchCandidate({ id })); | dispatch(fetchCandidate({ id })); | ||||
| adsSliderRef.current.slickNext(); | adsSliderRef.current.slickNext(); | ||||
| }; | }; | ||||
| const deleteCurrentCandidate = () => { | |||||
| dispatch(deleteCandidate({id})) | |||||
| } | |||||
| const navigateToDetailsPage = (id) => { | const navigateToDetailsPage = (id) => { | ||||
| history.push({ | history.push({ | ||||
| pathname: ADS_PAGE + "/" + id, | pathname: ADS_PAGE + "/" + id, | ||||
| from: history.location.pathname, | from: history.location.pathname, | ||||
| }, | }, | ||||
| }); | }); | ||||
| } | |||||
| }; | |||||
| const handleApiResponseSuccessDelete = () => { | |||||
| history.push({ | |||||
| pathname: CANDIDATES_PAGE, | |||||
| state: { | |||||
| from: history.location.pathname, | |||||
| }, | |||||
| }); | |||||
| }; | |||||
| const deleteCandidateHandler = () => { | |||||
| dispatch( | |||||
| deleteCandidate({ | |||||
| id, | |||||
| handleApiResponseSuccess: handleApiResponseSuccessDelete, | |||||
| }) | |||||
| ); | |||||
| }; | |||||
| return (candidate && Object.keys(candidate).length === 0) || | return (candidate && Object.keys(candidate).length === 0) || | ||||
| user === undefined ? ( | user === undefined ? ( | ||||
| <p>Loading...</p> | <p>Loading...</p> | ||||
| ) : ( | ) : ( | ||||
| <div className="main-candidate-container pl-144 pt-36px"> | <div className="main-candidate-container pl-144 pt-36px"> | ||||
| <ConfirmDialog | |||||
| open={showDelete} | |||||
| title={"Brisanje kandidata"} | |||||
| subtitle={candidate.firstName + " " + candidate.lastName} | |||||
| imgSrc={deleteIcon} | |||||
| content="Da li ste sigurni da zelite da obrisete kandidata?" | |||||
| onClose={() => { | |||||
| setDelete(false); | |||||
| }} | |||||
| onConfirm={deleteCandidateHandler} | |||||
| /> | |||||
| <div className="l-t-rectangle"></div> | <div className="l-t-rectangle"></div> | ||||
| <div className="r-b-rectangle"></div> | <div className="r-b-rectangle"></div> | ||||
| <div className="top-candidate-container"> | <div className="top-candidate-container"> | ||||
| </p> | </p> | ||||
| </div> | </div> | ||||
| <div className="candidate-option-container"> | <div className="candidate-option-container"> | ||||
| <IconButton className="c-btn c-btn--primary-outlined candidate-btn" onClick={deleteCurrentCandidate}> | |||||
| <IconButton | |||||
| className="c-btn c-btn--primary-outlined candidate-btn" | |||||
| onClick={() => setDelete(true)} | |||||
| > | |||||
| Obrisi | Obrisi | ||||
| <img src={deleteImage} alt="delete" className="candidates-image" /> | <img src={deleteImage} alt="delete" className="candidates-image" /> | ||||
| </IconButton> | </IconButton> |
| import React, { useEffect } from "react"; | |||||
| import arrow_left from "../../assets/images/arrow_left.png"; | |||||
| import arrow_right from "../../assets/images/arrow_right.png"; | |||||
| import adImage from "../../assets/images/.net_icon.png"; | |||||
| import Slider from "react-slick"; | |||||
| import useDynamicRefs from "use-dynamic-refs"; | |||||
| import { fetchAdsCandidates } from "../../store/actions/candidates/candidatesActions"; | |||||
| import { useDispatch, useSelector } from "react-redux"; | |||||
| import CandidateCard from "../../components/Candidates/CandidateCard"; | |||||
| const AdsCandidatesPage = () => { | |||||
| const dispatch = useDispatch(); | |||||
| const { adsCandidates } = useSelector((s) => s.candidates); | |||||
| const [getRef, setRef] = useDynamicRefs(); | |||||
| useEffect(() => { | |||||
| dispatch( | |||||
| fetchAdsCandidates({ | |||||
| currentPage: 0, | |||||
| pageSize: 0, | |||||
| minExperience: 0, | |||||
| maxExperience: 0, | |||||
| employmentType: "", | |||||
| minDateOfApplication: "", | |||||
| maxDateOfApplication: "", | |||||
| technologies: [], | |||||
| }) | |||||
| ); | |||||
| },[dispatch]); | |||||
| var settings = { | |||||
| dots: false, | |||||
| infinite: false, | |||||
| speed: 400, | |||||
| slidesToShow: 4, | |||||
| slidesToScroll: 4, | |||||
| initialSlide: 0, | |||||
| arrows: true, | |||||
| variableWidth: true, | |||||
| responsive: [ | |||||
| { | |||||
| breakpoint: 1024, | |||||
| settings: { | |||||
| slidesToShow: 3, | |||||
| slidesToScroll: 3, | |||||
| infinite: true, | |||||
| dots: false, | |||||
| }, | |||||
| }, | |||||
| { | |||||
| breakpoint: 900, | |||||
| settings: { | |||||
| slidesToShow: 2, | |||||
| slidesToScroll: 2, | |||||
| initialSlide: 0, | |||||
| }, | |||||
| }, | |||||
| { | |||||
| breakpoint: 480, | |||||
| settings: { | |||||
| slidesToShow: 1, | |||||
| slidesToScroll: 1, | |||||
| }, | |||||
| }, | |||||
| ], | |||||
| }; | |||||
| const getDummyCandidates = (len) => { | |||||
| const candidates = []; | |||||
| for (let i = 0; i < 4 - len + 1; i++) { | |||||
| candidates.push( | |||||
| <CandidateCard key={i} className="hiddenAd" history={history} /> | |||||
| ); | |||||
| } | |||||
| return candidates; | |||||
| }; | |||||
| const activeAdsArrowLeftHandler = (index) => { | |||||
| getRef(index.toString()).current.slickPrev(); | |||||
| }; | |||||
| const activeAdsArrowRightHandler = (index) => { | |||||
| getRef(index.toString()).current.slickNext(); | |||||
| }; | |||||
| return ( | |||||
| <div className="ads-candidates-container top-cnd"> | |||||
| {adsCandidates.map((adCandidates, index) => ( | |||||
| <div className="ads-candidates" key={index}> | |||||
| <div className="ads-candidates-top-container"> | |||||
| <img src={adImage} style={{ width: "49px", height: "39px" }} /> | |||||
| <p className="ads-candidates-title">{adCandidates.title}</p> | |||||
| <p className="ads-candidates-numberOfApplicants"> | |||||
| | {adCandidates.nubmerOfApplicants} prijavljenih | |||||
| </p> | |||||
| </div> | |||||
| <div | |||||
| className="ads-candidates-slider" | |||||
| style={{ display: "flex", marginTop: "31px" }} | |||||
| > | |||||
| {adCandidates.applicants.length > 3 && ( | |||||
| <div className="active-ads-ads-arrows"> | |||||
| <button onClick={() => activeAdsArrowLeftHandler(index)}> | |||||
| <img src={arrow_left} alt="arrow-left" /> | |||||
| </button> | |||||
| <button onClick={() => activeAdsArrowRightHandler(index)}> | |||||
| <img src={arrow_right} alt="arrow-right" /> | |||||
| </button> | |||||
| </div> | |||||
| )} | |||||
| <Slider | |||||
| {...settings} | |||||
| ref={setRef(index.toString())} | |||||
| style={{ width: "100%" }} | |||||
| > | |||||
| {adCandidates.applicants.map((candidate, index) => ( | |||||
| <CandidateCard | |||||
| key={index} | |||||
| candidate={candidate} | |||||
| history={history} | |||||
| className={index === 0 ? "" : "left-move-candidateAd"} | |||||
| /> | |||||
| ))} | |||||
| {adCandidates.applicants.length <= 4 && | |||||
| getDummyCandidates(adCandidates.applicants.length)} | |||||
| </Slider> | |||||
| </div> | |||||
| </div> | |||||
| ))} | |||||
| </div> | |||||
| ); | |||||
| }; | |||||
| export default AdsCandidatesPage; |
| import IconButton from "../../components/IconButton/IconButton"; | import IconButton from "../../components/IconButton/IconButton"; | ||||
| import React, { useEffect, useState } from "react"; | import React, { useEffect, useState } from "react"; | ||||
| import { useDispatch, useSelector } from "react-redux"; | |||||
| import { | |||||
| fetchAdsCandidates, | |||||
| filterCandidates, | |||||
| } from "../../store/actions/candidates/candidatesActions"; | |||||
| import tableImage from "../../assets/images/table.png"; | import tableImage from "../../assets/images/table.png"; | ||||
| import adImage from "../../assets/images/.net_icon.png"; | |||||
| import filterImage from "../../assets/images/filters.png"; | import filterImage from "../../assets/images/filters.png"; | ||||
| import { formatDate } from "../../util/helpers/dateHelpers"; | |||||
| import planeImage from "../../assets/images/planeVector.png"; | import planeImage from "../../assets/images/planeVector.png"; | ||||
| import arrow_left from "../../assets/images/arrow_left.png"; | |||||
| import arrow_right from "../../assets/images/arrow_right.png"; | |||||
| import { useMediaQuery } from "@mui/material"; | import { useMediaQuery } from "@mui/material"; | ||||
| import { useTheme } from "@mui/system"; | import { useTheme } from "@mui/system"; | ||||
| import { CANDIDATES_PAGE } from "../../constants/pages"; | |||||
| import PropTypes from "prop-types"; | import PropTypes from "prop-types"; | ||||
| import Slider from "react-slick"; | |||||
| import CandidateCard from "../../components/Candidates/CandidateCard"; | |||||
| import useDynamicRefs from "use-dynamic-refs"; | |||||
| import CandidateFilters from "../../components/Candidates/CandidateFilters"; | import CandidateFilters from "../../components/Candidates/CandidateFilters"; | ||||
| import Pagination from "@mui/material/Pagination"; | |||||
| import { PAGE_SIZE_CANDIDATES } from "../../constants/keyCodeConstants"; | import { PAGE_SIZE_CANDIDATES } from "../../constants/keyCodeConstants"; | ||||
| import AdsCandidatesPage from "./AdsCandidatesPage"; | |||||
| import TableViewPage from "./TableViewPage"; | |||||
| import { setTechnologiesReq } from "../../store/actions/technologies/technologiesActions"; | |||||
| import { selectTechnologies } from "../../store/selectors/technologiesSelectors"; | |||||
| import { useDispatch, useSelector } from "react-redux"; | |||||
| import InviteDialog from "../../components/MUI/InviteDialog"; | |||||
| import addUser from "../../assets/images/addUser.png"; | |||||
| import x from "../../assets/images/x.png"; | |||||
| const CandidatesPage = ({ history }) => { | const CandidatesPage = ({ history }) => { | ||||
| const dispatch = useDispatch(); | const dispatch = useDispatch(); | ||||
| const { candidates } = useSelector((s) => s.candidates); | |||||
| const { pagination } = useSelector((s) => s.candidates); // pagination is total number of candidates on backend | |||||
| const { adsCandidates } = useSelector((s) => s.candidates); | |||||
| const theme = useTheme(); | const theme = useTheme(); | ||||
| const matches = useMediaQuery(theme.breakpoints.down("sm")); | const matches = useMediaQuery(theme.breakpoints.down("sm")); | ||||
| const [isTableView, setIsTableView] = useState(true); | const [isTableView, setIsTableView] = useState(true); | ||||
| const [getRef, setRef] = useDynamicRefs(); | |||||
| const [toggleFiltersDrawer, setToggleFiltersDrawer] = useState(false); | const [toggleFiltersDrawer, setToggleFiltersDrawer] = useState(false); | ||||
| const [page, setPage] = React.useState(1); | const [page, setPage] = React.useState(1); | ||||
| const technologies = useSelector(selectTechnologies); | |||||
| const [showInvite, setShowInvite] = useState(false); | |||||
| useEffect(() => { | useEffect(() => { | ||||
| dispatch( | |||||
| filterCandidates({ | |||||
| currentPage: page, | |||||
| pageSize: PAGE_SIZE_CANDIDATES, | |||||
| minExperience: 0, | |||||
| maxExperience: 0, | |||||
| employmentType: "", | |||||
| minDateOfApplication: "", | |||||
| maxDateOfApplication: "", | |||||
| technologies: [], | |||||
| }) | |||||
| ); | |||||
| dispatch(fetchAdsCandidates()); | |||||
| }, [dispatch]); | |||||
| const navigate = (applicantId) => { | |||||
| history.push({ | |||||
| pathname: CANDIDATES_PAGE + "/" + applicantId, | |||||
| state: { | |||||
| from: history.location.pathname, | |||||
| }, | |||||
| }); | |||||
| }; | |||||
| dispatch(setTechnologiesReq()); | |||||
| }, []); | |||||
| const changeView = () => { | const changeView = () => { | ||||
| setIsTableView(!isTableView); | setIsTableView(!isTableView); | ||||
| setToggleFiltersDrawer((oldState) => !oldState); | setToggleFiltersDrawer((oldState) => !oldState); | ||||
| }; | }; | ||||
| var settings = { | |||||
| dots: false, | |||||
| infinite: false, | |||||
| speed: 400, | |||||
| slidesToShow: 4, | |||||
| slidesToScroll: 4, | |||||
| initialSlide: 0, | |||||
| arrows: true, | |||||
| variableWidth: true, | |||||
| responsive: [ | |||||
| { | |||||
| breakpoint: 1024, | |||||
| settings: { | |||||
| slidesToShow: 3, | |||||
| slidesToScroll: 3, | |||||
| infinite: true, | |||||
| dots: false, | |||||
| }, | |||||
| }, | |||||
| { | |||||
| breakpoint: 900, | |||||
| settings: { | |||||
| slidesToShow: 2, | |||||
| slidesToScroll: 2, | |||||
| initialSlide: 0, | |||||
| }, | |||||
| }, | |||||
| { | |||||
| breakpoint: 480, | |||||
| settings: { | |||||
| slidesToShow: 1, | |||||
| slidesToScroll: 1, | |||||
| }, | |||||
| }, | |||||
| ], | |||||
| }; | |||||
| const getDummyCandidates = (len) => { | |||||
| const candidates = []; | |||||
| for (let i = 0; i < 4 - len + 1; i++) { | |||||
| candidates.push( | |||||
| <CandidateCard key={i} className="hiddenAd" history={history} /> | |||||
| ); | |||||
| } | |||||
| return candidates; | |||||
| }; | |||||
| const activeAdsArrowLeftHandler = (index) => { | |||||
| getRef(index.toString()).current.slickPrev(); | |||||
| }; | |||||
| const activeAdsArrowRightHandler = (index) => { | |||||
| getRef(index.toString()).current.slickNext(); | |||||
| }; | |||||
| const handleChange = (event, value) => { | |||||
| dispatch( | |||||
| filterCandidates({ | |||||
| currentPage: value, | |||||
| pageSize: PAGE_SIZE_CANDIDATES, | |||||
| minExperience: 0, | |||||
| maxExperience: 5, | |||||
| employmentType: "Intership", | |||||
| minDateOfApplication: "10/05/2020", | |||||
| maxDateOfApplication: "10/10/2022", | |||||
| technologies: [], | |||||
| }) | |||||
| ); | |||||
| setPage(value); | |||||
| const inviteCandidate = () => { | |||||
| setShowInvite(true) | |||||
| }; | }; | ||||
| return ( | return ( | ||||
| <div className="main-candidates-container pl-144 pt-36px"> | <div className="main-candidates-container pl-144 pt-36px"> | ||||
| <InviteDialog | |||||
| open={showInvite} | |||||
| onClose={() => { | |||||
| setShowInvite(false); | |||||
| }} | |||||
| title={ | |||||
| <div | |||||
| className="flex-center" | |||||
| style={{ justifyContent: "space-between" }} | |||||
| > | |||||
| <div className="flex-center" style={{ justifyContent: "start" }}> | |||||
| <img | |||||
| style={{ | |||||
| position: "relative", | |||||
| top: -0.25, | |||||
| paddingRight: "10px", | |||||
| }} | |||||
| src={addUser} | |||||
| /> | |||||
| <h5>Invite korisnika</h5> | |||||
| <div className="vr"></div> | |||||
| <p className="dialog-subtitle">Registration link</p> | |||||
| </div> | |||||
| <IconButton onClick={() => setShowInvite(false)}> | |||||
| <img | |||||
| style={{ | |||||
| position: "relative", | |||||
| top: -0.25, | |||||
| }} | |||||
| src={x} | |||||
| /> | |||||
| </IconButton> | |||||
| </div> | |||||
| } | |||||
| /> | |||||
| <CandidateFilters | <CandidateFilters | ||||
| open={toggleFiltersDrawer} | open={toggleFiltersDrawer} | ||||
| handleClose={handleToggleFiltersDrawer} | handleClose={handleToggleFiltersDrawer} | ||||
| pageSize={PAGE_SIZE_CANDIDATES} | pageSize={PAGE_SIZE_CANDIDATES} | ||||
| currentPage={page} | currentPage={page} | ||||
| isTableView={isTableView} | |||||
| technologies={technologies} | |||||
| /> | /> | ||||
| <div className="l-t-rectangle"></div> | <div className="l-t-rectangle"></div> | ||||
| <div className="r-b-rectangle"></div> | <div className="r-b-rectangle"></div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| {isTableView ? ( | {isTableView ? ( | ||||
| <div className="candidates-table"> | |||||
| <table | |||||
| className="usersTable" | |||||
| style={{ width: "1117px", height: "100px" }} | |||||
| > | |||||
| <thead> | |||||
| <tr className="headingRow"> | |||||
| <th>Ime i prezime</th> | |||||
| <th>Iskustvo</th> | |||||
| <th>Datum prijave</th> | |||||
| <th>Pozicija</th> | |||||
| <th>CV link</th> | |||||
| </tr> | |||||
| </thead> | |||||
| <tbody> | |||||
| {candidates.map((candidate, index) => ( | |||||
| <tr | |||||
| key={index} | |||||
| className="secondaryRow cadidate-row" | |||||
| style={{ | |||||
| width: "800px", | |||||
| height: "40px", | |||||
| borderRadius: "12px", | |||||
| cursor: "pointer", | |||||
| }} | |||||
| onClick={() => navigate(candidate.applicantId)} | |||||
| > | |||||
| <td> | |||||
| {candidate.firstName} {candidate.lastName} | |||||
| </td> | |||||
| <td>{candidate.experience}</td> | |||||
| <td>{formatDate(candidate.dateOfApplication)}</td> | |||||
| <td>{candidate.position}</td> | |||||
| <td> | |||||
| <a href={candidate.CV} className="cvLink"> | |||||
| {candidate.firstName} | |||||
| {candidate.lastName}.pdf | |||||
| </a> | |||||
| </td> | |||||
| </tr> | |||||
| ))} | |||||
| </tbody> | |||||
| </table> | |||||
| <Pagination | |||||
| count={ | |||||
| parseInt(pagination) <= PAGE_SIZE_CANDIDATES | |||||
| ? 1 | |||||
| : Math.ceil(parseInt(pagination) / PAGE_SIZE_CANDIDATES) | |||||
| } | |||||
| color="primary" | |||||
| style={{ alignSelf: "center", marginTop: "20px" }} | |||||
| onChange={handleChange} | |||||
| shape="rounded" | |||||
| /> | |||||
| </div> | |||||
| <TableViewPage history={history} page={page} setPage={setPage} /> | |||||
| ) : ( | ) : ( | ||||
| <div className="ads-candidates-container top-cnd"> | |||||
| {adsCandidates.map((adCandidates, index) => ( | |||||
| <div className="ads-candidates" key={index}> | |||||
| <div className="ads-candidates-top-container"> | |||||
| <img src={adImage} style={{ width: "49px", height: "39px" }} /> | |||||
| <p className="ads-candidates-title">{adCandidates.title}</p> | |||||
| <p className="ads-candidates-numberOfApplicants"> | |||||
| | {adCandidates.nubmerOfApplicants} prijavljenih | |||||
| </p> | |||||
| </div> | |||||
| <div | |||||
| className="ads-candidates-slider" | |||||
| style={{ display: "flex", marginTop: "31px" }} | |||||
| > | |||||
| {adCandidates.applicants.length > 3 && ( | |||||
| <div className="active-ads-ads-arrows"> | |||||
| <button onClick={() => activeAdsArrowLeftHandler(index)}> | |||||
| <img src={arrow_left} alt="arrow-left" /> | |||||
| </button> | |||||
| <button onClick={() => activeAdsArrowRightHandler(index)}> | |||||
| <img src={arrow_right} alt="arrow-right" /> | |||||
| </button> | |||||
| </div> | |||||
| )} | |||||
| <Slider | |||||
| {...settings} | |||||
| ref={setRef(index.toString())} | |||||
| style={{ width: "100%" }} | |||||
| > | |||||
| {adCandidates.applicants.map((candidate, index) => ( | |||||
| <CandidateCard | |||||
| key={index} | |||||
| candidate={candidate} | |||||
| history={history} | |||||
| className={index === 0 ? "" : "left-move-candidateAd"} | |||||
| /> | |||||
| ))} | |||||
| {adCandidates.applicants.length <= 4 && | |||||
| getDummyCandidates(adCandidates.applicants.length)} | |||||
| </Slider> | |||||
| </div> | |||||
| </div> | |||||
| ))} | |||||
| </div> | |||||
| <AdsCandidatesPage/> | |||||
| )} | )} | ||||
| <IconButton className={'c-btn candidate-btn invite-btn invite-btn-color ' + (isTableView === false ? 'proba' : '')}> | |||||
| <IconButton | |||||
| className={ | |||||
| "c-btn candidate-btn invite-btn invite-btn-color " + | |||||
| (isTableView === false ? "proba" : "") | |||||
| } | |||||
| onClick={inviteCandidate} | |||||
| > | |||||
| <img src={planeImage} alt="table" className="candidates-image" /> | <img src={planeImage} alt="table" className="candidates-image" /> | ||||
| Invite | Invite | ||||
| </IconButton> | </IconButton> |
| import React, { useEffect } from "react"; | |||||
| import Pagination from "@mui/material/Pagination"; | |||||
| import { formatDate } from "../../util/helpers/dateHelpers"; | |||||
| import { useDispatch, useSelector } from "react-redux"; | |||||
| import PropTypes from "prop-types"; | |||||
| import { CANDIDATES_PAGE } from "../../constants/pages"; | |||||
| import { filterCandidates } from "../../store/actions/candidates/candidatesActions"; | |||||
| import { PAGE_SIZE_CANDIDATES } from "../../constants/keyCodeConstants"; | |||||
| const TableViewPage = ({ history, setPage, page }) => { | |||||
| const dispatch = useDispatch(); | |||||
| const { candidates } = useSelector((s) => s.candidates); | |||||
| const { pagination } = useSelector((s) => s.candidates); // pagination is total number of candidates on backend | |||||
| const navigate = (applicantId) => { | |||||
| history.push({ | |||||
| pathname: CANDIDATES_PAGE + "/" + applicantId, | |||||
| state: { | |||||
| from: history.location.pathname, | |||||
| }, | |||||
| }); | |||||
| }; | |||||
| useEffect(() => { | |||||
| dispatch( | |||||
| filterCandidates({ | |||||
| currentPage: page, | |||||
| pageSize: PAGE_SIZE_CANDIDATES, | |||||
| minExperience: 0, | |||||
| maxExperience: 0, | |||||
| employmentType: "", | |||||
| minDateOfApplication: "", | |||||
| maxDateOfApplication: "", | |||||
| technologies: [], | |||||
| }) | |||||
| ); | |||||
| }, [dispatch]); | |||||
| const handleChange = (_, value) => { | |||||
| dispatch( | |||||
| filterCandidates({ | |||||
| currentPage: value, | |||||
| pageSize: PAGE_SIZE_CANDIDATES, | |||||
| minExperience: 0, | |||||
| maxExperience: 0, | |||||
| employmentType: "", | |||||
| minDateOfApplication: "", | |||||
| maxDateOfApplication: "", | |||||
| technologies: [], | |||||
| }) | |||||
| ); | |||||
| setPage(value); | |||||
| }; | |||||
| return ( | |||||
| <div className="candidates-table"> | |||||
| <table | |||||
| className="usersTable" | |||||
| style={{ width: "1117px", height: "100px" }} | |||||
| > | |||||
| <thead> | |||||
| <tr className="headingRow"> | |||||
| <th>Ime i prezime</th> | |||||
| <th>Iskustvo</th> | |||||
| <th>Datum prijave</th> | |||||
| <th>Pozicija</th> | |||||
| <th>CV link</th> | |||||
| </tr> | |||||
| </thead> | |||||
| <tbody> | |||||
| {candidates.map((candidate, index) => ( | |||||
| <tr | |||||
| key={index} | |||||
| className="secondaryRow cadidate-row" | |||||
| style={{ | |||||
| width: "800px", | |||||
| height: "40px", | |||||
| borderRadius: "12px", | |||||
| cursor: "pointer", | |||||
| }} | |||||
| onClick={() => navigate(candidate.applicantId)} | |||||
| > | |||||
| <td> | |||||
| {candidate.firstName} {candidate.lastName} | |||||
| </td> | |||||
| <td>{candidate.experience}</td> | |||||
| <td>{formatDate(candidate.dateOfApplication)}</td> | |||||
| <td>{candidate.position}</td> | |||||
| <td> | |||||
| <a href={candidate.CV} className="cvLink"> | |||||
| {candidate.firstName} | |||||
| {candidate.lastName}.pdf | |||||
| </a> | |||||
| </td> | |||||
| </tr> | |||||
| ))} | |||||
| </tbody> | |||||
| </table> | |||||
| <Pagination | |||||
| count={ | |||||
| parseInt(pagination) <= PAGE_SIZE_CANDIDATES | |||||
| ? 1 | |||||
| : Math.ceil(parseInt(pagination) / PAGE_SIZE_CANDIDATES) | |||||
| } | |||||
| color="primary" | |||||
| style={{ alignSelf: "center", marginTop: "20px" }} | |||||
| onChange={handleChange} | |||||
| shape="rounded" | |||||
| /> | |||||
| </div> | |||||
| ); | |||||
| }; | |||||
| TableViewPage.propTypes = { | |||||
| history: PropTypes.shape({ | |||||
| replace: PropTypes.func, | |||||
| push: PropTypes.func, | |||||
| location: PropTypes.shape({ | |||||
| pathname: PropTypes.string, | |||||
| }), | |||||
| }), | |||||
| setPage: PropTypes.func, | |||||
| page: PropTypes.number, | |||||
| }; | |||||
| export default TableViewPage; |
| }, | }, | ||||
| candidates: { | candidates: { | ||||
| filteredCandidates:base + "/applicants", | filteredCandidates:base + "/applicants", | ||||
| allAdsCandidates: base + "/applicants/adsApplicants" | |||||
| allFilteredAdsCandidates: base + "/applicants/adsApplicants" | |||||
| }, | }, | ||||
| ads: { | ads: { | ||||
| allAds: base + "/ads", | allAds: base + "/ads", |
| getRequest(apiEndpoints.candidates.filteredCandidates + "/" + id); | getRequest(apiEndpoints.candidates.filteredCandidates + "/" + id); | ||||
| export const createComment = (data) => | export const createComment = (data) => | ||||
| postRequest(apiEndpoints.comments.addComment, data); | postRequest(apiEndpoints.comments.addComment, data); | ||||
| export const getAllAdsCandidates = () => | |||||
| getRequest(apiEndpoints.candidates.allAdsCandidates); | |||||
| export const getFilteredAdsCandidates = (payload) => { | |||||
| let technologiesQuery = ""; | |||||
| for (let i = 0; i < payload.technologies.length; i++) { | |||||
| technologiesQuery += `technologies=${payload.technologies[i]}&`; | |||||
| } | |||||
| return getRequest( | |||||
| apiEndpoints.candidates.allFilteredAdsCandidates + | |||||
| "?currentPage=" + | |||||
| payload.currentPage + | |||||
| "&pageSize=" + | |||||
| payload.pageSize + | |||||
| "&minExperience=" + | |||||
| payload.minExperience + | |||||
| "&maxExperience=" + | |||||
| payload.maxExperience + | |||||
| "&employmentType=" + | |||||
| payload.employmentType + | |||||
| "&minDateOfApplication=" + | |||||
| payload.minDateOfApplication + | |||||
| "&maxDateOfApplication=" + | |||||
| payload.maxDateOfApplication + | |||||
| "&" + | |||||
| technologiesQuery | |||||
| ); | |||||
| } | |||||
| export const deleteCandidate = (id) => | export const deleteCandidate = (id) => | ||||
| deleteRequest(apiEndpoints.candidates.allCandidates + "?id=" + id); | |||||
| deleteRequest(apiEndpoints.candidates.filteredCandidates + "?id=" + id); |
| payload, | payload, | ||||
| }); | }); | ||||
| export const fetchAdsCandidates = () => ({ | |||||
| export const fetchAdsCandidates = (payload) => ({ | |||||
| type: ADS_CANDIDATES_FETCH, | type: ADS_CANDIDATES_FETCH, | ||||
| payload | |||||
| }); | }); | ||||
| export const fetchAdsCandidatesError = (payload) => ({ | export const fetchAdsCandidatesError = (payload) => ({ | ||||
| export const fetchAdsCandidatesSuccess = (payload) => ({ | export const fetchAdsCandidatesSuccess = (payload) => ({ | ||||
| type: ADS_CANDIDATES_SUCCESS, | type: ADS_CANDIDATES_SUCCESS, | ||||
| payload, | payload, | ||||
| }); | |||||
| }); |
| export const FETCH_TECHNOLOGIES_SUCCESS = "FETCH_TECHNOLOGIES_SUCCESS"; | export const FETCH_TECHNOLOGIES_SUCCESS = "FETCH_TECHNOLOGIES_SUCCESS"; | ||||
| export const CHANGE_ISCHECKED_VALUE = "CHANGE_ISCHECKED_VALUE"; | export const CHANGE_ISCHECKED_VALUE = "CHANGE_ISCHECKED_VALUE"; | ||||
| export const RESET_IS_CHECKED_VALUE = "RESET_IS_CHECKED_VALUE" |
| FETCH_TECHNOLOGIES_ERR, | FETCH_TECHNOLOGIES_ERR, | ||||
| FETCH_TECHNOLOGIES_SUCCESS, | FETCH_TECHNOLOGIES_SUCCESS, | ||||
| FETCH_TECHNOLOGIES_REQ, | FETCH_TECHNOLOGIES_REQ, | ||||
| CHANGE_ISCHECKED_VALUE | |||||
| CHANGE_ISCHECKED_VALUE, | |||||
| RESET_IS_CHECKED_VALUE | |||||
| } from "./technologiesActionConstants"; | } from "./technologiesActionConstants"; | ||||
| export const setTechnologiesReq = () => ({ | export const setTechnologiesReq = () => ({ | ||||
| export const changeIsCheckedValue = (payload) => ({ | export const changeIsCheckedValue = (payload) => ({ | ||||
| type: CHANGE_ISCHECKED_VALUE, | type: CHANGE_ISCHECKED_VALUE, | ||||
| payload, | payload, | ||||
| }); | |||||
| }); | |||||
| export const resetIsCheckedValue = () => ({ | |||||
| type:RESET_IS_CHECKED_VALUE | |||||
| }) |
| candidates: [], | candidates: [], | ||||
| adsCandidates: [], | adsCandidates: [], | ||||
| errorMessage: "", | errorMessage: "", | ||||
| pagination: 0, | |||||
| pagination: 0 | |||||
| }; | }; | ||||
| export default createReducer( | export default createReducer( | ||||
| ...state, | ...state, | ||||
| errorMessage: action.payload, | errorMessage: action.payload, | ||||
| }; | }; | ||||
| } | |||||
| } |
| FETCH_TECHNOLOGIES_SUCCESS, | FETCH_TECHNOLOGIES_SUCCESS, | ||||
| FETCH_TECHNOLOGIES_ERR, | FETCH_TECHNOLOGIES_ERR, | ||||
| CHANGE_ISCHECKED_VALUE, | CHANGE_ISCHECKED_VALUE, | ||||
| RESET_IS_CHECKED_VALUE | |||||
| } from "../../actions/technologies/technologiesActionConstants"; | } from "../../actions/technologies/technologiesActionConstants"; | ||||
| const initialState = { | const initialState = { | ||||
| [FETCH_TECHNOLOGIES_SUCCESS]: setStateTechnologies, | [FETCH_TECHNOLOGIES_SUCCESS]: setStateTechnologies, | ||||
| [FETCH_TECHNOLOGIES_ERR]: setStateErrorMessage, | [FETCH_TECHNOLOGIES_ERR]: setStateErrorMessage, | ||||
| [CHANGE_ISCHECKED_VALUE]: setIsCheckedTechnology, | [CHANGE_ISCHECKED_VALUE]: setIsCheckedTechnology, | ||||
| [RESET_IS_CHECKED_VALUE]: resetIsCheckedTechnologies | |||||
| }, | }, | ||||
| initialState | initialState | ||||
| ); | ); | ||||
| ), | ), | ||||
| }; | }; | ||||
| } | } | ||||
| function resetIsCheckedTechnologies(state){ | |||||
| return {...state,technologies:state.technologies.map(t => ({...t,isChecked:false}))} | |||||
| } |
| import { | import { | ||||
| createComment, | createComment, | ||||
| getCandidate, | getCandidate, | ||||
| getAllAdsCandidates, | |||||
| getFilteredAdsCandidates, | |||||
| deleteCandidate, | deleteCandidate, | ||||
| getFilteredCandidates | getFilteredCandidates | ||||
| } from "../../request/candidatesRequest"; | } from "../../request/candidatesRequest"; | ||||
| import { authScopeStringGetHelper } from "../../util/helpers/authScopeHelpers"; | import { authScopeStringGetHelper } from "../../util/helpers/authScopeHelpers"; | ||||
| import { | import { | ||||
| ADS_CANDIDATES_FETCH, | ADS_CANDIDATES_FETCH, | ||||
| FILTER_CANDIDATES | |||||
| FILTER_CANDIDATES, | |||||
| } from "../actions/candidates/candidatesActionConstants"; | } from "../actions/candidates/candidatesActionConstants"; | ||||
| import { | import { | ||||
| fetchAdsCandidatesError, | fetchAdsCandidatesError, | ||||
| fetchAdsCandidatesSuccess, | fetchAdsCandidatesSuccess, | ||||
| filterCandidatesSuccess, | filterCandidatesSuccess, | ||||
| filterCandidatesError, | |||||
| filterCandidatesError | |||||
| } from "../actions/candidates/candidatesActions"; | } from "../actions/candidates/candidatesActions"; | ||||
| import { rejectErrorCodeHelper } from "../../util/helpers/rejectErrorCodeHelper"; | import { rejectErrorCodeHelper } from "../../util/helpers/rejectErrorCodeHelper"; | ||||
| import { | import { | ||||
| CANDIDATE_COMMENTS_FETCH, | CANDIDATE_COMMENTS_FETCH, | ||||
| DELETE_CANDIDATE, | DELETE_CANDIDATE, | ||||
| } from "../actions/candidate/candidateActionConstants"; | } from "../actions/candidate/candidateActionConstants"; | ||||
| import { CANDIDATES_PAGE } from "../../constants/pages"; | |||||
| import history from "../utils/history"; | |||||
| export function* filterCandidates({ payload }) { | export function* filterCandidates({ payload }) { | ||||
| } | } | ||||
| } | } | ||||
| export function* getAdsCandidates() { | |||||
| export function* getAdsCandidates({payload}) { | |||||
| try { | try { | ||||
| const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN); | const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN); | ||||
| yield call(addHeaderToken, JwtToken); | yield call(addHeaderToken, JwtToken); | ||||
| const { data } = yield call(getAllAdsCandidates); | |||||
| const { data } = yield call(getFilteredAdsCandidates,payload); | |||||
| yield put(fetchAdsCandidatesSuccess(data)); | yield put(fetchAdsCandidatesSuccess(data)); | ||||
| if(payload.handleApiResponseSuccess){ | |||||
| yield call(payload.handleApiResponseSuccess) | |||||
| } | |||||
| } catch (error) { | } catch (error) { | ||||
| const errorMessage = yield call(rejectErrorCodeHelper, error); | const errorMessage = yield call(rejectErrorCodeHelper, error); | ||||
| yield put(fetchAdsCandidatesError(errorMessage)); | yield put(fetchAdsCandidatesError(errorMessage)); | ||||
| } | } | ||||
| export function* deleteSingleCandidate({ payload }) { | export function* deleteSingleCandidate({ payload }) { | ||||
| console.log(payload) | |||||
| try { | try { | ||||
| yield call(deleteCandidate, payload.id); | yield call(deleteCandidate, payload.id); | ||||
| yield call(history.replace, CANDIDATES_PAGE); | |||||
| if(payload.handleApiResponseSuccess){ | |||||
| yield call(payload.handleApiResponseSuccess) | |||||
| } | |||||
| yield put(deleteCandidateSuccess()); | yield put(deleteCandidateSuccess()); | ||||
| } catch (error) { | } catch (error) { | ||||
| const errorMessage = yield call(rejectErrorCodeHelper, error); | const errorMessage = yield call(rejectErrorCodeHelper, error); |