| CANDIDATES_DETAILS_PAGE, | CANDIDATES_DETAILS_PAGE, | ||||
| SELECTION_PROCESS_PAGE, | SELECTION_PROCESS_PAGE, | ||||
| SELECTION_PROCESS_OF_APPLICANT_PAGE, | SELECTION_PROCESS_OF_APPLICANT_PAGE, | ||||
| PATTERNS_PAGE, | |||||
| PATTERN_DETAILS_PAGE, | |||||
| SCHEDULE_PAGE, | SCHEDULE_PAGE, | ||||
| STATS_PAGE | STATS_PAGE | ||||
| } from "./constants/pages"; | } from "./constants/pages"; | ||||
| import ForgotPasswordConfirmationPage from "./pages/ForgotPasswordPage/ForgotPasswordConfirmationPageMUI"; | import ForgotPasswordConfirmationPage from "./pages/ForgotPasswordPage/ForgotPasswordConfirmationPageMUI"; | ||||
| import ResetPasswordPage from "./pages/ForgotPasswordPage/ResetPasswordPageMUI"; | import ResetPasswordPage from "./pages/ForgotPasswordPage/ResetPasswordPageMUI"; | ||||
| 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 UserDetails from "./pages/UsersPage/UserDetails"; | import UserDetails from "./pages/UsersPage/UserDetails"; | ||||
| import CandidateDetailsPage from "./pages/CandidatesPage/CandidateDetailsPage"; | import CandidateDetailsPage from "./pages/CandidatesPage/CandidateDetailsPage"; | ||||
| import SelectionProcessPage from "./pages/SelectionProcessPage/SelectionProcessPage"; | import SelectionProcessPage from "./pages/SelectionProcessPage/SelectionProcessPage"; | ||||
| import SelectionProcessOfApplicantPage from "./pages/SelectionProcessPage/SelectionProcessOfApplicantPage"; | import SelectionProcessOfApplicantPage from "./pages/SelectionProcessPage/SelectionProcessOfApplicantPage"; | ||||
| import PatternsPage from "./pages/PatternsPage/PatternsPage"; | |||||
| import PatternDetailsPage from "./pages/PatternsPage/PatternDetailsPage"; | |||||
| import SchedulePage from "./pages/SchedulePage/SchedulePage"; | import SchedulePage from "./pages/SchedulePage/SchedulePage"; | ||||
| import StatsPage from "./pages/StatsPage/StatsPage"; | import StatsPage from "./pages/StatsPage/StatsPage"; | ||||
| <PrivateRoute exact path={USER_DETAILS_PAGE} component={UserDetails} /> | <PrivateRoute exact path={USER_DETAILS_PAGE} component={UserDetails} /> | ||||
| <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={CANDIDATES_DETAILS_PAGE} component={CandidateDetailsPage} /> | |||||
| <PrivateRoute exact path={SELECTION_PROCESS_PAGE} component={SelectionProcessPage} /> | |||||
| <PrivateRoute exact path={SELECTION_PROCESS_OF_APPLICANT_PAGE} component={SelectionProcessOfApplicantPage} /> | |||||
| <PrivateRoute | |||||
| exact | |||||
| path={CANDIDATES_DETAILS_PAGE} | |||||
| component={CandidateDetailsPage} | |||||
| /> | |||||
| <PrivateRoute | |||||
| exact | |||||
| path={SELECTION_PROCESS_PAGE} | |||||
| component={SelectionProcessPage} | |||||
| /> | |||||
| <PrivateRoute | |||||
| exact | |||||
| path={SELECTION_PROCESS_OF_APPLICANT_PAGE} | |||||
| component={SelectionProcessOfApplicantPage} | |||||
| /> | |||||
| <PrivateRoute | |||||
| exact | |||||
| path={PATTERN_DETAILS_PAGE} | |||||
| component={PatternDetailsPage} | |||||
| /> | |||||
| <PrivateRoute exact path={PATTERNS_PAGE} component={PatternsPage} /> | |||||
| <PrivateRoute exact path={SCHEDULE_PAGE} component={SchedulePage} /> | <PrivateRoute exact path={SCHEDULE_PAGE} component={SchedulePage} /> | ||||
| <PrivateRoute exact path={STATS_PAGE} component={StatsPage} /> | <PrivateRoute exact path={STATS_PAGE} component={StatsPage} /> | ||||
| <Redirect from="*" to={NOT_FOUND_PAGE} /> | <Redirect from="*" to={NOT_FOUND_PAGE} /> |
| .patterns { | |||||
| padding: 0 72px; | |||||
| @include media-below($bp-xl) { | |||||
| padding: 0 18px; | |||||
| } | |||||
| } | |||||
| .patterns-header { | |||||
| display: flex; | |||||
| justify-content: space-between; | |||||
| align-items: center; | |||||
| margin-top: 16px; | |||||
| padding-left: calc(144px - 72px); | |||||
| margin-bottom: 18px !important; | |||||
| @include media-below($bp-xl) { | |||||
| padding-left: 18px; | |||||
| } | |||||
| } | |||||
| .pattern-header-active-button { | |||||
| background-color: $mainBlueLight !important; | |||||
| } | |||||
| .patterns-header button { | |||||
| margin-left: 14px; | |||||
| } | |||||
| .patterns-cards { | |||||
| padding: 0 calc(138px - 72px) 0 calc(144px - 72px); | |||||
| display: flex; | |||||
| flex-wrap: wrap; | |||||
| width: 100% !important; | |||||
| margin-bottom: 18px !important; | |||||
| @include media-below($bp-xl) { | |||||
| padding: 0 18px !important; | |||||
| flex-direction: column !important; | |||||
| } | |||||
| } | |||||
| .pattern-card-parent { | |||||
| width: calc(100% / 3) !important; | |||||
| margin-bottom: 36px; | |||||
| padding-right: 36px; | |||||
| @include media-below($bp-xl) { | |||||
| width: 100% !important; | |||||
| padding: 0 !important; | |||||
| } | |||||
| } | |||||
| /* PATTERN CARD */ | |||||
| .pattern-card-with-icon { | |||||
| position: relative; | |||||
| } | |||||
| .pattern-card { | |||||
| position: relative; | |||||
| box-sizing: border-box; | |||||
| padding: 72px !important; | |||||
| display: flex; | |||||
| flex-direction: column; | |||||
| align-items: center; | |||||
| justify-content: center; | |||||
| gap: 18px; | |||||
| isolation: isolate; | |||||
| background: #ffffff; | |||||
| border: 1px solid #e4e4e4; | |||||
| border-radius: 18px; | |||||
| width: 100% !important; | |||||
| transition: 0.3s; | |||||
| cursor: pointer; | |||||
| } | |||||
| .pattern-card:hover { | |||||
| scale: 1.05; | |||||
| border-color: $mainBlue !important; | |||||
| background-color: $mainBlueLight !important; | |||||
| } | |||||
| .pattern-card-edit { | |||||
| position: absolute; | |||||
| top: 9px !important; | |||||
| right: 9px !important; | |||||
| border-radius: 50% !important; | |||||
| width: 40px !important; | |||||
| height: 40px !important; | |||||
| z-index: 100; | |||||
| } | |||||
| .pattern-card-date p { | |||||
| font-family: "Source Sans Pro"; | |||||
| font-style: normal; | |||||
| font-weight: 400; | |||||
| font-size: 12px; | |||||
| line-height: 15px; | |||||
| color: #272727; | |||||
| flex: none; | |||||
| order: 0; | |||||
| flex-grow: 0; | |||||
| z-index: 0; | |||||
| } | |||||
| .pattern-card-title p { | |||||
| font-family: "Source Sans Pro"; | |||||
| font-style: normal; | |||||
| font-weight: 600; | |||||
| font-size: 24px; | |||||
| line-height: 32px; | |||||
| letter-spacing: 0.02em; | |||||
| color: $mainBlue; | |||||
| flex: none; | |||||
| order: 1; | |||||
| flex-grow: 0; | |||||
| z-index: 1; | |||||
| } | |||||
| .pattern-card-selection-proccess { | |||||
| box-sizing: border-box; | |||||
| display: flex; | |||||
| flex-direction: row; | |||||
| justify-content: center; | |||||
| align-items: center; | |||||
| padding: 9px; | |||||
| gap: 10px; | |||||
| border: 1px solid #e4e4e4; | |||||
| border-radius: 9px; | |||||
| flex: none; | |||||
| order: 2; | |||||
| flex-grow: 0; | |||||
| z-index: 2; | |||||
| } | |||||
| .pattern-card-date, | |||||
| .pattern-card-title, | |||||
| .pattern-card-selection-proccess { | |||||
| display: flex !important; | |||||
| justify-content: center !important; | |||||
| } | |||||
| .patterns-button { | |||||
| padding-bottom: 18px; | |||||
| display: flex; | |||||
| justify-content: flex-end; | |||||
| } | |||||
| /* AD DETAILS */ | |||||
| .pattern-details { | |||||
| padding: 42px 36px 72px 36px !important; | |||||
| @include media-below($bp-xl) { | |||||
| margin-top: 9px; | |||||
| } | |||||
| } | |||||
| .pattern-details-header { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: flex-end; | |||||
| @include media-below($bp-xl) { | |||||
| font-family: "Source Sans Pro"; | |||||
| font-style: normal; | |||||
| font-weight: 400; | |||||
| font-size: 14px; | |||||
| justify-content: flex-start; | |||||
| } | |||||
| } | |||||
| .pattern-details-header p { | |||||
| font-family: "Source Sans Pro"; | |||||
| font-style: normal; | |||||
| font-weight: 400; | |||||
| font-size: 16px; | |||||
| line-height: 20px; | |||||
| text-align: right; | |||||
| } | |||||
| .pattern-details-header p span { | |||||
| color: #9d9d9d; | |||||
| } | |||||
| .pattern-details-card { | |||||
| margin: 41px auto 0 auto !important; | |||||
| padding: 0 405px !important; | |||||
| @include media-below($bp-xl) { | |||||
| margin: 9px auto 0 auto !important; | |||||
| padding: 0 !important; | |||||
| } | |||||
| } | |||||
| .pattern-details-card-title { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| margin-bottom: 7px; | |||||
| @include media-below($bp-xl) { | |||||
| margin-top: 9px; | |||||
| } | |||||
| } | |||||
| .pattern-details-card-title-title h1 { | |||||
| font-size: 36px; | |||||
| margin-right: 4px; | |||||
| @include media-below($bp-xl) { | |||||
| font-family: "Source Sans Pro"; | |||||
| font-style: normal; | |||||
| font-weight: 600; | |||||
| font-size: 18px; | |||||
| line-height: 32px; | |||||
| letter-spacing: 0.02em; | |||||
| } | |||||
| } | |||||
| .pattern-details-card-title-sub { | |||||
| font-size: 24px; | |||||
| color: $mainBlue; | |||||
| font-weight: 600; | |||||
| @include media-below($bp-xl) { | |||||
| font-family: "Source Sans Pro"; | |||||
| font-style: normal; | |||||
| font-weight: 600; | |||||
| font-size: 18px; | |||||
| line-height: 32px; | |||||
| letter-spacing: 0.02em; | |||||
| } | |||||
| } | |||||
| .pattern-details-card-sub-card { | |||||
| margin-bottom: 18px; | |||||
| } | |||||
| .pattern-details-card-sub-card-title { | |||||
| margin-bottom: 10px; | |||||
| } | |||||
| .pattern-details-card-screening-title p { | |||||
| font-family: "Source Sans Pro"; | |||||
| font-style: normal; | |||||
| font-weight: 400; | |||||
| font-size: 16px; | |||||
| line-height: 20px; | |||||
| color: #272727; | |||||
| } | |||||
| .pattern-details-card-sub-card-emails { | |||||
| display: flex; | |||||
| flex-wrap: wrap; | |||||
| } | |||||
| .pattern-details-card-sub-card-emails > div { | |||||
| margin-right: 9px; | |||||
| margin-bottom: 4px; | |||||
| } | |||||
| .pattern-details-card-sub-card-emails-email { | |||||
| display: flex; | |||||
| flex-direction: row; | |||||
| justify-content: center; | |||||
| align-items: center; | |||||
| padding: 9px; | |||||
| gap: 10px; | |||||
| background: #ffffff; | |||||
| border: 1px solid #e4e4e4; | |||||
| border-radius: 9px; | |||||
| flex: none; | |||||
| order: 0; | |||||
| flex-grow: 0; | |||||
| } | |||||
| .pattern-details-card-sub-card-add-email { | |||||
| display: flex; | |||||
| } | |||||
| .pattern-details-card-sub-card-add-email input { | |||||
| margin-right: 18px; | |||||
| flex: 50; | |||||
| box-sizing: border-box; | |||||
| display: flex; | |||||
| flex-direction: row; | |||||
| align-items: center; | |||||
| padding: 18px; | |||||
| gap: 10px; | |||||
| background: #ffffff; | |||||
| border: 1px solid #e4e4e4; | |||||
| border-radius: 7px; | |||||
| outline: none; | |||||
| } | |||||
| .pattern-details-card-sub-card-add-email button { | |||||
| box-sizing: border-box; | |||||
| display: flex; | |||||
| flex-direction: row; | |||||
| justify-content: center; | |||||
| align-items: center; | |||||
| padding: 18px; | |||||
| gap: 10px; | |||||
| background: #ffffff; | |||||
| border: 1px solid #226cb0; | |||||
| border-radius: 9px; | |||||
| flex: 1; | |||||
| cursor: pointer; | |||||
| transition: 0.3s; | |||||
| } | |||||
| .pattern-details-card-sub-card-add-email button:hover { | |||||
| background-color: $mainBlueLight; | |||||
| } | |||||
| .pattern-details-card-sub-card-add-email button img { | |||||
| width: 12px; | |||||
| height: 12px; | |||||
| } | |||||
| .pattern-details-card-sub-card-message-pattern textarea { | |||||
| resize: none; | |||||
| width: 100%; | |||||
| box-sizing: border-box; | |||||
| display: flex; | |||||
| flex-direction: row; | |||||
| align-items: flex-start; | |||||
| padding: 18px; | |||||
| gap: 10px; | |||||
| background: #f4f4f4; | |||||
| border: 1px solid #e4e4e4; | |||||
| border-radius: 7px; | |||||
| min-height: 256px; | |||||
| } | |||||
| .pattern-details-card-buttons { | |||||
| display: flex; | |||||
| justify-content: flex-end; | |||||
| align-items: center; | |||||
| } | |||||
| .pattern-details-card-buttons > * { | |||||
| margin-left: 18px !important; | |||||
| } | |||||
| .custom-modal { | |||||
| padding: 36px !important; | |||||
| border: none !important; | |||||
| border-radius: 18px; | |||||
| } | |||||
| .add-pattern-modal { | |||||
| width: 512px; | |||||
| min-height: 618px; | |||||
| } | |||||
| .add-pattern-modal-header { | |||||
| display: flex; | |||||
| justify-content: space-between; | |||||
| align-items: center; | |||||
| margin-bottom: 18px; | |||||
| } | |||||
| .add-pattern-modal-header-title { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| } | |||||
| .add-pattern-modal-header-title > * { | |||||
| margin-right: 4px; | |||||
| } | |||||
| .add-pattern-modal-header-title-image img { | |||||
| width: 18px; | |||||
| height: 18px; | |||||
| } | |||||
| .add-pattern-modal-header-title-title p { | |||||
| font-family: "Source Sans Pro"; | |||||
| font-style: normal; | |||||
| font-weight: 600; | |||||
| font-size: 24px; | |||||
| line-height: 32px; | |||||
| letter-spacing: 0.02em; | |||||
| color: #272727; | |||||
| } | |||||
| .add-pattern-modal-header-title-sub sub { | |||||
| font-family: "Source Sans Pro"; | |||||
| font-style: normal; | |||||
| font-weight: 600; | |||||
| line-height: 32px; | |||||
| font-size: 18px; | |||||
| letter-spacing: 0.02em; | |||||
| color: $mainBlue; | |||||
| } | |||||
| .add-pattern-modal-header-close img { | |||||
| width: 9px; | |||||
| height: 10.5px; | |||||
| cursor: pointer; | |||||
| } | |||||
| .add-pattern-modal-form-control { | |||||
| display: flex; | |||||
| flex-direction: column; | |||||
| margin-bottom: 9px; | |||||
| } | |||||
| .add-pattern-modal-form-control label { | |||||
| font-family: "Source Sans Pro"; | |||||
| font-style: normal; | |||||
| font-weight: 400; | |||||
| font-size: 16px; | |||||
| line-height: 20px; | |||||
| color: #272727; | |||||
| margin-bottom: 4.5px; | |||||
| } | |||||
| .add-pattern-modal-form-control input, | |||||
| .add-pattern-modal-form-control select, | |||||
| .add-pattern-modal-form-control textarea { | |||||
| box-sizing: border-box; | |||||
| display: flex; | |||||
| flex-direction: row; | |||||
| align-items: center; | |||||
| padding: 18px; | |||||
| gap: 10px; | |||||
| border: 1px solid #e4e4e4; | |||||
| border-radius: 7px; | |||||
| outline: none; | |||||
| } | |||||
| .add-pattern-modal-form-control textarea { | |||||
| resize: none; | |||||
| } | |||||
| .add-pattern-modal-form-control input[type="submit"] { | |||||
| box-sizing: border-box; | |||||
| display: flex; | |||||
| flex-direction: row; | |||||
| justify-content: center; | |||||
| align-items: center; | |||||
| padding: 18px 72px; | |||||
| gap: 10px; | |||||
| background: #226cb0; | |||||
| color: white; | |||||
| border-radius: 9px; | |||||
| cursor: pointer; | |||||
| } | |||||
| .edit-pattern-modal { | |||||
| width: 512px; | |||||
| min-height: 618px; | |||||
| } | |||||
| .edit-pattern-modal-header { | |||||
| display: flex; | |||||
| justify-content: space-between; | |||||
| align-items: center; | |||||
| margin-bottom: 18px; | |||||
| } | |||||
| .edit-pattern-modal-header-title { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| } | |||||
| .edit-pattern-modal-header-title > * { | |||||
| margin-right: 4px; | |||||
| } | |||||
| .edit-pattern-modal-header-title-image img { | |||||
| width: 18px; | |||||
| height: 18px; | |||||
| } | |||||
| .edit-pattern-modal-header-title-title p { | |||||
| font-family: "Source Sans Pro"; | |||||
| font-style: normal; | |||||
| font-weight: 600; | |||||
| font-size: 24px; | |||||
| line-height: 32px; | |||||
| letter-spacing: 0.02em; | |||||
| color: #272727; | |||||
| } | |||||
| .edit-pattern-modal-header-title-sub sub { | |||||
| font-family: "Source Sans Pro"; | |||||
| font-style: normal; | |||||
| font-weight: 600; | |||||
| line-height: 32px; | |||||
| font-size: 18px; | |||||
| letter-spacing: 0.02em; | |||||
| color: $mainBlue; | |||||
| } | |||||
| .edit-pattern-modal-header-close img { | |||||
| width: 9px; | |||||
| height: 10.5px; | |||||
| cursor: pointer; | |||||
| } | |||||
| .edit-pattern-modal-form-control { | |||||
| display: flex; | |||||
| flex-direction: column; | |||||
| margin-bottom: 9px; | |||||
| } | |||||
| .edit-pattern-modal-form-control label { | |||||
| font-family: "Source Sans Pro"; | |||||
| font-style: normal; | |||||
| font-weight: 400; | |||||
| font-size: 16px; | |||||
| line-height: 20px; | |||||
| color: #272727; | |||||
| margin-bottom: 4.5px; | |||||
| } | |||||
| .edit-pattern-modal-form-control input, | |||||
| .edit-pattern-modal-form-control select, | |||||
| .edit-pattern-modal-form-control textarea { | |||||
| box-sizing: border-box; | |||||
| display: flex; | |||||
| flex-direction: row; | |||||
| align-items: center; | |||||
| padding: 18px; | |||||
| gap: 10px; | |||||
| border: 1px solid #e4e4e4; | |||||
| border-radius: 7px; | |||||
| outline: none; | |||||
| } | |||||
| .edit-pattern-modal-form-control textarea { | |||||
| resize: none; | |||||
| } | |||||
| .edit-pattern-modal-form-control input[type="submit"] { | |||||
| box-sizing: border-box; | |||||
| display: flex; | |||||
| flex-direction: row; | |||||
| justify-content: center; | |||||
| align-items: center; | |||||
| padding: 18px 72px; | |||||
| gap: 10px; | |||||
| background: #226cb0; | |||||
| color: white; | |||||
| border-radius: 9px; | |||||
| cursor: pointer; | |||||
| } | |||||
| /* CUSTOM-FILTER-DRAWER */ | |||||
| .custom-drawer { | |||||
| display: flex; | |||||
| height: 100% !important; | |||||
| flex-direction: column; | |||||
| justify-content: space-between; | |||||
| } | |||||
| .custom-filter-drawer-header-container { | |||||
| display: flex; | |||||
| justify-content: space-between; | |||||
| } | |||||
| .custom-filter-drawer-header { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| } | |||||
| .custom-filter-drawer-header-close { | |||||
| cursor: pointer; | |||||
| } | |||||
| .custom-filter-drawer-header > * { | |||||
| margin-right: 0.25rem; | |||||
| } | |||||
| .custom-filter-drawer-header img { | |||||
| width: 18px; | |||||
| height: 15.75px; | |||||
| } | |||||
| .custom-filter-drawer-header sub { | |||||
| color: #226cb0; | |||||
| } | |||||
| .custom-filter-drawer-content { | |||||
| margin-top: 18px !important; | |||||
| box-sizing: border-box; | |||||
| } | |||||
| .custom-drawer-sub-card { | |||||
| margin-bottom: 18px; | |||||
| } | |||||
| .custom-drawer-sub-card-label { | |||||
| margin-bottom: 10px; | |||||
| } | |||||
| .custom-drawer-sub-card-label p { | |||||
| font-family: "Source Sans Pro"; | |||||
| font-style: normal; | |||||
| font-weight: 600; | |||||
| font-size: 16px; | |||||
| line-height: 20px; | |||||
| color: #272727; | |||||
| } | |||||
| .custom-drawer-sub-card-content-sub-label { | |||||
| font-family: "Source Sans Pro"; | |||||
| font-style: normal; | |||||
| font-weight: 400; | |||||
| font-size: 16px; | |||||
| line-height: 20px; | |||||
| color: #272727; | |||||
| margin-bottom: 4.5px; | |||||
| } | |||||
| .custom-drawer-sub-card-content input[type="date"] { | |||||
| box-sizing: border-box; | |||||
| display: flex; | |||||
| flex-direction: row; | |||||
| justify-content: space-between; | |||||
| align-items: center; | |||||
| padding: 18px; | |||||
| gap: 10px; | |||||
| border: 1px solid #e4e4e4; | |||||
| border-radius: 9px; | |||||
| } | |||||
| .custom-drawer-submit { | |||||
| margin-top: 18px; | |||||
| padding-bottom: 18px; | |||||
| } | |||||
| .custom-drawer-submit > * { | |||||
| width: 100%; | |||||
| } |
| let btnRef = useRef(); | let btnRef = useRef(); | ||||
| // get authenticated user | // get authenticated user | ||||
| const {user} = useSelector(s => s.user); | |||||
| const { user } = useSelector((s) => s.user); | |||||
| const { t } = useTranslation(); | const { t } = useTranslation(); | ||||
| display: "flex", | display: "flex", | ||||
| justifyContent: "center", | justifyContent: "center", | ||||
| alignItems: "center", | alignItems: "center", | ||||
| width: matches ? '100%' : 'auto' | |||||
| width: matches ? "100%" : "auto", | |||||
| }} | }} | ||||
| > | > | ||||
| {matches ? ( | {matches ? ( | ||||
| <Box | |||||
| <Box | |||||
| className="responsive-nav-cont" | className="responsive-nav-cont" | ||||
| style={{ | style={{ | ||||
| display: "flex", | display: "flex", | ||||
| <img | <img | ||||
| style={{ height: "37px", width: "37px", marginLeft: "0px" }} | style={{ height: "37px", width: "37px", marginLeft: "0px" }} | ||||
| src={HrLogo} | src={HrLogo} | ||||
| className='responsive-logo' | |||||
| className="responsive-logo" | |||||
| /> | /> | ||||
| <div | <div | ||||
| style={{ | style={{ | ||||
| display: "flex", | display: "flex", | ||||
| alignItems: "center", | alignItems: "center", | ||||
| }} | }} | ||||
| className='icons-cont' | |||||
| className="icons-cont" | |||||
| > | > | ||||
| <img src={searchIcon} /> | <img src={searchIcon} /> | ||||
| <IconButton | <IconButton | ||||
| padding: "0", | padding: "0", | ||||
| textDecoration: "none", | textDecoration: "none", | ||||
| }} | }} | ||||
| className={pathname === `/${n}` ? 'text-blue' : 'text-black'} | |||||
| className={pathname === `/${n}` ? "text-blue" : "text-black"} | |||||
| as={Link} | as={Link} | ||||
| to={`/${n}`} | to={`/${n}`} | ||||
| > | > | ||||
| ); | ); | ||||
| }; | }; | ||||
| export default NavbarComponent; | |||||
| export default NavbarComponent; |
| import React from "react"; | |||||
| import PropTypes from "prop-types"; | |||||
| import editIcon from "../../assets/images/edit.png"; | |||||
| import { IconButton } from "@mui/material"; | |||||
| const PatternCard = ({ | |||||
| createdAt, | |||||
| title, | |||||
| selectionProcess, | |||||
| isShownEdit, | |||||
| onShowPatternDetails, | |||||
| onOpenEditModal, | |||||
| }) => { | |||||
| return ( | |||||
| <div className="pattern-card-with-icon"> | |||||
| {isShownEdit && ( | |||||
| <div className="pattern-card-edit"> | |||||
| <IconButton | |||||
| onClick={onOpenEditModal} | |||||
| className={`c-btn--primary-outlined c-btn pattern-card-edit`} | |||||
| > | |||||
| <img | |||||
| style={{ width: "16px !important", height: "16px !important" }} | |||||
| src={editIcon} | |||||
| /> | |||||
| </IconButton> | |||||
| </div> | |||||
| )} | |||||
| <div className="pattern-card" onClick={onShowPatternDetails}> | |||||
| <div className="pattern-card-date"> | |||||
| <p>{new Date(createdAt).toLocaleDateString()}</p> | |||||
| </div> | |||||
| <div className="pattern-card-title"> | |||||
| <p>{title}</p> | |||||
| </div> | |||||
| <div className="pattern-card-selection-proccess"> | |||||
| <p>{selectionProcess}</p> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| ); | |||||
| }; | |||||
| PatternCard.propTypes = { | |||||
| createdAt: PropTypes.any, | |||||
| title: PropTypes.string, | |||||
| selectionProcess: PropTypes.string, | |||||
| isShownEdit: PropTypes.bool, | |||||
| onShowPatternDetails: PropTypes.func, | |||||
| onOpenEditModal: PropTypes.func, | |||||
| }; | |||||
| export default PatternCard; |
| import React from "react"; | |||||
| import PropType from "prop-types"; | |||||
| import Box from "@mui/material/Box"; | |||||
| import Drawer from "@mui/material/Drawer"; | |||||
| import filterIcon from "../../assets/images/filters.png"; | |||||
| import x from "../../assets/images/x.png"; | |||||
| const CustomDrawer = ({ title, open, onCloseDrawer, children }) => { | |||||
| const list = () => ( | |||||
| <Box | |||||
| sx={{ | |||||
| width: 360, | |||||
| height: "100%", | |||||
| borderRadius: "18px 0 0 18px", | |||||
| padding: "36px", | |||||
| }} | |||||
| role="presentation" | |||||
| onKeyDown={onCloseDrawer} | |||||
| > | |||||
| <div> | |||||
| <div className="custom-filter-drawer-header-container"> | |||||
| <div className="custom-filter-drawer-header"> | |||||
| <img src={filterIcon} alt="filter_icon" /> | |||||
| <h3>Filteri</h3> | |||||
| <p> | |||||
| <sub>| {title}</sub> | |||||
| </p> | |||||
| </div> | |||||
| <div | |||||
| className="custom-filter-drawer-header-close" | |||||
| onClick={onCloseDrawer} | |||||
| > | |||||
| <img src={x} alt="x" /> | |||||
| </div> | |||||
| </div> | |||||
| <div className="custom-filter-drawer-content">{children}</div> | |||||
| </div> | |||||
| </Box> | |||||
| ); | |||||
| return ( | |||||
| <div> | |||||
| <Drawer anchor="right" open={open} onClose={onCloseDrawer}> | |||||
| {list()} | |||||
| </Drawer> | |||||
| </div> | |||||
| ); | |||||
| }; | |||||
| CustomDrawer.propTypes = { | |||||
| title: PropType.string, | |||||
| open: PropType.bool, | |||||
| onCloseDrawer: PropType.func, | |||||
| children: PropType.any, | |||||
| }; | |||||
| export default CustomDrawer; |
| import * as React from "react"; | |||||
| import PropTypes from "prop-types"; | |||||
| import Box from "@mui/material/Box"; | |||||
| import Modal from "@mui/material/Modal"; | |||||
| const style = { | |||||
| position: "absolute", | |||||
| top: "50%", | |||||
| left: "50%", | |||||
| transform: "translate(-50%, -50%)", | |||||
| width: 400, | |||||
| bgcolor: "background.paper", | |||||
| border: "2px solid #000", | |||||
| boxShadow: 24, | |||||
| p: 4, | |||||
| }; | |||||
| const CustomModal = ({ open, onCloseModal, children, classes }) => { | |||||
| const handleClose = () => onCloseModal(); | |||||
| return ( | |||||
| <Modal | |||||
| open={open} | |||||
| onClose={handleClose} | |||||
| aria-labelledby="modal-modal-title" | |||||
| aria-describedby="modal-modal-description" | |||||
| > | |||||
| <Box sx={style} className={`custom-modal ${classes}`}> | |||||
| {children} | |||||
| </Box> | |||||
| </Modal> | |||||
| ); | |||||
| }; | |||||
| CustomModal.propTypes = { | |||||
| open: PropTypes.bool, | |||||
| onCloseModal: PropTypes.func, | |||||
| children: PropTypes.any, | |||||
| classes: PropTypes.string, | |||||
| }; | |||||
| export default CustomModal; |
| export const RESET_PASSWORD_PAGE = '/reset-password'; | export const RESET_PASSWORD_PAGE = '/reset-password'; | ||||
| export const SELECTION_PROCESS_PAGE = '/selectionFlow'; | export const SELECTION_PROCESS_PAGE = '/selectionFlow'; | ||||
| export const SELECTION_PROCESS_OF_APPLICANT_PAGE = '/selectionflow/:id'; | export const SELECTION_PROCESS_OF_APPLICANT_PAGE = '/selectionflow/:id'; | ||||
| export const PATTERNS_PAGE = '/patterns'; | |||||
| export const PATTERN_DETAILS_PAGE = '/patterns/:id'; | |||||
| export const SCHEDULE_PAGE = '/schedule' | export const SCHEDULE_PAGE = '/schedule' | ||||
| export const STATS_PAGE = '/statistics'; | export const STATS_PAGE = '/statistics'; |
| @import './assets/styles/layout'; | @import './assets/styles/layout'; | ||||
| @import './assets/styles/overwrite'; | @import './assets/styles/overwrite'; | ||||
| @import './assets/styles/utility'; | @import './assets/styles/utility'; | ||||
| @import './assets/styles/components/patterns'; | |||||
| .flex-center{ | .flex-center{ |
| import AddAdModal from "../../components/Ads/AddAdModal"; | import AddAdModal from "../../components/Ads/AddAdModal"; | ||||
| import AdFilters from "../../components/Ads/AdFilters"; | import AdFilters from "../../components/Ads/AdFilters"; | ||||
| import { useDispatch } from "react-redux"; | import { useDispatch } from "react-redux"; | ||||
| import { setAdsReq, setFilteredAdsReq } from "../../store/actions/ads/adsAction"; | |||||
| import { | |||||
| setAdsReq, | |||||
| setFilteredAdsReq, | |||||
| } from "../../store/actions/ads/adsAction"; | |||||
| import { useSelector } from "react-redux"; | import { useSelector } from "react-redux"; | ||||
| import { selectAds } from "../../store/selectors/adsSelectors"; | import { selectAds } from "../../store/selectors/adsSelectors"; | ||||
| import { AD_DETAILS_PAGE } from "../../constants/pages"; | import { AD_DETAILS_PAGE } from "../../constants/pages"; | ||||
| useEffect(() => { | useEffect(() => { | ||||
| if (search) { | if (search) { | ||||
| // history.push("/ads"); | // history.push("/ads"); | ||||
| const searchParams = search.split('?')[1] | |||||
| const technologyParams = searchParams.split('&').filter(x => x.includes('technologies')) | |||||
| const technologies = [] | |||||
| technologyParams.forEach(p => { | |||||
| const tech = p.split('=') | |||||
| technologies.push(tech[1]) | |||||
| const searchParams = search.split("?")[1]; | |||||
| const technologyParams = searchParams | |||||
| .split("&") | |||||
| .filter((x) => x.includes("technologies")); | |||||
| const technologies = []; | |||||
| technologyParams.forEach((p) => { | |||||
| const tech = p.split("="); | |||||
| technologies.push(tech[1]); | |||||
| }); | }); | ||||
| const params = new URLSearchParams(search); | const params = new URLSearchParams(search); | ||||
| dispatch( | dispatch( | ||||
| setFilteredAdsReq({ | setFilteredAdsReq({ | ||||
| minExperience: params.get('minExperience'), | |||||
| maxExperience: params.get('maxExperience'), | |||||
| minExperience: params.get("minExperience"), | |||||
| maxExperience: params.get("maxExperience"), | |||||
| technologies, | technologies, | ||||
| workHour: params.get('workHour'), | |||||
| employmentType: params.get('employmentType'), | |||||
| workHour: params.get("workHour"), | |||||
| employmentType: params.get("employmentType"), | |||||
| }) | }) | ||||
| ); | ); | ||||
| } else { | } else { | ||||
| dispatch(setAdsReq()); | dispatch(setAdsReq()); | ||||
| } | } | ||||
| }, []) | |||||
| }, []); | |||||
| const handleToggleFiltersDrawer = () => { | const handleToggleFiltersDrawer = () => { | ||||
| setToggleFiltersDrawer((oldState) => !oldState); | setToggleFiltersDrawer((oldState) => !oldState); |
| import React, { useEffect, useState } from "react"; | |||||
| import { IconButton } from "@mui/material"; | |||||
| import { Link } from "react-router-dom"; | |||||
| import plusIcon from "../../assets/images/plus.png"; | |||||
| import sendMessage from "../../assets/images/send_message.png"; | |||||
| import { useParams } from "react-router-dom"; | |||||
| import { useDispatch, useSelector } from "react-redux"; | |||||
| import { setPatternReq } from "../../store/actions/pattern/patternActions"; | |||||
| import { selectPattern } from "../../store/selectors/patternSelectors"; | |||||
| const PatternDetailsPage = () => { | |||||
| const [emails, setEmails] = useState([]); | |||||
| const [email, setEmail] = useState(""); | |||||
| const pattern = useSelector(selectPattern); | |||||
| const { id } = useParams(); | |||||
| const dispatch = useDispatch(); | |||||
| const regex = /^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$/ | |||||
| useEffect(() => { | |||||
| dispatch(setPatternReq({ id })); | |||||
| }, []); | |||||
| const addNewEmailHandler = () => { | |||||
| setEmails((oldState) => [...oldState, email]); | |||||
| setEmail(""); | |||||
| }; | |||||
| return ( | |||||
| <> | |||||
| {!pattern && ( | |||||
| <div> | |||||
| <p>Loading...</p> | |||||
| </div> | |||||
| )} | |||||
| {pattern && ( | |||||
| <div className="pattern-details"> | |||||
| <div className="pattern-details-header"> | |||||
| <p> | |||||
| <span>Napravljen:</span>{" "} | |||||
| {new Date(pattern.createdAt).toLocaleDateString()} | |||||
| </p> | |||||
| </div> | |||||
| <div className="pattern-details-card"> | |||||
| <div className="pattern-details-card-title"> | |||||
| <div className="pattern-details-card-title-title"> | |||||
| <h1>Šablon</h1> | |||||
| </div> | |||||
| <div className="pattern-details-card-title-sub"> | |||||
| <sub> | Zakazivanje termina</sub> | |||||
| </div> | |||||
| </div> | |||||
| <div className="pattern-details-card-sub-card"> | |||||
| <div className="pattern-details-card-sub-card-title"> | |||||
| <p>Screening test</p> | |||||
| </div> | |||||
| <div className="pattern-details-card-sub-card-emails"> | |||||
| {emails && | |||||
| emails.map((email, index) => ( | |||||
| <div | |||||
| key={index} | |||||
| className="pattern-details-card-sub-card-emails-email" | |||||
| > | |||||
| {email} | |||||
| </div> | |||||
| ))} | |||||
| </div> | |||||
| </div> | |||||
| <div className="pattern-details-card-sub-card"> | |||||
| <div className="pattern-details-card-sub-card-title"> | |||||
| <p>Screening test</p> | |||||
| </div> | |||||
| <div className="pattern-details-card-sub-card-add-email"> | |||||
| <input | |||||
| type="text" | |||||
| onChange={(e) => setEmail(e.target.value)} | |||||
| value={email} | |||||
| placeholder="ex. petar.petrovic@mail.com" | |||||
| /> | |||||
| <button | |||||
| onClick={addNewEmailHandler} | |||||
| disabled={!regex.test(email)} | |||||
| > | |||||
| <img src={plusIcon} alt="plus" /> | |||||
| </button> | |||||
| </div> | |||||
| </div> | |||||
| <div className="pattern-details-card-sub-card"> | |||||
| <div className="pattern-details-card-sub-card-title"> | |||||
| <p>Teskt poruke</p> | |||||
| </div> | |||||
| <div className="pattern-details-card-sub-card-message-pattern"> | |||||
| <textarea | |||||
| disabled | |||||
| // value={`Postovani, | |||||
| // Ovom prilikom Vas obavestavamo da je datum Screening testa zakazan za [selected Date] | |||||
| // Srdacan pozdrav, | |||||
| // Diligent HR Team`} | |||||
| value={pattern.message} | |||||
| ></textarea> | |||||
| </div> | |||||
| </div> | |||||
| <div className="pattern-details-card-buttons"> | |||||
| <Link className="ad-details-buttons-link" to="/patterns"> | |||||
| Nazad na sve šablone | |||||
| </Link> | |||||
| <IconButton className="c-btn c-btn--primary add-ad-btn"> | |||||
| <img | |||||
| style={{ | |||||
| marginRight: "5px", | |||||
| width: "12px", | |||||
| height: "12px", | |||||
| }} | |||||
| src={sendMessage} | |||||
| /> | |||||
| PORUKU | |||||
| </IconButton> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| )} | |||||
| </> | |||||
| ); | |||||
| }; | |||||
| export default PatternDetailsPage; |
| import React, { useState, useEffect } from "react"; | |||||
| import PropTypes from "prop-types"; | |||||
| import FilterButton from "../../components/Button/FilterButton"; | |||||
| import { useTheme } from "@mui/system"; | |||||
| import { | |||||
| Checkbox, | |||||
| FormControlLabel, | |||||
| FormGroup, | |||||
| IconButton, | |||||
| useMediaQuery, | |||||
| } from "@mui/material"; | |||||
| import userPageBtnIcon from "../../assets/images/userPageBtnIcon.png"; | |||||
| import PatternCard from "../../components/Patterns/PatternCard"; | |||||
| import { useDispatch, useSelector } from "react-redux"; | |||||
| import { setPatternsReq } from "../../store/actions/patterns/patternsActions"; | |||||
| import { selectPatterns } from "../../store/selectors/patternsSelectors"; | |||||
| import { selectProcesses } from "../../store/selectors/processesSelectors"; | |||||
| import { PATTERN_DETAILS_PAGE } from "../../constants/pages"; | |||||
| import CustomModal from "../../components/UI/CustomModal"; | |||||
| import plusIcon from "../../assets/images/plus.png"; | |||||
| import xIcon from "../../assets/images/x.png"; | |||||
| import { setProcessesReq } from "../../store/actions/processes/processesAction"; | |||||
| import { createPatternReq } from "../../store/actions/createPattern/createPatternActions"; | |||||
| import { updatePatternReq } from "../../store/actions/updatePattern/updatePatternActions"; | |||||
| import CustomDrawer from "../../components/UI/CustomDrawer"; | |||||
| const PatternsPage = ({ history }) => { | |||||
| const theme = useTheme(); | |||||
| const matches = useMediaQuery(theme.breakpoints.down("sm")); | |||||
| const [isShownEdit, setIsShownEdit] = useState(false); | |||||
| const [openFilterDrawer, setOpenFilterDrawer] = useState(false); | |||||
| const [openAddPatternModal, setOpenAddPatternModal] = useState(false); | |||||
| const [openEditPatternModal, setOpenEditPatternModal] = useState(false); | |||||
| const [editPattern, setEditPattern] = useState(null); | |||||
| const [addPatternTitle, setAddPatternTitle] = useState(""); | |||||
| const [addPatternCategory, setAddPatternCategory] = useState(1); | |||||
| const [addPatternMessage, setAddPatternMessage] = useState(""); | |||||
| const patterns = useSelector(selectPatterns); | |||||
| const processes = useSelector(selectProcesses); | |||||
| const dispatch = useDispatch(); | |||||
| useEffect(() => { | |||||
| dispatch(setPatternsReq()); | |||||
| dispatch(setProcessesReq()); | |||||
| }, []); | |||||
| useEffect(() => { | |||||
| if (processes.length > 0) { | |||||
| setAddPatternCategory(processes[0].id); | |||||
| } | |||||
| }, [processes]); | |||||
| const closeAddPatternModalHandler = () => { | |||||
| setOpenAddPatternModal(false); | |||||
| }; | |||||
| const openEditModalHandler = (pattern) => { | |||||
| setEditPattern({ | |||||
| id: pattern.id, | |||||
| title: pattern.title, | |||||
| createdAt: pattern.createdAt, | |||||
| selectionLevelId: pattern.selectionLevel.id, | |||||
| message: pattern.message, | |||||
| }); | |||||
| setOpenEditPatternModal(true); | |||||
| }; | |||||
| const closeEditPatternModalHandler = () => { | |||||
| setEditPattern(null); | |||||
| setOpenEditPatternModal(false); | |||||
| }; | |||||
| const closeFilterDrawerHandler = () => { | |||||
| setOpenFilterDrawer(false); | |||||
| }; | |||||
| const submitAddPatternHandler = (e) => { | |||||
| e.preventDefault(); | |||||
| if (addPatternTitle.length === 0 || addPatternMessage.length === 0) { | |||||
| return; | |||||
| } | |||||
| dispatch( | |||||
| createPatternReq({ | |||||
| title: addPatternTitle, | |||||
| selectionLevelId: addPatternCategory, | |||||
| message: addPatternMessage, | |||||
| }) | |||||
| ); | |||||
| setOpenAddPatternModal(false); | |||||
| setAddPatternTitle(""); | |||||
| setAddPatternCategory(processes[0].id); | |||||
| setAddPatternMessage(""); | |||||
| }; | |||||
| const submitEditPatternHandler = (e) => { | |||||
| e.preventDefault(); | |||||
| if (editPattern.title.length === 0 || editPattern.message.length === 0) { | |||||
| return; | |||||
| } | |||||
| dispatch(updatePatternReq(editPattern)); | |||||
| setOpenEditPatternModal(false); | |||||
| }; | |||||
| return ( | |||||
| <> | |||||
| <CustomDrawer | |||||
| title="Šabloni" | |||||
| open={openFilterDrawer} | |||||
| onCloseDrawer={closeFilterDrawerHandler} | |||||
| > | |||||
| <form> | |||||
| <div className="custom-drawer"> | |||||
| <div> | |||||
| <div className="custom-drawer-sub-card"> | |||||
| <div className="custom-drawer-sub-card-label"> | |||||
| <p>Kategorija</p> | |||||
| </div> | |||||
| <div className="custom-drawer-sub-card-content"> | |||||
| <FormGroup> | |||||
| {processes.map((process) => ( | |||||
| <FormControlLabel | |||||
| key={process.id} | |||||
| control={<Checkbox value={process.name} />} | |||||
| label={process.name} | |||||
| /> | |||||
| ))} | |||||
| </FormGroup> | |||||
| </div> | |||||
| </div> | |||||
| <div className="custom-drawer-sub-card"> | |||||
| <div className="custom-drawer-sub-card-label"> | |||||
| <p>Datum kreiranja</p> | |||||
| </div> | |||||
| <div className="custom-drawer-sub-card-content"> | |||||
| <FormGroup style={{ marginBottom: "9px" }}> | |||||
| <label className="custom-drawer-sub-card-content-sub-label"> | |||||
| Od | |||||
| </label> | |||||
| <input type="date" /> | |||||
| </FormGroup> | |||||
| <FormGroup> | |||||
| <label className="custom-drawer-sub-card-content-sub-label"> | |||||
| Do | |||||
| </label> | |||||
| <input type="date" /> | |||||
| </FormGroup> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div className="custom-drawer-submit"> | |||||
| <button className="c-btn c-btn--primary">Pretrazi</button> | |||||
| </div> | |||||
| </div> | |||||
| </form> | |||||
| </CustomDrawer> | |||||
| <CustomModal | |||||
| open={openAddPatternModal} | |||||
| onCloseModal={closeAddPatternModalHandler} | |||||
| classes="add-pattern-modal" | |||||
| > | |||||
| <div className="add-pattern-modal-header"> | |||||
| <div className="add-pattern-modal-header-title"> | |||||
| <div className="add-pattern-modal-header-title-image"> | |||||
| <img src={plusIcon} alt="plus" /> | |||||
| </div> | |||||
| <div className="add-pattern-modal-header-title-title"> | |||||
| <p>Dodavanje</p> | |||||
| </div> | |||||
| <div className="add-pattern-modal-header-title-sub"> | |||||
| <sub> | Šablon</sub> | |||||
| </div> | |||||
| </div> | |||||
| <div | |||||
| className="add-pattern-modal-header-close" | |||||
| onClick={closeAddPatternModalHandler} | |||||
| > | |||||
| <img src={xIcon} alt="close" /> | |||||
| </div> | |||||
| </div> | |||||
| <form onSubmit={submitAddPatternHandler}> | |||||
| <div className="add-pattern-modal-form-control"> | |||||
| <label>Naslov</label> | |||||
| <input | |||||
| type="text" | |||||
| placeholder="ex. Datum HR intervjua" | |||||
| onChange={(e) => setAddPatternTitle(e.target.value)} | |||||
| value={addPatternTitle} | |||||
| /> | |||||
| </div> | |||||
| <div className="add-pattern-modal-form-control"> | |||||
| <label>Kategorija</label> | |||||
| <select | |||||
| name="add-pattern-category" | |||||
| value={addPatternCategory} | |||||
| onChange={(e) => setAddPatternCategory(e.target.value)} | |||||
| > | |||||
| {processes.map((process) => ( | |||||
| <option key={process.id} value={process.id}> | |||||
| {process.name} | |||||
| </option> | |||||
| ))} | |||||
| </select> | |||||
| </div> | |||||
| <div className="add-pattern-modal-form-control"> | |||||
| <label>Tekst poruke</label> | |||||
| <textarea | |||||
| rows="11" | |||||
| value={addPatternMessage} | |||||
| onChange={(e) => setAddPatternMessage(e.target.value)} | |||||
| ></textarea> | |||||
| </div> | |||||
| <div className="add-pattern-modal-form-control"> | |||||
| <input type="submit" value="DODAJ ŠABLON" /> | |||||
| </div> | |||||
| </form> | |||||
| </CustomModal> | |||||
| <CustomModal | |||||
| open={openEditPatternModal} | |||||
| onCloseModal={closeEditPatternModalHandler} | |||||
| classes="edit-pattern-modal" | |||||
| > | |||||
| <div className="edit-pattern-modal-header"> | |||||
| <div className="edit-pattern-modal-header-title"> | |||||
| <div className="edit-pattern-modal-header-title-image"> | |||||
| <img src={userPageBtnIcon} alt="plus" /> | |||||
| </div> | |||||
| <div className="edit-pattern-modal-header-title-title"> | |||||
| <p>Uređivanje</p> | |||||
| </div> | |||||
| <div className="edit-pattern-modal-header-title-sub"> | |||||
| <sub> | Šablon</sub> | |||||
| </div> | |||||
| </div> | |||||
| <div | |||||
| className="edit-pattern-modal-header-close" | |||||
| onClick={closeEditPatternModalHandler} | |||||
| > | |||||
| <img src={xIcon} alt="close" /> | |||||
| </div> | |||||
| </div> | |||||
| <form onSubmit={submitEditPatternHandler}> | |||||
| <div className="edit-pattern-modal-form-control"> | |||||
| <label>Naslov</label> | |||||
| <input | |||||
| type="text" | |||||
| placeholder="ex. Datum HR intervjua" | |||||
| onChange={(e) => | |||||
| setEditPattern((oldState) => ({ | |||||
| ...oldState, | |||||
| title: e.target.value, | |||||
| })) | |||||
| } | |||||
| value={editPattern ? editPattern.title : ""} | |||||
| /> | |||||
| </div> | |||||
| <div className="edit-pattern-modal-form-control"> | |||||
| <label>Kategorija</label> | |||||
| <select | |||||
| name="edit-pattern-category" | |||||
| value={editPattern ? editPattern.selectionLevelId : 1} | |||||
| onChange={(e) => | |||||
| setEditPattern((oldState) => ({ | |||||
| ...oldState, | |||||
| selectionLevelId: e.target.value, | |||||
| })) | |||||
| } | |||||
| > | |||||
| {processes.map((process) => ( | |||||
| <option key={process.id} value={process.id}> | |||||
| {process.name} | |||||
| </option> | |||||
| ))} | |||||
| </select> | |||||
| </div> | |||||
| <div className="edit-pattern-modal-form-control"> | |||||
| <label>Tekst poruke</label> | |||||
| <textarea | |||||
| rows="11" | |||||
| onChange={(e) => | |||||
| setEditPattern((oldState) => ({ | |||||
| ...oldState, | |||||
| message: e.target.value, | |||||
| })) | |||||
| } | |||||
| value={editPattern ? editPattern.message : ""} | |||||
| ></textarea> | |||||
| </div> | |||||
| <div className="edit-pattern-modal-form-control"> | |||||
| <input type="submit" value="UREDI ŠABLON" /> | |||||
| </div> | |||||
| </form> | |||||
| </CustomModal> | |||||
| <div className="patterns"> | |||||
| <div className="patterns-header"> | |||||
| <div> | |||||
| <h1>Napravljeni Šabloni</h1> | |||||
| </div> | |||||
| <div> | |||||
| <IconButton | |||||
| onClick={() => setIsShownEdit((oldState) => !oldState)} | |||||
| className={`c-btn--primary-outlined editEnableBtn c-btn userPageBtn ${ | |||||
| isShownEdit && "pattern-header-active-button" | |||||
| }`} | |||||
| > | |||||
| {!matches && "Režim uređivanja"} | |||||
| <img | |||||
| style={{ | |||||
| position: "relative", | |||||
| top: -0.25, | |||||
| paddingLeft: matches ? "0px" : "10px", | |||||
| }} | |||||
| src={userPageBtnIcon} | |||||
| /> | |||||
| </IconButton> | |||||
| <FilterButton onShowFilters={() => setOpenFilterDrawer(true)} /> | |||||
| </div> | |||||
| </div> | |||||
| <div className="patterns-cards"> | |||||
| {!patterns && ( | |||||
| <div> | |||||
| <p>Loading...</p> | |||||
| </div> | |||||
| )} | |||||
| {patterns && patterns.length === 0 && ( | |||||
| <div> | |||||
| <p>Trenutno nema dodatih sablona</p> | |||||
| </div> | |||||
| )} | |||||
| {patterns && | |||||
| patterns.length > 0 && | |||||
| patterns.map((pattern) => ( | |||||
| <div className="pattern-card-parent" key={pattern.id}> | |||||
| <PatternCard | |||||
| createdAt={pattern.createdAt} | |||||
| title={pattern.title} | |||||
| selectionProcess={pattern.selectionLevel.name} | |||||
| onOpenEditModal={openEditModalHandler.bind(this, pattern)} | |||||
| isShownEdit={isShownEdit} | |||||
| onShowPatternDetails={() => | |||||
| history.push( | |||||
| PATTERN_DETAILS_PAGE.replace(":id", pattern.id) | |||||
| ) | |||||
| } | |||||
| /> | |||||
| </div> | |||||
| ))} | |||||
| </div> | |||||
| <div className="patterns-button"> | |||||
| <IconButton | |||||
| className="c-btn c-btn--primary add-ad-btn" | |||||
| onClick={() => setOpenAddPatternModal(true)} | |||||
| > | |||||
| Dodaj Šablon | |||||
| </IconButton> | |||||
| </div> | |||||
| </div> | |||||
| </> | |||||
| ); | |||||
| }; | |||||
| PatternsPage.propTypes = { | |||||
| history: PropTypes.any, | |||||
| }; | |||||
| export default PatternsPage; |
| technologies: { | technologies: { | ||||
| allTechnologies: base + "/technologies", | allTechnologies: base + "/technologies", | ||||
| }, | }, | ||||
| comments:{ | |||||
| addComment:base + '/comments' | |||||
| comments: { | |||||
| addComment: base + "/comments", | |||||
| }, | }, | ||||
| processes: { | processes: { | ||||
| allLevels: base + "/selectionlevels", | allLevels: base + "/selectionlevels", | ||||
| getApplicantProcesses: base + "/applicants/processes", | getApplicantProcesses: base + "/applicants/processes", | ||||
| // allProcesses: base + "/selectionprocesses", | // allProcesses: base + "/selectionprocesses", | ||||
| }, | }, | ||||
| patterns: { | |||||
| allPatterns: base + "/patterns", | |||||
| patternById: base + "/patterns/:id", | |||||
| createPattern: base + "/patterns", | |||||
| updatePattern: base + "/patterns/:id", | |||||
| }, | |||||
| stats:{ | stats:{ | ||||
| stats: base + "/stats" | stats: base + "/stats" | ||||
| } | } |
| import { getRequest, postRequest, putRequest } from "."; | |||||
| import apiEndpoints from "./apiEndpoints"; | |||||
| export const getAllPatterns = () => | |||||
| getRequest(apiEndpoints.patterns.allPatterns); | |||||
| export const getPatternById = (id) => | |||||
| getRequest(apiEndpoints.patterns.patternById.replace(":id", id)); | |||||
| export const createPatternRequest = (payload) => | |||||
| postRequest(apiEndpoints.patterns.createPattern, payload); | |||||
| export const updatePatternRequest = (payload) => | |||||
| putRequest( | |||||
| apiEndpoints.patterns.updatePattern.replace(":id", payload.id), | |||||
| payload | |||||
| ); |
| import { | |||||
| createFetchType, | |||||
| createSuccessType, | |||||
| createErrorType, | |||||
| } from "../actionHelpers"; | |||||
| const CREATE_PATTERN_SCOPE = "CREATE_PATTERN"; | |||||
| export const CREATE_PATTERN_REQ = createFetchType(CREATE_PATTERN_SCOPE); | |||||
| export const CREATE_PATTERN_ERR = createErrorType(CREATE_PATTERN_SCOPE); | |||||
| export const CREATE_PATTERN_SUCCESS = createSuccessType(CREATE_PATTERN_SCOPE); |
| import { | |||||
| CREATE_PATTERN_REQ, | |||||
| CREATE_PATTERN_ERR, | |||||
| CREATE_PATTERN_SUCCESS, | |||||
| } from "./createPatternActionConstants"; | |||||
| export const createPatternReq = (payload) => ({ | |||||
| type: CREATE_PATTERN_REQ, | |||||
| payload, | |||||
| }); | |||||
| export const createPatternError = (payload) => ({ | |||||
| type: CREATE_PATTERN_ERR, | |||||
| payload, | |||||
| }); | |||||
| export const createPattern = (payload) => ({ | |||||
| type: CREATE_PATTERN_SUCCESS, | |||||
| payload, | |||||
| }); |
| import { | |||||
| createFetchType, | |||||
| createSuccessType, | |||||
| createErrorType, | |||||
| } from "../actionHelpers"; | |||||
| const FETCH_PATTERN_SCOPE = "FETCH_PATTERN"; | |||||
| export const FETCH_PATTERN_REQ = createFetchType(FETCH_PATTERN_SCOPE); | |||||
| export const FETCH_PATTERN_ERR = createErrorType(FETCH_PATTERN_SCOPE); | |||||
| export const FETCH_PATTERN_SUCCESS = createSuccessType(FETCH_PATTERN_SCOPE); |
| import { | |||||
| FETCH_PATTERN_REQ, | |||||
| FETCH_PATTERN_ERR, | |||||
| FETCH_PATTERN_SUCCESS, | |||||
| } from "./patternActionConstants"; | |||||
| export const setPatternReq = (payload) => ({ | |||||
| type: FETCH_PATTERN_REQ, | |||||
| payload, | |||||
| }); | |||||
| export const setPatternError = (payload) => ({ | |||||
| type: FETCH_PATTERN_ERR, | |||||
| payload, | |||||
| }); | |||||
| export const setPattern = (payload) => ({ | |||||
| type: FETCH_PATTERN_SUCCESS, | |||||
| payload, | |||||
| }); |
| import { | |||||
| createFetchType, | |||||
| createSuccessType, | |||||
| createErrorType, | |||||
| } from "../actionHelpers"; | |||||
| const FETCH_PATTERNS_SCOPE = "FETCH_PATTERNS"; | |||||
| export const FETCH_PATTERNS_REQ = createFetchType(FETCH_PATTERNS_SCOPE); | |||||
| export const FETCH_PATTERNS_ERR = createErrorType(FETCH_PATTERNS_SCOPE); | |||||
| export const FETCH_PATTERNS_SUCCESS = createSuccessType(FETCH_PATTERNS_SCOPE); |
| import { | |||||
| FETCH_PATTERNS_REQ, | |||||
| FETCH_PATTERNS_ERR, | |||||
| FETCH_PATTERNS_SUCCESS, | |||||
| } from "./patternsActionConstants"; | |||||
| export const setPatternsReq = () => ({ | |||||
| type: FETCH_PATTERNS_REQ, | |||||
| }); | |||||
| export const setPatternsError = (payload) => ({ | |||||
| type: FETCH_PATTERNS_ERR, | |||||
| payload, | |||||
| }); | |||||
| export const setPatterns = (payload) => ({ | |||||
| type: FETCH_PATTERNS_SUCCESS, | |||||
| payload, | |||||
| }); |
| import { | |||||
| createFetchType, | |||||
| createSuccessType, | |||||
| createErrorType, | |||||
| } from "../actionHelpers"; | |||||
| const UPDATE_PATTERN_SCOPE = "UPDATE_PATTERN"; | |||||
| export const UPDATE_PATTERN_REQ = createFetchType(UPDATE_PATTERN_SCOPE); | |||||
| export const UPDATE_PATTERN_ERR = createErrorType(UPDATE_PATTERN_SCOPE); | |||||
| export const UPDATE_PATTERN_SUCCESS = createSuccessType(UPDATE_PATTERN_SCOPE); |
| import { | |||||
| UPDATE_PATTERN_REQ, | |||||
| UPDATE_PATTERN_ERR, | |||||
| UPDATE_PATTERN_SUCCESS, | |||||
| } from "./updatePatternActionConstants"; | |||||
| export const updatePatternReq = (payload) => ({ | |||||
| type: UPDATE_PATTERN_REQ, | |||||
| payload, | |||||
| }); | |||||
| export const updatePatternError = (payload) => ({ | |||||
| type: UPDATE_PATTERN_ERR, | |||||
| payload, | |||||
| }); | |||||
| export const updatePattern = (payload) => ({ | |||||
| type: UPDATE_PATTERN_SUCCESS, | |||||
| payload, | |||||
| }); |
| import userDetailsReducer from "./user/userDetailsReducer"; | import userDetailsReducer from "./user/userDetailsReducer"; | ||||
| import inviteUserReducer from "./user/inviteUserReducer"; | import inviteUserReducer from "./user/inviteUserReducer"; | ||||
| import statusReducer from "./processes/statusReducer"; | import statusReducer from "./processes/statusReducer"; | ||||
| import patternsReducer from "./pattern/patternsReducer"; | |||||
| import patternReducer from "./pattern/patternReducer"; | |||||
| import createPatternReducer from "./pattern/createPatternReducer"; | |||||
| import updatePatternReducer from "./pattern/updatePatternReducer"; | |||||
| import statsReducer from "./stats/statsReducer"; | import statsReducer from "./stats/statsReducer"; | ||||
| export default combineReducers({ | export default combineReducers({ | ||||
| userDetails: userDetailsReducer, | userDetails: userDetailsReducer, | ||||
| invite: inviteUserReducer, | invite: inviteUserReducer, | ||||
| statuses: statusReducer, | statuses: statusReducer, | ||||
| patterns: patternsReducer, | |||||
| pattern: patternReducer, | |||||
| createPattern: createPatternReducer, | |||||
| updatePattern: updatePatternReducer, | |||||
| stats: statsReducer, | stats: statsReducer, | ||||
| }); | }); |
| import { | |||||
| CREATE_PATTERN_ERR, | |||||
| CREATE_PATTERN_SUCCESS, | |||||
| } from "../../actions/createPattern/createPatternActionConstants"; | |||||
| import createReducer from "../../utils/createReducer"; | |||||
| const initialState = { | |||||
| pattern: null, | |||||
| errorMessage: "", | |||||
| }; | |||||
| export default createReducer( | |||||
| { | |||||
| [CREATE_PATTERN_SUCCESS]: setCreatePattern, | |||||
| [CREATE_PATTERN_ERR]: setCreatePatternErrorMessage, | |||||
| }, | |||||
| initialState | |||||
| ); | |||||
| function setCreatePattern(state, action) { | |||||
| return { | |||||
| ...state, | |||||
| pattern: action.payload, | |||||
| }; | |||||
| } | |||||
| function setCreatePatternErrorMessage(state, action) { | |||||
| return { | |||||
| ...state, | |||||
| errorMessage: action.payload, | |||||
| }; | |||||
| } |
| import createReducer from "../../utils/createReducer"; | |||||
| import { | |||||
| FETCH_PATTERN_SUCCESS, | |||||
| FETCH_PATTERN_ERR, | |||||
| } from "../../actions/pattern/patternActionConstants"; | |||||
| const initialState = { | |||||
| pattern: null, | |||||
| errorMessage: "", | |||||
| }; | |||||
| export default createReducer( | |||||
| { | |||||
| [FETCH_PATTERN_SUCCESS]: setStatePattern, | |||||
| [FETCH_PATTERN_ERR]: setStateErrorMessage, | |||||
| }, | |||||
| initialState | |||||
| ); | |||||
| function setStatePattern(state, action) { | |||||
| return { ...state, pattern: action.payload }; | |||||
| } | |||||
| function setStateErrorMessage(state, action) { | |||||
| return { ...state, errorMessage: action.payload }; | |||||
| } |
| import { | |||||
| FETCH_PATTERNS_ERR, | |||||
| FETCH_PATTERNS_SUCCESS, | |||||
| } from "../../actions/patterns/patternsActionConstants"; | |||||
| import createReducer from "../../utils/createReducer"; | |||||
| const initialState = { | |||||
| patterns: [], | |||||
| errorMessage: "", | |||||
| }; | |||||
| export default createReducer( | |||||
| { | |||||
| [FETCH_PATTERNS_SUCCESS]: setStatePatterns, | |||||
| [FETCH_PATTERNS_ERR]: setPatternsErrorMessage, | |||||
| }, | |||||
| initialState | |||||
| ); | |||||
| function setStatePatterns(state, action) { | |||||
| return { | |||||
| ...state, | |||||
| patterns: action.payload, | |||||
| }; | |||||
| } | |||||
| function setPatternsErrorMessage(state, action) { | |||||
| return { | |||||
| ...state, | |||||
| errorMessage: action.payload, | |||||
| }; | |||||
| } |
| import { | |||||
| UPDATE_PATTERN_ERR, | |||||
| UPDATE_PATTERN_SUCCESS, | |||||
| } from "../../actions/updatePattern/updatePatternActionConstants"; | |||||
| import createReducer from "../../utils/createReducer"; | |||||
| const initialState = { | |||||
| pattern: null, | |||||
| errorMessage: "", | |||||
| }; | |||||
| export default createReducer( | |||||
| { | |||||
| [UPDATE_PATTERN_SUCCESS]: setUpdatePattern, | |||||
| [UPDATE_PATTERN_ERR]: setUpdatePatternErrorMessage, | |||||
| }, | |||||
| initialState | |||||
| ); | |||||
| function setUpdatePattern(state, action) { | |||||
| return { | |||||
| ...state, | |||||
| pattern: action.payload, | |||||
| }; | |||||
| } | |||||
| function setUpdatePatternErrorMessage(state, action) { | |||||
| return { | |||||
| ...state, | |||||
| errorMessage: action.payload, | |||||
| }; | |||||
| } |
| const result = yield call(createNewAd, payload); | const result = yield call(createNewAd, payload); | ||||
| const ad = result.data; | const ad = result.data; | ||||
| yield put(setCreateAd(ad)); | yield put(setCreateAd(ad)); | ||||
| const resultAds = yield call(getAllAds); | |||||
| yield put(setAds(resultAds.data)); | |||||
| const resultArchiveAds = yield call(getAllArchiveAds); | |||||
| yield put(setArchiveAds(resultArchiveAds.data)); | |||||
| } catch (error) { | } catch (error) { | ||||
| yield put(setCreateAdError(error)); | yield put(setCreateAdError(error)); | ||||
| } | } |
| import { all } from "redux-saga/effects"; | import { all } from "redux-saga/effects"; | ||||
| import adsSaga from "./adsSaga"; | import adsSaga from "./adsSaga"; | ||||
| import candidatesSaga from './candidatesSaga'; | |||||
| import candidatesSaga from "./candidatesSaga"; | |||||
| import loginSaga from "./loginSaga"; | import loginSaga from "./loginSaga"; | ||||
| import technologiesSaga from "./technologiesSaga"; | import technologiesSaga from "./technologiesSaga"; | ||||
| import usersSaga from "./usersSaga"; | import usersSaga from "./usersSaga"; | ||||
| import processesSaga from "./processSaga"; | import processesSaga from "./processSaga"; | ||||
| import patternsSage from "./patternsSaga"; | |||||
| import statsSaga from "./statsSaga"; | import statsSaga from "./statsSaga"; | ||||
| export default function* rootSaga() { | export default function* rootSaga() { | ||||
| technologiesSaga(), | technologiesSaga(), | ||||
| candidatesSaga(), | candidatesSaga(), | ||||
| processesSaga(), | processesSaga(), | ||||
| patternsSage(), | |||||
| statsSaga() | statsSaga() | ||||
| ]); | ]); | ||||
| } | } |
| import { all, call, put, takeLatest } from "redux-saga/effects"; | |||||
| import { | |||||
| createPatternRequest, | |||||
| getAllPatterns, | |||||
| getPatternById, | |||||
| updatePatternRequest, | |||||
| } from "../../request/patternsRequest"; | |||||
| import { | |||||
| setPatterns, | |||||
| setPatternsError, | |||||
| } from "../actions/patterns/patternsActions"; | |||||
| import { setPattern, setPatternError } from "../actions/pattern/patternActions"; | |||||
| import { | |||||
| createPattern, | |||||
| createPatternError, | |||||
| } from "../actions/createPattern/createPatternActions"; | |||||
| import { FETCH_PATTERNS_REQ } from "../actions/patterns/patternsActionConstants"; | |||||
| import { FETCH_PATTERN_REQ } from "../actions/pattern/patternActionConstants"; | |||||
| import { CREATE_PATTERN_REQ } from "../actions/createPattern/createPatternActionConstants"; | |||||
| import { UPDATE_PATTERN_REQ } from "../actions/updatePattern/updatePatternActionConstants"; | |||||
| import { | |||||
| updatePattern, | |||||
| updatePatternError, | |||||
| } from "../actions/updatePattern/updatePatternActions"; | |||||
| export function* getPatterns() { | |||||
| try { | |||||
| const result = yield call(getAllPatterns); | |||||
| yield put(setPatterns(result.data)); | |||||
| } catch (error) { | |||||
| yield put(setPatternsError(error)); | |||||
| } | |||||
| } | |||||
| export function* getPattern({ payload }) { | |||||
| try { | |||||
| const result = yield call(getPatternById, payload.id); | |||||
| yield put(setPattern(result.data)); | |||||
| } catch (error) { | |||||
| yield put(setPatternError(error)); | |||||
| } | |||||
| } | |||||
| export function* createPatternSaga({ payload }) { | |||||
| try { | |||||
| const result = yield call(createPatternRequest, payload); | |||||
| yield put(createPattern(result.data)); | |||||
| const resultPatterns = yield call(getAllPatterns); | |||||
| yield put(setPatterns(resultPatterns.data)); | |||||
| } catch (error) { | |||||
| yield put(createPatternError(error)); | |||||
| } | |||||
| } | |||||
| export function* updatePatternSaga({ payload }) { | |||||
| try { | |||||
| const result = yield call(updatePatternRequest, payload); | |||||
| yield put(updatePattern(result.data)); | |||||
| const resultPatterns = yield call(getAllPatterns); | |||||
| yield put(setPatterns(resultPatterns.data)); | |||||
| } catch (error) { | |||||
| yield put(updatePatternError(error)); | |||||
| } | |||||
| } | |||||
| export default function* adsSaga() { | |||||
| yield all([ | |||||
| takeLatest(FETCH_PATTERNS_REQ, getPatterns), | |||||
| takeLatest(FETCH_PATTERN_REQ, getPattern), | |||||
| takeLatest(CREATE_PATTERN_REQ, createPatternSaga), | |||||
| takeLatest(UPDATE_PATTERN_REQ, updatePatternSaga), | |||||
| ]); | |||||
| } |
| import { createSelector } from "@reduxjs/toolkit"; | |||||
| export const patternSelector = (state) => state.pattern; | |||||
| export const selectPattern = createSelector( | |||||
| patternSelector, | |||||
| (state) => state.pattern | |||||
| ); | |||||
| export const selectPatternError = createSelector( | |||||
| patternSelector, | |||||
| (state) => state.errorMessage | |||||
| ); |
| import { createSelector } from "@reduxjs/toolkit"; | |||||
| export const patternsSelector = (state) => state.patterns; | |||||
| export const selectPatterns = createSelector( | |||||
| patternsSelector, | |||||
| (state) => state.patterns | |||||
| ); | |||||
| export const selectPatternsError = createSelector( | |||||
| patternsSelector, | |||||
| (state) => state.errorMessage | |||||
| ); |