| @@ -12,7 +12,8 @@ import { | |||
| BASE_PAGE, | |||
| RESET_PASSWORD_PAGE, | |||
| USERS_PAGE, | |||
| CANDIDATES_PAGE | |||
| CANDIDATES_PAGE, | |||
| SELECTION_PROCESS_PAGE | |||
| } from "./constants/pages"; | |||
| // import LoginPage from './pages/LoginPage/LoginPage'; | |||
| @@ -30,6 +31,7 @@ import ResetPasswordPage from "./pages/ForgotPasswordPage/ResetPasswordPageMUI"; | |||
| import UsersPage from "./pages/UsersPage/UsersPage"; | |||
| import CandidatesPage from './pages/CandidatesPage/CandidatesPage' | |||
| import AdDetailsPage from "./pages/AdsPage/AdDetailsPage"; | |||
| import SelectionProcessPage from "./pages/SelectionProcessPage/SelectionProcessPage"; | |||
| const AppRoutes = () => ( | |||
| <Switch> | |||
| @@ -48,6 +50,7 @@ const AppRoutes = () => ( | |||
| <PrivateRoute exact path={AD_DETAILS_PAGE} component={AdDetailsPage} /> | |||
| <PrivateRoute exact path={USERS_PAGE} component={UsersPage} /> | |||
| <PrivateRoute exact path={CANDIDATES_PAGE} component={CandidatesPage} /> | |||
| <PrivateRoute exact path={SELECTION_PROCESS_PAGE} component={SelectionProcessPage} /> | |||
| <Redirect from="*" to={NOT_FOUND_PAGE} /> | |||
| </Switch> | |||
| ); | |||
| @@ -0,0 +1,372 @@ | |||
| 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; | |||
| } | |||
| @@ -0,0 +1,69 @@ | |||
| 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; | |||
| @@ -8,4 +8,5 @@ export const NOT_FOUND_PAGE = '/not-found'; | |||
| export const USERS_PAGE = '/users'; | |||
| export const CANDIDATES_PAGE = '/candidates'; | |||
| 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'; | |||
| @@ -118,5 +118,8 @@ nav:{ | |||
| ads: { | |||
| activeAds: "Aktivni Oglasi", | |||
| archiveAds: "Arhiva" | |||
| }, | |||
| selection:{ | |||
| title: "Tok Selekcije" | |||
| } | |||
| }; | |||
| @@ -16,6 +16,7 @@ | |||
| @import './assets/styles/components/user-profile'; | |||
| @import './assets/styles/components/auth'; | |||
| @import './assets/styles/components/login'; | |||
| @import './assets/styles/components/selectionProcessPage'; | |||
| @import './assets/styles/components/login-card'; | |||
| @import './assets/styles/components/forgot-password'; | |||
| @import './assets/styles/components/input'; | |||
| @@ -0,0 +1,161 @@ | |||
| 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; | |||