fixed code
This commit is contained in:
parent
edd01168a5
commit
c44c1fe27c
31
src/App.js
31
src/App.js
@ -1,7 +1,9 @@
|
|||||||
import React, { useState, Suspense, lazy } from 'react';
|
import React, { Suspense, lazy } from 'react';
|
||||||
import { HashRouter as Router, Route, Switch } from 'react-router-dom';
|
import { HashRouter as Router, Route, Switch } from 'react-router-dom';
|
||||||
|
import { useSelector } from 'react-redux';
|
||||||
import 'bootstrap/dist/css/bootstrap.min.css';
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
import './fonts/stylesheet.css';
|
import './fonts/stylesheet.css';
|
||||||
|
import { selectAuth } from './redux/outstaffingSlice';
|
||||||
|
|
||||||
const AuthPageForDevelopers = lazy(() => import('./pages/AuthPageForDevelopers'));
|
const AuthPageForDevelopers = lazy(() => import('./pages/AuthPageForDevelopers'));
|
||||||
// const AuthPageForPartners = lazy(() => import('./pages/AuthPageForPartners'));
|
// const AuthPageForPartners = lazy(() => import('./pages/AuthPageForPartners'));
|
||||||
@ -11,18 +13,13 @@ const CalendarPage = lazy(() => import('./pages/CalendarPage'));
|
|||||||
const ReportPage = lazy(() => import('./pages/ReportFormPage.js'));
|
const ReportPage = lazy(() => import('./pages/ReportFormPage.js'));
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
const [isAuth, setIsAuth] = useState(true);
|
const isAuth = useSelector(selectAuth);
|
||||||
const [candidates, setCandidates] = useState([]);
|
// const [candidateForCalendar, setCandidateForCalendar] = useState([]);
|
||||||
const [candidateForCalendar, setCandidateForCalendar] = useState([]);
|
|
||||||
|
|
||||||
const getCandidate = (candidateArr) => {
|
// const getCandidateForCalendar = (candidate) => {
|
||||||
console.log('candidateArr ', candidateArr);
|
// console.log('candidate ', candidate);
|
||||||
setCandidates(candidateArr);
|
// setCandidateForCalendar(candidate);
|
||||||
};
|
// };
|
||||||
|
|
||||||
const getCandidateForCalendar = (candidate) => {
|
|
||||||
setCandidateForCalendar(candidate);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Router>
|
<Router>
|
||||||
@ -30,13 +27,13 @@ const App = () => {
|
|||||||
{isAuth ? (
|
{isAuth ? (
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route path="/" exact>
|
<Route path="/" exact>
|
||||||
<HomePage getCandidate={getCandidate} />
|
<HomePage />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/candidate/:id">
|
<Route path="/candidate/:id">
|
||||||
<CandidatePage candidatesArr={candidates} getCandidateForCalendar={getCandidateForCalendar} />
|
<CandidatePage />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/calendar">
|
<Route path="/calendar">
|
||||||
<CalendarPage candidateForCalendar={candidateForCalendar} />
|
<CalendarPage />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/report">
|
<Route path="/report">
|
||||||
<ReportPage />
|
<ReportPage />
|
||||||
@ -47,8 +44,8 @@ const App = () => {
|
|||||||
</Switch>
|
</Switch>
|
||||||
) : (
|
) : (
|
||||||
<Route path="/" exact>
|
<Route path="/" exact>
|
||||||
<AuthPageForDevelopers setAuth={setIsAuth} />
|
{/* <AuthPageForPartners /> */}
|
||||||
{/* <AuthPageForPartners setAuth={setIsAuth} /> */}
|
<AuthPageForDevelopers />
|
||||||
</Route>
|
</Route>
|
||||||
)}
|
)}
|
||||||
</Suspense>
|
</Suspense>
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { useDispatch } from 'react-redux';
|
||||||
|
import { auth } from '../../redux/outstaffingSlice';
|
||||||
import style from './AuthForDevelopers.module.css';
|
import style from './AuthForDevelopers.module.css';
|
||||||
import ellipse from '../../images/ellipse.png';
|
import ellipse from '../../images/ellipse.png';
|
||||||
import arrow from '../../images/arrow__login_page.png';
|
import arrow from '../../images/arrow__login_page.png';
|
||||||
@ -11,7 +13,8 @@ import telegram from '../../images/telegram.png';
|
|||||||
import vector from '../../images/Vector_Smart_Object.png';
|
import vector from '../../images/Vector_Smart_Object.png';
|
||||||
import vectorBlack from '../../images/Vector_Smart_Object_black.png';
|
import vectorBlack from '../../images/Vector_Smart_Object_black.png';
|
||||||
|
|
||||||
const AuthForDevelopers = ({ setAuthed }) => {
|
const AuthForDevelopers = () => {
|
||||||
|
const dispatch = useDispatch();
|
||||||
return (
|
return (
|
||||||
<section className={style.developers}>
|
<section className={style.developers}>
|
||||||
<div className={style.developers__background}>
|
<div className={style.developers__background}>
|
||||||
@ -35,7 +38,7 @@ const AuthForDevelopers = ({ setAuthed }) => {
|
|||||||
<label htmlFor="password">Пароль:</label>
|
<label htmlFor="password">Пароль:</label>
|
||||||
<input id="password" type="password" placeholder="Пароль" />
|
<input id="password" type="password" placeholder="Пароль" />
|
||||||
|
|
||||||
<button className={style.form__btn} type="submit" onClick={() => setAuthed(true)}>
|
<button className={style.form__btn} type="submit" onClick={() => dispatch(auth(true))}>
|
||||||
Войти
|
Войти
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { useDispatch } from 'react-redux';
|
||||||
|
import { auth } from '../../redux/outstaffingSlice';
|
||||||
import style from './AuthForPartners.module.css';
|
import style from './AuthForPartners.module.css';
|
||||||
import ellipse from '../../images/ellipse.png';
|
import ellipse from '../../images/ellipse.png';
|
||||||
import arrow from '../../images/arrow__login_page.png';
|
import arrow from '../../images/arrow__login_page.png';
|
||||||
import medium from '../../images/medium_male_big.png';
|
import medium from '../../images/medium_male_big.png';
|
||||||
import cross from '../../images/cross.png';
|
import cross from '../../images/cross.png';
|
||||||
// import specialists from '../../images/specialists.png';
|
|
||||||
import text from '../../images/Body_Text.png';
|
import text from '../../images/Body_Text.png';
|
||||||
import align from '../../images/align-left.png';
|
import align from '../../images/align-left.png';
|
||||||
import phone from '../../images/phone.png';
|
import phone from '../../images/phone.png';
|
||||||
@ -12,7 +13,9 @@ import telegram from '../../images/telegram.png';
|
|||||||
import vector from '../../images/Vector_Smart_Object.png';
|
import vector from '../../images/Vector_Smart_Object.png';
|
||||||
import vectorBlack from '../../images/Vector_Smart_Object_black.png';
|
import vectorBlack from '../../images/Vector_Smart_Object_black.png';
|
||||||
|
|
||||||
const AuthForPartners = ({ setAuthed }) => {
|
const AuthForPartners = () => {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className={style.partners}>
|
<section className={style.partners}>
|
||||||
<div className={style.partners__background}>
|
<div className={style.partners__background}>
|
||||||
@ -36,7 +39,7 @@ const AuthForPartners = ({ setAuthed }) => {
|
|||||||
<label htmlFor="password">Пароль:</label>
|
<label htmlFor="password">Пароль:</label>
|
||||||
<input id="password" type="password" placeholder="Пароль" />
|
<input id="password" type="password" placeholder="Пароль" />
|
||||||
|
|
||||||
<button className={style.form__btn} type="submit" onClick={() => setAuthed(true)}>
|
<button className={style.form__btn} type="submit" onClick={() => dispatch(auth(true))}>
|
||||||
Войти
|
Войти
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import { useSelector } from 'react-redux';
|
||||||
|
import { selectCurrentCandidate } from '../../redux/outstaffingSlice';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import style from './Calendar.module.css';
|
import style from './Calendar.module.css';
|
||||||
import calendarMale from '../../images/medium_male.png';
|
import calendarMale from '../../images/medium_male.png';
|
||||||
@ -6,7 +8,9 @@ import rectangle from '../../images/rectangle_secondPage.png';
|
|||||||
import CalendarComponent from './CalendarComponent';
|
import CalendarComponent from './CalendarComponent';
|
||||||
import { currentMonth } from './calendarHelper';
|
import { currentMonth } from './calendarHelper';
|
||||||
|
|
||||||
const Calendar = ({ candidateForCalendar }) => {
|
const Calendar = () => {
|
||||||
|
const candidateForCalendar = useSelector(selectCurrentCandidate);
|
||||||
|
|
||||||
const [month, setMonth] = useState('');
|
const [month, setMonth] = useState('');
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -1,24 +1,24 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useHistory, useParams } from 'react-router-dom';
|
import { useHistory, useParams } from 'react-router-dom';
|
||||||
|
import { useSelector, useDispatch } from 'react-redux';
|
||||||
|
import { selectCandidates, currentCandidate, selectCurrentCandidate } from '../../redux/outstaffingSlice';
|
||||||
import style from './Candidate.module.css';
|
import style from './Candidate.module.css';
|
||||||
import arrow from '../../images/right-arrow.png';
|
import arrow from '../../images/right-arrow.png';
|
||||||
import rectangle from '../../images/rectangle_secondPage.png';
|
import rectangle from '../../images/rectangle_secondPage.png';
|
||||||
import Sidebar from '../Sidebar/Sidebar';
|
import Sidebar from '../Sidebar/Sidebar';
|
||||||
import SectionOne from './sections/SectionOne';
|
import SectionSkills from './SectionSkills';
|
||||||
import SectionTwo from './sections/SectionTwo';
|
|
||||||
import SectionThree from './sections/SectionThree';
|
|
||||||
import SectionFour from './sections/SectionFour';
|
|
||||||
import SectionFive from './sections/SectionFive';
|
|
||||||
import SectionSkills from './sections/SectionSkills';
|
|
||||||
|
|
||||||
const Candidate = ({ candidatesArr, getCandidateForCalendar }) => {
|
const Candidate = () => {
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
|
||||||
const { id: candidateId } = useParams();
|
const { id: candidateId } = useParams();
|
||||||
|
|
||||||
const currentCandidate = candidatesArr.find((el) => Number(el.id) === Number(candidateId));
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const { name, skillsName, img } = currentCandidate;
|
const candidatesArr = useSelector(selectCandidates);
|
||||||
|
dispatch(currentCandidate(candidatesArr.find((el) => Number(el.id) === Number(candidateId))));
|
||||||
|
const currentCandidateObj = useSelector(selectCurrentCandidate);
|
||||||
|
|
||||||
|
const { name, skillsName, img, skills } = currentCandidateObj;
|
||||||
|
|
||||||
let classes;
|
let classes;
|
||||||
|
|
||||||
@ -66,24 +66,67 @@ const Candidate = ({ candidatesArr, getCandidateForCalendar }) => {
|
|||||||
<div className={style.candidate__main}>
|
<div className={style.candidate__main}>
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-12 col-xl-4">
|
<div className="col-12 col-xl-4">
|
||||||
<Sidebar getCandidateForCalendar={getCandidateForCalendar} currentCandidateObj={currentCandidate} />
|
<Sidebar />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-12 col-xl-8">
|
<div className="col-12 col-xl-8">
|
||||||
<div className={style.candidate__main__description}>
|
<div className={style.candidate__main__description}>
|
||||||
<h2>{name}</h2>
|
<h2>{name}</h2>
|
||||||
<img src={rectangle} alt="" />
|
<img src={rectangle} alt="" />
|
||||||
<p># Описание опыта</p>
|
<p># Описание опыта</p>
|
||||||
<SectionOne />
|
<div className={style.SectionOne}>
|
||||||
|
<h3>SVM - сервис выездных менеджеров для банка ПСБ</h3>
|
||||||
|
<p>
|
||||||
|
Приложение, которое позволяет управлять работой т.н. выездных менеджеров (ВМ). Банк предоставляет их
|
||||||
|
услуги своим (потенциальным или реальным) клиентам, позволяя подключать расчетно-кассовое
|
||||||
|
обслуживание или регистрировать свой бизнес. Клиенту не нужно приходить в отделение/офис банка - все
|
||||||
|
необходимые бумаги ВМ подготовит заранее и принесет на согласование и подпись в удобное ему (клиент)
|
||||||
|
время и место.
|
||||||
|
</p>
|
||||||
|
<h4>Senior PHP/JS Developer</h4>
|
||||||
|
</div>
|
||||||
<p># Средства и инструменты:</p>
|
<p># Средства и инструменты:</p>
|
||||||
<SectionTwo />
|
<div className={style.SectionTwo}>
|
||||||
|
<p>
|
||||||
|
- Разработал и внедрил веб приложения, а также программное обеспечение с использованием Node.js,
|
||||||
|
MySQL, JavaScript, HTML, CSS, React.js и Vue.JS. - Поддерживал существующий веб-сайт на базе PHP.
|
||||||
|
Перевел существующую платформу с Laravel на современную архитектуру React/Redux и Node.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
- Проектировал и разрабатывал компоненты пользовательского интерфейса с использованием HTML, CSS и
|
||||||
|
JavaScript. - Повысил скорость загрузки веб-сайта и время безотказной работы за счете переписывания
|
||||||
|
всех основных компонентов и внедрения новой архетиктуры. - Разработал персональное APIs.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
<p># Описание опыта</p>
|
<p># Описание опыта</p>
|
||||||
<SectionThree />
|
<div className={style.SectionThree}>
|
||||||
|
<h3>Multitur - личный кабинет для сервиса поиска/подбора отелей</h3>
|
||||||
|
<p>
|
||||||
|
Личный кабинет для сотрудников отелей, который позволяет управлять информацией по отелю на сайте.
|
||||||
|
</p>
|
||||||
|
<h4>Senior PHP/JS Developer</h4>
|
||||||
|
</div>
|
||||||
<p># Средства и инструменты:</p>
|
<p># Средства и инструменты:</p>
|
||||||
<SectionFour />
|
<div className={style.SectionFour}>
|
||||||
|
<p>Backend - REST API на PHP 7.1 с использованием фреймворка Laravel 5.8</p>
|
||||||
|
<p>Frontend - Vue.js</p>
|
||||||
|
<p>БД - MYSQL</p>
|
||||||
|
</div>
|
||||||
<p># Функционал:</p>
|
<p># Функционал:</p>
|
||||||
<SectionFive />
|
<>
|
||||||
<SectionSkills />
|
<div className={style.SectionFive}>
|
||||||
|
<p>Регистрации/авторизации;</p>
|
||||||
|
<p>Управления правами менеджеров отеля, назначение поставщиков</p>
|
||||||
|
<p>Управления описанием и профилем отелей;</p>
|
||||||
|
<p>Управления финансами, ценообразованием, квотами;</p>
|
||||||
|
<p>Переписки со своими менеджерами, а также с вышестоящими инстанциями;</p>
|
||||||
|
<p>Управления новостями отеля;</p>
|
||||||
|
<p>Просмотра расширенной статистики по заявкам и людям;</p>
|
||||||
|
</div>
|
||||||
|
<button type="submit" className={style.SectionFive__btn}>
|
||||||
|
Выбрать к собеседованию
|
||||||
|
</button>
|
||||||
|
</>
|
||||||
|
<SectionSkills skillsArr={skills} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -182,3 +182,162 @@
|
|||||||
text-align: left;
|
text-align: left;
|
||||||
margin: 20px 0px;
|
margin: 20px 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.SectionOne > h3 {
|
||||||
|
font-family: 'GT Eesti Pro Display';
|
||||||
|
font-size: 2.2em;
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: normal;
|
||||||
|
letter-spacing: normal;
|
||||||
|
line-height: 36px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.SectionOne > p {
|
||||||
|
font-family: 'GT Eesti Pro Display';
|
||||||
|
font-size: 1.8em;
|
||||||
|
font-weight: 100;
|
||||||
|
font-style: normal;
|
||||||
|
letter-spacing: normal;
|
||||||
|
line-height: 28px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.SectionOne > h4 {
|
||||||
|
font-family: 'GT Eesti Pro Display';
|
||||||
|
font-size: 1.8em;
|
||||||
|
font-weight: 700;
|
||||||
|
font-style: normal;
|
||||||
|
letter-spacing: normal;
|
||||||
|
line-height: 36px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.SectionTwo > p {
|
||||||
|
font-family: 'GT Eesti Pro Display';
|
||||||
|
font-size: 1.8em;
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: normal;
|
||||||
|
letter-spacing: normal;
|
||||||
|
line-height: 28px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.SectionThree > h3 {
|
||||||
|
font-family: 'GT Eesti Pro Display';
|
||||||
|
font-size: 2.2em;
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: normal;
|
||||||
|
letter-spacing: normal;
|
||||||
|
line-height: 36px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.SectionThree > p {
|
||||||
|
font-family: 'GT Eesti Pro Display';
|
||||||
|
font-size: 1.8em;
|
||||||
|
font-weight: 100;
|
||||||
|
font-style: normal;
|
||||||
|
letter-spacing: normal;
|
||||||
|
line-height: 28px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.SectionThree > h4 {
|
||||||
|
font-family: 'GT Eesti Pro Display';
|
||||||
|
font-size: 1.8em;
|
||||||
|
font-weight: 700;
|
||||||
|
font-style: normal;
|
||||||
|
letter-spacing: normal;
|
||||||
|
line-height: 36px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.SectionFour > p {
|
||||||
|
font-family: 'GT Eesti Pro Display';
|
||||||
|
font-size: 1.8em;
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: normal;
|
||||||
|
letter-spacing: normal;
|
||||||
|
line-height: 18px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.SectionFive > p {
|
||||||
|
font-family: 'GT Eesti Pro Display';
|
||||||
|
font-size: 1.8em;
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: normal;
|
||||||
|
letter-spacing: normal;
|
||||||
|
line-height: 16px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 576.98px) {
|
||||||
|
.SectionFive__btn {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 575.98px) {
|
||||||
|
.SectionFive__btn {
|
||||||
|
display: block;
|
||||||
|
width: 221px;
|
||||||
|
height: 49px;
|
||||||
|
box-shadow: 0 8px 20px rgba(82, 151, 34, 0.21);
|
||||||
|
border-radius: 24px;
|
||||||
|
background-color: #ffffff;
|
||||||
|
background-image: linear-gradient(to top, #6aaf5c 0%, #52b709 100%),
|
||||||
|
linear-gradient(
|
||||||
|
36deg,
|
||||||
|
rgba(255, 255, 255, 0) 0%,
|
||||||
|
rgba(255, 255, 255, 0.16) 47%,
|
||||||
|
rgba(255, 255, 255, 0.17) 50%,
|
||||||
|
rgba(255, 255, 255, 0) 100%
|
||||||
|
);
|
||||||
|
color: #ffffff;
|
||||||
|
font-family: 'Muller';
|
||||||
|
font-size: 1.3em;
|
||||||
|
letter-spacing: normal;
|
||||||
|
text-align: left;
|
||||||
|
border: none;
|
||||||
|
text-align: center;
|
||||||
|
margin: 28px auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.SectionSkills {
|
||||||
|
display: flex;
|
||||||
|
border: 1px solid #69bf2c;
|
||||||
|
padding: 28px 40px 16px 30px;
|
||||||
|
margin-top: 60px;
|
||||||
|
border-radius: 10px;
|
||||||
|
margin-bottom: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 575.98px) {
|
||||||
|
.SectionSkills {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.SectionSkills > h3 {
|
||||||
|
font-family: 'GT Eesti Pro Display';
|
||||||
|
font-size: 1.8em;
|
||||||
|
font-weight: 700;
|
||||||
|
font-style: normal;
|
||||||
|
letter-spacing: normal;
|
||||||
|
line-height: 28px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.SectionSkills > p {
|
||||||
|
font-family: 'GT Eesti Pro Display';
|
||||||
|
font-size: 1.8em;
|
||||||
|
font-weight: 100;
|
||||||
|
font-style: normal;
|
||||||
|
letter-spacing: normal;
|
||||||
|
line-height: 28px;
|
||||||
|
text-align: left;
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
15
src/components/Candidate/SectionSkills.js
Normal file
15
src/components/Candidate/SectionSkills.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import style from './Candidate.module.css';
|
||||||
|
|
||||||
|
const SectionSkills = ({ skillsArr }) => {
|
||||||
|
return (
|
||||||
|
<div className={style.SectionSkills}>
|
||||||
|
<h3>Навыки:</h3>
|
||||||
|
{skillsArr.map((skills) => (
|
||||||
|
<p key={skills.id}>{skills.skill.name}</p>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SectionSkills;
|
@ -1,156 +0,0 @@
|
|||||||
.SectionOne > h3 {
|
|
||||||
font-family: 'GT Eesti Pro Display';
|
|
||||||
font-size: 2.2em;
|
|
||||||
font-weight: 400;
|
|
||||||
font-style: normal;
|
|
||||||
letter-spacing: normal;
|
|
||||||
line-height: 36px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.SectionOne > p {
|
|
||||||
font-family: 'GT Eesti Pro Display';
|
|
||||||
font-size: 1.8em;
|
|
||||||
font-weight: 100;
|
|
||||||
font-style: normal;
|
|
||||||
letter-spacing: normal;
|
|
||||||
line-height: 28px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.SectionOne > h4 {
|
|
||||||
font-family: 'GT Eesti Pro Display';
|
|
||||||
font-size: 1.8em;
|
|
||||||
font-weight: 700;
|
|
||||||
font-style: normal;
|
|
||||||
letter-spacing: normal;
|
|
||||||
line-height: 36px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.SectionTwo > p {
|
|
||||||
font-family: 'GT Eesti Pro Display';
|
|
||||||
font-size: 1.8em;
|
|
||||||
font-weight: 400;
|
|
||||||
font-style: normal;
|
|
||||||
letter-spacing: normal;
|
|
||||||
line-height: 28px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.SectionThree > h3 {
|
|
||||||
font-family: 'GT Eesti Pro Display';
|
|
||||||
font-size: 2.2em;
|
|
||||||
font-weight: 400;
|
|
||||||
font-style: normal;
|
|
||||||
letter-spacing: normal;
|
|
||||||
line-height: 36px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.SectionThree > p {
|
|
||||||
font-family: 'GT Eesti Pro Display';
|
|
||||||
font-size: 1.8em;
|
|
||||||
font-weight: 100;
|
|
||||||
font-style: normal;
|
|
||||||
letter-spacing: normal;
|
|
||||||
line-height: 28px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.SectionThree > h4 {
|
|
||||||
font-family: 'GT Eesti Pro Display';
|
|
||||||
font-size: 1.8em;
|
|
||||||
font-weight: 700;
|
|
||||||
font-style: normal;
|
|
||||||
letter-spacing: normal;
|
|
||||||
line-height: 36px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.SectionFour > p {
|
|
||||||
font-family: 'GT Eesti Pro Display';
|
|
||||||
font-size: 1.8em;
|
|
||||||
font-weight: 400;
|
|
||||||
font-style: normal;
|
|
||||||
letter-spacing: normal;
|
|
||||||
line-height: 18px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.SectionFive > p {
|
|
||||||
font-family: 'GT Eesti Pro Display';
|
|
||||||
font-size: 1.8em;
|
|
||||||
font-weight: 400;
|
|
||||||
font-style: normal;
|
|
||||||
letter-spacing: normal;
|
|
||||||
line-height: 16px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 576.98px) {
|
|
||||||
.SectionFive__btn {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 575.98px) {
|
|
||||||
.SectionFive__btn {
|
|
||||||
display: block;
|
|
||||||
width: 221px;
|
|
||||||
height: 49px;
|
|
||||||
box-shadow: 0 8px 20px rgba(82, 151, 34, 0.21);
|
|
||||||
border-radius: 24px;
|
|
||||||
background-color: #ffffff;
|
|
||||||
background-image: linear-gradient(to top, #6aaf5c 0%, #52b709 100%),
|
|
||||||
linear-gradient(
|
|
||||||
36deg,
|
|
||||||
rgba(255, 255, 255, 0) 0%,
|
|
||||||
rgba(255, 255, 255, 0.16) 47%,
|
|
||||||
rgba(255, 255, 255, 0.17) 50%,
|
|
||||||
rgba(255, 255, 255, 0) 100%
|
|
||||||
);
|
|
||||||
color: #ffffff;
|
|
||||||
font-family: 'Muller';
|
|
||||||
font-size: 1.3em;
|
|
||||||
letter-spacing: normal;
|
|
||||||
text-align: left;
|
|
||||||
border: none;
|
|
||||||
text-align: center;
|
|
||||||
margin: 28px auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.SectionSkills {
|
|
||||||
border: 1px solid #69bf2c;
|
|
||||||
padding: 28px 40px 16px 30px;
|
|
||||||
margin-top: 60px;
|
|
||||||
border-radius: 10px;
|
|
||||||
margin-bottom: 60px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 575.98px) {
|
|
||||||
.SectionSkills {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.SectionSkills > h3 {
|
|
||||||
font-family: 'GT Eesti Pro Display';
|
|
||||||
font-size: 1.8em;
|
|
||||||
font-weight: 700;
|
|
||||||
font-style: normal;
|
|
||||||
letter-spacing: normal;
|
|
||||||
line-height: 28px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.SectionSkills > p {
|
|
||||||
font-family: 'GT Eesti Pro Display';
|
|
||||||
font-size: 1.8em;
|
|
||||||
font-weight: 100;
|
|
||||||
font-style: normal;
|
|
||||||
letter-spacing: normal;
|
|
||||||
line-height: 28px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import style from './Section.module.css';
|
|
||||||
|
|
||||||
const SectionFive = () => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div className={style.SectionFive}>
|
|
||||||
<p>Регистрации/авторизации;</p>
|
|
||||||
<p>Управления правами менеджеров отеля, назначение поставщиков</p>
|
|
||||||
<p>Управления описанием и профилем отелей;</p>
|
|
||||||
<p>Управления финансами, ценообразованием, квотами;</p>
|
|
||||||
<p>Переписки со своими менеджерами, а также с вышестоящими инстанциями;</p>
|
|
||||||
<p>Управления новостями отеля;</p>
|
|
||||||
<p>Просмотра расширенной статистики по заявкам и людям;</p>
|
|
||||||
</div>
|
|
||||||
<button type="submit" className={style.SectionFive__btn}>
|
|
||||||
Выбрать к собеседованию
|
|
||||||
</button>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default SectionFive;
|
|
@ -1,14 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import style from './Section.module.css';
|
|
||||||
|
|
||||||
const SectionFour = () => {
|
|
||||||
return (
|
|
||||||
<div className={style.SectionFour}>
|
|
||||||
<p>Backend - REST API на PHP 7.1 с использованием фреймворка Laravel 5.8</p>
|
|
||||||
<p>Frontend - Vue.js</p>
|
|
||||||
<p>БД - MYSQL</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default SectionFour;
|
|
@ -1,19 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import style from './Section.module.css';
|
|
||||||
|
|
||||||
const SectionOne = () => {
|
|
||||||
return (
|
|
||||||
<div className={style.SectionOne}>
|
|
||||||
<h3>SVM - сервис выездных менеджеров для банка ПСБ</h3>
|
|
||||||
<p>
|
|
||||||
Приложение, которое позволяет управлять работой т.н. выездных менеджеров (ВМ). Банк предоставляет их услуги
|
|
||||||
своим (потенциальным или реальным) клиентам, позволяя подключать расчетно-кассовое обслуживание или
|
|
||||||
регистрировать свой бизнес. Клиенту не нужно приходить в отделение/офис банка - все необходимые бумаги ВМ
|
|
||||||
подготовит заранее и принесет на согласование и подпись в удобное ему (клиент) время и место.
|
|
||||||
</p>
|
|
||||||
<h4>Senior PHP/JS Developer</h4>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default SectionOne;
|
|
@ -1,18 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import style from './Section.module.css';
|
|
||||||
|
|
||||||
const SectionSkills = () => {
|
|
||||||
return (
|
|
||||||
<div className={style.SectionSkills}>
|
|
||||||
<h3>Навыки:</h3>
|
|
||||||
<p>
|
|
||||||
PHP: Native, Laravel, Zend Framework, CodeIgniter, YII, Symfony. JavaScript: Native, jQuery, AngularJS, ExtJS,
|
|
||||||
BackboneJS, ReactJS + Redux, VueJS. Search Engines: Sphinx, Elastic Search. Cache: Memcache, Redis. Profiling:
|
|
||||||
Xdebug, XHProf. WebSockets: Ratchet, Socket.io. Очереди: RabbitMQ, Beanstalk. MySQL, PostgreSQL, Oracle, MsSQL,
|
|
||||||
Vertica, HBase, Cassandra, MongoDB, Redis, Tarantool. CSS 2/3 (Sass, Less). HTML 4/5.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default SectionSkills;
|
|
@ -1,14 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import style from './Section.module.css';
|
|
||||||
|
|
||||||
const SectionThree = () => {
|
|
||||||
return (
|
|
||||||
<div className={style.SectionThree}>
|
|
||||||
<h3>Multitur - личный кабинет для сервиса поиска/подбора отелей</h3>
|
|
||||||
<p>Личный кабинет для сотрудников отелей, который позволяет управлять информацией по отелю на сайте.</p>
|
|
||||||
<h4>Senior PHP/JS Developer</h4>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default SectionThree;
|
|
@ -1,21 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import style from './Section.module.css';
|
|
||||||
|
|
||||||
const SectionTwo = () => {
|
|
||||||
return (
|
|
||||||
<div className={style.SectionTwo}>
|
|
||||||
<p>
|
|
||||||
- Разработал и внедрил веб приложения, а также программное обеспечение с использованием Node.js, MySQL,
|
|
||||||
JavaScript, HTML, CSS, React.js и Vue.JS. - Поддерживал существующий веб-сайт на базе PHP. Перевел существующую
|
|
||||||
платформу с Laravel на современную архитектуру React/Redux и Node.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
- Проектировал и разрабатывал компоненты пользовательского интерфейса с использованием HTML, CSS и JavaScript. -
|
|
||||||
Повысил скорость загрузки веб-сайта и время безотказной работы за счете переписывания всех основных компонентов
|
|
||||||
и внедрения новой архетиктуры. - Разработал персональное APIs.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default SectionTwo;
|
|
@ -1,12 +1,13 @@
|
|||||||
import React from 'react';
|
import React, { useState } from 'react';
|
||||||
import style from './Description.module.css';
|
import style from './Description.module.css';
|
||||||
import dog from '../../images/dog.jpg';
|
import dog from '../../images/dog.jpg';
|
||||||
import rectangle from '../../images/rectangle_secondPage.png';
|
import rectangle from '../../images/rectangle_secondPage.png';
|
||||||
import arrowLeft from '../../images/arrow_left.png';
|
|
||||||
import arrowRight from '../../images/arrow_right.png';
|
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
import { LEVELS } from '../constants/constants';
|
||||||
|
|
||||||
|
const Description = ({ candidatesListArr, onLoadMore }) => {
|
||||||
|
const [text, setText] = useState([]);
|
||||||
|
|
||||||
const Description = ({ candidatesListArr, getCandidate, onLoadMore }) => {
|
|
||||||
return (
|
return (
|
||||||
<section className={style.description}>
|
<section className={style.description}>
|
||||||
<div className="container">
|
<div className="container">
|
||||||
@ -17,15 +18,24 @@ const Description = ({ candidatesListArr, getCandidate, onLoadMore }) => {
|
|||||||
<img className={style.description__img} src={dog} alt="" />
|
<img className={style.description__img} src={dog} alt="" />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-12 col-xl-6">
|
<div className="col-12 col-xl-6">
|
||||||
<h3 className={style.description__title}>{el.header} разработчик</h3>
|
<h3 className={style.description__title}>
|
||||||
|
{el.skillsName} разработчик, {LEVELS[el.level]}
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
{text.length > 0 ? (
|
||||||
|
<>
|
||||||
<p className={style.description__text}>
|
<p className={style.description__text}>
|
||||||
- 10 лет пишу приложения под IOS, отлично владею Objective-C и Swift.
|
- 10 лет пишу приложения под IOS, отлично владею Objective-C и Swift.
|
||||||
</p>
|
</p>
|
||||||
<p className={style.description__text}>- 5 лет руковожу командами мобильной разработки.</p>
|
<p className={style.description__text}>- 5 лет руковожу командами мобильной разработки.</p>
|
||||||
<p className={style.description__text}>- 3 года преподаю в IOS-школе Сбера</p>
|
<p className={style.description__text}>- 3 года преподаю в IOS-школе Сбера</p>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<p className={style.description__textSecondary}>Описание отсутствует</p>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="col-12 col-xl-4">
|
<div className="col-12 col-xl-4">
|
||||||
<Link to={`/candidate/${el.id}`} onClick={() => getCandidate(candidatesListArr)}>
|
<Link to={`/candidate/${el.id}`}>
|
||||||
<button className={style.description__button}>Подробное резюме</button>
|
<button className={style.description__button}>Подробное резюме</button>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
@ -49,7 +59,7 @@ const Description = ({ candidatesListArr, getCandidate, onLoadMore }) => {
|
|||||||
<div className={style.description__footer__btn}>
|
<div className={style.description__footer__btn}>
|
||||||
<button onClick={() => onLoadMore(2)}>Загрузить еще</button>
|
<button onClick={() => onLoadMore(2)}>Загрузить еще</button>
|
||||||
</div>
|
</div>
|
||||||
<div className={style.description__footer__box}>
|
{/* <div className={style.description__footer__box}>
|
||||||
<div className={style.arrow__left}>
|
<div className={style.arrow__left}>
|
||||||
<img src={arrowLeft} alt="" />
|
<img src={arrowLeft} alt="" />
|
||||||
</div>
|
</div>
|
||||||
@ -57,7 +67,7 @@ const Description = ({ candidatesListArr, getCandidate, onLoadMore }) => {
|
|||||||
<div className={style.arrow__right}>
|
<div className={style.arrow__right}>
|
||||||
<img src={arrowRight} alt="" />
|
<img src={arrowRight} alt="" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> */}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -84,6 +84,17 @@
|
|||||||
line-height: 28px;
|
line-height: 28px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.description__textSecondary {
|
||||||
|
font-family: 'GT Eesti Pro Display';
|
||||||
|
font-size: 1.7em;
|
||||||
|
font-weight: 100;
|
||||||
|
font-style: normal;
|
||||||
|
letter-spacing: normal;
|
||||||
|
line-height: 24px;
|
||||||
|
text-align: left;
|
||||||
|
line-height: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 575.98px) {
|
@media (max-width: 575.98px) {
|
||||||
.description__text {
|
.description__text {
|
||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
|
@ -2,22 +2,24 @@ import React, { useState, useEffect } from 'react';
|
|||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import Outstaffing from '../Outstaffing/Outstaffing';
|
import Outstaffing from '../Outstaffing/Outstaffing';
|
||||||
import Description from '../Description/Description';
|
import Description from '../Description/Description';
|
||||||
|
import { fetchProfile, fetchSkills } from '../../server/server';
|
||||||
import front from '../../images/front_end.png';
|
import front from '../../images/front_end.png';
|
||||||
import back from '../../images/back_end.png';
|
import back from '../../images/back_end.png';
|
||||||
import design from '../../images/design.png';
|
import design from '../../images/design.png';
|
||||||
import { fetchProfile, fetchSkills } from '../../server/server';
|
|
||||||
import { profiles, selectProfiles, tags, candidates, selectCandidates, selectTab } from '../../redux/outstaffingSlice';
|
import { profiles, selectProfiles, tags, candidates, selectCandidates, selectTab } from '../../redux/outstaffingSlice';
|
||||||
|
|
||||||
const Home = ({ getCandidate }) => {
|
const Home = () => {
|
||||||
const [count, setCount] = useState(2);
|
const [index, setIndex] = useState(2);
|
||||||
|
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const profilesArr = useSelector(selectProfiles);
|
const profilesArr = useSelector(selectProfiles);
|
||||||
|
|
||||||
const candidatesArr = useSelector(selectCandidates);
|
const candidatesArr = useSelector(selectCandidates);
|
||||||
|
|
||||||
const selectedTab = useSelector(selectTab);
|
const selectedTab = useSelector(selectTab);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchProfile('https://guild.craft-group.xyz/api/profile')
|
fetchProfile(`https://guild.craft-group.xyz/api/profile?limit=`, index)
|
||||||
.then((profileArr) => dispatch(profiles(profileArr)))
|
.then((profileArr) => dispatch(profiles(profileArr)))
|
||||||
.catch((e) => console.log(e));
|
.catch((e) => console.log(e));
|
||||||
|
|
||||||
@ -32,28 +34,25 @@ const Home = ({ getCandidate }) => {
|
|||||||
);
|
);
|
||||||
dispatch(tags(tempTags));
|
dispatch(tags(tempTags));
|
||||||
});
|
});
|
||||||
}, [dispatch]);
|
}, [dispatch, index]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
dispatch(
|
dispatch(
|
||||||
candidates(
|
candidates(
|
||||||
profilesArr.map((profile) => {
|
profilesArr.map((profile) => {
|
||||||
let skillsName = '';
|
let skillsName = '';
|
||||||
let img;
|
|
||||||
let header;
|
let header;
|
||||||
|
let img;
|
||||||
|
|
||||||
if (Number(profile.position_id) === 1) {
|
if (Number(profile.position_id) === 1) {
|
||||||
skillsName = 'Frontend';
|
skillsName = 'Frontend';
|
||||||
img = front;
|
img = front;
|
||||||
header = 'Фронтенд';
|
|
||||||
} else if (Number(profile.position_id) === 2) {
|
} else if (Number(profile.position_id) === 2) {
|
||||||
skillsName = 'Backend';
|
skillsName = 'Backend';
|
||||||
img = back;
|
img = back;
|
||||||
header = 'Бэкенд';
|
|
||||||
} else if (Number(profile.position_id) === 3) {
|
} else if (Number(profile.position_id) === 3) {
|
||||||
skillsName = 'Marketer';
|
skillsName = 'Marketer';
|
||||||
img = design;
|
img = design;
|
||||||
header = 'Маркетинг';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -61,19 +60,18 @@ const Home = ({ getCandidate }) => {
|
|||||||
profileId: profile.position_id,
|
profileId: profile.position_id,
|
||||||
name: profile.fio,
|
name: profile.fio,
|
||||||
skills: profile.skillValues,
|
skills: profile.skillValues,
|
||||||
|
level: profile.level,
|
||||||
skillsName,
|
skillsName,
|
||||||
img,
|
|
||||||
header,
|
header,
|
||||||
|
img,
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}, [profilesArr, dispatch]);
|
}, [profilesArr, dispatch]);
|
||||||
|
|
||||||
const shorthandArray = candidatesArr.slice(0, count);
|
|
||||||
|
|
||||||
const loadMore = (count) => {
|
const loadMore = (count) => {
|
||||||
setCount((prev) => prev + count);
|
setIndex((prev) => prev + count);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -81,9 +79,8 @@ const Home = ({ getCandidate }) => {
|
|||||||
<Outstaffing />
|
<Outstaffing />
|
||||||
<Description
|
<Description
|
||||||
candidatesListArr={
|
candidatesListArr={
|
||||||
selectedTab ? candidatesArr.filter((item) => item.skillsName === selectedTab) : shorthandArray
|
selectedTab ? candidatesArr.filter((item) => item.skillsName === selectedTab) : candidatesArr
|
||||||
}
|
}
|
||||||
getCandidate={getCandidate}
|
|
||||||
onLoadMore={loadMore}
|
onLoadMore={loadMore}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
@ -4,6 +4,9 @@ import style from './Outstaffing.module.css';
|
|||||||
import OutstaffingBlock from './OutstaffingBlock';
|
import OutstaffingBlock from './OutstaffingBlock';
|
||||||
import TagSelect from '../Select/TagSelect';
|
import TagSelect from '../Select/TagSelect';
|
||||||
import { selectTags, selectTab, selectCandidates } from '../../redux/outstaffingSlice';
|
import { selectTags, selectTab, selectCandidates } from '../../redux/outstaffingSlice';
|
||||||
|
import front from '../../images/front_end.png';
|
||||||
|
import back from '../../images/back_end.png';
|
||||||
|
import design from '../../images/design.png';
|
||||||
|
|
||||||
const Outstaffing = () => {
|
const Outstaffing = () => {
|
||||||
const tagsArr = useSelector(selectTags);
|
const tagsArr = useSelector(selectTags);
|
||||||
@ -30,6 +33,8 @@ const Outstaffing = () => {
|
|||||||
data={candidatesArr.find((item) => item.skillsName === 'Frontend')}
|
data={candidatesArr.find((item) => item.skillsName === 'Frontend')}
|
||||||
dataTags={tagsArr.flat().filter((tag) => tag.name === 'skills_front')}
|
dataTags={tagsArr.flat().filter((tag) => tag.name === 'skills_front')}
|
||||||
selected={selected === 'Frontend'}
|
selected={selected === 'Frontend'}
|
||||||
|
img={front}
|
||||||
|
header="Фронтенд"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-12 col-xl-4">
|
<div className="col-12 col-xl-4">
|
||||||
@ -37,6 +42,8 @@ const Outstaffing = () => {
|
|||||||
data={candidatesArr.find((item) => item.skillsName === 'Backend')}
|
data={candidatesArr.find((item) => item.skillsName === 'Backend')}
|
||||||
dataTags={tagsArr.flat().filter((tag) => tag.name === 'skills_back')}
|
dataTags={tagsArr.flat().filter((tag) => tag.name === 'skills_back')}
|
||||||
selected={selected === 'Backend'}
|
selected={selected === 'Backend'}
|
||||||
|
img={back}
|
||||||
|
header="Бэкенд"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-12 col-xl-4">
|
<div className="col-12 col-xl-4">
|
||||||
@ -44,6 +51,8 @@ const Outstaffing = () => {
|
|||||||
data={candidatesArr.find((item) => item.skillsName === 'Marketer')}
|
data={candidatesArr.find((item) => item.skillsName === 'Marketer')}
|
||||||
dataTags={tagsArr.flat().filter((tag) => tag.name === 'skills_design')}
|
dataTags={tagsArr.flat().filter((tag) => tag.name === 'skills_design')}
|
||||||
selected={selected === 'Marketer'}
|
selected={selected === 'Marketer'}
|
||||||
|
img={design}
|
||||||
|
header="Маркетинг"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -3,12 +3,12 @@ import { useDispatch, useSelector } from 'react-redux';
|
|||||||
import { selectedTab, selectItems, selectedItems } from '../../redux/outstaffingSlice';
|
import { selectedTab, selectItems, selectedItems } from '../../redux/outstaffingSlice';
|
||||||
import style from './Outstaffing.module.css';
|
import style from './Outstaffing.module.css';
|
||||||
|
|
||||||
const OutstaffingBlock = ({ dataTags = [], data = {}, selected }) => {
|
const OutstaffingBlock = ({ dataTags = [], data = {}, selected, img, header }) => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const itemsArr = useSelector(selectItems);
|
const itemsArr = useSelector(selectItems);
|
||||||
|
|
||||||
const { header, img, skillsName } = data;
|
const { skillsName } = data;
|
||||||
|
|
||||||
const handleBlockClick = (item) => {
|
const handleBlockClick = (item) => {
|
||||||
if (!itemsArr.find((el) => item === el.value)) {
|
if (!itemsArr.find((el) => item === el.value)) {
|
||||||
|
@ -1,24 +1,22 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import dogBig from '../../images/dog.jpg';
|
import dogBig from '../../images/dog.jpg';
|
||||||
import arrowLeft from '../../images/arrow_left.png';
|
|
||||||
import arrowRight from '../../images/arrow_right.png';
|
|
||||||
import style from './Sidebar.module.css';
|
import style from './Sidebar.module.css';
|
||||||
|
|
||||||
const Sidebar = ({ getCandidateForCalendar, currentCandidateObj }) => {
|
const Sidebar = () => {
|
||||||
return (
|
return (
|
||||||
<div className={style.candidateSidebar}>
|
<div className={style.candidateSidebar}>
|
||||||
<div className={style.candidateSidebar__info}>
|
<div className={style.candidateSidebar__info}>
|
||||||
<img src={dogBig} alt="" />
|
<img src={dogBig} alt="" />
|
||||||
<p className={style.candidateSidebar__info__e}>Опыт работы</p>
|
<p className={style.candidateSidebar__info__e}>Опыт работы</p>
|
||||||
<p className={style.candidateSidebar__info__y}>4+ лет</p>
|
<p className={style.candidateSidebar__info__y}>4+ лет</p>
|
||||||
<Link to={`/calendar`} onClick={() => getCandidateForCalendar(currentCandidateObj)}>
|
<Link to={`/calendar`}>
|
||||||
<button className={style.candidateSidebar__info__btn}>Выбрать к собеседованию</button>
|
<button className={style.candidateSidebar__info__btn}>Выбрать к собеседованию</button>
|
||||||
</Link>
|
</Link>
|
||||||
<p className={style.candidateSidebar__info__l}>Посмотреть ещё</p>
|
{/* <p className={style.candidateSidebar__info__l}>Посмотреть ещё</p> */}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={style.candidateSidebar__arrows}>
|
{/* <div className={style.candidateSidebar__arrows}>
|
||||||
<div className={style.arrow__left}>
|
<div className={style.arrow__left}>
|
||||||
<img src={arrowLeft} alt="" />
|
<img src={arrowLeft} alt="" />
|
||||||
</div>
|
</div>
|
||||||
@ -26,7 +24,7 @@ const Sidebar = ({ getCandidateForCalendar, currentCandidateObj }) => {
|
|||||||
<div className={style.arrow__right}>
|
<div className={style.arrow__right}>
|
||||||
<img src={arrowRight} alt="" />
|
<img src={arrowRight} alt="" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> */}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
6
src/components/constants/constants.js
Normal file
6
src/components/constants/constants.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export const LEVELS = {
|
||||||
|
1: 'Junior',
|
||||||
|
2: 'Middle',
|
||||||
|
3: 'Middle+',
|
||||||
|
4: 'Senior',
|
||||||
|
};
|
@ -1,8 +1,8 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import AuthForDevelopers from '../components/Auth/AuthForDevelopers';
|
import AuthForDevelopers from '../components/Auth/AuthForDevelopers';
|
||||||
|
|
||||||
const AuthPageForDevelopers = ({ setAuth }) => {
|
const AuthPageForDevelopers = () => {
|
||||||
return <AuthForDevelopers setAuthed={setAuth} />;
|
return <AuthForDevelopers />;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default AuthPageForDevelopers;
|
export default AuthPageForDevelopers;
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import AuthForPartners from '../components/Auth/AuthForPartners';
|
import AuthForPartners from '../components/Auth/AuthForPartners';
|
||||||
|
|
||||||
const AuthPageForPartners = ({ setAuth }) => {
|
const AuthPageForPartners = () => {
|
||||||
return <AuthForPartners setAuthed={setAuth} />;
|
return <AuthForPartners />;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default AuthPageForPartners;
|
export default AuthPageForPartners;
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Calendar from '../components/Calendar/Calendar';
|
import Calendar from '../components/Calendar/Calendar';
|
||||||
|
|
||||||
const CalendarPage = ({ candidateForCalendar }) => {
|
const CalendarPage = () => {
|
||||||
return <Calendar candidateForCalendar={candidateForCalendar} />;
|
return <Calendar />;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default CalendarPage;
|
export default CalendarPage;
|
||||||
|
@ -2,8 +2,6 @@ import React from 'react';
|
|||||||
|
|
||||||
import Candidate from '../components/Candidate/Candidate';
|
import Candidate from '../components/Candidate/Candidate';
|
||||||
|
|
||||||
const CandidatePage = ({ candidatesArr, getCandidateForCalendar }) => (
|
const CandidatePage = () => <Candidate />;
|
||||||
<Candidate candidatesArr={candidatesArr} getCandidateForCalendar={getCandidateForCalendar} />
|
|
||||||
);
|
|
||||||
|
|
||||||
export default CandidatePage;
|
export default CandidatePage;
|
||||||
|
@ -2,6 +2,6 @@ import React from 'react';
|
|||||||
|
|
||||||
import Home from '../components/Home/Home';
|
import Home from '../components/Home/Home';
|
||||||
|
|
||||||
const HomePage = ({ getCandidate }) => <Home getCandidate={getCandidate} />;
|
const HomePage = () => <Home />;
|
||||||
|
|
||||||
export default HomePage;
|
export default HomePage;
|
||||||
|
@ -4,8 +4,10 @@ const initialState = {
|
|||||||
tags: [],
|
tags: [],
|
||||||
profiles: [],
|
profiles: [],
|
||||||
candidates: [],
|
candidates: [],
|
||||||
selectedTab: '',
|
|
||||||
selectedItems: [],
|
selectedItems: [],
|
||||||
|
selectedTab: '',
|
||||||
|
currentCandidate: {},
|
||||||
|
auth: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const outstaffingSlice = createSlice({
|
export const outstaffingSlice = createSlice({
|
||||||
@ -27,15 +29,24 @@ export const outstaffingSlice = createSlice({
|
|||||||
selectedItems: (state, action) => {
|
selectedItems: (state, action) => {
|
||||||
state.selectedItems = action.payload;
|
state.selectedItems = action.payload;
|
||||||
},
|
},
|
||||||
|
currentCandidate: (state, action) => {
|
||||||
|
state.currentCandidate = action.payload;
|
||||||
|
},
|
||||||
|
auth: (state, action) => {
|
||||||
|
state.auth = action.payload;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const { tags, profiles, candidates, selectedTab, selectedItems } = outstaffingSlice.actions;
|
export const { tags, profiles, candidates, selectedTab, selectedItems, auth, currentCandidate } =
|
||||||
|
outstaffingSlice.actions;
|
||||||
|
|
||||||
export const selectProfiles = (state) => state.outstaffing.profiles;
|
export const selectProfiles = (state) => state.outstaffing.profiles;
|
||||||
export const selectTags = (state) => state.outstaffing.tags;
|
export const selectTags = (state) => state.outstaffing.tags;
|
||||||
export const selectCandidates = (state) => state.outstaffing.candidates;
|
export const selectCandidates = (state) => state.outstaffing.candidates;
|
||||||
export const selectTab = (state) => state.outstaffing.selectedTab;
|
export const selectTab = (state) => state.outstaffing.selectedTab;
|
||||||
export const selectItems = (state) => state.outstaffing.selectedItems;
|
export const selectItems = (state) => state.outstaffing.selectedItems;
|
||||||
|
export const selectCurrentCandidate = (state) => state.outstaffing.currentCandidate;
|
||||||
|
export const selectAuth = (state) => state.outstaffing.auth;
|
||||||
|
|
||||||
export default outstaffingSlice.reducer;
|
export default outstaffingSlice.reducer;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
export const fetchProfile = async (link, index = '') => {
|
export const fetchProfile = async (link, index) => {
|
||||||
const response = await fetch(`${link}/${index}`);
|
const response = await fetch(`${link}${index}`);
|
||||||
let data = await response.json();
|
let data = await response.json();
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
Loading…
Reference in New Issue
Block a user