diff --git a/src/App.js b/src/App.js index 3e807c38..738fec5f 100644 --- a/src/App.js +++ b/src/App.js @@ -28,6 +28,8 @@ import {PartnerBid} from './pages/PartnerBid/PartnerBid' import {PartnerCategories} from "./pages/PartnerСategories/PartnerСategories"; import {PartnerTreaties} from "./pages/PartnerTreaties/PartnerTreaties"; import {PartnerEmployees} from "./pages/PartnerEmployees/PartnerEmployees"; +import {AuthForCandidate} from "./pages/AuthForCandidate/AuthForCandidate"; +import {RegistrationForCandidate} from "./pages/RegistrationForCandidate/RegistrationForCandidate"; import './fonts/stylesheet.css' import 'bootstrap/dist/css/bootstrap.min.css' @@ -44,6 +46,8 @@ const App = () => { }/> }/> + }/> + }/> }/> }/> @@ -77,7 +81,7 @@ const App = () => { }/> - }/> + }/> diff --git a/src/components/AuthHeader/AuthHeader.js b/src/components/AuthHeader/AuthHeader.js index 8f1c65d3..f86d48aa 100644 --- a/src/components/AuthHeader/AuthHeader.js +++ b/src/components/AuthHeader/AuthHeader.js @@ -1,4 +1,5 @@ import React from "react"; +import { NavLink } from "react-router-dom"; import userIcon from "../../images/userIcon.png"; @@ -17,7 +18,11 @@ export const AuthHeader = ({}) => {
diff --git a/src/components/AuthHeader/authHeader.scss b/src/components/AuthHeader/authHeader.scss index 1447a2b9..921f8388 100644 --- a/src/components/AuthHeader/authHeader.scss +++ b/src/components/AuthHeader/authHeader.scss @@ -41,14 +41,20 @@ font-size: 18px; line-height: 32px; - a, - a:hover { + a { color: #897676; } + a:hover { + text-decoration: none; + } a:focus { color: #000000; } + + .candidate { + color: #1458DD; + } } } } diff --git a/src/components/CategoriesItem/CategoriesItem.js b/src/components/CategoriesItem/CategoriesItem.js new file mode 100644 index 00000000..97b472b3 --- /dev/null +++ b/src/components/CategoriesItem/CategoriesItem.js @@ -0,0 +1,25 @@ +import React from "react"; +import {Link} from "react-router-dom"; + +import rightArrow from "../../images/arrowRight.png" + +import './categoriesItem.scss' + +export const CategoriesItem = ({img, title, skills, available, link}) => { + return( + +
+ img +
{title}
+
+
+

{skills}

+
+ arrow +
+
+ + ) +}; + +export default CategoriesItem diff --git a/src/components/CategoriesItem/categoriesItem.scss b/src/components/CategoriesItem/categoriesItem.scss new file mode 100644 index 00000000..26cd6db8 --- /dev/null +++ b/src/components/CategoriesItem/categoriesItem.scss @@ -0,0 +1,63 @@ +.categoriesItem { + display: flex; + flex-direction: column; + padding: 33px 32px 25px 28px; + width: 32%; + background: #FFFFFF; + border-radius: 12px; + transition: all 0.3s ease; + position: relative; + + &:hover { + box-shadow: 6px 5px 20px rgba(87, 98, 80, 0.21); + transform: scale(1.02); + text-decoration: none; + } + + &__disable { + opacity: 0.5; + pointer-events: none; + } + + + &__title { + display: flex; + align-items: center; + margin-bottom: 27px; + + h5 { + color: #000000; + font-weight: 500; + font-size: 18px; + line-height: 22px; + margin-left: 18px; + max-width: 190px; + margin-bottom: 0; + } + } + + &__description { + display: flex; + justify-content: space-between; + align-items: center; + + p { + max-width: 181px; + margin-bottom: 0; + color: #6F6F6F; + font-weight: 400; + font-size: 12px; + line-height: 20px; + } + + .more { + display: flex; + align-items: center; + justify-content: center; + width: 48px; + height: 48px; + background: #DDEEC6; + border-radius: 50px; + } + } +} diff --git a/src/components/StepsForCandidate/StepsForCandidate.js b/src/components/StepsForCandidate/StepsForCandidate.js new file mode 100644 index 00000000..8656d458 --- /dev/null +++ b/src/components/StepsForCandidate/StepsForCandidate.js @@ -0,0 +1,20 @@ +import React from 'react'; + +import './stepForCandidate.scss' + +export const StepsForCandidate = ({step}) => { + return( +
+
+ 2 +

шага для твоего входа в команду

+
+
+

{step}

+ из 2 +
+
+ ) +}; + +export default StepsForCandidate diff --git a/src/components/StepsForCandidate/stepForCandidate.scss b/src/components/StepsForCandidate/stepForCandidate.scss new file mode 100644 index 00000000..165953d8 --- /dev/null +++ b/src/components/StepsForCandidate/stepForCandidate.scss @@ -0,0 +1,50 @@ +.step { + position: absolute; + display: flex; + align-items: center; + justify-content: space-between; + top: -100px; + padding:0 55px 0 85px; + width: 100%; + + &__start { + display: flex; + align-items: center; + + span { + font-weight: 900; + font-size: 258px; + line-height: 32px; + color: #52B709; + } + + p { + margin-left: 20px; + max-width: 230px; + font-weight: 500; + font-size: 22px; + line-height: 32px; + color: #000000; + } + } + + &__info { + display: flex; + align-items: center; + p { + background: #DDEEC6; + border-radius: 44px; + padding: 8px 26px; + font-weight: 400; + font-size: 16px; + line-height: 32px; + } + + span { + margin-left: 55px; + font-weight: 400; + font-size: 16px; + line-height: 32px; + } + } +} diff --git a/src/images/authCandidateFormImg.png b/src/images/authCandidateFormImg.png new file mode 100644 index 00000000..37cb25bf Binary files /dev/null and b/src/images/authCandidateFormImg.png differ diff --git a/src/pages/AuthForCandidate/AuthForCandidate.js b/src/pages/AuthForCandidate/AuthForCandidate.js new file mode 100644 index 00000000..05bf8fe2 --- /dev/null +++ b/src/pages/AuthForCandidate/AuthForCandidate.js @@ -0,0 +1,188 @@ +import React, {useEffect, useRef, useState} from "react"; +import {loading, selectIsLoading} from "../../redux/loaderSlice"; +import {apiRequest} from "../../api/request"; +import {auth, selectAuth, setUserInfo} from "../../redux/outstaffingSlice"; +import {setRole} from "../../redux/roleSlice"; +import {useDispatch, useSelector} from "react-redux"; +import { useNavigate } from "react-router-dom"; + +import AuthHeader from "../../components/AuthHeader/AuthHeader"; +import SideBar from "../../components/SideBar/SideBar"; +import CategoriesItem from "../../components/CategoriesItem/CategoriesItem" +import StepsForCandidate from "../../components/StepsForCandidate/StepsForCandidate" +import {Footer} from "../../components/Footer/Footer"; + +import BackEndImg from "../../pages/PartnerСategories/images/personalBackEnd.png" +import FrontendImg from "../../pages/PartnerСategories/images/PersonalFrontend.png" +import ArchitectureImg from "../../pages/PartnerСategories/images/PersonalArchitecture.png" +import DesignImg from "../../pages/PartnerСategories/images/PersonalDesign.png" +import TestImg from "../../pages/PartnerСategories/images/PersonalTesters.png" +import AdminImg from "../../pages/PartnerСategories/images/PersonalAdmin.png" +import ManageImg from "../../pages/PartnerСategories/images/PersonalMng.png" +import CopyImg from "../../pages/PartnerСategories/images/PersonalCopy.png" +import SmmImg from "../../pages/PartnerСategories/images/PersonalSMM.png" + +import authImg from "../../images/authCandidateFormImg.png" +import arrowBtn from "../../images/arrowRight.png"; + +import './authForCandidate.scss'; + +export const AuthForCandidate = () => { + + const isLoading = useSelector(selectIsLoading); + const ref = useRef(); + const dispatch = useDispatch(); + const isAuth = useSelector(selectAuth); + let navigate = useNavigate(); + const getToken = localStorage.getItem("auth_token"); + + const [personalInfoItems] = useState([ + { + title: 'Backend разработчики', + link: '/registration-candidate', + description: 'Java PHP Python C# React Vue.js NodeJs Golang Ruby JavaScript', + available: true, + img: BackEndImg + }, + { + title: 'Frontend разработчики', + link: '/registration-candidate', + description: 'Java PHP Python C# React Vue.js NodeJs Golang Ruby JavaScript', + available: true, + img: FrontendImg + }, + { + title: 'Архитектура проектов', + link: '/registration-candidate', + description: 'Потоки данных ER ERP CRM CQRS UML BPMN', + available: true, + img: ArchitectureImg + }, + { + title: 'Дизайн проектов', + link: '/registration-candidate', + description: 'Java PHP Python C# React Vue.js NodeJs Golang Ruby JavaScript', + available: true, + img: DesignImg + }, + { + title: 'Тестирование проектов', + link: '/registration-candidate', + description: 'SQL Postman TestRail Kibana Ручное тестирование', + available: false, + img: TestImg + }, + { + title: 'Администрирование проектов', + link: '/registration-candidate', + description: 'DevOps ELK Kubernetes Docker Bash Apache Oracle Git', + available: false, + img: AdminImg + }, + { + title: 'Управление проектом', + link: '/registration-candidate', + description: 'Scrum Kanban Agile Miro CustDev', + available: false, + img: ManageImg + }, + { + title: 'Копирайтинг проектов', + link: '/registration-candidate', + description: 'Теги Заголовок H1 Дескриптор Абзац Сценарий', + available: false, + img: CopyImg + }, + { + title: 'Реклама и SMM', + link: '/registration-candidate', + description: 'Java PHP Python C# React Vue.js NodeJs Golang Ruby JavaScript', + available: false, + img: SmmImg + }, + ]); + + useEffect(() => { + if (isAuth || getToken) { + navigate("/profile"); + } + }, [getToken]); + + const submitHandler = () => { + let formData = new FormData(ref.current); + if (!isLoading) { + dispatch(loading(true)); + apiRequest("/user/login", { + method: "POST", + data: formData, + }).then((res) => { + if (!res.access_token) { + dispatch(loading(false)); + } else { + localStorage.setItem("auth_token", res.access_token); + localStorage.setItem("id", res.id); + localStorage.setItem("cardId", res.card_id); + localStorage.setItem("role_status", res.status); + localStorage.setItem( + "access_token_expired_at", + res.access_token_expired_at + ); + dispatch(auth(true)); + dispatch(setUserInfo(res)); + dispatch(loading(false)); + dispatch(setRole("ROLE_PARTNER")); + } + }); + } + }; + + return( +
+ +
+
+
+

Войти, уже есть доступ

+ img +

если вы получили доступ пройдя 2 шага для входа или хотите узнать свои результаты в кабинете

+
+
+ + + + + + +
+
+
+

Хочу в команду Айти специалистов

+
+ +
+

Для нас не имеет значение Ваша локация.

+
+ + {personalInfoItems.map((item, index) => { + return + }) + + } +
+
+
+ +
+
+ ) +}; diff --git a/src/pages/AuthForCandidate/authForCandidate.scss b/src/pages/AuthForCandidate/authForCandidate.scss new file mode 100644 index 00000000..2b648202 --- /dev/null +++ b/src/pages/AuthForCandidate/authForCandidate.scss @@ -0,0 +1,112 @@ +.auth-candidate { + font-family: "LabGrotesque", sans-serif; + overflow: hidden; + position: relative; + background-color: #f1f1f1; + + .auth { + &__wrapper { + background: #FFFFFF; + border-radius: 12px; + padding: 50px 0 35px 56px; + margin-top: 40px; + display: flex; + } + + &__info { + margin-right: 115px; + h3 { + font-weight: 500; + font-size: 30px; + line-height: 32px; + margin-bottom: 20px; + } + + p { + max-width: 310px; + margin-top: 17px; + font-weight: 400; + font-size: 16px; + line-height: 30px; + } + } + + &__form { + display: flex; + flex-direction: column; + + input { + margin-bottom: 30px; + background: #EFF2F7; + border-radius: 8px; + min-width: 300px; + width: 100%; + padding: 8px 12px; + border: none; + outline: none; + font-weight: 400; + font-size: 15px; + line-height: 18px; + } + + label { + margin-bottom: 15px; + font-weight: 400; + font-size: 15px; + line-height: 18px; + color: #000000; + } + + button { + background: #52B709; + border-radius: 44px; + max-width: 130px; + border: none; + font-weight: 500; + font-size: 18px; + line-height: 32px; + color: white; + height: 45px; + } + } + } + + &__start { + margin-top: 60px; + display: flex; + flex-direction: column; + align-items: center; + + &__title { + font-weight: 500; + font-size: 44px; + line-height: 32px; + color: #000000; + text-align: center; + + span { + color: #52B709; + } + } + + &__description { + font-weight: 400; + font-size: 22px; + line-height: 32px; + } + + &__categoriesWrapper { + display: flex; + position: relative; + margin-top: 200px; + flex-wrap: wrap; + row-gap: 24px; + column-gap: 21px; + width: 100%; + } + } + + footer { + margin-top: 70px; + } +} diff --git a/src/pages/RegistrationForCandidate/RegistrationForCandidate.js b/src/pages/RegistrationForCandidate/RegistrationForCandidate.js new file mode 100644 index 00000000..b78b122e --- /dev/null +++ b/src/pages/RegistrationForCandidate/RegistrationForCandidate.js @@ -0,0 +1,72 @@ +import React from 'react'; + +import AuthHeader from "../../components/AuthHeader/AuthHeader"; +import SideBar from "../../components/SideBar/SideBar"; +import StepsForCandidate from "../../components/StepsForCandidate/StepsForCandidate" +import {Footer} from "../../components/Footer/Footer"; + +import BackEndImg from "../../pages/PartnerСategories/images/personalBackEnd.png" +import arrowBtn from "../../images/arrowRight.png"; + +import './registationForCandidate.scss' + +export const RegistrationForCandidate = () => { + return( +
+ +
+
+

Хочу в команду Айти специалистов

+
+ +
+

Для нас не имеет значение Ваша локация.

+ +
+
+
+ img +

Backend разработчики

+
+

Java PHP Python C# React Vue.js NodeJs Golang Ruby JavaScript

+
+ img +
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+
+
+
+ +
+ ) +} diff --git a/src/pages/RegistrationForCandidate/registationForCandidate.scss b/src/pages/RegistrationForCandidate/registationForCandidate.scss new file mode 100644 index 00000000..17a7a0f7 --- /dev/null +++ b/src/pages/RegistrationForCandidate/registationForCandidate.scss @@ -0,0 +1,128 @@ +.registrationCandidate { + font-family: "LabGrotesque", sans-serif; + position: relative; + background-color: #f1f1f1; + + &__start { + display: flex; + position: relative; + flex-direction: column; + align-items: center; + margin-top: 55px; + + .step { + top: 36.5%; + } + } + + &__formWrapper { + position: relative; + margin-top: 200px; + display: flex; + padding: 33px 69px 32px 30px; + background: #FFFFFF; + border-radius: 12px; + width: 100%; + } + + &__info { + display: flex; + flex-direction: column; + row-gap: 30px; + + &__category { + display: flex; + align-items: center; + + img { + width: 48px; + } + + p { + margin-left: 18px; + font-weight: 500; + font-size: 18px; + line-height: 22px; + max-width: 120px; + } + } + + &__skills { + max-width: 180px; + font-weight: 400; + font-size: 12px; + line-height: 20px; + color: #6F6F6F; + } + + &__arrow { + width: 48px; + height: 48px; + background: #DDEEC6; + border-radius: 50px; + display: flex; + justify-content: center; + align-items: center; + + img { + transform: rotate(180deg); + } + } + } + + &__form { + display: flex; + flex-wrap: wrap; + margin-left: 70px; + margin-top: 20px; + row-gap: 28px; + column-gap: 55px; + + &__input { + display: flex; + flex-direction: column; + width: 46%; + + label { + font-weight: 400; + font-size: 15px; + line-height: 18px; + color: #000000; + margin-bottom: 15px; + } + + input { + background: #EFF2F7; + border-radius: 8px; + width: 100%; + padding: 8px 12px; + border: none; + outline: none; + font-weight: 400; + font-size: 15px; + line-height: 18px; + } + } + + &__submit { + width: 100%; + margin-top: 10px; + + button { + border: none; + font-weight: 500; + font-size: 18px; + line-height: 32px; + color: #FFFFFF; + background: #52B709; + border-radius: 44px; + width: 180px; + height: 46px; + } + } + } + + footer { + margin-top: 80px; + } +}