| BASE_PAGE, | BASE_PAGE, | ||||
| RESET_PASSWORD_PAGE, | RESET_PASSWORD_PAGE, | ||||
| USERS_PAGE, | USERS_PAGE, | ||||
| CANDIDATES_PAGE | |||||
| CANDIDATES_PAGE, | |||||
| SELECTION_PROCESS_PAGE | |||||
| } from "./constants/pages"; | } from "./constants/pages"; | ||||
| // import LoginPage from './pages/LoginPage/LoginPage'; | // import LoginPage from './pages/LoginPage/LoginPage'; | ||||
| import UsersPage from "./pages/UsersPage/UsersPage"; | import UsersPage from "./pages/UsersPage/UsersPage"; | ||||
| import CandidatesPage from './pages/CandidatesPage/CandidatesPage' | import CandidatesPage from './pages/CandidatesPage/CandidatesPage' | ||||
| import AdDetailsPage from "./pages/AdsPage/AdDetailsPage"; | import AdDetailsPage from "./pages/AdsPage/AdDetailsPage"; | ||||
| import SelectionProcessPage from "./pages/SelectionProcessPage/SelectionProcessPage"; | |||||
| const AppRoutes = () => ( | const AppRoutes = () => ( | ||||
| <Switch> | <Switch> | ||||
| <PrivateRoute exact path={AD_DETAILS_PAGE} component={AdDetailsPage} /> | <PrivateRoute exact path={AD_DETAILS_PAGE} component={AdDetailsPage} /> | ||||
| <PrivateRoute exact path={USERS_PAGE} component={UsersPage} /> | <PrivateRoute exact path={USERS_PAGE} component={UsersPage} /> | ||||
| <PrivateRoute exact path={CANDIDATES_PAGE} component={CandidatesPage} /> | <PrivateRoute exact path={CANDIDATES_PAGE} component={CandidatesPage} /> | ||||
| <PrivateRoute exact path={SELECTION_PROCESS_PAGE} component={SelectionProcessPage} /> | |||||
| <Redirect from="*" to={NOT_FOUND_PAGE} /> | <Redirect from="*" to={NOT_FOUND_PAGE} /> | ||||
| </Switch> | </Switch> | ||||
| ); | ); |
| h1, | |||||
| h3 { | |||||
| margin: 0; | |||||
| padding: 0; | |||||
| } | |||||
| .ads { | |||||
| margin-top: 36px; | |||||
| padding-left: 3rem; | |||||
| } | |||||
| .active-ads-header { | |||||
| padding-left: 81px; | |||||
| display: flex; | |||||
| justify-content: space-between; | |||||
| align-items: center; | |||||
| } | |||||
| .activee{ | |||||
| /* Blue 4 */ | |||||
| background : #E8F7FF; | |||||
| border : 1px solid #226CB0; | |||||
| } | |||||
| .active-ads | |||||
| { | |||||
| overflow-x: scroll; | |||||
| padding-bottom: 100px; | |||||
| } | |||||
| .active-ads-subheader { | |||||
| font-family: 'Source Sans Pro'; | |||||
| font-style: normal; | |||||
| font-weight: 600; | |||||
| font-size: 24px; | |||||
| line-height: 36px; | |||||
| padding-left: 0.3rem; | |||||
| /* identical to box height, or 100% */ | |||||
| color:#226CB0; | |||||
| letter-spacing: 0.02em; | |||||
| } | |||||
| .active-ads-subheader-spliter { | |||||
| font-family: 'Source Sans Pro'; | |||||
| font-style: normal; | |||||
| font-weight: 600; | |||||
| font-size: 24px; | |||||
| line-height: 36px; | |||||
| padding-left: 0.3rem; | |||||
| /* identical to box height, or 100% */ | |||||
| color:#272727; | |||||
| letter-spacing: 0.02em; | |||||
| } | |||||
| .filter-vector { | |||||
| margin-left: 0.5rem !important; | |||||
| } | |||||
| .active-ads-ads { | |||||
| display: flex; | |||||
| margin-top: 39px; | |||||
| position: relative; | |||||
| } | |||||
| .active-ads-ads-ad { | |||||
| padding-left: 81px; | |||||
| display: flex; | |||||
| } | |||||
| .selection-card { | |||||
| display: flex; | |||||
| flex-direction: column; | |||||
| justify-content: start; | |||||
| align-items: left; | |||||
| // width: 550px; | |||||
| height: fit-content; | |||||
| padding: 36px; | |||||
| background: #F4F4F4; | |||||
| border: 1px solid #e4e4e4; | |||||
| border-radius: 18px; | |||||
| gap: 18px; | |||||
| margin-right: 36px; | |||||
| } | |||||
| .bg-danger{ | |||||
| background-color: #272727; | |||||
| } | |||||
| .selection-item { | |||||
| display: flex; | |||||
| flex-direction: row; | |||||
| justify-content: left; | |||||
| vertical-align: top; | |||||
| align-items: left; | |||||
| width: 400px; | |||||
| // height: 400px; | |||||
| padding: 18px 36px; | |||||
| background: #FFFFFF; | |||||
| border: 1px solid #e4e4e4; | |||||
| border-radius: 18px; | |||||
| gap: 18px; | |||||
| margin-right: 36px; | |||||
| } | |||||
| .selection-item-date p { | |||||
| text-align: right; | |||||
| font-family: "Source Sans Pro"; | |||||
| font-style: normal; | |||||
| font-weight: 400; | |||||
| font-size: 16px; | |||||
| line-height: 15px; | |||||
| color: #272727; | |||||
| flex: none; | |||||
| order: 4; | |||||
| flex-grow: 0; | |||||
| } | |||||
| .selection-card-title h3 { | |||||
| font-family: "Source Sans Pro"; | |||||
| font-style: normal; | |||||
| font-weight: 600; | |||||
| font-size: 32px; | |||||
| line-height: 32px; | |||||
| letter-spacing: 0.02em; | |||||
| color: #272727; | |||||
| flex: none; | |||||
| order: 0; | |||||
| flex-grow: 0; | |||||
| } | |||||
| .ad-card-logo img { | |||||
| width: 61px; | |||||
| height: 49px; | |||||
| flex: none; | |||||
| order: 2; | |||||
| flex-grow: 0; | |||||
| } | |||||
| .selection-item-name, .selection-item-date{ | |||||
| margin: auto 0 !important; | |||||
| } | |||||
| .selection-item-name p { | |||||
| height: 20px; | |||||
| font-family: 'Source Sans Pro'; | |||||
| font-style: normal; | |||||
| font-weight: 600; | |||||
| font-size: 16px; | |||||
| line-height: 20px; | |||||
| text-align: right; | |||||
| color: #226CB0; | |||||
| flex: none; | |||||
| order: 2; | |||||
| flex-grow: 0; | |||||
| } | |||||
| .ad-card-buttons { | |||||
| display: flex; | |||||
| flex-direction: row; | |||||
| align-items: flex-start; | |||||
| justify-content: center; | |||||
| padding: 0px; | |||||
| gap: 18px; | |||||
| width: 281px; | |||||
| height: 38px; | |||||
| flex: none; | |||||
| order: 0; | |||||
| flex-grow: 0; | |||||
| } | |||||
| .selection-item-buttons button { | |||||
| box-sizing: border-box; | |||||
| display: flex; | |||||
| flex-direction: row; | |||||
| justify-content: center; | |||||
| font-size: 16px; | |||||
| align-items: center; | |||||
| padding: 9px; | |||||
| gap: 10px; | |||||
| min-width: 76px; | |||||
| height: 38px; | |||||
| border: 1px solid #e4e4e4; | |||||
| border-radius: 9px; | |||||
| flex: none; | |||||
| order: 0; | |||||
| flex-grow: 0; | |||||
| } | |||||
| .add-ad { | |||||
| margin-top: 49px; | |||||
| display: flex; | |||||
| justify-content: flex-end; | |||||
| align-items: center; | |||||
| padding-right: 5rem !important; | |||||
| padding-bottom: 49px; | |||||
| } | |||||
| .add-ad-btn { | |||||
| display: flex; | |||||
| flex-direction: row; | |||||
| justify-content: center; | |||||
| align-items: center; | |||||
| padding: 18px 72px; | |||||
| gap: 10px; | |||||
| width: 201px; | |||||
| height: 51px; | |||||
| background: #226cb0; | |||||
| border-radius: 9px; | |||||
| } | |||||
| .ad-filters-header-container { | |||||
| display: flex; | |||||
| justify-content: space-between; | |||||
| } | |||||
| .ad-filters-header { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| } | |||||
| .ad-filters-header-close { | |||||
| cursor: pointer; | |||||
| } | |||||
| .ad-filters-header > * { | |||||
| margin-right: 0.25rem; | |||||
| } | |||||
| .ad-filters-header img { | |||||
| width: 18px; | |||||
| height: 15.75px; | |||||
| } | |||||
| .ad-filters-header sub { | |||||
| color: #226cb0; | |||||
| } | |||||
| .ad-filters-sub-title { | |||||
| font-family: "Source Sans Pro"; | |||||
| font-style: normal; | |||||
| font-weight: 600; | |||||
| font-size: 16px; | |||||
| line-height: 20px; | |||||
| color: #272727; | |||||
| } | |||||
| .ad-filters-experience { | |||||
| margin-top: 18px; | |||||
| box-sizing: border-box; | |||||
| } | |||||
| .ad-filters-experience-slider { | |||||
| margin-top: 5px; | |||||
| } | |||||
| .ad-filters-technologies { | |||||
| margin-top: 18px; | |||||
| } | |||||
| .ad-filters-employment-type { | |||||
| display: flex; | |||||
| } | |||||
| .ad-filters-employment-type > button { | |||||
| margin-right: 0.5rem; | |||||
| margin-top: 18px; | |||||
| } | |||||
| .ad-filters-search { | |||||
| margin-top: 18px; | |||||
| padding-bottom: 18px; | |||||
| } | |||||
| .ad-filters-search > * { | |||||
| width: 100%; | |||||
| } | |||||
| .sel-item{ | |||||
| display: flex; | |||||
| flex-direction: row; | |||||
| justify-content: space-between; | |||||
| align-items: center; | |||||
| padding: 18px 36px; | |||||
| gap: 18px; | |||||
| width: 458px; | |||||
| /* White */ | |||||
| background: #FFFFFF; | |||||
| /* Gray E4 */ | |||||
| border: 1px solid #E4E4E4; | |||||
| border-radius: 18px; | |||||
| } | |||||
| .sel-item .p{ | |||||
| /* Paragraph */ | |||||
| font-family: 'Source Sans Pro'; | |||||
| font-style: normal; | |||||
| font-weight: 400; | |||||
| font-size: 16px; | |||||
| line-height: 20px; | |||||
| /* Main Black */ | |||||
| color: #272727; | |||||
| /* Inside auto layout */ | |||||
| flex: none; | |||||
| order: 0; | |||||
| flex-grow: 0; | |||||
| } | |||||
| .sel-item .date{ | |||||
| /* 22.07. | 14:10h */ | |||||
| /* Paragraph */ | |||||
| font-family: 'Source Sans Pro'; | |||||
| font-style: normal; | |||||
| font-weight: 400; | |||||
| font-size: 16px; | |||||
| line-height: 20px; | |||||
| /* Main Black */ | |||||
| color: #272727; | |||||
| } | |||||
| .sel-item .rig{ | |||||
| height: 20px; | |||||
| /* Bold Paragraph */ | |||||
| font-family: 'Source Sans Pro'; | |||||
| font-style: normal; | |||||
| font-weight: 600; | |||||
| font-size: 16px; | |||||
| line-height: 20px; | |||||
| text-align: right; | |||||
| /* Main Blue */ | |||||
| color: #226CB0; | |||||
| /* Inside auto layout */ | |||||
| flex: none; | |||||
| order: 1; | |||||
| flex-grow: 0; | |||||
| } | |||||
| .sel-item .p button { | |||||
| box-sizing: border-box; | |||||
| display: flex; | |||||
| flex-direction: row; | |||||
| justify-content: center; | |||||
| font-size: 16px; | |||||
| align-items: center; | |||||
| padding: 9px; | |||||
| gap: 10px; | |||||
| min-width: 76px; | |||||
| height: 38px; | |||||
| border: 1px solid #e4e4e4; | |||||
| border-radius: 9px; | |||||
| flex: none; | |||||
| order: 0; | |||||
| flex-grow: 0; | |||||
| } |
| import React from "react"; | |||||
| import PropTypes from "prop-types"; | |||||
| const dragStart = (e, applicant) => { | |||||
| // e.dataTransfer.setData("applicant", applicant.id); | |||||
| e.dataTransfer.setData("text/plain",JSON.stringify(applicant)); | |||||
| } | |||||
| const dragOver = (e) => { | |||||
| e.preventDefault(); | |||||
| } | |||||
| const dropItem = (e,selId) =>{ | |||||
| var data = e.dataTransfer.getData("text/plain"); | |||||
| const applicant = JSON.parse(data); | |||||
| if(applicant.currentSelection !== selId){ | |||||
| // SEND REQUEST TO BACKEND TO STORE NEW SELECTION | |||||
| console.log('jup') | |||||
| } | |||||
| } | |||||
| const Selection = (props) => { | |||||
| console.log(props.selection); | |||||
| const applicants = props.selection.applicants; | |||||
| const renderList = applicants.map((item, index) => { | |||||
| return <div draggable key={index} className="sel-item" onDragStart={e => dragStart(e,item)}> | |||||
| <div className="p"> | |||||
| <button>{item.status}</button> | |||||
| </div> | |||||
| <div className="date"> | |||||
| <p>{item.date}</p> | |||||
| </div> | |||||
| <div className="rig"> | |||||
| <p>{item.name}</p> | |||||
| </div> | |||||
| </div> | |||||
| } | |||||
| ); | |||||
| return ( | |||||
| <div dropppable="true" id={props.selection.id} className="selection-card" | |||||
| onDragOver={e => dragOver(e)} | |||||
| onDrop={e => dropItem(e,props.selection.id)} | |||||
| > | |||||
| <div className="selection-card-title"> | |||||
| <h3>{props.selection.name}</h3> | |||||
| </div> | |||||
| {renderList} | |||||
| </div> | |||||
| ); | |||||
| }; | |||||
| Selection.propTypes = { | |||||
| selection: PropTypes.shape({ | |||||
| id: PropTypes.number, | |||||
| name : PropTypes.string, | |||||
| applicants: PropTypes.arrayOf(PropTypes.shape({ | |||||
| id: PropTypes.number, | |||||
| name: PropTypes.string, | |||||
| date: PropTypes.string, | |||||
| status: PropTypes.string, | |||||
| currentSelection: PropTypes.number, | |||||
| map: PropTypes.func | |||||
| })) | |||||
| }), | |||||
| }; | |||||
| export default Selection; |
| export const USERS_PAGE = '/users'; | export const USERS_PAGE = '/users'; | ||||
| export const CANDIDATES_PAGE = '/candidates'; | export const CANDIDATES_PAGE = '/candidates'; | ||||
| export const FORGOT_PASSWORD_CONFIRMATION_PAGE = '/forgot-password-confirmation'; | export const FORGOT_PASSWORD_CONFIRMATION_PAGE = '/forgot-password-confirmation'; | ||||
| export const RESET_PASSWORD_PAGE = '/reset-password'; | |||||
| export const RESET_PASSWORD_PAGE = '/reset-password'; | |||||
| export const SELECTION_PROCESS_PAGE = '/selection-process'; |
| ads: { | ads: { | ||||
| activeAds: "Aktivni Oglasi", | activeAds: "Aktivni Oglasi", | ||||
| archiveAds: "Arhiva" | archiveAds: "Arhiva" | ||||
| }, | |||||
| selection:{ | |||||
| title: "Tok Selekcije" | |||||
| } | } | ||||
| }; | }; |
| @import './assets/styles/components/user-profile'; | @import './assets/styles/components/user-profile'; | ||||
| @import './assets/styles/components/auth'; | @import './assets/styles/components/auth'; | ||||
| @import './assets/styles/components/login'; | @import './assets/styles/components/login'; | ||||
| @import './assets/styles/components/selectionProcessPage'; | |||||
| @import './assets/styles/components/login-card'; | @import './assets/styles/components/login-card'; | ||||
| @import './assets/styles/components/forgot-password'; | @import './assets/styles/components/forgot-password'; | ||||
| @import './assets/styles/components/input'; | @import './assets/styles/components/input'; |
| import React, { useState } from "react"; | |||||
| import Selection from "../../components/Selection/Selection"; | |||||
| import IconButton from "../../components/IconButton/IconButton"; | |||||
| import filterVector from "../../assets/images/filter_vector.png"; | |||||
| import { useTranslation } from "react-i18next"; | |||||
| import AddAdModal from "../../components/Ads/AddAdModal"; | |||||
| import AdFilters from "../../components/Ads/AdFilters"; | |||||
| const SelectionProcessPage = () => { | |||||
| const [toggleFiltersDrawer, setToggleFiltersDrawer] = useState(false); | |||||
| const [toggleModal, setToggleModal] = useState(false); | |||||
| const { t } = useTranslation(); | |||||
| const handleToggleFiltersDrawer = () => { | |||||
| setToggleFiltersDrawer((oldState) => !oldState); | |||||
| }; | |||||
| const handleToggleModal = () => { | |||||
| setToggleModal((oldState) => !oldState); | |||||
| }; | |||||
| const selections = [ | |||||
| { | |||||
| id: 1, | |||||
| name: "HR interview", | |||||
| applicants: [ | |||||
| { | |||||
| id: 1, | |||||
| name: "Stefan Petrovic", | |||||
| status: "Zakazan", | |||||
| date: "01.01.2022 11:00", | |||||
| currentSelection: 1 | |||||
| }, | |||||
| { | |||||
| id: 2, | |||||
| name: "Stefan Petrovic", | |||||
| status: "Otkazan", | |||||
| date: "01.01.2022 11:00", | |||||
| currentSelection: 1 | |||||
| }, | |||||
| { | |||||
| id: 3, | |||||
| name: "Stefan Petrovic", | |||||
| status: "Ceka na zakazivanje", | |||||
| currentSelection: 1 | |||||
| }] | |||||
| }, | |||||
| { | |||||
| id: 2, | |||||
| name: "Screening test", | |||||
| applicants: [ | |||||
| { | |||||
| id: 1, | |||||
| name: "Stefan Petrovic", | |||||
| status: "Zakazan", | |||||
| date: "01.01.2022 11:00", | |||||
| currentSelection: 2 | |||||
| }, | |||||
| { | |||||
| id: 2, | |||||
| name: "Stefan Petrovic", | |||||
| status: "Otkazan", | |||||
| date: "01.01.2022 11:00", | |||||
| currentSelection: 2 | |||||
| }] | |||||
| }, | |||||
| { | |||||
| id: 3, | |||||
| name: "Technical interview", | |||||
| applicants: [ | |||||
| { | |||||
| id: 1, | |||||
| name: "Stefan Petrovic", | |||||
| status: "Zakazan", | |||||
| date: "01.01.2022 11:00", | |||||
| currentSelection: 3 | |||||
| }, | |||||
| { | |||||
| id: 2, | |||||
| name: "Stefan Petrovic", | |||||
| status: "Otkazan", | |||||
| date: "01.01.2022 11:00", | |||||
| currentSelection: 3 | |||||
| }, | |||||
| { | |||||
| id: 3, | |||||
| name: "Stefan Petrovic", | |||||
| status: "Ceka na zakazivanje", | |||||
| currentSelection: 3 | |||||
| }] | |||||
| }, | |||||
| { | |||||
| id: 4, | |||||
| name: "Final decision", | |||||
| applicants: [ | |||||
| { | |||||
| id: 1, | |||||
| name: "Stefan Petrovic", | |||||
| status: "Zakazan", | |||||
| date: "01.01.2022 11:00", | |||||
| currentSelection: 4 | |||||
| }, | |||||
| { | |||||
| id: 2, | |||||
| name: "Stefan Petrovic", | |||||
| status: "Otkazan", | |||||
| date: "01.01.2022 11:00", | |||||
| currentSelection: 4 | |||||
| }] | |||||
| } | |||||
| ] | |||||
| const renderList = selections.map((item, index) => { | |||||
| return <Selection selection={item} key={index}/> | |||||
| } | |||||
| ); | |||||
| return ( | |||||
| <> | |||||
| <div className="l-t-rectangle"></div> | |||||
| <div className="r-b-rectangle"></div> | |||||
| <AdFilters /> | |||||
| <AdFilters | |||||
| open={toggleFiltersDrawer} | |||||
| handleClose={handleToggleFiltersDrawer} | |||||
| /> | |||||
| <AddAdModal open={toggleModal} handleClose={handleToggleModal} /> | |||||
| <div className="ads"> | |||||
| <div className="active-ads"> | |||||
| <div className="active-ads-header"> | |||||
| <h1>{t("selection.title")} | |||||
| <span className="active-ads-subheader-spliter"> | |||||
| | | |||||
| </span> | |||||
| <span className="active-ads-subheader"> | |||||
| Svi kandidati | |||||
| </span> | |||||
| </h1> | |||||
| <IconButton | |||||
| sx={{ marginLeft: "15px" }} | |||||
| className="c-btn c-btn--primary-outlined" | |||||
| onClick={handleToggleFiltersDrawer} | |||||
| > | |||||
| Filteri{" "} | |||||
| <img src={filterVector} alt="filter" className="filter-vector" /> | |||||
| </IconButton> | |||||
| </div> | |||||
| <div className="active-ads-ads"> | |||||
| <div className="active-ads-ads-ad"> | |||||
| {renderList} | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </> | |||||
| ); | |||||
| }; | |||||
| export default SelectionProcessPage; |