diff --git a/src/App.js b/src/App.js index cad6d725..2716efae 100644 --- a/src/App.js +++ b/src/App.js @@ -1,26 +1,28 @@ import React, { Suspense, lazy } from 'react' import { BrowserRouter as Router, Route, Switch } from 'react-router-dom' import { useSelector } from 'react-redux' -import { selectAuth } from './redux/outstaffingSlice'; +import { selectAuth } from './redux/outstaffingSlice' import 'bootstrap/dist/css/bootstrap.min.css' import './fonts/stylesheet.css' -import { ProtectedRoute } from './components/ProtectedRoute/ProtectedRoute'; +import { ProtectedRoute } from './components/ProtectedRoute/ProtectedRoute' -import { YMInitializer } from 'react-yandex-metrika'; +import { YMInitializer } from 'react-yandex-metrika' -import AuthPageForDevelopers from './pages/AuthPageForDevelopers'; -import AuthPageForPartners from './pages/AuthPageForPartners'; -import HomePage from './pages/HomePage'; -import CandidatePage from './pages/CandidatePage'; -import CalendarPage from'./pages/CalendarPage'; -import ReportPage from './pages/ReportFormPage.js'; -import FormPage from './pages/FormPage.js'; +import AuthPageForDevelopers from './pages/AuthPageForDevelopers' +import AuthPageForPartners from './pages/AuthPageForPartners' +import HomePage from './pages/HomePage' +import CandidatePage from './pages/CandidatePage' +import CalendarPage from './pages/CalendarPage' +import ReportPage from './pages/ReportFormPage.js' +import FormPage from './pages/FormPage.js' +import SingleReportPage from './pages/SingleReportPage' const App = (props) => { const isAuth = useSelector(selectAuth) - return (<> -

IT Аутстаффинг в России

- + return ( + <> +

IT Аутстаффинг в России

+ @@ -29,15 +31,24 @@ const App = (props) => { - + - - -
Page not found
} /> + + + +
Page not found
} />
-
- - {/* + + {/* { ) } - export default App diff --git a/src/components/Achievement/Achievement.js b/src/components/Achievement/Achievement.js new file mode 100644 index 00000000..fbcfc336 --- /dev/null +++ b/src/components/Achievement/Achievement.js @@ -0,0 +1,19 @@ +import React from 'react' + +import './achievement.scss' + +export const Achievement = ({ achievement }) => { + return ( +
+
+ +
+
+
{achievement.title}
+
+ {achievement.description} +
+
+
+ ) +} diff --git a/src/components/Achievement/achievement.scss b/src/components/Achievement/achievement.scss new file mode 100644 index 00000000..7dd0836f --- /dev/null +++ b/src/components/Achievement/achievement.scss @@ -0,0 +1,51 @@ +.achievement { + position: relative; + width: 50px; + height: 50px; + margin: 0 1rem; + + &__popup { + position: absolute; + top: 50px; + left: 0; + width: 140px; + min-height: 70px; + padding: 1rem; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + display: none; + text-align: left; + border-bottom: 3px solid #52b709; + border-left: 3px solid #52b709; + } + + &__title { + color: #18586e; + font-size: 20px; + margin: 0; + padding: 0; + } + + &__description { + color: #18586e; + font-size: 14px; + margin: 0; + padding: 0; + } + + &__icon { + width: 50px; + height: 50px; + } + + img { + width: 100%; + height: 100%; + } + + &:hover .achievement__popup { + display: block; + } +} diff --git a/src/components/Description/Description.js b/src/components/Description/Description.js index 08c31995..10a6cf2d 100644 --- a/src/components/Description/Description.js +++ b/src/components/Description/Description.js @@ -35,7 +35,7 @@ const Description = ({ onLoadMore, isLoadingMore }) => { { candidatesListArr && candidatesListArr.length > 0 ? candidatesListArr.map((el) => (
-
+
diff --git a/src/components/Description/Description.module.css b/src/components/Description/Description.module.css index fc5ac83f..a280d355 100644 --- a/src/components/Description/Description.module.css +++ b/src/components/Description/Description.module.css @@ -30,8 +30,11 @@ @media (max-width: 575.98px) { .description__img { position: absolute; - top: 80px; - left: 0; + top: 100px; + left: calc(50% - 60px); + } + .description__wrapper { + padding: 45px 40px 0 40px; } } diff --git a/src/components/Form/Form.js b/src/components/Form/Form.js index 3b1febbb..abfe71b7 100644 --- a/src/components/Form/Form.js +++ b/src/components/Form/Form.js @@ -3,6 +3,7 @@ import style from './Form.module.css'; import { fetchForm } from '../../server/server'; import { auth } from '../../redux/outstaffingSlice'; import { useHistory, useParams, Redirect } from 'react-router-dom'; +import { Loader } from '../Loader/Loader'; import PhoneInput from 'react-phone-input-2' import 'react-phone-input-2/lib/style.css' import './form.css'; @@ -25,6 +26,7 @@ const Form = () => { phone: '', comment: '', }); + const [isFetching, setIsFetching] = useState(false); const handleChange = (e) => { const { id, value } = e.target; @@ -38,6 +40,7 @@ const Form = () => { const handleSubmit = (e) => { e.preventDefault(); + setIsFetching(true) const formData = new FormData(); formData.append('profile_id', urlParams.id); formData.append('email', data.email); @@ -48,14 +51,13 @@ const Form = () => { profile_id: urlParams.id, ...data, }, history, role, logout: dispatch(auth(false)) }).then( (res)=> res.json() - .then( resJSON => setStatus(resJSON)) + .then( resJSON => { + setStatus(resJSON); + setIsFetching(false); + }) ) }; - - - console.log('s',status) - return ( <> {status && { >
diff --git a/src/components/Sidebar/Sidebar.js b/src/components/Sidebar/Sidebar.js index 7fa5e4bf..0c8cf3e8 100644 --- a/src/components/Sidebar/Sidebar.js +++ b/src/components/Sidebar/Sidebar.js @@ -1,37 +1,53 @@ -import React from 'react'; -import { Link } from 'react-router-dom'; -import maleBig from '../../images/medium_male_big.png'; -import style from './Sidebar.module.css'; +import React from 'react' +import { Link } from 'react-router-dom' +import { Achievement } from '../Achievement/Achievement' + +import maleBig from '../../images/medium_male_big.png' +import './sidebar.scss' const getYearsString = (years) => { - let yearsString; - if (years%10 === 1) { - yearsString = 'год'; + let yearsString + if (years % 10 === 1) { + yearsString = 'год' } else if (years === 11 || years === 12 || years === 13 || years === 14) { - yearsString = 'лет'; - } else if (years%10 === 2 || years%10 === 3 || years%10 === 4) { - yearsString = 'года'; + yearsString = 'лет' + } else if (years % 10 === 2 || years % 10 === 3 || years % 10 === 4) { + yearsString = 'года' } else { - yearsString = 'лет'; + yearsString = 'лет' } - return `${years} ${yearsString}`; + return `${years} ${yearsString}` } const Sidebar = ({ candidate }) => { + console.log('c', candidate) return ( -
-
- - { candidate && candidate.years_of_exp && <> -

Опыт работы

-

{getYearsString(candidate.years_of_exp)}

- } - - +
+
+ + {candidate && candidate.years_of_exp && ( + <> +

Опыт работы

+

+ {getYearsString(candidate.years_of_exp)} +

+ + )} + + +
+ {candidate && + candidate.achievements && + candidate.achievements.map((item) => { + return + })} +
- ); -}; + ) +} -export default Sidebar; +export default Sidebar diff --git a/src/components/Sidebar/Sidebar.module.css b/src/components/Sidebar/sidebar.scss similarity index 86% rename from src/components/Sidebar/Sidebar.module.css rename to src/components/Sidebar/sidebar.scss index 04efe60f..d1d991cc 100644 --- a/src/components/Sidebar/Sidebar.module.css +++ b/src/components/Sidebar/sidebar.scss @@ -6,6 +6,14 @@ border-bottom: none !important; position: sticky; top: 80px; + + &__achievements { + display: flex; + flex-wrap: wrap; + justify-content: flex-start; + padding: 0 1rem; + margin-bottom: 80px; + } } .candidateSidebar__info { @@ -25,7 +33,7 @@ border-radius: 100px; } -.candidateSidebar__info__e { +.candidateSidebar__experience-title { font-family: 'GT Eesti Pro Display'; font-size: 1.8em; font-weight: normal; @@ -35,7 +43,7 @@ margin-top: 20px; } -.candidateSidebar__info__y { +.candidateSidebar__experience { font-family: 'GT Eesti Pro Display'; font-size: 3em; font-weight: 700; @@ -44,7 +52,7 @@ line-height: normal; } -.candidateSidebar__info__btn { +.candidateSidebar__select { width: 280px; height: 60px; border-radius: 100px; @@ -58,10 +66,10 @@ line-height: normal; text-align: center; margin-top: 20px; - margin-bottom: 120px; + margin-bottom: 40px; } -.candidateSidebar__info__btn:hover { +.candidateSidebar__select:hover { background: rgba(0, 0, 0, 0); color: #73c141; box-shadow: inset 0 0 0 3px #73c141; @@ -142,7 +150,8 @@ flex-direction: column; } - .candidateSidebar__info__e, .candidateSidebar__info__y { + .candidateSidebar__info__e, + .candidateSidebar__info__y { width: 180px; } -} \ No newline at end of file +} diff --git a/src/components/TaskItem/TaskItem.js b/src/components/TaskItem/TaskItem.js new file mode 100644 index 00000000..9a9c2467 --- /dev/null +++ b/src/components/TaskItem/TaskItem.js @@ -0,0 +1,16 @@ +import React from 'react' + +import './taskItem.scss' + +export const TaskItem = ({ index, text, hours }) => { + return ( +
+
{index}.
+
{text}
+
+
{hours}
+
Количество часов
+
+
+ ) +} diff --git a/src/components/TaskItem/taskItem.scss b/src/components/TaskItem/taskItem.scss new file mode 100644 index 00000000..0a6f10f5 --- /dev/null +++ b/src/components/TaskItem/taskItem.scss @@ -0,0 +1,72 @@ +.task-item { + display: flex; + justify-content: flex-start; + align-items: center; + + &__index { + margin-top: 0.2rem; + color: #282828; + font-family: 'GT Eesti Pro Display'; + font-size: 20px; + font-weight: 700; + line-height: 48.74px; + text-align: left; + letter-spacing: 0.34px; + } + + &__text { + min-width: 525px; + max-width: 525px; + margin-left: 1.6rem; + color: #000000; + font-family: 'GT Eesti Pro Display'; + font-size: 15px; + font-weight: 400; + letter-spacing: normal; + line-height: normal; + text-align: left; + } + + &__hours { + margin-left: 3.3rem; + display: flex; + &-value { + width: 34px; + height: 34px; + display: flex; + justify-content: center; + align-items: center; + box-shadow: 6px 5px 20px rgba(82, 151, 34, 0.21); + border-radius: 50%; + 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 Extra Bold'; + font-size: 16px; + font-weight: 400; + text-align: left; + letter-spacing: 0.8px; + } + + &-text { + margin-left: 1rem; + width: 69px; + height: 25px; + color: #000000; + font-family: 'GT Eesti Pro Display - Thin'; + font-size: 13px; + font-weight: 400; + letter-spacing: normal; + line-height: normal; + text-align: left; + } + } +} diff --git a/src/images/nextDateArrow.svg b/src/images/nextDateArrow.svg new file mode 100644 index 00000000..10c1120a --- /dev/null +++ b/src/images/nextDateArrow.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/prevDateArrow.svg b/src/images/prevDateArrow.svg new file mode 100644 index 00000000..ac2e970d --- /dev/null +++ b/src/images/prevDateArrow.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/index.css b/src/index.css index 38d2390e..0a8ccf69 100644 --- a/src/index.css +++ b/src/index.css @@ -24,4 +24,12 @@ h1 { .container { position: relative !important; +} + +@media (max-width: 568px) { + .col-xs-12 { + width: 100% !important; + max-width: 100%; + flex: initial; + } } \ No newline at end of file diff --git a/src/pages/FormPage.js b/src/pages/FormPage.js index 1973a0cd..e8ce5d08 100644 --- a/src/pages/FormPage.js +++ b/src/pages/FormPage.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { useHistory, useParams, Link } from 'react-router-dom'; import { currentCandidate, selectCurrentCandidate, auth } from '../redux/outstaffingSlice'; diff --git a/src/pages/SingleReportPage.js b/src/pages/SingleReportPage.js new file mode 100644 index 00000000..66d7cb67 --- /dev/null +++ b/src/pages/SingleReportPage.js @@ -0,0 +1,107 @@ +import React from 'react' +import { WithLogout } from '../hoc/withLogout' +import arrowLeft from '../images/right-arrow.png' + +import SVG from 'react-inlinesvg' + +import prevDateArrowIcon from '../images/prevDateArrow.svg' +import nextDateArrowIcon from '../images/nextDateArrow.svg' + +import './singleReportPage.scss' +import { TaskItem } from '../components/TaskItem/TaskItem' + +const tasks = [ + { + index: 1, + text: 'Задача «67 – Навигационная система – Главное меню – Обновить иконки» заблокирована из-за отсутствия новых иконок', + hours: 3 + }, + { + index: 2, + text: 'Задача «83 – Навигационная система – Поиск по почтовому индексу – Добавить экран поиска по почтовому индексу» не может быть завершена, т.к. работа над задачей «82 – Навигационная система – Разработать модуль поиска по почтовому индексу» ещё не начата', + hours: 3 + } +] + +const SingleReportPage = () => { + return ( + +
+
+
+ +
+
+ Вернуться к списку +
+
+ +
+
Отчет за день
+
+
+ +
+
+ +

+
+
+ +
+
+
+ +
+
+
+

Какие задачи были выполнены?

+
+ {tasks.map((task) => { + return ( +
+ +
+ ) + })} +
+ +
+
+
+

Какие сложности возникли?

+
+
+ 91 – Навигационная система – Поиск адреса – Разобраться, почему + находятся несколько пересечений Невского пр. и Казанской ул. +
+
+ +
+
+
+

Что планируется сделать завтра?

+
+
+ 91 – Навигационная система – Поиск адреса – Разобраться, почему + находятся несколько пересечений Невского пр. и Казанской ул. +
+
+ +
+
+
+
+
+
+
+
+
+ ) +} + +export default SingleReportPage diff --git a/src/pages/singleReportPage.scss b/src/pages/singleReportPage.scss new file mode 100644 index 00000000..f5cd9f04 --- /dev/null +++ b/src/pages/singleReportPage.scss @@ -0,0 +1,97 @@ +.single-report-page { + padding-top: 4.6rem; + + &__back { + display: flex; + justify-content: flex-start; + align-items: center; + + &-text { + margin-left: 3.1rem; + color: #000000; + font-family: 'GT Eesti Pro Display - Thin'; + font-size: 18px; + font-weight: 400; + letter-spacing: normal; + line-height: 36px; + text-align: left; + } + } + + &__title { + display: flex; + justify-content: flex-start; + align-items: center; + margin-top: 3rem; + + &-text { + color: #282828; + font-family: 'GT Eesti Pro Display'; + font-size: 33px; + font-weight: 700; + line-height: 48.74px; + text-align: left; + letter-spacing: 0.56px; + } + + &-date { + margin-top: 0.2rem; + margin-left: 3rem; + display: flex; + justify-content: flex-start; + align-items: center; + } + + button { + border: none; + outline: none; + width: 31px; + height: 31px; + background-color: #f6f6f6; + border-radius: 50%; + display: flex; + justify-content: center; + align-items: center; + } + } + + &__marker { + width: 6px; + height: 6px; + background-color: #18586e; + border-radius: 50%; + margin-right: 0.8rem; + } + + &__tasks, + &__troubles, + &__scheduled { + margin-top: 3.7rem; + &-title { + display: flex; + justify-content: flex-start; + align-items: center; + h3 { + color: #18586e; + font-family: 'GT Eesti Pro Display'; + font-size: 20px; + font-weight: 500; + letter-spacing: normal; + line-height: normal; + text-align: left; + } + } + + &-item { + margin-top: 2.4rem; + width: 580px; + color: #000000; + font-family: 'GT Eesti Pro Display'; + font-size: 15px; + font-weight: 400; + letter-spacing: normal; + line-height: normal; + text-align: left; + } + } +}