| "react-dom": "^17.0.2", | "react-dom": "^17.0.2", | ||||
| "react-helmet-async": "^1.0.9", | "react-helmet-async": "^1.0.9", | ||||
| "react-i18next": "^11.10.0", | "react-i18next": "^11.10.0", | ||||
| "react-mentions": "^4.4.7", | |||||
| "react-redux": "^7.2.4", | "react-redux": "^7.2.4", | ||||
| "react-router-dom": "^5.2.0", | "react-router-dom": "^5.2.0", | ||||
| "react-scripts": "4.0.3", | "react-scripts": "4.0.3", | ||||
| "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", | "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", | ||||
| "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" | "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" | ||||
| }, | }, | ||||
| "node_modules/react-mentions": { | |||||
| "version": "4.4.7", | |||||
| "resolved": "https://registry.npmjs.org/react-mentions/-/react-mentions-4.4.7.tgz", | |||||
| "integrity": "sha512-VNriu2h/uOB+RS0mwZgPG2Vf+UtdDvRh5zbXa2TNc1WqacKuNDgTdhlbo9LEOZRBxRzIeTUYQmYJ7p9M9rDHqQ==", | |||||
| "dependencies": { | |||||
| "@babel/runtime": "7.4.5", | |||||
| "invariant": "^2.2.4", | |||||
| "prop-types": "^15.5.8", | |||||
| "substyle": "^9.1.0" | |||||
| }, | |||||
| "peerDependencies": { | |||||
| "react": ">=16.8.3", | |||||
| "react-dom": ">=16.8.3" | |||||
| } | |||||
| }, | |||||
| "node_modules/react-mentions/node_modules/@babel/runtime": { | |||||
| "version": "7.4.5", | |||||
| "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.5.tgz", | |||||
| "integrity": "sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ==", | |||||
| "dependencies": { | |||||
| "regenerator-runtime": "^0.13.2" | |||||
| } | |||||
| }, | |||||
| "node_modules/react-redux": { | "node_modules/react-redux": { | ||||
| "version": "7.2.9", | "version": "7.2.9", | ||||
| "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.9.tgz", | "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.9.tgz", | ||||
| "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz", | "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz", | ||||
| "integrity": "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==" | "integrity": "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==" | ||||
| }, | }, | ||||
| "node_modules/substyle": { | |||||
| "version": "9.4.1", | |||||
| "resolved": "https://registry.npmjs.org/substyle/-/substyle-9.4.1.tgz", | |||||
| "integrity": "sha512-VOngeq/W1/UkxiGzeqVvDbGDPM8XgUyJVWjrqeh+GgKqspEPiLYndK+XRcsKUHM5Muz/++1ctJ1QCF/OqRiKWA==", | |||||
| "dependencies": { | |||||
| "@babel/runtime": "^7.3.4", | |||||
| "invariant": "^2.2.4" | |||||
| }, | |||||
| "peerDependencies": { | |||||
| "react": ">=16.8.3" | |||||
| } | |||||
| }, | |||||
| "node_modules/supports-color": { | "node_modules/supports-color": { | ||||
| "version": "5.5.0", | "version": "5.5.0", | ||||
| "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", | ||||
| "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", | "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", | ||||
| "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" | "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" | ||||
| }, | }, | ||||
| "react-mentions": { | |||||
| "version": "4.4.7", | |||||
| "resolved": "https://registry.npmjs.org/react-mentions/-/react-mentions-4.4.7.tgz", | |||||
| "integrity": "sha512-VNriu2h/uOB+RS0mwZgPG2Vf+UtdDvRh5zbXa2TNc1WqacKuNDgTdhlbo9LEOZRBxRzIeTUYQmYJ7p9M9rDHqQ==", | |||||
| "requires": { | |||||
| "@babel/runtime": "7.4.5", | |||||
| "invariant": "^2.2.4", | |||||
| "prop-types": "^15.5.8", | |||||
| "substyle": "^9.1.0" | |||||
| }, | |||||
| "dependencies": { | |||||
| "@babel/runtime": { | |||||
| "version": "7.4.5", | |||||
| "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.5.tgz", | |||||
| "integrity": "sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ==", | |||||
| "requires": { | |||||
| "regenerator-runtime": "^0.13.2" | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| "react-redux": { | "react-redux": { | ||||
| "version": "7.2.9", | "version": "7.2.9", | ||||
| "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.9.tgz", | "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.9.tgz", | ||||
| "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz", | "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz", | ||||
| "integrity": "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==" | "integrity": "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==" | ||||
| }, | }, | ||||
| "substyle": { | |||||
| "version": "9.4.1", | |||||
| "resolved": "https://registry.npmjs.org/substyle/-/substyle-9.4.1.tgz", | |||||
| "integrity": "sha512-VOngeq/W1/UkxiGzeqVvDbGDPM8XgUyJVWjrqeh+GgKqspEPiLYndK+XRcsKUHM5Muz/++1ctJ1QCF/OqRiKWA==", | |||||
| "requires": { | |||||
| "@babel/runtime": "^7.3.4", | |||||
| "invariant": "^2.2.4" | |||||
| } | |||||
| }, | |||||
| "supports-color": { | "supports-color": { | ||||
| "version": "5.5.0", | "version": "5.5.0", | ||||
| "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", |
| "react-dom": "^17.0.2", | "react-dom": "^17.0.2", | ||||
| "react-helmet-async": "^1.0.9", | "react-helmet-async": "^1.0.9", | ||||
| "react-i18next": "^11.10.0", | "react-i18next": "^11.10.0", | ||||
| "react-mentions": "^4.4.7", | |||||
| "react-redux": "^7.2.4", | "react-redux": "^7.2.4", | ||||
| "react-router-dom": "^5.2.0", | "react-router-dom": "^5.2.0", | ||||
| "react-scripts": "4.0.3", | "react-scripts": "4.0.3", |
| import MainContainer from "./components/Section/MainContainer"; | import MainContainer from "./components/Section/MainContainer"; | ||||
| import AppRoutes from "./AppRoutes"; | import AppRoutes from "./AppRoutes"; | ||||
| import { useDispatch } from "react-redux"; | import { useDispatch } from "react-redux"; | ||||
| import {refreshUserToken} from "./store/actions/login/loginActions"; | |||||
| import { refreshUserToken } from "./store/actions/login/loginActions"; | |||||
| import { BASE_PAGE } from "./constants/pages"; | import { BASE_PAGE } from "./constants/pages"; | ||||
| const App = () => { | const App = () => { | ||||
| const dispatch = useDispatch() | |||||
| const dispatch = useDispatch(); | |||||
| useEffect(() => { | useEffect(() => { | ||||
| if(history.location.pathname === BASE_PAGE) | |||||
| if (history.location.pathname === BASE_PAGE) { | |||||
| return; | return; | ||||
| dispatch(refreshUserToken()) | |||||
| },[]) | |||||
| } | |||||
| dispatch(refreshUserToken()); | |||||
| }, []); | |||||
| return ( | return ( | ||||
| <> | <> |
| USERS_PAGE, | USERS_PAGE, | ||||
| CANDIDATES_PAGE, | CANDIDATES_PAGE, | ||||
| USER_DETAILS_PAGE | USER_DETAILS_PAGE | ||||
| CANDIDATES_PAGE, | |||||
| CANDIDATES_DETAILS_PAGE | |||||
| } from "./constants/pages"; | } from "./constants/pages"; | ||||
| // import LoginPage from './pages/LoginPage/LoginPage'; | // import LoginPage from './pages/LoginPage/LoginPage'; | ||||
| 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/CandidateDetailsPage/CandidateDetailsPage"; | |||||
| const AppRoutes = () => ( | const AppRoutes = () => ( | ||||
| <Switch> | <Switch> | ||||
| <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} /> | |||||
| <Redirect from="*" to={NOT_FOUND_PAGE} /> | <Redirect from="*" to={NOT_FOUND_PAGE} /> | ||||
| </Switch> | </Switch> | ||||
| ); | ); |
| .main-candidate-container { | |||||
| display: flex; | |||||
| flex-direction: column; | |||||
| } | |||||
| .top-candidate-container { | |||||
| display: flex; | |||||
| width: 100%; | |||||
| justify-content: space-between; | |||||
| } | |||||
| .candidate-header { | |||||
| height: 36px; | |||||
| font-family: Source Sans Pro; | |||||
| font-size: 36px; | |||||
| font-weight: 600; | |||||
| line-height: 36px; | |||||
| letter-spacing: 0.02em; | |||||
| text-align: left; | |||||
| color: #272727; | |||||
| } | |||||
| .separation-line { | |||||
| margin-left: 5px; | |||||
| margin-right: 5px; | |||||
| font-size: 20px; | |||||
| align-self: flex-end; | |||||
| } | |||||
| .candidate-lower-header { | |||||
| font-family: Source Sans Pro; | |||||
| font-size: 24px; | |||||
| font-weight: 600; | |||||
| line-height: 32px; | |||||
| letter-spacing: 0.02em; | |||||
| text-align: left; | |||||
| color: #226cb0; | |||||
| align-self: flex-end; | |||||
| } | |||||
| .candidate-option-container { | |||||
| display: flex; | |||||
| height: 38px; | |||||
| } | |||||
| .content-candidate-container { | |||||
| display: flex; | |||||
| justify-content: space-between; | |||||
| margin-top: 14px; | |||||
| } | |||||
| .technologies-candidate-container { | |||||
| display: flex; | |||||
| margin-top: 18px; | |||||
| } | |||||
| .technology-candidate-card { | |||||
| display: flex; | |||||
| flex-direction: row; | |||||
| justify-content: center; | |||||
| align-items: center; | |||||
| padding: 9px; | |||||
| gap: 10px; | |||||
| background: #ffffff; | |||||
| border: 1px solid #e4e4e4; | |||||
| border-radius: 9px; | |||||
| } | |||||
| .technology-candidate-card:not(:last-child) { | |||||
| margin-right: 18px; | |||||
| } | |||||
| .comment-container { | |||||
| width: 612px; | |||||
| height: 404px; | |||||
| background: #ffffff; | |||||
| border: 1px solid #e4e4e4; | |||||
| border-radius: 12px; | |||||
| margin-top: 16px; | |||||
| } | |||||
| .candidate-informations-container { | |||||
| display: flex; | |||||
| flex-direction: column; | |||||
| } | |||||
| .candidate-informations-sub-container { | |||||
| margin-top: 36px; | |||||
| } | |||||
| .informations-candidate-header { | |||||
| font-family: "Source Sans Pro"; | |||||
| font-style: normal; | |||||
| font-weight: 600; | |||||
| font-size: 16px; | |||||
| line-height: 20px; | |||||
| color: #272727; | |||||
| } | |||||
| .candidate-property-container { | |||||
| display: flex; | |||||
| flex-direction: column; | |||||
| } | |||||
| .candidate-property { | |||||
| margin-top: 18px; | |||||
| font-family: Source Sans Pro; | |||||
| font-size: 16px; | |||||
| font-weight: 400; | |||||
| line-height: 20px; | |||||
| letter-spacing: 0em; | |||||
| } | |||||
| .candidate-property-value { | |||||
| @extend .candidate-property; | |||||
| color: #1e92d0; | |||||
| } | |||||
| .candidate-informations-sub-container { | |||||
| display: flex; | |||||
| } | |||||
| .comment-container { | |||||
| display: flex; | |||||
| flex-direction: column; | |||||
| padding-left: 36px; | |||||
| padding-right: 36px; | |||||
| padding-top: 36px; | |||||
| } | |||||
| .comment-sub-container { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| } | |||||
| .comment-sub-container:not(:first-child) { | |||||
| margin-top: 36px; | |||||
| } | |||||
| .comment-sender { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: center; | |||||
| width: 40px; | |||||
| height: 40px; | |||||
| border-radius: 50%; | |||||
| box-sizing: border-box; | |||||
| border: 1px solid; | |||||
| border-color: #226cb0; | |||||
| } | |||||
| .comment-sender p { | |||||
| color: #226cb0; | |||||
| } | |||||
| .comment-message { | |||||
| display: flex; | |||||
| flex-direction: column; | |||||
| justify-content: center; | |||||
| align-items: flex-end; | |||||
| padding: 9px; | |||||
| gap: 9px; | |||||
| height: 62px; | |||||
| background: #f4f4f4; | |||||
| border-radius: 12px; | |||||
| margin-left: 18px; | |||||
| } | |||||
| .comment-message-content { | |||||
| align-self: flex-start; | |||||
| height: 20px; | |||||
| font-family: "Source Sans Pro"; | |||||
| font-style: normal; | |||||
| font-size: 16px; | |||||
| line-height: 20px; | |||||
| } | |||||
| .comment-message-date { | |||||
| align-self: flex-end; | |||||
| height: 15px; | |||||
| font-family: "Source Sans Pro"; | |||||
| font-style: normal; | |||||
| font-weight: 400; | |||||
| font-size: 12px; | |||||
| line-height: 15px; | |||||
| color: #272727; | |||||
| } | |||||
| .comment-separation-line { | |||||
| width: 100%; | |||||
| height: 0px; | |||||
| border: 1px solid #e4e4e4; | |||||
| background: #e4e4e4; | |||||
| } | |||||
| .send-comment-container { | |||||
| margin-top: 18px; | |||||
| } | |||||
| .send-comment-container p { | |||||
| font-family: "Source Sans Pro"; | |||||
| font-weight: 400; | |||||
| font-size: 16px; | |||||
| line-height: 20px; | |||||
| color: #9d9d9d; | |||||
| } | |||||
| .send-comment-sub-container { | |||||
| display: flex; | |||||
| margin-top: 9px; | |||||
| height: 56px; | |||||
| margin-bottom: 36px; | |||||
| } | |||||
| .comment-send-btn { | |||||
| display: flex; | |||||
| flex-direction: row; | |||||
| justify-content: center; | |||||
| align-items: center; | |||||
| padding: 18px 36px; | |||||
| gap: 10px; | |||||
| background: #ffffff; | |||||
| border: 1px solid #226cb0; | |||||
| border-radius: 9px; | |||||
| border: 1px solid #226cb0; | |||||
| width: 156px; | |||||
| margin-left: 18px; | |||||
| } | |||||
| .comment-send-btn:hover { | |||||
| cursor: pointer; | |||||
| } | |||||
| .comment-send-btn p { | |||||
| width: 62px; | |||||
| height: 15px; | |||||
| font-family: "Source Sans Pro"; | |||||
| font-style: normal; | |||||
| font-weight: 600; | |||||
| font-size: 12px; | |||||
| line-height: 15px; | |||||
| letter-spacing: 0.04em; | |||||
| text-transform: uppercase; | |||||
| color: #226cb0; | |||||
| flex: none; | |||||
| order: 1; | |||||
| flex-grow: 0; | |||||
| } | |||||
| .comment-send-btn img { | |||||
| width: 12px; | |||||
| height: 12px; | |||||
| } | |||||
| .candidate-users { | |||||
| background-color: #f4f4f4; | |||||
| } | |||||
| .candidate-user { | |||||
| color: #226cb0; | |||||
| } | |||||
| .applicant-ads-container { | |||||
| margin-top: 36px; | |||||
| } | |||||
| .applicant-ads-container > p { | |||||
| font-family: "Source Sans Pro"; | |||||
| font-weight: 600; | |||||
| font-size: 24px; | |||||
| line-height: 32px; | |||||
| letter-spacing: 0.02em; | |||||
| color: #272727; | |||||
| } | |||||
| .applicant-ads-sub-container { | |||||
| margin-top: 18px; | |||||
| } | |||||
| .applicant-add { | |||||
| display: flex; | |||||
| flex-direction: column; | |||||
| align-items: center; | |||||
| padding: 36px; | |||||
| gap: 18px; | |||||
| background: #ffffff; | |||||
| border: 1px solid #e4e4e4; | |||||
| border-radius: 12px; | |||||
| width: 247px; | |||||
| height: 238px; | |||||
| } | |||||
| .applicant-add-date { | |||||
| font-family: Source Sans Pro; | |||||
| font-size: 12px; | |||||
| font-weight: 400; | |||||
| line-height: 15px; | |||||
| letter-spacing: 0em; | |||||
| } | |||||
| .applicant-add-title { | |||||
| font-family: "Source Sans Pro"; | |||||
| font-weight: 600; | |||||
| font-size: 16px; | |||||
| line-height: 20px; | |||||
| color: #226cb0; | |||||
| } | |||||
| .applicant-add-site { | |||||
| display: flex; | |||||
| flex-direction: column; | |||||
| justify-content: center; | |||||
| align-items: center; | |||||
| background: #ffffff; | |||||
| padding: 5px; | |||||
| border: 1px solid #e4e4e4; | |||||
| border-radius: 8px; | |||||
| font-size: 16px; | |||||
| font-family: "Source Sans Pro"; | |||||
| font-weight: 400; | |||||
| color: #272727; | |||||
| } | |||||
| .applicant-ads-buttons-container { | |||||
| display: flex; | |||||
| align-self: flex-end; | |||||
| align-items: center; | |||||
| margin-bottom: 54px; | |||||
| margin-top: 18px; | |||||
| } | |||||
| .applicant-cv-button { | |||||
| display: flex; | |||||
| flex-direction: row; | |||||
| justify-content: center; | |||||
| align-items: center; | |||||
| padding: 18px 72px; | |||||
| gap: 10px; | |||||
| background: #226cb0; | |||||
| border-radius: 9px; | |||||
| width: 212px; | |||||
| height: 51px; | |||||
| font-family: "Source Sans Pro"; | |||||
| font-weight: 600; | |||||
| font-size: 12px; | |||||
| line-height: 15px; | |||||
| letter-spacing: 0.04em; | |||||
| text-transform: uppercase; | |||||
| color: #ffffff; | |||||
| } | |||||
| .applicant-ads-back-button { | |||||
| margin-right: 36px; | |||||
| font-family: "Source Sans Pro"; | |||||
| font-weight: 400; | |||||
| font-size: 16px; | |||||
| line-height: 20px; | |||||
| text-decoration-line: underline; | |||||
| color: #226cb0; | |||||
| } | |||||
| .tagStyle { | |||||
| color: #226cb0; | |||||
| font-family: Source Sans Pro; | |||||
| font-size: 16px; | |||||
| font-weight: 600; | |||||
| line-height: 20px; | |||||
| letter-spacing: 0em; | |||||
| } | |||||
| .comment-input { | |||||
| @extend .tagStyle; | |||||
| width: 368px; | |||||
| } | |||||
| .comment-input ::placeholder { | |||||
| width: 139px; | |||||
| height: 20px; | |||||
| font-family: "Source Sans Pro"; | |||||
| font-style: italic; | |||||
| font-weight: 400; | |||||
| font-size: 16px; | |||||
| line-height: 20px; | |||||
| color: #9d9d9d; | |||||
| flex: none; | |||||
| order: 0; | |||||
| flex-grow: 0; | |||||
| } | |||||
| .comment-input-list{ | |||||
| @extend .tagStyle; | |||||
| } | |||||
| @media only screen and (max-width: 930px) { | |||||
| .comment-container { | |||||
| width:500px; | |||||
| } | |||||
| } | |||||
| @media only screen and (max-width: 820px) { | |||||
| .comment-container { | |||||
| width:400px; | |||||
| }; | |||||
| .comment-send-btn{ | |||||
| width: 130; | |||||
| padding: 12px 28px; | |||||
| }; | |||||
| .send-comment-sub-container{ | |||||
| height: 45px; | |||||
| margin-bottom: 20px | |||||
| }; | |||||
| .comment-input ::placeholder{ | |||||
| font-size: 14px; | |||||
| line-height: 18px; | |||||
| padding-top:2px; | |||||
| } | |||||
| } | |||||
| @media only screen and (max-width: 700px) { | |||||
| .comment-container { | |||||
| width:380px; | |||||
| } | |||||
| .comment-send-btn{ | |||||
| width: 110; | |||||
| padding: 10px 20px; | |||||
| }; | |||||
| } | |||||
| @media only screen and (max-width:680px) { | |||||
| .content-candidate-container{ | |||||
| flex-direction: column; | |||||
| } | |||||
| .comment-container { | |||||
| margin-top: 30px; | |||||
| } | |||||
| } | |||||
| @media only screen and (max-width:540px) { | |||||
| .candidate-header{ | |||||
| height: 30px; | |||||
| font-family: Source Sans Pro; | |||||
| font-size: 30px; | |||||
| line-height: 30px; | |||||
| } | |||||
| .candidate-lower-header{ | |||||
| font-size: 18px; | |||||
| line-height: 26px; | |||||
| } | |||||
| .applicant-cv-button { | |||||
| padding: 10px 52px; | |||||
| gap: 7px; | |||||
| border-radius: 7px; | |||||
| width: 180px; | |||||
| height: 40px; | |||||
| font-size: 10px; | |||||
| line-height: 12px; | |||||
| text-align: center; | |||||
| } | |||||
| } | |||||
| @media only screen and (max-width:480px) { | |||||
| .comment-container { | |||||
| width:297px; | |||||
| } | |||||
| .comment-send-btn{ | |||||
| padding: 5px 5px; | |||||
| }; | |||||
| .comment-container{ | |||||
| padding: 20px; | |||||
| } | |||||
| .candidate-header{ | |||||
| height: 20x; | |||||
| font-size: 20px; | |||||
| line-height: 20px; | |||||
| } | |||||
| .candidate-lower-header{ | |||||
| font-size: 17px; | |||||
| line-height:17px; | |||||
| } | |||||
| } |
| .main-candidates-container { | .main-candidates-container { | ||||
| display: flex; | display: flex; | ||||
| flex-direction: column; | flex-direction: column; | ||||
| margin-top: 30px; | |||||
| margin-left: 100px; | |||||
| margin-right: 100px; | |||||
| } | } | ||||
| .top-candidates-container { | .top-candidates-container { |
| import LogoutIcon from "@mui/icons-material/Logout"; | import LogoutIcon from "@mui/icons-material/Logout"; | ||||
| import UserProfile from "../Profile/UserProfile"; | import UserProfile from "../Profile/UserProfile"; | ||||
| import { useSelector } from "react-redux"; | import { useSelector } from "react-redux"; | ||||
| import { userSelector } from "../../store/selectors/userSelectors"; | |||||
| //import { userSelector } from "../../store/selectors/userSelectors"; | |||||
| import { Link } from "react-router-dom"; | import { Link } from "react-router-dom"; | ||||
| const NavbarComponent = () => { | const NavbarComponent = () => { | ||||
| let btnRef = useRef(); | let btnRef = useRef(); | ||||
| // get authenticated user | // get authenticated user | ||||
| const user = useSelector(userSelector); | |||||
| const {user} = useSelector(s => s.user); | |||||
| const { t } = useTranslation(); | const { t } = useTranslation(); | ||||
| import { useTranslation } from "react-i18next"; | import { useTranslation } from "react-i18next"; | ||||
| import avatarLogo from "../../assets/images/Avatar.png"; | import avatarLogo from "../../assets/images/Avatar.png"; | ||||
| import PropTypes from "prop-types"; | import PropTypes from "prop-types"; | ||||
| import { userSelector } from "../../store/selectors/userSelectors"; | |||||
| import { useDispatch, useSelector } from "react-redux"; | import { useDispatch, useSelector } from "react-redux"; | ||||
| import { logoutUser } from '../../store/actions/login/loginActions' | |||||
| import { logoutUser } from "../../store/actions/login/loginActions"; | |||||
| const UserProfile = ({ show, innerRef }) => { | const UserProfile = ({ show, innerRef }) => { | ||||
| const { t } = useTranslation(); | const { t } = useTranslation(); | ||||
| const dispatch = useDispatch() | |||||
| const dispatch = useDispatch(); | |||||
| // const theme = useTheme(); | // const theme = useTheme(); | ||||
| // const matches = useMediaQuery(theme.breakpoints.down("sm")); | // const matches = useMediaQuery(theme.breakpoints.down("sm")); | ||||
| const user = useSelector(userSelector); | |||||
| const { user } = useSelector((s) => s.user); | |||||
| const logout = () => { | const logout = () => { | ||||
| dispatch(logoutUser()) | |||||
| } | |||||
| dispatch(logoutUser()); | |||||
| }; | |||||
| return ( | return ( | ||||
| <Box className={`user-view flex-center ${show && "active"}`}> | <Box className={`user-view flex-center ${show && "active"}`}> |
| export const USERS_PAGE = '/users'; | export const USERS_PAGE = '/users'; | ||||
| export const USER_DETAILS_PAGE = '/users/:id'; | export const USER_DETAILS_PAGE = '/users/:id'; | ||||
| export const CANDIDATES_PAGE = '/candidates'; | export const CANDIDATES_PAGE = '/candidates'; | ||||
| export const CANDIDATES_DETAILS_PAGE = '/candidates/:id'; | |||||
| 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'; |
| @import './assets/styles/components/app-button'; | @import './assets/styles/components/app-button'; | ||||
| @import './assets/styles/components/usersPage'; | @import './assets/styles/components/usersPage'; | ||||
| @import './assets/styles/components/candidatesPage'; | @import './assets/styles/components/candidatesPage'; | ||||
| @import './assets/styles/components/candidatePage'; | |||||
| @import './assets/styles/components/loader'; | @import './assets/styles/components/loader'; | ||||
| @import './assets/styles/components/radio'; | @import './assets/styles/components/radio'; | ||||
| @import './assets/styles/components/modal'; | @import './assets/styles/components/modal'; |
| import React from "react"; | |||||
| import { useEffect, useState, useRef } from "react"; | |||||
| import { Link, useParams } from "react-router-dom"; | |||||
| import editImage from "../../../src/assets/images/edit.png"; | |||||
| import deleteImage from "../../../src/assets/images/delete.png"; | |||||
| import planeImage from "../../../src/assets/images/planeVectorBlue.png"; | |||||
| import dotnetImage from "../../../src/assets/images/.net_icon.png"; | |||||
| import IconButton from "../../components/IconButton/IconButton"; | |||||
| import { formatDateTime, formatDate } from "../../util/helpers/dateHelpers"; | |||||
| import { setUsersReq } from "../../store/actions/users/usersActions"; | |||||
| import { createCandidateComment } from "../../store/actions/candidate/candidateActions"; | |||||
| import { useDispatch, useSelector } from "react-redux"; | |||||
| import { MentionsInput, Mention } from "react-mentions"; | |||||
| import { fetchCandidate } from "../../store/actions/candidate/candidateActions"; | |||||
| import { useMediaQuery } from "@mui/material"; | |||||
| import { useTheme } from "@mui/system"; | |||||
| const CandidateDetailsPage = () => { | |||||
| const dispatch = useDispatch(); | |||||
| const { users } = useSelector((s) => s.users); | |||||
| const { user } = useSelector((s) => s.user); | |||||
| const { candidate } = useSelector((s) => s.candidate); | |||||
| const [value, setValue] = useState(""); | |||||
| let { id } = useParams(); | |||||
| const messageContainer = useRef(); | |||||
| const theme = useTheme(); | |||||
| const matches = useMediaQuery(theme.breakpoints.down("680")); | |||||
| useEffect(() => { | |||||
| dispatch(fetchCandidate({ id })); | |||||
| dispatch(setUsersReq()); | |||||
| }, [dispatch]); | |||||
| useEffect(() => { | |||||
| messageContainer.current !== undefined | |||||
| ? (messageContainer.current.scrollTop = | |||||
| messageContainer.current.scrollHeight) | |||||
| : ""; | |||||
| }, [messageContainer.current, candidate.comments]); | |||||
| const handleChange = (event) => { | |||||
| setValue(event.target.value); | |||||
| }; | |||||
| const getArray = () => { | |||||
| let newArray = users.map(function (value) { | |||||
| return { id: value.id, display: value.firstName + value.lastName }; | |||||
| }); | |||||
| return newArray; | |||||
| }; | |||||
| const tranformDisplay = (id, display) => { | |||||
| console.log(id); | |||||
| return "@" + display + " "; | |||||
| }; | |||||
| const sendComment = () => { | |||||
| // can't send an empty message | |||||
| if (value.trim().length === 0) { | |||||
| return; | |||||
| } | |||||
| dispatch( | |||||
| createCandidateComment({ | |||||
| content: value, | |||||
| userId: user.id, | |||||
| applicantId: parseInt(id), | |||||
| user: { | |||||
| id: user.id, | |||||
| firstName: user.firstName, | |||||
| lastName: user.lastName, | |||||
| email: user.email, | |||||
| }, | |||||
| }) | |||||
| ); | |||||
| setValue(""); | |||||
| }; | |||||
| return (candidate && Object.keys(candidate).length === 0) || | |||||
| user === undefined ? ( | |||||
| <p>Loading...</p> | |||||
| ) : ( | |||||
| <div className="main-candidate-container pl-144 pt-36px"> | |||||
| <div className="l-t-rectangle"></div> | |||||
| <div className="r-b-rectangle"></div> | |||||
| <div className="top-candidate-container"> | |||||
| <div> | |||||
| <p className="candidate-header">Kandidat</p> | |||||
| <span className="separation-line">|</span> | |||||
| <p className="candidate-lower-header"> | |||||
| {candidate.firstName} {candidate.lastName} | |||||
| </p> | |||||
| </div> | |||||
| <div className="candidate-option-container"> | |||||
| <IconButton className="c-btn c-btn--primary-outlined candidate-btn"> | |||||
| Obrisi | |||||
| <img src={deleteImage} alt="delete" className="candidates-image" /> | |||||
| </IconButton> | |||||
| <IconButton className="c-btn c-btn--primary-outlined candidate-btn"> | |||||
| Uredi profil | |||||
| <img src={editImage} alt="edit" className="candidates-image" /> | |||||
| </IconButton> | |||||
| </div> | |||||
| </div> | |||||
| <div className="content-candidate-container"> | |||||
| <div className="details-candidate-container"> | |||||
| <p style={{ margin: 0 }}> | |||||
| {candidate.experience === 0 | |||||
| ? "No experience" | |||||
| : "Experience:" + candidate.experience} | |||||
| </p> | |||||
| <div className="technologies-candidate-container"> | |||||
| {candidate.technologyApplicants.map((obj, index) => ( | |||||
| <div className="technology-candidate-card" key={index}> | |||||
| {obj.technology.name} | |||||
| </div> | |||||
| ))} | |||||
| </div> | |||||
| <div className="candidate-informations-container"> | |||||
| <div className="candidate-informations-sub-container"> | |||||
| <div className="candidate-property-container"> | |||||
| <p className="informations-candidate-header">Kontakt</p> | |||||
| <p className="candidate-property">Email:</p> | |||||
| <p className="candidate-property">Telefon:</p> | |||||
| </div> | |||||
| <div | |||||
| style={{ alignSelf: "flex-end", marginLeft: 42 }} | |||||
| className="candidate-property-container" | |||||
| > | |||||
| <p className="candidate-property-value">{candidate.email}</p> | |||||
| <p className="candidate-property-value"> | |||||
| {candidate.phoneNumber} | |||||
| </p> | |||||
| </div> | |||||
| </div> | |||||
| <div className="candidate-informations-sub-container"> | |||||
| <div className="candidate-property-container"> | |||||
| <p className="informations-candidate-header">Drustvene mreze</p> | |||||
| <p className="candidate-property">Linkedln</p> | |||||
| <p className="candidate-property">GitHub</p> | |||||
| <p className="candidate-property">BitBucket</p> | |||||
| </div> | |||||
| <div | |||||
| style={{ alignSelf: "flex-end", marginLeft: 42 }} | |||||
| className="candidate-property-container" | |||||
| > | |||||
| <p className="candidate-property-value"> | |||||
| {candidate.linkedlnLink ?? "/"} | |||||
| </p> | |||||
| <p className="candidate-property-value"> | |||||
| {candidate.gitHubLink ?? "/"} | |||||
| </p> | |||||
| <p className="candidate-property-value"> | |||||
| {candidate.bitBucketLink ?? "/"} | |||||
| </p> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div className="comment-container"> | |||||
| <div | |||||
| style={{ | |||||
| minHeight: "219px", | |||||
| overflowX: "auto", | |||||
| paddingBottom: "10px", | |||||
| paddingTop: "10px", | |||||
| }} | |||||
| ref={messageContainer} | |||||
| > | |||||
| {candidate.comments.map((comment, index) => ( | |||||
| <div className="comment-sub-container" key={index}> | |||||
| <div className="comment-sender"> | |||||
| <p> | |||||
| {comment.user.firstName.charAt(0)} | |||||
| {comment.user.lastName.charAt(0)} | |||||
| </p> | |||||
| </div> | |||||
| <div className="comment-message"> | |||||
| <p className="comment-message-content">{comment.content}</p> | |||||
| <p className="comment-message-date"> | |||||
| {formatDateTime(comment.dateOfSending)} | |||||
| </p> | |||||
| </div> | |||||
| </div> | |||||
| ))} | |||||
| </div> | |||||
| <div className="comment-separation-line"></div> | |||||
| <div className="send-comment-container"> | |||||
| <p>Komentar</p> | |||||
| <div className="send-comment-sub-container"> | |||||
| <MentionsInput | |||||
| value={value} | |||||
| onChange={handleChange} | |||||
| className="comment-input" | |||||
| placeholder={"ex. Odlican kandidat"} | |||||
| style={{ | |||||
| input: !matches | |||||
| ? { padding: 18, borderRadius: 7 } | |||||
| : { padding: 9, borderRadius: 5 }, | |||||
| control: !matches | |||||
| ? { | |||||
| padding: 18, | |||||
| color: "#fff", | |||||
| suggestions: { list: { backgroundColor: "#F4F4F4" } }, | |||||
| } | |||||
| : { | |||||
| padding: 9, | |||||
| color: "#fff", | |||||
| suggestions: { list: { backgroundColor: "#F4F4F4" } }, | |||||
| }, | |||||
| }} | |||||
| > | |||||
| <Mention | |||||
| trigger="@" | |||||
| className="comment-input-list" | |||||
| data={getArray} | |||||
| displayTransform={(id, display) => | |||||
| tranformDisplay(id, display) | |||||
| } | |||||
| markup="@[__display__]" | |||||
| style={{ highlighter: { padding: 18, borderRadius: 7 } }} | |||||
| /> | |||||
| </MentionsInput> | |||||
| <div className="comment-send-btn" onClick={sendComment}> | |||||
| <img | |||||
| src={planeImage} | |||||
| alt="plane" | |||||
| className="candidates-image" | |||||
| /> | |||||
| <p>Komentar</p> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div className="applicant-ads-container"> | |||||
| <p>Sve prijave</p> | |||||
| <div className="applicant-ads-sub-container"> | |||||
| {candidate.applicantAds.map((obj, index) => ( | |||||
| <div key={index} className="applicant-add"> | |||||
| <p className="applicant-add-date"> | |||||
| {formatDate(obj.add.createdAt)} | |||||
| </p> | |||||
| <p className="applicant-add-title">{obj.add.title}</p> | |||||
| <img | |||||
| src={dotnetImage} | |||||
| alt="technology-image" | |||||
| className="applicant-add-technology-image" | |||||
| /> | |||||
| <div className="applicant-add-site">dilig.net</div> | |||||
| </div> | |||||
| ))} | |||||
| </div> | |||||
| </div> | |||||
| <div className="applicant-ads-buttons-container"> | |||||
| <Link to="/candidates" className="applicant-ads-back-button"> | |||||
| Nazad na sve kandidate | |||||
| </Link> | |||||
| <div className="applicant-cv-button">Preuzmi cv</div> | |||||
| </div> | |||||
| </div> | |||||
| ); | |||||
| }; | |||||
| export default CandidateDetailsPage; |
| import React, { useEffect } from "react"; | import React, { useEffect } from "react"; | ||||
| import { useDispatch, useSelector } from "react-redux"; | import { useDispatch, useSelector } from "react-redux"; | ||||
| import { fetchCandidates } from "../../store/actions/candidates/candidatesActions"; | import { fetchCandidates } from "../../store/actions/candidates/candidatesActions"; | ||||
| import { refreshUserToken } from "../../store/actions/login/loginActions"; | |||||
| import tableImage from "../../assets/images/table.png"; | import tableImage from "../../assets/images/table.png"; | ||||
| import modeImage from "../../assets/images/mode.png"; | import modeImage from "../../assets/images/mode.png"; | ||||
| import filterImage from "../../assets/images/filters.png"; | import filterImage from "../../assets/images/filters.png"; | ||||
| import planeImage from "../../assets/images/planeVector.png"; | import planeImage from "../../assets/images/planeVector.png"; | ||||
| import { useMediaQuery } from "@mui/material"; | import { useMediaQuery } from "@mui/material"; | ||||
| import { useTheme } from "@mui/system"; | import { useTheme } from "@mui/system"; | ||||
| import { CANDIDATES_PAGE } from "../../constants/pages"; | |||||
| import PropTypes from 'prop-types'; | |||||
| const CandidatesPage = () => { | |||||
| const CandidatesPage = ({history}) => { | |||||
| const dispatch = useDispatch(); | const dispatch = useDispatch(); | ||||
| const {candidates} = useSelector((s) => s.candidates); | const {candidates} = useSelector((s) => s.candidates); | ||||
| const theme = useTheme(); | const theme = useTheme(); | ||||
| const matches = useMediaQuery(theme.breakpoints.down("sm")); | const matches = useMediaQuery(theme.breakpoints.down("sm")); | ||||
| useEffect(() => { | useEffect(() => { | ||||
| dispatch(refreshUserToken()); | |||||
| dispatch(fetchCandidates()); | dispatch(fetchCandidates()); | ||||
| }, [dispatch]); | }, [dispatch]); | ||||
| const navigate = (applicantId) => { | |||||
| history.push({ | |||||
| pathname: CANDIDATES_PAGE + "/" + applicantId, | |||||
| state: { | |||||
| from: history.location.pathname, | |||||
| }, | |||||
| }) | |||||
| } | |||||
| return candidates[0] === undefined ? ( | return candidates[0] === undefined ? ( | ||||
| <p>Loading...</p> | <p>Loading...</p> | ||||
| ) : ( | ) : ( | ||||
| <div className="main-candidates-container"> | |||||
| <div className="main-candidates-container pl-144 pt-36px"> | |||||
| <div className="l-t-rectangle"></div> | |||||
| <div className="r-b-rectangle"></div> | |||||
| <div className="top-candidates-container"> | <div className="top-candidates-container"> | ||||
| {!matches ? ( | {!matches ? ( | ||||
| <p className="candidates-header">Kandidati</p> | <p className="candidates-header">Kandidati</p> | ||||
| <tr | <tr | ||||
| key={index} | key={index} | ||||
| className="secondaryRow cadidate-row" | className="secondaryRow cadidate-row" | ||||
| style={{ width: "800px", height: "40px", borderRadius: "12px" }} | |||||
| style={{ width: "800px", height: "40px", borderRadius: "12px",cursor:"pointer" }} | |||||
| onClick={() => navigate(candidate.applicantId)} | |||||
| > | > | ||||
| <td> | <td> | ||||
| {candidate.firstName} {candidate.lastName} | {candidate.firstName} {candidate.lastName} | ||||
| ); | ); | ||||
| }; | }; | ||||
| CandidatesPage.propTypes = { | |||||
| history: PropTypes.shape({ | |||||
| replace: PropTypes.func, | |||||
| push: PropTypes.func, | |||||
| location: PropTypes.shape({ | |||||
| pathname: PropTypes.string, | |||||
| }), | |||||
| }), | |||||
| } | |||||
| export default CandidatesPage; | export default CandidatesPage; |
| allArchiveAds: base + "/ads/archive", | allArchiveAds: base + "/ads/archive", | ||||
| adDetails: base + "/ads/details", | adDetails: base + "/ads/details", | ||||
| }, | }, | ||||
| <<<<<<< HEAD | |||||
| candidates:{ | |||||
| allCandidates:base + "/applicants", | |||||
| }, | |||||
| comments:{ | |||||
| addComment:base + '/comments' | |||||
| } | |||||
| ======= | |||||
| >>>>>>> FE_dev | |||||
| }; | }; |
| import { getRequest } from "."; | |||||
| import { getRequest, postRequest } from "."; | |||||
| import apiEndpoints from "./apiEndpoints"; | import apiEndpoints from "./apiEndpoints"; | ||||
| export const getAllCandidates = () => getRequest(apiEndpoints.candidates.allCandidates) | |||||
| export const getAllCandidates = () => getRequest(apiEndpoints.candidates.allCandidates) | |||||
| export const getCandidate = (id) => getRequest(apiEndpoints.candidates.allCandidates + "/" + id) | |||||
| export const createComment = (data) => postRequest(apiEndpoints.comments.addComment,data) |
| import { | |||||
| createErrorType, | |||||
| createFetchType, | |||||
| createLoadingType, | |||||
| createSuccessType, | |||||
| } from "../actionHelpers"; | |||||
| const CANDIDATE_SCOPE = 'CANDIDATE' | |||||
| const CANDIDATE_SCOPE_COMMENTS = 'CANDIDATE_COMMENTS' | |||||
| export const CANDIDATE_FETCH = createFetchType(CANDIDATE_SCOPE); | |||||
| export const CANDIDATE_ERROR = createErrorType(CANDIDATE_SCOPE) | |||||
| export const CANDIDATE_SUCCESS = createSuccessType(CANDIDATE_SCOPE) | |||||
| export const CANDIDATE_LOADING = createLoadingType(CANDIDATE_SCOPE) | |||||
| export const CANDIDATE_COMMENTS_FETCH = createFetchType(CANDIDATE_SCOPE_COMMENTS); | |||||
| export const CANDIDATE_COMMENTS_ERROR = createErrorType(CANDIDATE_SCOPE_COMMENTS) | |||||
| export const CANDIDATE_COMMENTS_SUCCESS = createSuccessType(CANDIDATE_SCOPE_COMMENTS) | |||||
| export const CANDIDATE_COMMENTS_LOADING = createLoadingType(CANDIDATE_SCOPE_COMMENTS) |
| import { | |||||
| CANDIDATE_FETCH, | |||||
| CANDIDATE_ERROR, | |||||
| CANDIDATE_SUCCESS, | |||||
| CANDIDATE_COMMENTS_FETCH, | |||||
| CANDIDATE_COMMENTS_ERROR, | |||||
| CANDIDATE_COMMENTS_SUCCESS, | |||||
| } from "./candidateActionConstants"; | |||||
| export const fetchCandidate = (payload) => ({ | |||||
| type: CANDIDATE_FETCH, | |||||
| payload, | |||||
| }); | |||||
| export const fetchCandidateError = (payload) => ({ | |||||
| type: CANDIDATE_ERROR, | |||||
| payload, | |||||
| }); | |||||
| export const fetchCandidateSuccess = (payload) => ({ | |||||
| type: CANDIDATE_SUCCESS, | |||||
| payload, | |||||
| }); | |||||
| export const createCandidateComment = (payload) => ({ | |||||
| type: CANDIDATE_COMMENTS_FETCH, | |||||
| payload, | |||||
| }); | |||||
| export const createCandidateCommentError = (payload) => ({ | |||||
| type: CANDIDATE_COMMENTS_ERROR, | |||||
| payload, | |||||
| }); | |||||
| export const createCandidateCommentSuccess = (payload) => ({ | |||||
| type: CANDIDATE_COMMENTS_SUCCESS, | |||||
| payload, | |||||
| }); |
| export const fetchCandidatesSuccess = (payload) => ({ | export const fetchCandidatesSuccess = (payload) => ({ | ||||
| type: CANDIDATES_SUCCESS, | type: CANDIDATES_SUCCESS, | ||||
| payload, | payload, | ||||
| }); | |||||
| }); | |||||
| if ( | if ( | ||||
| error.response.config.url !== apiEndpoints.authentications.login && | error.response.config.url !== apiEndpoints.authentications.login && | ||||
| error.response.config.url !== | error.response.config.url !== | ||||
| apiEndpoints.authentications.confirmSecurityQuestion && | |||||
| apiEndpoints.authentications.confirmSecurityQuestion && | |||||
| error.response.status === 401 | error.response.status === 401 | ||||
| ) { | ) { | ||||
| return dispatch(logoutUser()); | return dispatch(logoutUser()); |
| import createReducer from "../../utils/createReducer"; | |||||
| import { | |||||
| CANDIDATE_ERROR, | |||||
| CANDIDATE_SUCCESS, | |||||
| CANDIDATE_COMMENTS_SUCCESS, | |||||
| CANDIDATE_COMMENTS_ERROR, | |||||
| } from "../../actions/candidate/candidateActionConstants"; | |||||
| const initialState = { | |||||
| candidate: {}, | |||||
| errorMessage: "", | |||||
| }; | |||||
| export default createReducer( | |||||
| { | |||||
| [CANDIDATE_SUCCESS]: setCandidate, | |||||
| [CANDIDATE_ERROR]: setError, | |||||
| [CANDIDATE_COMMENTS_SUCCESS]: setComments, | |||||
| [CANDIDATE_COMMENTS_ERROR]: setCommentsError, | |||||
| }, | |||||
| initialState | |||||
| ); | |||||
| function setCandidate(state, action) { | |||||
| return { | |||||
| ...state, | |||||
| candidate: action.payload, | |||||
| }; | |||||
| } | |||||
| function setError(state, action) { | |||||
| return { | |||||
| ...state, | |||||
| errorMessage: action.payload, | |||||
| }; | |||||
| } | |||||
| function setComments(state, action) { | |||||
| const currentDate = new Date(); | |||||
| var datetime = | |||||
| currentDate.getFullYear() + | |||||
| "-" + | |||||
| (currentDate.getMonth() + 1) + | |||||
| "-" + | |||||
| currentDate.getDate() + | |||||
| "T" + | |||||
| currentDate.getHours() + | |||||
| ":" + | |||||
| (currentDate.getMinutes() <= 9 | |||||
| ? "0" + currentDate.getMinutes() | |||||
| : currentDate.getMinutes()) + | |||||
| ":" + | |||||
| (currentDate.getSeconds() <= 9 | |||||
| ? "0" + currentDate.getSeconds() | |||||
| : currentDate.getSeconds()); | |||||
| const obj = { | |||||
| content: action.payload.myObj.content, | |||||
| dateOfSending: datetime, | |||||
| user: action.payload.user, | |||||
| }; | |||||
| return { | |||||
| ...state, | |||||
| candidate: { | |||||
| ...state.candidate, | |||||
| comments: [...state.candidate.comments, obj], | |||||
| }, | |||||
| }; | |||||
| } | |||||
| function setCommentsError(state, action) { | |||||
| return { | |||||
| ...state, | |||||
| errorMessage: action.payload, | |||||
| }; | |||||
| } |
| export default createReducer( | export default createReducer( | ||||
| { | { | ||||
| [CANDIDATES_SUCCESS]: setCandidates, | [CANDIDATES_SUCCESS]: setCandidates, | ||||
| [CANDIDATES_ERROR]: setError, | |||||
| [CANDIDATES_ERROR]: setError | |||||
| }, | }, | ||||
| initialState | initialState | ||||
| ); | ); | ||||
| ...state, | ...state, | ||||
| errorMessage: action.payload, | errorMessage: action.payload, | ||||
| }; | }; | ||||
| } | |||||
| } |
| <<<<<<< HEAD | |||||
| import { combineReducers } from 'redux'; | |||||
| import loginReducer from './login/loginReducer'; | |||||
| import loadingReducer from './loading/loadingReducer'; | |||||
| import userReducer from './user/userReducer'; | |||||
| import randomDataReducer from './randomData/randomDataReducer'; | |||||
| import usersReducer from './user/usersReducer'; | |||||
| import candidatesReducer from './candidates/candidatesReducer'; | |||||
| import candidateReducer from './candidate/candidateReducer'; | |||||
| ======= | |||||
| import { combineReducers } from "redux"; | import { combineReducers } from "redux"; | ||||
| import loginReducer from "./login/loginReducer"; | import loginReducer from "./login/loginReducer"; | ||||
| import loadingReducer from "./loading/loadingReducer"; | import loadingReducer from "./loading/loadingReducer"; | ||||
| import adReducer from "./ad/adReducer"; | import adReducer from "./ad/adReducer"; | ||||
| import archiveAdsReducer from "./ad/archiveAdsReducer"; | import archiveAdsReducer from "./ad/archiveAdsReducer"; | ||||
| import candidatesReducer from "./candidates/candidatesReducer"; | import candidatesReducer from "./candidates/candidatesReducer"; | ||||
| >>>>>>> FE_dev | |||||
| export default combineReducers({ | export default combineReducers({ | ||||
| login: loginReducer, | login: loginReducer, | ||||
| loading: loadingReducer, | loading: loadingReducer, | ||||
| randomData: randomDataReducer, | randomData: randomDataReducer, | ||||
| users: usersReducer, | users: usersReducer, | ||||
| <<<<<<< HEAD | |||||
| candidates:candidatesReducer, | |||||
| candidate:candidateReducer | |||||
| ======= | |||||
| ads: adsReducer, | ads: adsReducer, | ||||
| ad: adReducer, | ad: adReducer, | ||||
| archiveAds: archiveAdsReducer, | archiveAds: archiveAdsReducer, | ||||
| candidates: candidatesReducer, | candidates: candidatesReducer, | ||||
| >>>>>>> FE_dev | |||||
| }); | }); |
| import createReducer from '../../utils/createReducer'; | |||||
| import createReducer from "../../utils/createReducer"; | |||||
| import { | import { | ||||
| SET_USER, | SET_USER, | ||||
| SET_USER_ERROR, | SET_USER_ERROR, | ||||
| RESET_USER_STATE | |||||
| } from '../../actions/user/userActionConstants'; | |||||
| RESET_USER_STATE, | |||||
| } from "../../actions/user/userActionConstants"; | |||||
| const initialState = { | const initialState = { | ||||
| id:"", | |||||
| firstName:"", | |||||
| lastName:"", | |||||
| username:"", | |||||
| token:"", | |||||
| refreshToken:"" | |||||
| user: { | |||||
| id: "", | |||||
| firstName: "", | |||||
| lastName: "", | |||||
| username: "", | |||||
| token: "", | |||||
| refreshToken: "", | |||||
| }, | |||||
| errorMessage: "", | |||||
| }; | }; | ||||
| export default createReducer( | export default createReducer( | ||||
| { | { | ||||
| [SET_USER]: setUser, | [SET_USER]: setUser, | ||||
| [SET_USER_ERROR]: setUserError, | [SET_USER_ERROR]: setUserError, | ||||
| [RESET_USER_STATE]:resetUserState | |||||
| [RESET_USER_STATE]: resetUserState, | |||||
| }, | }, | ||||
| initialState, | |||||
| initialState | |||||
| ); | ); | ||||
| function setUser(state, action) { | function setUser(state, action) { | ||||
| return { | return { | ||||
| id:action.payload.id, | |||||
| firstName:action.payload.firstName, | |||||
| lastName:action.payload.lastName, | |||||
| username:action.payload.username, | |||||
| token:action.payload.token, | |||||
| refreshToken:action.payload.refreshToken, | |||||
| ...state, | |||||
| user: action.payload, | |||||
| }; | }; | ||||
| } | } | ||||
| import { all, call, put, takeEvery } from "redux-saga/effects"; | import { all, call, put, takeEvery } from "redux-saga/effects"; | ||||
| import { JWT_TOKEN } from "../../constants/localStorage"; | import { JWT_TOKEN } from "../../constants/localStorage"; | ||||
| import { addHeaderToken } from "../../request"; | import { addHeaderToken } from "../../request"; | ||||
| import { getAllCandidates } from "../../request/candidatesRequest"; | |||||
| import { getAllCandidates,createComment,getCandidate } from "../../request/candidatesRequest"; | |||||
| import { authScopeStringGetHelper } from "../../util/helpers/authScopeHelpers"; | import { authScopeStringGetHelper } from "../../util/helpers/authScopeHelpers"; | ||||
| import { CANDIDATES_FETCH } from "../actions/candidates/candidatesActionConstants"; | |||||
| import { CANDIDATES_FETCH} from "../actions/candidates/candidatesActionConstants"; | |||||
| import { fetchCandidatesError,fetchCandidatesSuccess } from "../actions/candidates/candidatesActions"; | import { fetchCandidatesError,fetchCandidatesSuccess } from "../actions/candidates/candidatesActions"; | ||||
| import { rejectErrorCodeHelper } from '../../util/helpers/rejectErrorCodeHelper'; | import { rejectErrorCodeHelper } from '../../util/helpers/rejectErrorCodeHelper'; | ||||
| import { fetchCandidateError, fetchCandidateSuccess,createCandidateCommentSuccess,createCandidateCommentError } from "../actions/candidate/candidateActions"; | |||||
| import { CANDIDATE_FETCH,CANDIDATE_COMMENTS_FETCH } from "../actions/candidate/candidateActionConstants"; | |||||
| export function* getCandidates() { | export function* getCandidates() { | ||||
| try { | try { | ||||
| console.log('oVde smo') | |||||
| const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN); | const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN); | ||||
| yield call(addHeaderToken, JwtToken); | yield call(addHeaderToken, JwtToken); | ||||
| const {data} = yield call(getAllCandidates); | const {data} = yield call(getAllCandidates); | ||||
| } | } | ||||
| } | } | ||||
| export function* getSingleCandidate({payload}){ | |||||
| try{ | |||||
| const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN); | |||||
| yield call(addHeaderToken, JwtToken); | |||||
| const {data} = yield call(getCandidate,payload.id) | |||||
| yield put(fetchCandidateSuccess(data)) | |||||
| } catch(error){ | |||||
| const errorMessage = yield call(rejectErrorCodeHelper, error); | |||||
| yield put(fetchCandidateError(errorMessage)) | |||||
| } | |||||
| } | |||||
| export function* addComment(data) { | |||||
| const {user,...myObj} = data.payload | |||||
| try{ | |||||
| const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN); | |||||
| yield call(addHeaderToken, JwtToken); | |||||
| yield call(createComment,myObj); | |||||
| yield put(createCandidateCommentSuccess({user,myObj})) | |||||
| } catch (error){ | |||||
| const errorMessage = yield call(rejectErrorCodeHelper, error); | |||||
| yield put(createCandidateCommentError(errorMessage)) | |||||
| } | |||||
| } | |||||
| export default function* candidatesSaga() { | export default function* candidatesSaga() { | ||||
| yield all([takeEvery(CANDIDATES_FETCH, getCandidates)]); | yield all([takeEvery(CANDIDATES_FETCH, getCandidates)]); | ||||
| yield all([takeEvery(CANDIDATE_FETCH, getSingleCandidate)]); | |||||
| yield all([takeEvery(CANDIDATE_COMMENTS_FETCH, addComment)]); | |||||
| } | } |
| import { createSelector } from "@reduxjs/toolkit"; | |||||
| export const candidateSelector = (state) => state.candidate; | |||||
| export const selectCandidate = createSelector( | |||||
| candidateSelector, | |||||
| (state) => state.candidate, | |||||
| ); |
| export function formatDateTime(date) { | export function formatDateTime(date) { | ||||
| const dt = new Date(date); | const dt = new Date(date); | ||||
| return format(dt, 'MM/dd/y hh:mm aa'); | |||||
| return format(dt, 'hh:mm dd.MM.y'); | |||||
| } | } | ||||
| export function getDateDay(date) { | export function getDateDay(date) { |
| "core-js-pure" "^3.0.0" | "core-js-pure" "^3.0.0" | ||||
| "regenerator-runtime" "^0.13.4" | "regenerator-runtime" "^0.13.4" | ||||
| "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2", "@babel/runtime@7.12.1": | |||||
| "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.3.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2", "@babel/runtime@7.12.1": | |||||
| "integrity" "sha512-J5AIf3vPj3UwXaAzb5j1xM4WAQDX3EMgemF8rjCP3SoW09LfRKAXQKt6CoVYl230P6iWdRcBbnLDDdnqWxZSCA==" | "integrity" "sha512-J5AIf3vPj3UwXaAzb5j1xM4WAQDX3EMgemF8rjCP3SoW09LfRKAXQKt6CoVYl230P6iWdRcBbnLDDdnqWxZSCA==" | ||||
| "resolved" "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.1.tgz" | "resolved" "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.1.tgz" | ||||
| "version" "7.12.1" | "version" "7.12.1" | ||||
| dependencies: | dependencies: | ||||
| "regenerator-runtime" "^0.13.4" | "regenerator-runtime" "^0.13.4" | ||||
| "@babel/runtime@7.4.5": | |||||
| "integrity" "sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ==" | |||||
| "resolved" "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.5.tgz" | |||||
| "version" "7.4.5" | |||||
| dependencies: | |||||
| "regenerator-runtime" "^0.13.2" | |||||
| "@babel/template@^7.10.4", "@babel/template@^7.12.13", "@babel/template@^7.3.3": | "@babel/template@^7.10.4", "@babel/template@^7.12.13", "@babel/template@^7.3.3": | ||||
| "integrity" "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==" | "integrity" "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==" | ||||
| "resolved" "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz" | "resolved" "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz" | ||||
| "strip-ansi" "6.0.0" | "strip-ansi" "6.0.0" | ||||
| "text-table" "0.2.0" | "text-table" "0.2.0" | ||||
| "react-dom@^17.0.2": | |||||
| "react-dom@^16.6.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.8.0 || ^17.0.0", "react-dom@^17.0.0 || ^18.0.0", "react-dom@^17.0.2", "react-dom@^17.0.2 || ^18.0.0", "react-dom@<18.0.0", "react-dom@>=16.6.0", "react-dom@>=16.8.3": | |||||
| "integrity" "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==" | "integrity" "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==" | ||||
| "resolved" "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz" | "resolved" "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz" | ||||
| "version" "17.0.2" | "version" "17.0.2" | ||||
| "resolved" "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz" | "resolved" "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz" | ||||
| "version" "18.2.0" | "version" "18.2.0" | ||||
| "react-redux@^7.2.4": | |||||
| "react-mentions@^4.4.7": | |||||
| "integrity" "sha512-VNriu2h/uOB+RS0mwZgPG2Vf+UtdDvRh5zbXa2TNc1WqacKuNDgTdhlbo9LEOZRBxRzIeTUYQmYJ7p9M9rDHqQ==" | |||||
| "resolved" "https://registry.npmjs.org/react-mentions/-/react-mentions-4.4.7.tgz" | |||||
| "version" "4.4.7" | |||||
| dependencies: | |||||
| "@babel/runtime" "7.4.5" | |||||
| "invariant" "^2.2.4" | |||||
| "prop-types" "^15.5.8" | |||||
| "substyle" "^9.1.0" | |||||
| "react-redux@^7.2.1 || ^8.0.2", "react-redux@^7.2.4": | |||||
| "integrity" "sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==" | "integrity" "sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==" | ||||
| "resolved" "https://registry.npmjs.org/react-redux/-/react-redux-7.2.9.tgz" | "resolved" "https://registry.npmjs.org/react-redux/-/react-redux-7.2.9.tgz" | ||||
| "version" "7.2.9" | "version" "7.2.9" | ||||
| "loose-envify" "^1.4.0" | "loose-envify" "^1.4.0" | ||||
| "prop-types" "^15.6.2" | "prop-types" "^15.6.2" | ||||
| "react@^17.0.2": | |||||
| "react@^16.0.0 || ^17.0.0 || ^18.0.0", "react@^16.3.0 || ^17.0.0", "react@^16.6.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17.0.0", "react@^16.8.3 || ^17 || ^18", "react@^16.9.0 || ^17.0.0 || ^18", "react@^17.0.0 || ^18.0.0", "react@^17.0.2", "react@^17.0.2 || ^18.0.0", "react@^18.2.0", "react@<18.0.0", "react@>= 16", "react@>= 16.8.0", "react@>=15", "react@>=16.6.0", "react@>=16.8.0", "react@>=16.8.3", "react@17.0.2": | |||||
| "integrity" "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==" | "integrity" "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==" | ||||
| "resolved" "https://registry.npmjs.org/react/-/react-17.0.2.tgz" | "resolved" "https://registry.npmjs.org/react/-/react-17.0.2.tgz" | ||||
| "version" "17.0.2" | "version" "17.0.2" | ||||
| "resolved" "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz" | "resolved" "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz" | ||||
| "version" "0.11.1" | "version" "0.11.1" | ||||
| "regenerator-runtime@^0.13.4", "regenerator-runtime@^0.13.7": | |||||
| "regenerator-runtime@^0.13.2", "regenerator-runtime@^0.13.4", "regenerator-runtime@^0.13.7": | |||||
| "integrity" "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" | "integrity" "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" | ||||
| "resolved" "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz" | "resolved" "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz" | ||||
| "version" "0.13.7" | "version" "0.13.7" | ||||
| "resolved" "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz" | "resolved" "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz" | ||||
| "version" "4.0.13" | "version" "4.0.13" | ||||
| "substyle@^9.1.0": | |||||
| "integrity" "sha512-VOngeq/W1/UkxiGzeqVvDbGDPM8XgUyJVWjrqeh+GgKqspEPiLYndK+XRcsKUHM5Muz/++1ctJ1QCF/OqRiKWA==" | |||||
| "resolved" "https://registry.npmjs.org/substyle/-/substyle-9.4.1.tgz" | |||||
| "version" "9.4.1" | |||||
| dependencies: | |||||
| "@babel/runtime" "^7.3.4" | |||||
| "invariant" "^2.2.4" | |||||
| "supports-color@^5.3.0": | "supports-color@^5.3.0": | ||||
| "integrity" "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==" | "integrity" "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==" | ||||
| "resolved" "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" | "resolved" "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" |