10
package-lock.json
generated
@ -48,6 +48,7 @@
|
|||||||
"react-select": "^5.7.0",
|
"react-select": "^5.7.0",
|
||||||
"react-slick": "^0.29.0",
|
"react-slick": "^0.29.0",
|
||||||
"react-syntax-highlighter": "^15.4.5",
|
"react-syntax-highlighter": "^15.4.5",
|
||||||
|
"react-timer-hook": "^3.0.5",
|
||||||
"react-yandex-metrika": "^2.6.0",
|
"react-yandex-metrika": "^2.6.0",
|
||||||
"redux-devtools-extension": "^2.13.9",
|
"redux-devtools-extension": "^2.13.9",
|
||||||
"resolve": "1.18.1",
|
"resolve": "1.18.1",
|
||||||
@ -21571,6 +21572,15 @@
|
|||||||
"react": ">= 0.14.0"
|
"react": ">= 0.14.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-timer-hook": {
|
||||||
|
"version": "3.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-timer-hook/-/react-timer-hook-3.0.5.tgz",
|
||||||
|
"integrity": "sha512-n+98SdmYvui2ne3KyWb3Ldu4k0NYQa3g/VzW6VEIfZJ8GAk/jJsIY700M8Nd2vNSTj05c7wKyQfJBqZ0x7zfiA==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16.8.0",
|
||||||
|
"react-dom": ">=16.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-transition-group": {
|
"node_modules/react-transition-group": {
|
||||||
"version": "4.4.5",
|
"version": "4.4.5",
|
||||||
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
|
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
"react-select": "^5.7.0",
|
"react-select": "^5.7.0",
|
||||||
"react-slick": "^0.29.0",
|
"react-slick": "^0.29.0",
|
||||||
"react-syntax-highlighter": "^15.4.5",
|
"react-syntax-highlighter": "^15.4.5",
|
||||||
|
"react-timer-hook": "^3.0.5",
|
||||||
"react-yandex-metrika": "^2.6.0",
|
"react-yandex-metrika": "^2.6.0",
|
||||||
"redux-devtools-extension": "^2.13.9",
|
"redux-devtools-extension": "^2.13.9",
|
||||||
"resolve": "1.18.1",
|
"resolve": "1.18.1",
|
||||||
|
18
src/App.js
@ -13,10 +13,7 @@ import { ProfileCalendar } from "./components/ProfileCalendar/ProfileCalendar";
|
|||||||
import FormPage from "./pages/FormPage/FormPage.js";
|
import FormPage from "./pages/FormPage/FormPage.js";
|
||||||
import SingleReportPage from "./pages/SingleReportPage/SingleReportPage";
|
import SingleReportPage from "./pages/SingleReportPage/SingleReportPage";
|
||||||
import { QuizPage } from "./pages/quiz/QuizPage";
|
import { QuizPage } from "./pages/quiz/QuizPage";
|
||||||
import { InterjacentPage } from "./pages/quiz/InterjacentPage";
|
import {QuizReportPage} from './pages/quiz/QuizReportPage';
|
||||||
import { QuizTestPage } from "./pages/quiz/QuizTestPage";
|
|
||||||
import { InstructionPage } from "./pages/quiz/InstructionPage";
|
|
||||||
import { ResultPage } from "./pages/quiz/ResultPage";
|
|
||||||
import { Profile } from "./pages/Profile/Profile.js";
|
import { Profile } from "./pages/Profile/Profile.js";
|
||||||
import { Summary } from "./pages/Summary/Summary";
|
import { Summary } from "./pages/Summary/Summary";
|
||||||
import { ViewReport } from "./pages/ViewReport/ViewReport";
|
import { ViewReport } from "./pages/ViewReport/ViewReport";
|
||||||
@ -32,9 +29,11 @@ import { PartnerEmployees } from "./pages/PartnerEmployees/PartnerEmployees";
|
|||||||
import {AuthForCandidate} from "./pages/AuthForCandidate/AuthForCandidate";
|
import {AuthForCandidate} from "./pages/AuthForCandidate/AuthForCandidate";
|
||||||
import {RegistrationForCandidate} from "./pages/RegistrationForCandidate/RegistrationForCandidate";
|
import {RegistrationForCandidate} from "./pages/RegistrationForCandidate/RegistrationForCandidate";
|
||||||
|
|
||||||
|
import './assets/global.scss'
|
||||||
import './fonts/stylesheet.css'
|
import './fonts/stylesheet.css'
|
||||||
import 'bootstrap/dist/css/bootstrap.min.css'
|
import 'bootstrap/dist/css/bootstrap.min.css'
|
||||||
|
import { ProfileCandidate } from './pages/ProfileCandidate/ProfileCandidate';
|
||||||
|
import { PassingTests } from './pages/quiz/PassingTests';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -61,10 +60,8 @@ const App = () => {
|
|||||||
|
|
||||||
<Route exact path='quiz'>
|
<Route exact path='quiz'>
|
||||||
<Route index element={<QuizPage/>}/>
|
<Route index element={<QuizPage/>}/>
|
||||||
<Route exact path='interjacent' element={<InterjacentPage/>}/>
|
<Route exact path='test' element={<PassingTests />}/>
|
||||||
<Route exact path='test' element={<QuizTestPage/>}/>
|
<Route exact path='report' element={<QuizReportPage/>}/>
|
||||||
<Route exact path='instruction' element={<InstructionPage/>}/>
|
|
||||||
<Route exact path='result' element={<ResultPage/>}/>
|
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
<Route exact path='profile'>
|
<Route exact path='profile'>
|
||||||
@ -83,6 +80,9 @@ const App = () => {
|
|||||||
<Route exact path='treaties' element={<PartnerTreaties/>}/>
|
<Route exact path='treaties' element={<PartnerTreaties/>}/>
|
||||||
<Route exact path='categories/employees' element={<PartnerEmployees/>}/>
|
<Route exact path='categories/employees' element={<PartnerEmployees/>}/>
|
||||||
</Route>
|
</Route>
|
||||||
|
<Route exact path='profile-candidate/:id'>
|
||||||
|
<Route index element={<ProfileCandidate />}/>
|
||||||
|
</Route>
|
||||||
|
|
||||||
<Route path="*" element={<Navigate to="/auth" replace/>}/>
|
<Route path="*" element={<Navigate to="/auth" replace/>}/>
|
||||||
</Routes>
|
</Routes>
|
||||||
|
25
src/assets/global.scss
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
a:hover {
|
||||||
|
text-decoration: none !important;
|
||||||
|
}
|
||||||
|
.main-title {
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 22px;
|
||||||
|
line-height: 145%;
|
||||||
|
color: #000000;
|
||||||
|
word-break: break-word;
|
||||||
|
span {
|
||||||
|
color: #52b709;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.btn-green {
|
||||||
|
background: #52b709;
|
||||||
|
border-radius: 44px;
|
||||||
|
width: 100%;
|
||||||
|
border: none;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 178%;
|
||||||
|
color: #ffffff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
20
src/components/CardControl/CardControl.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import rightArrow from "../../images/arrowRight.png"
|
||||||
|
import { Link } from 'react-router-dom'
|
||||||
|
import './CardControl.scss'
|
||||||
|
|
||||||
|
export const CardControl = ({title,path,description, img}) => {
|
||||||
|
return (
|
||||||
|
<Link to={`/${path}`} className='control-card'>
|
||||||
|
<div className='control-card__about'>
|
||||||
|
<img src={img} alt='itemImg' />
|
||||||
|
<h3>{title}</h3>
|
||||||
|
</div>
|
||||||
|
<div className='control-card__info'>
|
||||||
|
<p dangerouslySetInnerHTML={{ __html: description }}></p>
|
||||||
|
<div className='control-card__infoLink'>
|
||||||
|
<img src={rightArrow} alt='arrow' />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Link>)
|
||||||
|
}
|
73
src/components/CardControl/CardControl.scss
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
.control-card{
|
||||||
|
max-width: 353px;
|
||||||
|
width: 100%;
|
||||||
|
padding: 35px 45px 15px 30px;
|
||||||
|
background: #FFFFFF;
|
||||||
|
border-radius: 12px;
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
box-shadow: 6px 5px 20px rgb(87 98 80 / 21%);
|
||||||
|
transform: scale(1.02);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1175px) {
|
||||||
|
width: 48%;
|
||||||
|
max-width: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 925px) {
|
||||||
|
width: 100%;
|
||||||
|
padding: 15px 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__about {
|
||||||
|
display: flex;
|
||||||
|
column-gap: 20px;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
|
||||||
|
@media (max-width: 925px) {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
color: #000000;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 22px;
|
||||||
|
max-width: 125px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__info {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 20px;
|
||||||
|
color: #000000;
|
||||||
|
margin-bottom: 0;
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #52B709;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&Link {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
background: #DDEEC6;
|
||||||
|
border-radius: 50px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,6 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: 33px 32px 25px 28px;
|
padding: 33px 32px 25px 28px;
|
||||||
width: 32%;
|
|
||||||
background: #FFFFFF;
|
background: #FFFFFF;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
footer {
|
footer {
|
||||||
border-top: 1px solid #EBEBEB;
|
border-top: 1px solid #ebebeb;
|
||||||
padding: 35px 0 50px;
|
padding: 35px 0 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
103
src/components/Navigation/Navigation.js
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import { NavLink } from 'react-router-dom'
|
||||||
|
import { urlForLocal } from '../../helper'
|
||||||
|
import { apiRequest } from '../../api/request';
|
||||||
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
|
import { getProfileInfo, setProfileInfo } from '../../redux/outstaffingSlice';
|
||||||
|
|
||||||
|
import avatarMok from "../../pages/PartnerTreaties/Images/avatarMok.png"
|
||||||
|
|
||||||
|
export const Navigation = () => {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
|
||||||
|
const profileInfo = useSelector(getProfileInfo);
|
||||||
|
const [user] = useState(localStorage.getItem('role_status') === '18' ? 'partner' : 'developer')
|
||||||
|
const [navInfo] = useState({
|
||||||
|
developer: [
|
||||||
|
{
|
||||||
|
path: '/summary',
|
||||||
|
name: 'Резюме'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/calendar',
|
||||||
|
name: 'Отчетность'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/tracker',
|
||||||
|
name: 'Трекер'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/payouts',
|
||||||
|
name: 'Выплаты'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/settings',
|
||||||
|
name: 'Настройки'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
partner: [
|
||||||
|
{
|
||||||
|
path: '/catalog',
|
||||||
|
name: 'Каталог'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/requests',
|
||||||
|
name: 'Запросы'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/categories',
|
||||||
|
name: 'Персонал'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/tracker',
|
||||||
|
name: 'Трекер'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/treaties',
|
||||||
|
name: 'Договора'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/settings',
|
||||||
|
name: 'Настройки'
|
||||||
|
},
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (localStorage.getItem('role_status') === '18') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
apiRequest(`/profile/${localStorage.getItem('cardId')}`)
|
||||||
|
.then((profileInfo) =>
|
||||||
|
dispatch(setProfileInfo(profileInfo))
|
||||||
|
);
|
||||||
|
|
||||||
|
}, [dispatch]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='profileHeader__info'>
|
||||||
|
<div className='profileHeader__container'>
|
||||||
|
<nav className='profileHeader__nav'>
|
||||||
|
{
|
||||||
|
navInfo[user].map((link, index) => {
|
||||||
|
return <NavLink key={index} end to={`/profile${link.path}`}>{link.name}</NavLink>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div className='profileHeader__personalInfo'>
|
||||||
|
<h3 className='profileHeader__personalInfoName'>
|
||||||
|
{user === 'developer' ?
|
||||||
|
profileInfo?.fio :
|
||||||
|
''
|
||||||
|
}
|
||||||
|
</h3>
|
||||||
|
<NavLink end to={'/profile'}>
|
||||||
|
<img src={profileInfo.photo ? urlForLocal(profileInfo.photo) : avatarMok} className='profileHeader__personalInfoAvatar' alt='avatar' />
|
||||||
|
</NavLink>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
0
src/components/Navigation/Navigation.scss
Normal file
@ -19,6 +19,7 @@ import {getRequestDates, setReportDate, setRequestDate} from "../../redux/report
|
|||||||
|
|
||||||
import 'moment/locale/ru'
|
import 'moment/locale/ru'
|
||||||
import './profileCalendar.scss'
|
import './profileCalendar.scss'
|
||||||
|
import { Navigation } from '../Navigation/Navigation';
|
||||||
|
|
||||||
|
|
||||||
export const ProfileCalendar = () => {
|
export const ProfileCalendar = () => {
|
||||||
@ -65,6 +66,7 @@ export const ProfileCalendar = () => {
|
|||||||
return (
|
return (
|
||||||
<div className='profile__calendar'>
|
<div className='profile__calendar'>
|
||||||
<ProfileHeader/>
|
<ProfileHeader/>
|
||||||
|
<Navigation />
|
||||||
<div className='container'>
|
<div className='container'>
|
||||||
<ProfileBreadcrumbs links={[{name: 'Главная', link: '/profile'},{name: 'Ваша отчетность', link: '/profile/calendar'}]} />
|
<ProfileBreadcrumbs links={[{name: 'Главная', link: '/profile'},{name: 'Ваша отчетность', link: '/profile/calendar'}]} />
|
||||||
<h2 className='summary__title'>Ваши отчеты</h2>
|
<h2 className='summary__title'>Ваши отчеты</h2>
|
||||||
|
@ -4,76 +4,19 @@ import {useDispatch, useSelector} from "react-redux";
|
|||||||
|
|
||||||
import {Loader} from '../Loader/Loader'
|
import {Loader} from '../Loader/Loader'
|
||||||
import {apiRequest} from "../../api/request";
|
import {apiRequest} from "../../api/request";
|
||||||
import {auth, getProfileInfo, setProfileInfo} from "../../redux/outstaffingSlice";
|
import {auth, setProfileInfo} from "../../redux/outstaffingSlice";
|
||||||
import {getRole} from "../../redux/roleSlice";
|
import {getRole} from "../../redux/roleSlice";
|
||||||
|
|
||||||
import {urlForLocal} from "../../helper";
|
|
||||||
|
|
||||||
import avatarMok from "../../pages/PartnerTreaties/Images/avatarMok.png"
|
|
||||||
|
|
||||||
import './profileHeader.scss'
|
import './profileHeader.scss'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export const ProfileHeader = () => {
|
export const ProfileHeader = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
|
||||||
const userRole = useSelector(getRole);
|
const userRole = useSelector(getRole);
|
||||||
const profileInfo = useSelector(getProfileInfo);
|
|
||||||
const [user] = useState(localStorage.getItem('role_status') === '18' ? 'partner' : 'developer')
|
const [user] = useState(localStorage.getItem('role_status') === '18' ? 'partner' : 'developer')
|
||||||
const [navInfo] = useState({
|
|
||||||
developer: [
|
|
||||||
{
|
|
||||||
path: '/summary',
|
|
||||||
name: 'Резюме'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/calendar',
|
|
||||||
name: 'Отчетность'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/tracker',
|
|
||||||
name: 'Трекер'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/payouts',
|
|
||||||
name: 'Выплаты'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/settings',
|
|
||||||
name: 'Настройки'
|
|
||||||
},
|
|
||||||
],
|
|
||||||
partner: [
|
|
||||||
{
|
|
||||||
path: '/catalog',
|
|
||||||
name: 'Каталог'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/requests',
|
|
||||||
name: 'Запросы'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/categories',
|
|
||||||
name: 'Персонал'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/tracker',
|
|
||||||
name: 'Трекер'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/treaties',
|
|
||||||
name: 'Договора'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/settings',
|
|
||||||
name: 'Настройки'
|
|
||||||
},
|
|
||||||
]
|
|
||||||
})
|
|
||||||
|
|
||||||
const [isLoggingOut, setIsLoggingOut] = useState(false);
|
const [isLoggingOut, setIsLoggingOut] = useState(false);
|
||||||
|
|
||||||
@ -113,29 +56,6 @@ export const ProfileHeader = () => {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='profileHeader__info'>
|
|
||||||
<div className='profileHeader__container'>
|
|
||||||
<nav className='profileHeader__nav'>
|
|
||||||
{
|
|
||||||
navInfo[user].map((link, index) => {
|
|
||||||
return <NavLink key={index} end to={`/profile${link.path}`}>{link.name}</NavLink>
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<div className='profileHeader__personalInfo'>
|
|
||||||
<h3 className='profileHeader__personalInfoName'>
|
|
||||||
{user === 'developer' ?
|
|
||||||
profileInfo?.fio :
|
|
||||||
''
|
|
||||||
}
|
|
||||||
</h3>
|
|
||||||
<NavLink end to={'/profile'}>
|
|
||||||
<img src={profileInfo.photo ? urlForLocal(profileInfo.photo) : avatarMok} className='profileHeader__personalInfoAvatar' alt='avatar'/>
|
|
||||||
</NavLink>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</header>
|
</header>
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
@ -22,6 +22,7 @@ import arrow from "../../images/right-arrow.png";
|
|||||||
|
|
||||||
import './reportForm.scss'
|
import './reportForm.scss'
|
||||||
import "react-datepicker/dist/react-datepicker.css";
|
import "react-datepicker/dist/react-datepicker.css";
|
||||||
|
import { Navigation } from '../Navigation/Navigation'
|
||||||
|
|
||||||
const ReportForm = () => {
|
const ReportForm = () => {
|
||||||
if(localStorage.getItem('role_status') === '18') {
|
if(localStorage.getItem('role_status') === '18') {
|
||||||
@ -99,6 +100,7 @@ const ReportForm = () => {
|
|||||||
return (
|
return (
|
||||||
<section className='report-form'>
|
<section className='report-form'>
|
||||||
<ProfileHeader/>
|
<ProfileHeader/>
|
||||||
|
<Navigation />
|
||||||
<div className='container'>
|
<div className='container'>
|
||||||
<ProfileBreadcrumbs links={[{name: 'Главная', link: '/profile'},
|
<ProfileBreadcrumbs links={[{name: 'Главная', link: '/profile'},
|
||||||
{name: 'Ваша отчетность', link: '/profile/calendar'},
|
{name: 'Ваша отчетность', link: '/profile/calendar'},
|
||||||
|
44
src/components/StarRating/StarRating.js
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import './StarRating.scss'
|
||||||
|
|
||||||
|
const StarRating = ({ countStars=1, countActiveStars=1, color='#52B709', size=61 }) => {
|
||||||
|
const [shadedStars, setShadedStars] = useState([])
|
||||||
|
const [noShadedStars, setNoShadedStars] = useState([])
|
||||||
|
const percent = (Math.abs(countActiveStars)) >= countStars ? 100 : (countActiveStars * 100 / countStars)
|
||||||
|
useEffect(() => {
|
||||||
|
for (let index = 0; index < countStars; index++) {
|
||||||
|
setShadedStars(prev => [...prev, '★'])
|
||||||
|
setNoShadedStars(prev => [...prev, '☆'])
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const ratingStyle = {
|
||||||
|
"--size": size+'px'
|
||||||
|
}
|
||||||
|
const activeStyle = {
|
||||||
|
"--width": percent + '%',
|
||||||
|
"--color": color,
|
||||||
|
"--content": shadedStars.join('')
|
||||||
|
}
|
||||||
|
const bodyStyle = {
|
||||||
|
"--content": noShadedStars.join(''),
|
||||||
|
"--color": color
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='rating' style={ratingStyle}>
|
||||||
|
<div className="rating__body" style={bodyStyle} data-content={noShadedStars.join('')}>
|
||||||
|
<div className="rating__active" style={activeStyle} data-content={shadedStars.join('')}></div>
|
||||||
|
<div className="rating__items">
|
||||||
|
<input type='radio' className="rating__item" value={1} name='star'></input>
|
||||||
|
<input type='radio' className="rating__item" value={2} name='star'></input>
|
||||||
|
<input type='radio' className="rating__item" value={3} name='star'></input>
|
||||||
|
<input type='radio' className="rating__item" value={4} name='star'></input>
|
||||||
|
<input type='radio' className="rating__item" value={5} name='star'></input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default React.memo(StarRating);
|
45
src/components/StarRating/StarRating.scss
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
.rating{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: var(--size);
|
||||||
|
line-height: 0.75;
|
||||||
|
&__body{
|
||||||
|
position: relative;
|
||||||
|
&::before{
|
||||||
|
content: attr(data-content);
|
||||||
|
display: block;
|
||||||
|
color: var(--color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&__active{
|
||||||
|
position: absolute;
|
||||||
|
height: 100%;
|
||||||
|
width: var(--width);
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
&::before{
|
||||||
|
content: attr(data-content);
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
color: var(--color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&__items{
|
||||||
|
display: flex;
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
&__item{
|
||||||
|
flex: 0 0 20%;
|
||||||
|
height: 100%;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
14
src/components/features/Candidate-lk/HeadBottom.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import medium_male from "../../../images/medium_male.png"
|
||||||
|
|
||||||
|
export const HeadBottom = () => {
|
||||||
|
return (
|
||||||
|
<div className="bottom-head">
|
||||||
|
<div className="bottom-head__container">
|
||||||
|
<div className="bottom-head__title">Мои тесты</div>
|
||||||
|
<div className="bottom-head__img"><img src={medium_male} alt="" /></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
21
src/components/features/quiz/AlertResult.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import suucessIcon from '../../../images/quiz/success.png'
|
||||||
|
|
||||||
|
export const AlertResult = () => {
|
||||||
|
|
||||||
|
const successTest = false
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='alert-result'>
|
||||||
|
<div className="alert-result__column">
|
||||||
|
<img src={suucessIcon} alt="suucessIcon" className="alert-result__icon" />
|
||||||
|
<div className='alert-result__text' style={{color: successTest ? '#52B709' : '#5B6871'}}>
|
||||||
|
Благодарим Вас за прохождение теста "Junior разработчик". Ваши результаты проверены, готовы пригласить Вас в команду
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{!successTest && <div className="alert-result__column">
|
||||||
|
<button className="alert-result__button quiz-btn">Запросить еще попытку</button>
|
||||||
|
</div>}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
24
src/components/features/quiz/BlockCompletedTest.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import compltedImage from "../../../images/quiz/compltedImage.png"
|
||||||
|
import { Link } from 'react-router-dom'
|
||||||
|
|
||||||
|
export const BlockCompletedTest = () => {
|
||||||
|
const id = localStorage.getItem('id')
|
||||||
|
return (
|
||||||
|
<div className='block-completed-test'>
|
||||||
|
<div className="block-completed-test__container">
|
||||||
|
<div className="block-completed-test__img">
|
||||||
|
<img src={compltedImage} alt="" />
|
||||||
|
</div>
|
||||||
|
<div className="block-completed-test__title">
|
||||||
|
Спасибо! <br />
|
||||||
|
Ваши ответы получены
|
||||||
|
</div>
|
||||||
|
<div className="block-completed-test__text">
|
||||||
|
В течении дня в вашем кабинете будет отображены данные о прохождении тестирования
|
||||||
|
</div>
|
||||||
|
<Link to={'/profile-candidate/' + id} className="block-completed-test__button quiz-btn">В кабинет</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
19
src/components/features/quiz/Card-introduction.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import questionIcon from "../../../images/question.png"
|
||||||
|
import './quiz.scss'
|
||||||
|
|
||||||
|
export const CardIntroduction = ({ title, description }) => {
|
||||||
|
return (
|
||||||
|
<div className="card-introduction">
|
||||||
|
<div className="card-introduction__title">{title}</div>
|
||||||
|
<div className="card-introduction__body">
|
||||||
|
<div className="card-introduction__icon">
|
||||||
|
<img src={questionIcon} alt="" />
|
||||||
|
</div>
|
||||||
|
<div className="card-introduction__text">
|
||||||
|
{description}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
34
src/components/features/quiz/CardAviableTest.js
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { Link } from 'react-router-dom'
|
||||||
|
import rightArrow from "../../../images/arrowRight.png"
|
||||||
|
import StarRating from '../../StarRating/StarRating'
|
||||||
|
|
||||||
|
|
||||||
|
export const CardAvailableTest = ({ title, description, path, passedTest }) => {
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='card-available-test'>
|
||||||
|
<Link to={`/${path}`} className="card-available-test__container" style={{ opacity: passedTest ? 0.3 : 1, pointerEvents: passedTest ? 'none' : 'all' }}>
|
||||||
|
<div className='card-available-test__top-head'>
|
||||||
|
<StarRating />
|
||||||
|
<h3 className='card-available-test__title'>{title}</h3>
|
||||||
|
</div>
|
||||||
|
<div className='card-available-test__info'>
|
||||||
|
<p dangerouslySetInnerHTML={{ __html: description }}></p>
|
||||||
|
<div className='card-available-test__infoLink'>
|
||||||
|
<img src={rightArrow} alt='arrow' />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
{passedTest && <div className='card-available-test__finished'>
|
||||||
|
<p>
|
||||||
|
Получить отчет по тестированию
|
||||||
|
</p>
|
||||||
|
<Link to={'/quiz/report'}>Отчет по тесту</Link>
|
||||||
|
</div>}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -1,24 +1,14 @@
|
|||||||
import React from 'react';
|
import React, { useEffect } from 'react';
|
||||||
|
import { useSelector } from 'react-redux';
|
||||||
|
import { selectedAnswersSelector, selectedTest } from '../../../redux/quizSlice';
|
||||||
|
|
||||||
export const GetOptionTask = ({ type, answer, handleChange, inputValue}) => {
|
export const GetOptionTask = ({ type, answer, handleChange, inputValue}) => {
|
||||||
|
|
||||||
|
const id = localStorage.getItem('id');
|
||||||
|
const dataTest = useSelector(selectedTest);
|
||||||
|
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "3":
|
|
||||||
return (
|
|
||||||
<div className="form-task__group" key={answer.id}>
|
|
||||||
<input className='form-task__check' type="checkbox" value={answer.answer_body} id={answer.id}
|
|
||||||
onChange={handleChange}/>
|
|
||||||
<label htmlFor={answer.id}>{answer.answer_body}</label>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
case "2":
|
|
||||||
case "4":
|
|
||||||
return (
|
|
||||||
<div className="form-task__group" key={answer.id}>
|
|
||||||
<input className='form-task__check' type="radio" value={answer.answer_body} name={'radio'} id={answer.id}
|
|
||||||
onChange={handleChange}/>
|
|
||||||
<label htmlFor={answer.id}>{answer.answer_body}</label>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
case "1":
|
case "1":
|
||||||
return (
|
return (
|
||||||
<div className="form-task__group">
|
<div className="form-task__group">
|
||||||
@ -26,10 +16,20 @@ export const GetOptionTask = ({type, answer, handleChange, inputValue}) => {
|
|||||||
onChange={handleChange} />
|
onChange={handleChange} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
case "3":
|
||||||
|
return (
|
||||||
|
<div className="form-task__group" key={answer.id}>
|
||||||
|
<input className='form-task__check' type="checkbox"
|
||||||
|
value={answer.answer_body} id={answer.id}
|
||||||
|
onChange={handleChange} />
|
||||||
|
<label htmlFor={answer.id}>{answer.answer_body}</label>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return (
|
return (
|
||||||
<div className="form-task__group" key={answer.id}>
|
<div className="form-task__group" key={answer.id}>
|
||||||
<input className='form-task__check' type="checkbox" value={answer.answer_body} id={answer.id}
|
<input className='form-task__check' type="radio" value={answer.answer_body} name={'radio'} id={answer.id}
|
||||||
onChange={handleChange} />
|
onChange={handleChange} />
|
||||||
<label htmlFor={answer.id}>{answer.answer_body}</label>
|
<label htmlFor={answer.id}>{answer.answer_body}</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -17,8 +17,8 @@ export const HeaderQuiz = ({header}) => {
|
|||||||
}, [userId, dispatch]);
|
}, [userId, dispatch]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
apiRequest(`/user-questionnaire/questionnaires-list?user_id=${userId}`)
|
// apiRequest(`/user-questionnaire/questionnaires-list?user_id=${userId}`)
|
||||||
.then(res => dispatch(setQuestionnairesList(res)))
|
// .then(res => dispatch(setQuestionnairesList(res)))
|
||||||
}, [userId, dispatch]);
|
}, [userId, dispatch]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
80
src/components/features/quiz/Quiz-passing-information.js
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import timer from '../../../images/quiz/timer.png'
|
||||||
|
import accempt from '../../../images/quiz/accempt.png'
|
||||||
|
import { useTimer } from 'react-timer-hook';
|
||||||
|
import StarRating from '../../StarRating/StarRating';
|
||||||
|
import { useSelector } from 'react-redux';
|
||||||
|
import { completedTestSelector } from '../../../redux/quizSlice';
|
||||||
|
|
||||||
|
|
||||||
|
export const QuizPassingInformation = ({ expiryTimestamp, setStartTest }) => {
|
||||||
|
const {
|
||||||
|
seconds,
|
||||||
|
minutes,
|
||||||
|
isRunning,
|
||||||
|
start,
|
||||||
|
pause,
|
||||||
|
resume,
|
||||||
|
restart
|
||||||
|
} = useTimer({
|
||||||
|
expiryTimestamp, autoStart: false, onExpire: () => {
|
||||||
|
console.warn('onExpire called')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const completedTest = useSelector(completedTestSelector)
|
||||||
|
|
||||||
|
|
||||||
|
const startTesting = () => {
|
||||||
|
setStartTest(true)
|
||||||
|
start()
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (completedTest) {
|
||||||
|
const time = new Date();
|
||||||
|
time.setSeconds(time.getSeconds() + 0);//600 - кол-во секунд для прохождения теста
|
||||||
|
restart(time, false)
|
||||||
|
}
|
||||||
|
}, [completedTest])
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='quiz-passing-information'>
|
||||||
|
<div className="quiz-passing-information__container">
|
||||||
|
<div className="quiz-passing-information__main">
|
||||||
|
<div className="quiz-passing-information__specialization">
|
||||||
|
<StarRating color={'#52B709'} countStars={1} countActiveStars={0.5} size={61} />
|
||||||
|
<div className='quiz-passing-information__specialization-title'>
|
||||||
|
Junior <br />
|
||||||
|
разработчик
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="quiz-passing-information__timer timer-quiz">
|
||||||
|
<div className="quiz-passing-information__icon">
|
||||||
|
<img src={timer} alt="" />
|
||||||
|
</div>
|
||||||
|
<div className="quiz-passing-information__text">
|
||||||
|
{completedTest ? 'Время вышло' : 'Время на прохождение теста:'} <br />
|
||||||
|
<span>{minutes.toString().padStart(2, '0') + ':' + seconds.toString().padStart(2, '0')} секунд</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="quiz-passing-information__attempt">
|
||||||
|
<div className="quiz-passing-information__icon">
|
||||||
|
<img src={accempt} alt="" />
|
||||||
|
</div>
|
||||||
|
<div className="quiz-passing-information__text">
|
||||||
|
Попыток прохождения: <br />
|
||||||
|
<span>1 попытка</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{(!completedTest && !isRunning) && <button className="quiz-passing-information__button btn-green" onClick={startTesting}>Начать</button>}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* {isRunning && <button className="quiz-passing-information__button quiz-btn" onClick={pause}>Завершить</button>} */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
27
src/components/features/quiz/QuizReport.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import StarRating from '../../StarRating/StarRating'
|
||||||
|
|
||||||
|
export const QuizReport = () => {
|
||||||
|
return (
|
||||||
|
<div className='report'>
|
||||||
|
<div className="report__row">
|
||||||
|
<div className="report__column">
|
||||||
|
<StarRating color={'#52B709'} countStars={1} countActiveStars={0.5} size={61} />
|
||||||
|
<div className="report__job-title">Junior <br /> разработчик</div>
|
||||||
|
</div>
|
||||||
|
<div className="report__column">
|
||||||
|
<div className="report__value">22</div>
|
||||||
|
<div className="report__text">Правильных ответов</div>
|
||||||
|
</div>
|
||||||
|
<div className="report__column">
|
||||||
|
<div className="report__value report__value_false">02</div>
|
||||||
|
<div className="report__text">Не правильных ответов</div>
|
||||||
|
</div>
|
||||||
|
<div className="report__column">
|
||||||
|
<div className="report__status-text">Статус:</div>
|
||||||
|
<div className="report__status">Пройдено!</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
20
src/components/features/quiz/SelectedCategory.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import iconSpecialization from "../../../images/icon-specialization.png"
|
||||||
|
import { Link } from 'react-router-dom'
|
||||||
|
|
||||||
|
export const SelectedCategory = ({setSelectedCategory}) => {
|
||||||
|
return (
|
||||||
|
<div className='selected-category'>
|
||||||
|
<div className="selected-category__container">
|
||||||
|
<div className="selected-category__title">Ваша выбранная <br /> категория</div>
|
||||||
|
<div className="selected-category__category">
|
||||||
|
<div className="selected-category__image">
|
||||||
|
<img src={iconSpecialization} alt="" />
|
||||||
|
</div>
|
||||||
|
<div className="selected-category__title-category">Backend <br /> разработчики</div>
|
||||||
|
</div>
|
||||||
|
<button onClick={()=>setSelectedCategory(true)} className="selected-category__button">Заменить специализацию </button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
@ -1,39 +1,42 @@
|
|||||||
import React, { useEffect, useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import { useNavigate } from "react-router-dom"
|
import { useNavigate } from "react-router-dom"
|
||||||
import { useSelector, useDispatch } from 'react-redux'
|
import { useSelector, useDispatch } from 'react-redux'
|
||||||
|
import questionIcon from "../../../images/question.png"
|
||||||
import { Progressbar } from './ProgressbarQuiz'
|
import { Progressbar } from './ProgressbarQuiz'
|
||||||
import { GetOptionTask } from './GetOptionTask'
|
import { GetOptionTask } from './GetOptionTask'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
fetchUserAnswersMany, fetchUserAnswerOne, fetchGetAnswers, selectAnswer, selectedTest
|
fetchUserAnswersMany, fetchUserAnswerOne, fetchGetAnswers, answersSelector, selectedTest, questionsSelector, setAnswers, setCompleteTest
|
||||||
} from './../../../redux/quizSlice'
|
} from './../../../redux/quizSlice'
|
||||||
|
|
||||||
import './quiz.scss'
|
import './quiz.scss'
|
||||||
import { apiRequest } from "../../../api/request";
|
import { apiRequest } from "../../../api/request";
|
||||||
|
import { HeaderQuiz } from './HeaderQuiz'
|
||||||
|
|
||||||
export const TaskQuiz = () => {
|
export const TaskQuiz = () => {
|
||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const listAnswers = useSelector(selectAnswer);
|
const answers = useSelector(answersSelector);
|
||||||
const dataTest = useSelector(selectedTest);
|
const questions = useSelector(questionsSelector);
|
||||||
|
|
||||||
|
|
||||||
|
const dataTest = useSelector(selectedTest);
|
||||||
const [index, setIndex] = useState(0);
|
const [index, setIndex] = useState(0);
|
||||||
const [checkedValues, setCheckedValues] = useState([]);
|
const [checkedValues, setCheckedValues] = useState([]);
|
||||||
const [stripValue, setStripValue] = useState(0);
|
//const [stripValue, setStripValue] = useState(0);
|
||||||
const [inputValue, setInputValue] = useState('');
|
const [inputValue, setInputValue] = useState('');
|
||||||
const [questions, setQuestions] = useState([]);
|
|
||||||
|
|
||||||
|
|
||||||
const id = localStorage.getItem('id');
|
const id = localStorage.getItem('id');
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
// fetch('https://itguild.info/api/user-questionnaire/questionnaires-list?user_id=110').then(response => response.json())
|
||||||
|
// .then(json => console.log(json))
|
||||||
apiRequest(`/question/get-questions?uuid=${dataTest.uuid}`)
|
apiRequest(`/question/get-questions?uuid=${dataTest.uuid}`)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
console.log(response)
|
console.log(response)
|
||||||
setQuestions(response);
|
|
||||||
dispatch(fetchGetAnswers(response[0].id));
|
dispatch(fetchGetAnswers(response[0].id));
|
||||||
setStripValue((+index + 1) * 100 / response.length)
|
setStripValue((+index + 1) * 100 / response.length)
|
||||||
})
|
})
|
||||||
@ -41,43 +44,46 @@ export const TaskQuiz = () => {
|
|||||||
|
|
||||||
const nextQuestion = async (e) => {
|
const nextQuestion = async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
//Проверка на валидацию ответов
|
//Проверка на валидацию ответов
|
||||||
if (checkedValues.length || inputValue) {
|
if (!(checkedValues.length || inputValue)) {
|
||||||
switch (questions[index].question_type_id) {
|
alert("Вы не ответили на вопрос")
|
||||||
case '3':
|
return
|
||||||
dispatch(fetchUserAnswersMany(checkedValues));
|
|
||||||
break;
|
|
||||||
case '2':
|
|
||||||
case '1':
|
|
||||||
case '4':
|
|
||||||
dispatch(fetchUserAnswerOne(checkedValues));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Проверка на существование следующего запроса
|
//отправка ответов на сервер
|
||||||
if (index < questions.length - 1) {
|
if (questions[index].question_type_id != 3) {
|
||||||
await dispatch(fetchGetAnswers(questions[index + 1].id));
|
//dispatch(fetchUserAnswerOne(checkedValues));
|
||||||
setIndex(prev => prev >= questions.length - 1 ? prev : prev + 1);
|
} else {
|
||||||
setStripValue((prev => prev + (100 / questions.length)));
|
console.log(checkedValues);
|
||||||
|
// dispatch(fetchUserAnswersMany(checkedValues));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Проверка на окончание теста
|
||||||
|
if (!(index < questions.length - 1)) {
|
||||||
|
dispatch(setCompleteTest())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch(fetchGetAnswers(questions[index + 1].id));
|
||||||
|
setIndex(prev => prev + 1);
|
||||||
setCheckedValues([]);
|
setCheckedValues([]);
|
||||||
setInputValue('')
|
setInputValue('')
|
||||||
} else {
|
|
||||||
navigate(`/quiz/result`);
|
|
||||||
alert("Тест пройден!")
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
alert("Вы не ответили на вопрос")
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const handleChange = (e) => {
|
const handleChange = (e) => {
|
||||||
const checked = e.target.checked;
|
const checked = e.target.checked;
|
||||||
switch (questions[index].question_type_id) {
|
|
||||||
case '3':
|
if (questions[index].question_type_id != 3) {
|
||||||
|
setCheckedValues([{
|
||||||
|
user_id: id,
|
||||||
|
user_questionnaire_uuid: dataTest.uuid,
|
||||||
|
question_id: questions[index].id,
|
||||||
|
response_body: e.target.value
|
||||||
|
}])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
checked ? setCheckedValues(prev => [...prev, {
|
checked ? setCheckedValues(prev => [...prev, {
|
||||||
user_id: id,
|
user_id: id,
|
||||||
user_questionnaire_uuid: dataTest.uuid,
|
user_questionnaire_uuid: dataTest.uuid,
|
||||||
@ -85,43 +91,26 @@ export const TaskQuiz = () => {
|
|||||||
response_body: e.target.value
|
response_body: e.target.value
|
||||||
}]) :
|
}]) :
|
||||||
setCheckedValues(prev => [...prev.filter(item => item.response_body !== e.target.value)]);
|
setCheckedValues(prev => [...prev.filter(item => item.response_body !== e.target.value)]);
|
||||||
break;
|
|
||||||
case '1':
|
|
||||||
case '2':
|
|
||||||
case '4':
|
|
||||||
setCheckedValues([{
|
|
||||||
user_id: id,
|
|
||||||
user_questionnaire_uuid: dataTest.uuid,
|
|
||||||
question_id: questions[index].id,
|
|
||||||
response_body: e.target.value
|
|
||||||
}])
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
console.log('render task');
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.StrictMode>
|
|
||||||
<Progressbar indexQuestion={index + 1} width={stripValue}/>
|
|
||||||
<div className="task">
|
<div className="task">
|
||||||
{!questions.length || !stripValue || !listAnswers.length ?
|
|
||||||
<h1 className={'_container'} style={{display: "block"}}>Loading....</h1>
|
|
||||||
:
|
|
||||||
<div className="task__container">
|
|
||||||
<div className="task__code code">
|
|
||||||
{/* <CodeSnippetlighter /> */}
|
|
||||||
</div>
|
|
||||||
<h3 className="task__title quiz-title_h3">{questions[index].question_body}</h3>
|
|
||||||
<div className="task__body">
|
|
||||||
<form className='task__form form-task'>
|
|
||||||
{
|
{
|
||||||
questions[index].question_type_id === 1 ?
|
<div className="task__container">
|
||||||
<GetOptionTask
|
<div className='task__header'>
|
||||||
type={1}
|
<img src={questionIcon} alt="" />
|
||||||
inputValue={checkedValues.length ? checkedValues[0].response_body : ''}
|
<h3 className="task__title quiz-title_h3">{questions[index].question_body}</h3>
|
||||||
handleChange={handleChange}
|
</div>
|
||||||
/>
|
|
||||||
:
|
<div className="task__body">
|
||||||
listAnswers.map((answer) => (
|
<form className='task__form form-task' onSubmit={nextQuestion}>
|
||||||
|
{
|
||||||
|
|
||||||
|
answers.map((answer) => (
|
||||||
<GetOptionTask
|
<GetOptionTask
|
||||||
key={answer.id}
|
key={answer.id}
|
||||||
type={questions[index].question_type_id}
|
type={questions[index].question_type_id}
|
||||||
@ -131,18 +120,22 @@ export const TaskQuiz = () => {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
<div className="form-task__buttons">
|
<div className="form-task__buttons">
|
||||||
{questions.length !== index + 1 &&
|
{/* {
|
||||||
<button type='submit' className='quiz-btn'
|
index != 0 && <button type='submit' className='form-task__btn quiz-btn quiz-btn_back'
|
||||||
onClick={(e) => nextQuestion(e)}>Далее</button>}
|
onClick={prevQuestion}>Назад</button>
|
||||||
{questions.length === index + 1 &&
|
} */}
|
||||||
<button onClick={(e) => nextQuestion(e)}
|
{
|
||||||
className='quiz-btn quiz-btn_dark-green'>Завершить</button>}
|
index != questions.length && <button onClick={nextQuestion}
|
||||||
|
className='form-task__btn quiz-btn'>Далее</button>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</React.StrictMode>
|
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
@use 'sass:math';
|
@use "sass:math";
|
||||||
@import 'functions.scss';
|
@import "functions.scss";
|
||||||
|
|
||||||
$maxWidthContainer: 1123;
|
$maxWidthContainer: 1123;
|
||||||
|
|
||||||
@ -31,25 +31,31 @@ $maxWidthContainer: 1123;
|
|||||||
}
|
}
|
||||||
.quiz-btn {
|
.quiz-btn {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
font-family: "Lab Grotesque";
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
box-shadow: 6px 5px 20px rgba(82, 151, 34, 0.21);
|
// box-shadow: 6px 5px 20px rgba(82, 151, 34, 0.21);
|
||||||
border-radius: 23px;
|
white-space: nowrap;
|
||||||
color: #ffffff;
|
background: #406128;
|
||||||
|
border-radius: 44px;
|
||||||
|
color: #fff;
|
||||||
outline: none;
|
outline: none;
|
||||||
border: 2px solid #52b709;
|
//border: 2px solid #52b709;
|
||||||
background: #52b709;
|
border: none;
|
||||||
transition: 0 all ease 0.8s;
|
transition: 0 all ease 0.8s;
|
||||||
padding: 14px 38px;
|
padding: 7px 51px;
|
||||||
line-height: 1;
|
|
||||||
font-family: "Muller Extra Bold";
|
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 16px;
|
font-size: 14px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
&:hover{
|
line-height: 200%;
|
||||||
text-decoration: none;
|
// &:hover{
|
||||||
color: #52b709;
|
// text-decoration: none;
|
||||||
background: #fff;
|
// color: #52b709;
|
||||||
|
// background: #fff;
|
||||||
|
// }
|
||||||
|
&_back {
|
||||||
|
background: #dddddd;
|
||||||
|
color: #000;
|
||||||
}
|
}
|
||||||
&_dark-green {
|
&_dark-green {
|
||||||
background-color: #1a310c;
|
background-color: #1a310c;
|
||||||
@ -60,16 +66,13 @@ $maxWidthContainer: 1123;
|
|||||||
background: #fff;
|
background: #fff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&_restriction{
|
|
||||||
max-width: 131px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.quiz-title_h3 {
|
.quiz-title_h3 {
|
||||||
color: #000000;
|
font-family: "Lab Grotesque";
|
||||||
font-family: "GT Eesti Pro Display";
|
font-weight: 700;
|
||||||
font-size: 25px;
|
font-size: 18px;
|
||||||
font-weight: 400;
|
line-height: 156%;
|
||||||
line-height: math.div(30, 25);
|
color: #52b709;
|
||||||
}
|
}
|
||||||
//=============================================
|
//=============================================
|
||||||
|
|
||||||
@ -80,213 +83,42 @@ $maxWidthContainer: 1123;
|
|||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-quiz{
|
|
||||||
@include adaptiv-value("padding-top", 48, 30, 1);
|
|
||||||
@include adaptiv-value("padding-bottom", 85, 30, 1);
|
|
||||||
&__container{
|
|
||||||
max-width: $maxWidthContainer+px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 0 10px;
|
|
||||||
}
|
|
||||||
&__title-main{
|
|
||||||
font-family: "GT Eesti Pro Display";
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: bold;
|
|
||||||
@include adaptiv-value("margin-bottom", 80, 30, 1);
|
|
||||||
}
|
|
||||||
&__body{
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
row-gap: 30px;
|
|
||||||
margin-bottom: 39px;
|
|
||||||
}
|
|
||||||
&__body_interjacent{
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
&__description{
|
|
||||||
max-width: 576px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
&__avatar{
|
|
||||||
position: relative;
|
|
||||||
display: block;
|
|
||||||
flex: 0 0 133px;
|
|
||||||
min-height: 133px;
|
|
||||||
margin-right: 31px;
|
|
||||||
img{
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: cover;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&__name-user{
|
|
||||||
color: #000000;
|
|
||||||
font-family: "GT Eesti Pro Display";
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 400;
|
|
||||||
line-height: math.div(30, 20);
|
|
||||||
margin-right: 70px;
|
|
||||||
}
|
|
||||||
&__title{
|
|
||||||
color: #000000;
|
|
||||||
font-family: "GT Eesti Pro Display";
|
|
||||||
@include adaptiv-value("font-size", 25, 16, 1);
|
|
||||||
font-weight: 700;
|
|
||||||
line-height: math.div(36, 25);
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
&::before{
|
|
||||||
position: absolute;
|
|
||||||
content: "";
|
|
||||||
width: prc(316, 370);
|
|
||||||
height: 5px;
|
|
||||||
border-radius: 3px;
|
|
||||||
background-color: #54b611;
|
|
||||||
bottom: -26px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.my-tests{
|
|
||||||
font-family: "GT Eesti Pro Display";
|
|
||||||
// @include adaptiv-value("padding-top", 85, 30, 1);
|
|
||||||
// @include adaptiv-value("padding-bottom", 85, 30, 1);
|
|
||||||
&__container{
|
|
||||||
max-width: $maxWidthContainer+px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 0 10px;
|
|
||||||
}
|
|
||||||
&__title{
|
|
||||||
color: #000000;
|
|
||||||
font-size: 25px;
|
|
||||||
font-weight: 400;
|
|
||||||
line-height: math.div(30, 25);
|
|
||||||
@include adaptiv-value("margin-bottom", 80, 30, 1);
|
|
||||||
}
|
|
||||||
&__items{
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
margin: 0 -41px -42px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.item-test{
|
|
||||||
flex: 0 1 50%;
|
|
||||||
padding: 0 41px;
|
|
||||||
margin: 0 0 42px 0;
|
|
||||||
@media (max-width: 760px) {
|
|
||||||
flex: 0 1 100%;
|
|
||||||
}
|
|
||||||
&__name-test{
|
|
||||||
color: #373936;
|
|
||||||
margin-bottom: 29px;
|
|
||||||
|
|
||||||
}
|
|
||||||
.active{
|
|
||||||
color: #54b611;
|
|
||||||
}
|
|
||||||
&__body{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.test-data{
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
&__calendar{
|
|
||||||
padding: 13px 21px;
|
|
||||||
box-shadow: 0 0 59px rgba(44, 44, 44, 0.05);
|
|
||||||
border-radius: 5px;
|
|
||||||
border: 1px solid #c4c4c4;
|
|
||||||
background-color: #f0f7e0;
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 13px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
margin-right: 17px;
|
|
||||||
img{
|
|
||||||
display: block;
|
|
||||||
margin-right: 11px;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
&__hr{
|
|
||||||
width: 28px;
|
|
||||||
height: 5px;
|
|
||||||
border-radius: 3px;
|
|
||||||
background-color: #54b611;
|
|
||||||
margin-right: 26px;
|
|
||||||
}
|
|
||||||
&__select{
|
|
||||||
max-width: 131px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.progressbar{
|
|
||||||
max-width: $maxWidthContainer+px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 0 10px;
|
|
||||||
&__body{
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
&__value{
|
|
||||||
flex: 0 0 39px;
|
|
||||||
height: 39px;
|
|
||||||
background-color: #5cb42b;
|
|
||||||
border-radius: 50%;
|
|
||||||
color: #fff;
|
|
||||||
letter-spacing: 1.1px;
|
|
||||||
font-size: 16px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
// flex: 1 1 auto;
|
|
||||||
margin-right: 19px;
|
|
||||||
}
|
|
||||||
&__strip{
|
|
||||||
flex: 1 1 auto;
|
|
||||||
height: 19px;
|
|
||||||
|
|
||||||
div{
|
|
||||||
border-radius: 10px;
|
|
||||||
height: 100%;
|
|
||||||
background-color: #5cb42b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.task {
|
.task {
|
||||||
@include adaptiv-value("padding-top", 35, 10, 1);
|
@include adaptiv-value("padding-top", 35, 10, 1);
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 12px;
|
||||||
&__container {
|
&__container {
|
||||||
max-width: $maxWidthContainer + px;
|
max-width: $maxWidthContainer + px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 0 10px;
|
padding: 31px 51px;
|
||||||
|
}
|
||||||
|
&__body {
|
||||||
|
margin-left: 50px;
|
||||||
|
}
|
||||||
|
&__header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 24px;
|
||||||
|
margin-bottom: 38px;
|
||||||
}
|
}
|
||||||
&__title {
|
&__title {
|
||||||
margin-bottom: 39px;
|
|
||||||
}
|
}
|
||||||
&__form {
|
&__form {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-task {
|
.form-task {
|
||||||
&__field {
|
&__field {
|
||||||
padding: 10px 15px;
|
padding: 10px 15px;
|
||||||
font-size: 17px;
|
font-size: 17px;
|
||||||
font-family: 'GT Eesti Pro Display';
|
font-family: "GT Eesti Pro Display";
|
||||||
letter-spacing: 0.3px;
|
letter-spacing: 0.3px;
|
||||||
outline: none;
|
outline: none;
|
||||||
border: 1px solid #52b709;
|
border: none;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
resize: vertical;
|
resize: vertical;
|
||||||
|
background: #eff1f3;
|
||||||
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
&__check {
|
&__check {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
@ -307,47 +139,55 @@ $maxWidthContainer: 1123;
|
|||||||
|
|
||||||
.form-task__group {
|
.form-task__group {
|
||||||
display: block;
|
display: block;
|
||||||
|
margin-bottom: 13px;
|
||||||
margin-bottom: 15px;
|
font-family: "Lab Grotesque";
|
||||||
|
|
||||||
label {
|
label {
|
||||||
color: #373936;
|
font-weight: 400;
|
||||||
font-family: "GT Eesti Pro Display";
|
font-size: 15px;
|
||||||
font-size: 18px;
|
line-height: 160%;
|
||||||
font-weight: 300;
|
color: #000000;
|
||||||
line-height: math.div(28,18);
|
|
||||||
position: relative;
|
position: relative;
|
||||||
|
margin: 0;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
&:before {
|
&:before {
|
||||||
content:'';
|
content: "";
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
background-color: transparent;
|
background-color: #eff1f3;
|
||||||
border: 2px solid #52b709;
|
border: 2px solid #eff1f3;
|
||||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05), inset 0px -15px 10px -12px rgba(0, 0, 0, 0.05);
|
border-radius: 8px;
|
||||||
padding: 11px;
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: relative;
|
position: relative;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
margin-right: 30px;
|
margin-right: 16px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
input[type="radio"] + label:before{
|
input[type="radio"]:checked + label::after {
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
input:checked + label:before{
|
|
||||||
background: #52b709;
|
|
||||||
}
|
|
||||||
input:checked + label:after {
|
|
||||||
|
|
||||||
content: "";
|
content: "";
|
||||||
display: block;
|
display: block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 6px;
|
top: 7.5px;
|
||||||
|
left: 6px;
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
background: #8dc63f;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
input:checked + label:before {
|
||||||
|
background: #eff1f3;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="checkbox"]:checked + label:after {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: 7px;
|
||||||
left: 9px;
|
left: 9px;
|
||||||
width: 7px;
|
width: 6px;
|
||||||
height: 14px;
|
height: 13px;
|
||||||
border: solid #fff;
|
border: solid #1c1243;
|
||||||
border-width: 0 2px 2px 0;
|
border-width: 0 2px 2px 0;
|
||||||
transform: rotate(45deg);
|
transform: rotate(45deg);
|
||||||
}
|
}
|
||||||
@ -408,3 +248,489 @@ $maxWidthContainer: 1123;
|
|||||||
color: #5cb42b;
|
color: #5cb42b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.selected-category {
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 12px;
|
||||||
|
&__container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 35px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
@media (max-width: 723px) {
|
||||||
|
justify-content: space-between;
|
||||||
|
row-gap: 25px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&__title {
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 156%;
|
||||||
|
color: #406128;
|
||||||
|
margin: 0 32px 0 0;
|
||||||
|
}
|
||||||
|
&__category {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 18px;
|
||||||
|
margin: 0 44px 0 0;
|
||||||
|
}
|
||||||
|
&__img {
|
||||||
|
height: 48px;
|
||||||
|
flex: 0 0 48px;
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&__title-category {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 122%;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
&__button {
|
||||||
|
background: #e1fccf;
|
||||||
|
border-radius: 44px;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 229%;
|
||||||
|
border: none;
|
||||||
|
padding: 5px 20px;
|
||||||
|
color: #000000;
|
||||||
|
@media (max-width: 723px) {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-introduction {
|
||||||
|
padding: 0px 25px;
|
||||||
|
margin: 0px 0px 50px 0px;
|
||||||
|
flex: 0 1 33.333%;
|
||||||
|
@media (max-width: 850px) {
|
||||||
|
flex: 0 1 50%;
|
||||||
|
}
|
||||||
|
@media (max-width: 850px) {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__body {
|
||||||
|
display: flex;
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
&__title {
|
||||||
|
font-weight: 900;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 171%;
|
||||||
|
color: #52b709;
|
||||||
|
margin: 0 0 30px 0;
|
||||||
|
}
|
||||||
|
&__icon {
|
||||||
|
flex: 0 0 25px;
|
||||||
|
height: 30px;
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&__text {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 200%;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.quiz-passing-information {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 12px;
|
||||||
|
&__container {
|
||||||
|
// @media (max-width: 600px) {
|
||||||
|
// display: block;
|
||||||
|
// }
|
||||||
|
// @media (max-width: 600px) {
|
||||||
|
// display: block;
|
||||||
|
// }
|
||||||
|
// @media (max-width: 600px) {
|
||||||
|
// display: block;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
&__main {
|
||||||
|
//flex: 1 1 auto;
|
||||||
|
padding: 35px 45px;
|
||||||
|
height: 100%;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1.2fr 1.2fr 0.6fr;
|
||||||
|
@media (max-width: 900px) {
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
grid-gap: 20px;
|
||||||
|
}
|
||||||
|
@media (max-width: 500px) {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&__icon {
|
||||||
|
flex: 0 0 32px;
|
||||||
|
height: 35px;
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&__text {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 167%;
|
||||||
|
color: #6f6f6f;
|
||||||
|
span {
|
||||||
|
color: #111112;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&__timer,
|
||||||
|
&__attempt {
|
||||||
|
display: flex;
|
||||||
|
gap: 23px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__specialization {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 15px;
|
||||||
|
}
|
||||||
|
&__specialization-title {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 122%;
|
||||||
|
color: #000000;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
&__button {
|
||||||
|
font-size: 18px;
|
||||||
|
max-width: 174px;
|
||||||
|
height: 46px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.block-text {
|
||||||
|
border-radius: 12px;
|
||||||
|
background: #fff;
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
padding: 18px 0;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 156%;
|
||||||
|
color: #000000;
|
||||||
|
a {
|
||||||
|
color: #406128;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-available-test {
|
||||||
|
position: relative;
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 12px;
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
|
||||||
|
&__container {
|
||||||
|
display: block;
|
||||||
|
@include adaptiv-value("padding-top", 30, 20, 1);
|
||||||
|
@include adaptiv-value("padding-bottom", 30, 20, 1);
|
||||||
|
@include adaptiv-value("padding-right", 28, 18, 1);
|
||||||
|
@include adaptiv-value("padding-left", 28, 18, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
box-shadow: 6px 5px 20px rgb(87 98 80 / 21%);
|
||||||
|
transform: scale(1.02);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__top-head {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 19px;
|
||||||
|
margin: 0 0 24px 0;
|
||||||
|
}
|
||||||
|
&__title {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 122%;
|
||||||
|
color: #000000;
|
||||||
|
max-width: 128px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__info {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
p {
|
||||||
|
flex: 0 1 66%;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 20px;
|
||||||
|
color: #000000;
|
||||||
|
margin-bottom: 0;
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #52b709;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&Link {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
background: #ddeec6;
|
||||||
|
border-radius: 50px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&__finished {
|
||||||
|
background: rgba(255, 255, 255, 0.76);
|
||||||
|
mix-blend-mode: normal;
|
||||||
|
border: 3px solid #52b709;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 13px 16px;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 10px;
|
||||||
|
p {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 129%;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
&:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
display: block;
|
||||||
|
background: #52b709;
|
||||||
|
border-radius: 44px;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 213%;
|
||||||
|
color: #ffffff;
|
||||||
|
padding: 9px 25px;
|
||||||
|
white-space: nowrap;
|
||||||
|
outline: none;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.block-completed-test {
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 12px;
|
||||||
|
// .block-completed-test__container
|
||||||
|
|
||||||
|
&__container {
|
||||||
|
padding: 41px 35px 29px 59px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// .block-completed-test__img
|
||||||
|
|
||||||
|
&__img {
|
||||||
|
flex: 0 0 54px;
|
||||||
|
height: 60px;
|
||||||
|
margin: 0 34px 0 0;
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// .block-completed-test__title
|
||||||
|
|
||||||
|
&__title {
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 156%;
|
||||||
|
margin: 0 60px 0 0;
|
||||||
|
color: #52b709;
|
||||||
|
}
|
||||||
|
|
||||||
|
// .block-completed-test__text
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
max-width: 386px;
|
||||||
|
margin: 0 26px 0 0;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 200%;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
// .block-completed-test__button
|
||||||
|
|
||||||
|
&__button {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.report {
|
||||||
|
// .report__row
|
||||||
|
|
||||||
|
&__row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// .report__column
|
||||||
|
|
||||||
|
&__column {
|
||||||
|
&:first-child {
|
||||||
|
background: #ffffff;
|
||||||
|
flex: 0 1 22%;
|
||||||
|
border-radius: 12px;
|
||||||
|
@media (max-width: 1000px) {
|
||||||
|
flex: 0 1 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
height: 128px;
|
||||||
|
border-radius: 0px 12px 0px 0px;
|
||||||
|
flex: 0 1 26%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background: #e1fccf;
|
||||||
|
gap: 21px;
|
||||||
|
&:last-child {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0;
|
||||||
|
}
|
||||||
|
@media (max-width: 1000px) {
|
||||||
|
flex: 0 1 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// .report__job-title
|
||||||
|
|
||||||
|
&__job-title {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 122%;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
// .report__value
|
||||||
|
|
||||||
|
&__value {
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 52px;
|
||||||
|
line-height: 56%;
|
||||||
|
color: #52b709;
|
||||||
|
// .report__value_false
|
||||||
|
|
||||||
|
&_false {
|
||||||
|
color: #5b6871;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// .report__text
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 138%;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
// .report__status-text
|
||||||
|
|
||||||
|
&__status-text {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 200%;
|
||||||
|
color: #000000;
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
// .report__status
|
||||||
|
|
||||||
|
&__status {
|
||||||
|
background: #1458dd;
|
||||||
|
border-radius: 44px;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 200%;
|
||||||
|
color: #ffffff;
|
||||||
|
padding: 7px 34px;
|
||||||
|
max-width: 154px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-result {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
@include adaptiv-value("padding-top", 39, 20, 1);
|
||||||
|
@include adaptiv-value("padding-bottom", 39, 20, 1);
|
||||||
|
@include adaptiv-value("padding-right", 61, 20, 1);
|
||||||
|
@include adaptiv-value("padding-left", 61, 20, 1);
|
||||||
|
background: #fff;
|
||||||
|
gap: 30px;
|
||||||
|
border-radius: 10px;
|
||||||
|
@media (max-width: 900px) {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
&__column {
|
||||||
|
display: flex;
|
||||||
|
@include adaptiv-value("gap", 44, 14, 1);
|
||||||
|
align-items: center;
|
||||||
|
@media (max-width: 900px) {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&__icon {
|
||||||
|
width: 39px;
|
||||||
|
height: 39px;
|
||||||
|
}
|
||||||
|
&__text {
|
||||||
|
font-weight: 700;
|
||||||
|
@include adaptiv-value("font-size", 18, 14, 1);
|
||||||
|
line-height: 156%;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
&__button {
|
||||||
|
width: 231px;
|
||||||
|
@include adaptiv-value("font-size", 16, 14, 1);
|
||||||
|
@media (max-width: 900px) {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BIN
src/images/icon-specialization.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
src/images/note.png
Normal file
After Width: | Height: | Size: 547 B |
BIN
src/images/question.png
Normal file
After Width: | Height: | Size: 803 B |
BIN
src/images/quiz/accempt.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
src/images/quiz/compltedImage.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
src/images/quiz/success.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
src/images/quiz/timer.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
@ -19,7 +19,7 @@ code {
|
|||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
display: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
.auth {
|
.auth {
|
||||||
&__wrapper {
|
&__wrapper {
|
||||||
background: #FFFFFF;
|
background: #ffffff;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
padding: 50px 0 35px 56px;
|
padding: 50px 0 35px 56px;
|
||||||
margin-top: 40px;
|
margin-top: 40px;
|
||||||
@ -55,7 +55,7 @@
|
|||||||
|
|
||||||
input {
|
input {
|
||||||
margin-bottom: 30px;
|
margin-bottom: 30px;
|
||||||
background: #EFF2F7;
|
background: #eff2f7;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
min-width: 300px;
|
min-width: 300px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -80,7 +80,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
background: #52B709;
|
background: #52b709;
|
||||||
border-radius: 44px;
|
border-radius: 44px;
|
||||||
max-width: 130px;
|
max-width: 130px;
|
||||||
border: none;
|
border: none;
|
||||||
@ -107,7 +107,7 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
span {
|
span {
|
||||||
color: #52B709;
|
color: #52b709;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 660px) {
|
@media (max-width: 660px) {
|
||||||
@ -122,13 +122,19 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&__categoriesWrapper {
|
&__categoriesWrapper {
|
||||||
display: flex;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
margin-top: 200px;
|
margin-top: 200px;
|
||||||
flex-wrap: wrap;
|
|
||||||
row-gap: 24px;
|
|
||||||
column-gap: 21px;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
display: grid;
|
||||||
|
grid-gap: 24px;
|
||||||
|
grid-template-columns: 1fr 1fr 1fr;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
@media (max-width: 955px) {
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
}
|
||||||
|
@media (max-width: 668px) {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
.categoriesItem {
|
.categoriesItem {
|
||||||
@media (max-width: 1094px) {
|
@media (max-width: 1094px) {
|
||||||
|
@ -11,6 +11,7 @@ import {ProfileHeader} from "../../components/ProfileHeader/ProfileHeader";
|
|||||||
import {ProfileBreadcrumbs} from "../../components/ProfileBreadcrumbs/ProfileBreadcrumbs"
|
import {ProfileBreadcrumbs} from "../../components/ProfileBreadcrumbs/ProfileBreadcrumbs"
|
||||||
import {apiRequest} from "../../api/request";
|
import {apiRequest} from "../../api/request";
|
||||||
import {Navigate} from "react-router-dom";
|
import {Navigate} from "react-router-dom";
|
||||||
|
import { Navigation } from '../../components/Navigation/Navigation'
|
||||||
|
|
||||||
|
|
||||||
const Home = () => {
|
const Home = () => {
|
||||||
@ -58,6 +59,7 @@ const Home = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ProfileHeader/>
|
<ProfileHeader/>
|
||||||
|
<Navigation />
|
||||||
<div className="catalog">
|
<div className="catalog">
|
||||||
<div className='container'>
|
<div className='container'>
|
||||||
<ProfileBreadcrumbs links={[
|
<ProfileBreadcrumbs links={[
|
||||||
|
@ -15,6 +15,7 @@ import deleteIcon from "../../images/close.png"
|
|||||||
|
|
||||||
|
|
||||||
import './partnerAddRequest.scss'
|
import './partnerAddRequest.scss'
|
||||||
|
import { Navigation } from '../../components/Navigation/Navigation';
|
||||||
|
|
||||||
export const PartnerAddRequest = () => {
|
export const PartnerAddRequest = () => {
|
||||||
if(localStorage.getItem('role_status') !== '18') {
|
if(localStorage.getItem('role_status') !== '18') {
|
||||||
@ -81,6 +82,7 @@ export const PartnerAddRequest = () => {
|
|||||||
return (
|
return (
|
||||||
<div className='partnerAddRequest'>
|
<div className='partnerAddRequest'>
|
||||||
<ProfileHeader />
|
<ProfileHeader />
|
||||||
|
<Navigation />
|
||||||
<div className='container'>
|
<div className='container'>
|
||||||
<ProfileBreadcrumbs links={[
|
<ProfileBreadcrumbs links={[
|
||||||
{name: 'Главная', link: '/profile'},
|
{name: 'Главная', link: '/profile'},
|
||||||
|
@ -1,20 +1,22 @@
|
|||||||
import React, {useEffect, useState} from 'react';
|
import React, {useEffect, useState} from 'react';
|
||||||
import {Link, Navigate} from "react-router-dom";
|
import {Link, Navigate, useNavigate} from "react-router-dom";
|
||||||
import {useSelector, useDispatch} from 'react-redux'
|
import {useSelector, useDispatch} from 'react-redux'
|
||||||
import {getPartnerRequestId, getPartnerRequests, setPartnerRequestId} from '../../redux/outstaffingSlice'
|
import {getPartnerRequestId, getPartnerRequests, setPartnerRequestId} from '../../redux/outstaffingSlice'
|
||||||
|
|
||||||
import {ProfileHeader} from "../../components/ProfileHeader/ProfileHeader";
|
import {ProfileHeader} from "../../components/ProfileHeader/ProfileHeader";
|
||||||
import {ProfileBreadcrumbs} from "../../components/ProfileBreadcrumbs/ProfileBreadcrumbs"
|
import {ProfileBreadcrumbs} from "../../components/ProfileBreadcrumbs/ProfileBreadcrumbs"
|
||||||
import {Footer} from "../../components/Footer/Footer";
|
import {Footer} from "../../components/Footer/Footer";
|
||||||
|
import { Navigation } from '../../components/Navigation/Navigation';
|
||||||
import {Loader} from "../../components/Loader/Loader"
|
import {Loader} from "../../components/Loader/Loader"
|
||||||
|
|
||||||
import {apiRequest} from "../../api/request";
|
import {apiRequest} from "../../api/request";
|
||||||
import {getCorrectDate} from "../../components/Calendar/calendarHelper";
|
import {getCorrectDate} from "../../components/Calendar/calendarHelper";
|
||||||
|
|
||||||
|
import {urlForLocal} from '../../helper'
|
||||||
|
|
||||||
import arrowSwitchDate from "../../images/arrowViewReport.png";
|
import arrowSwitchDate from "../../images/arrowViewReport.png";
|
||||||
import backEndImg from "../../images/QualificationInfo.png";
|
import backEndImg from "../../images/QualificationInfo.png";
|
||||||
import middle from "../../images/QualificationInfoMiddle.png";
|
import middle from "../../images/QualificationInfoMiddle.png";
|
||||||
import personImg from "../../images/mokPerson.png"
|
|
||||||
import deleteBtn from "../../images/deleteBtn.png"
|
import deleteBtn from "../../images/deleteBtn.png"
|
||||||
|
|
||||||
import './partnerBid.scss'
|
import './partnerBid.scss'
|
||||||
@ -23,9 +25,11 @@ export const PartnerBid = () => {
|
|||||||
if(localStorage.getItem('role_status') !== '18') {
|
if(localStorage.getItem('role_status') !== '18') {
|
||||||
return <Navigate to="/profile" replace/>
|
return <Navigate to="/profile" replace/>
|
||||||
}
|
}
|
||||||
|
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const requestId = useSelector(getPartnerRequestId);
|
const requestId = useSelector(getPartnerRequestId);
|
||||||
const partnerRequests = useSelector(getPartnerRequests);
|
const partnerRequests = useSelector(getPartnerRequests);
|
||||||
|
const navigate= useNavigate();
|
||||||
|
|
||||||
if (!requestId) {
|
if (!requestId) {
|
||||||
return <Navigate to="/profile/requests" replace/>
|
return <Navigate to="/profile/requests" replace/>
|
||||||
@ -39,29 +43,37 @@ export const PartnerBid = () => {
|
|||||||
})
|
})
|
||||||
}, [requestId]);
|
}, [requestId]);
|
||||||
|
|
||||||
|
const deleteRequest = () => {
|
||||||
|
apiRequest('/request/update-request', {
|
||||||
|
method: 'PUT',
|
||||||
|
data: {
|
||||||
|
user_id: localStorage.getItem('id'),
|
||||||
|
request_id: requestId,
|
||||||
|
status: 0,
|
||||||
|
// title: 'bro',
|
||||||
|
// position_id: 1,
|
||||||
|
// knowledge_level_id: 2,
|
||||||
|
// specialist_count: 2,
|
||||||
|
// descr: 'broooooo',
|
||||||
|
// skill_ids: [1, 2, 3]
|
||||||
|
}
|
||||||
|
}).then((res) => {
|
||||||
|
navigate('/profile/requests');
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
const [requestInfo, setRequestInfo] = useState({})
|
const [requestInfo, setRequestInfo] = useState({})
|
||||||
const [loader, setLoader] = useState(false)
|
const [loader, setLoader] = useState(false)
|
||||||
|
const [levels] = useState({
|
||||||
const [mokPersons] = useState([
|
1: "Junior",
|
||||||
{
|
2: "Middle",
|
||||||
name: 'Дмитрий, PHP Back end - разработчик, Middle',
|
3: "Middle+",
|
||||||
link: '/candidate/110',
|
4: "Senior",
|
||||||
img: personImg
|
})
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Дмитрий, PHP Back end - разработчик, Middle',
|
|
||||||
link: '/candidate/111',
|
|
||||||
img: personImg
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Дмитрий, PHP Back end - разработчик, Middle',
|
|
||||||
link: '/candidate/112',
|
|
||||||
img: personImg
|
|
||||||
}
|
|
||||||
])
|
|
||||||
return (
|
return (
|
||||||
<div className='partnerBid'>
|
<div className='partnerBid'>
|
||||||
<ProfileHeader />
|
<ProfileHeader />
|
||||||
|
<Navigation />
|
||||||
<div className='container'>
|
<div className='container'>
|
||||||
<ProfileBreadcrumbs links={[
|
<ProfileBreadcrumbs links={[
|
||||||
{name: 'Главная', link: '/profile'},
|
{name: 'Главная', link: '/profile'},
|
||||||
@ -77,7 +89,7 @@ export const PartnerBid = () => {
|
|||||||
<h3>{requestInfo.title}</h3>
|
<h3>{requestInfo.title}</h3>
|
||||||
<div className='partnerBid__qualification__buttons'>
|
<div className='partnerBid__qualification__buttons'>
|
||||||
<button>Редактировать</button>
|
<button>Редактировать</button>
|
||||||
<img src={deleteBtn} alt='delete'/>
|
<img src={deleteBtn} alt='delete' onClick={() => deleteRequest()}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='partnerBid__switcher'>
|
<div className='partnerBid__switcher'>
|
||||||
@ -100,6 +112,7 @@ export const PartnerBid = () => {
|
|||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
{Boolean(Object.keys(requestInfo).length) && !loader &&
|
{Boolean(Object.keys(requestInfo).length) && !loader &&
|
||||||
|
<>
|
||||||
<div className='table__wrapper'>
|
<div className='table__wrapper'>
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
@ -148,27 +161,25 @@ export const PartnerBid = () => {
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
}
|
|
||||||
<div className='partnerBid__suitable'>
|
<div className='partnerBid__suitable'>
|
||||||
<div className='partnerBid__suitable__title'>
|
<div className='partnerBid__suitable__title'>
|
||||||
<p>Подходящие сотрудники по запросу</p>
|
<p>Подходящие сотрудники по запросу</p>
|
||||||
</div>
|
</div>
|
||||||
<div className='partnerBid__suitable__persons'>
|
<div className='partnerBid__suitable__persons'>
|
||||||
{mokPersons.map((person, index) => {
|
{requestInfo.result_profiles.length && requestInfo.result_profiles.map((person, index) => {
|
||||||
return <div key={index} className='partnerBid__suitable__person'>
|
return <div key={index} className='partnerBid__suitable__person'>
|
||||||
<img src={person.img} alt='avatar' />
|
<img src={urlForLocal(person.photo)} alt='avatar' />
|
||||||
<p>{person.name}</p>
|
<p>{person.fio} - {person.position_title}, {levels[person.level]}</p>
|
||||||
<Link className='partnerBid__suitable__person__more' to={person.link}>
|
<Link className='partnerBid__suitable__person__more' to={`/candidate/${person.id}`}>
|
||||||
Подробнее
|
Подробнее
|
||||||
</Link>
|
</Link>
|
||||||
<div className='partnerBid__suitable__person__info'>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
<Footer/>
|
<Footer/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -59,6 +59,7 @@
|
|||||||
width: 44px;
|
width: 44px;
|
||||||
height: 44px;
|
height: 44px;
|
||||||
margin-left: 21px;
|
margin-left: 21px;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -339,6 +340,30 @@
|
|||||||
row-gap: 18px;
|
row-gap: 18px;
|
||||||
position: relative;
|
position: relative;
|
||||||
top: -15px;
|
top: -15px;
|
||||||
|
max-height: 420px;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: 4px;
|
||||||
|
background: 0 0;
|
||||||
|
box-shadow: 0 0 14px rgba(0, 0, 0, 0.04);
|
||||||
|
border-radius: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: 4px;
|
||||||
|
border-radius: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-thumb {
|
||||||
|
background: #8db274;
|
||||||
|
border-radius: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-track {
|
||||||
|
background: #c5c0c6;
|
||||||
|
border-radius: 20px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__person {
|
&__person {
|
||||||
@ -353,8 +378,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
img {
|
img {
|
||||||
width: 88px;
|
max-width: 88px;
|
||||||
height: 88px;
|
height: 88px;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
@ -364,6 +390,7 @@
|
|||||||
line-height: 32px;
|
line-height: 32px;
|
||||||
margin-left: 60px;
|
margin-left: 60px;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
&:after {
|
&:after {
|
||||||
content: "";
|
content: "";
|
||||||
|
@ -14,6 +14,7 @@ import {apiRequest} from "../../api/request";
|
|||||||
import cursorImg from "../../images/cursorImg.png"
|
import cursorImg from "../../images/cursorImg.png"
|
||||||
|
|
||||||
import './partnerRequests.scss'
|
import './partnerRequests.scss'
|
||||||
|
import { Navigation } from '../../components/Navigation/Navigation';
|
||||||
|
|
||||||
export const PartnerRequests = () => {
|
export const PartnerRequests = () => {
|
||||||
if(localStorage.getItem('role_status') !== '18') {
|
if(localStorage.getItem('role_status') !== '18') {
|
||||||
@ -33,6 +34,7 @@ export const PartnerRequests = () => {
|
|||||||
return (
|
return (
|
||||||
<div className='partnerRequests'>
|
<div className='partnerRequests'>
|
||||||
<ProfileHeader />
|
<ProfileHeader />
|
||||||
|
<Navigation />
|
||||||
<div className='container'>
|
<div className='container'>
|
||||||
<ProfileBreadcrumbs links={[
|
<ProfileBreadcrumbs links={[
|
||||||
{name: 'Главная', link: '/profile'},
|
{name: 'Главная', link: '/profile'},
|
||||||
|
@ -7,11 +7,13 @@ import { ProfileHeader } from "../../components/ProfileHeader/ProfileHeader";
|
|||||||
import kontur from "../../images/konturLogo.png";
|
import kontur from "../../images/konturLogo.png";
|
||||||
import astral from "../../images/astralLogo.png";
|
import astral from "../../images/astralLogo.png";
|
||||||
import "./partnerSettings.scss";
|
import "./partnerSettings.scss";
|
||||||
|
import { Navigation } from "../../components/Navigation/Navigation";
|
||||||
|
|
||||||
export const PartnerSettings = () => {
|
export const PartnerSettings = () => {
|
||||||
return (
|
return (
|
||||||
<div className="settings">
|
<div className="settings">
|
||||||
<ProfileHeader />
|
<ProfileHeader />
|
||||||
|
<Navigation />
|
||||||
<div className="container settings__page">
|
<div className="container settings__page">
|
||||||
<ProfileBreadcrumbs
|
<ProfileBreadcrumbs
|
||||||
links={[
|
links={[
|
||||||
|
@ -15,6 +15,7 @@ import lockDone from "./Images/lockDone.svg"
|
|||||||
import avatarMok from "./Images/avatarMok.png"
|
import avatarMok from "./Images/avatarMok.png"
|
||||||
|
|
||||||
import './partnerTreaties.scss'
|
import './partnerTreaties.scss'
|
||||||
|
import { Navigation } from '../../components/Navigation/Navigation';
|
||||||
|
|
||||||
export const PartnerTreaties = () => {
|
export const PartnerTreaties = () => {
|
||||||
const [toggleTab, setToggleTab] = useState(1);
|
const [toggleTab, setToggleTab] = useState(1);
|
||||||
@ -25,6 +26,7 @@ export const PartnerTreaties = () => {
|
|||||||
return(
|
return(
|
||||||
<div className="treaties">
|
<div className="treaties">
|
||||||
<ProfileHeader/>
|
<ProfileHeader/>
|
||||||
|
<Navigation />
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<ProfileBreadcrumbs
|
<ProfileBreadcrumbs
|
||||||
links={[
|
links={[
|
||||||
|
@ -22,6 +22,7 @@ import rightArrow from "../../images/arrowRight.png"
|
|||||||
import avatarImg from "../PartnerEmployees/avatarMok.png";
|
import avatarImg from "../PartnerEmployees/avatarMok.png";
|
||||||
|
|
||||||
import "./partnerСategories.scss"
|
import "./partnerСategories.scss"
|
||||||
|
import { Navigation } from '../../components/Navigation/Navigation';
|
||||||
|
|
||||||
export const PartnerCategories = () => {
|
export const PartnerCategories = () => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
@ -130,6 +131,7 @@ export const PartnerCategories = () => {
|
|||||||
return (
|
return (
|
||||||
<div className="partnerCategories">
|
<div className="partnerCategories">
|
||||||
<ProfileHeader />
|
<ProfileHeader />
|
||||||
|
<Navigation />
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<ProfileBreadcrumbs links={[
|
<ProfileBreadcrumbs links={[
|
||||||
{name: 'Главная', link: '/profile'},
|
{name: 'Главная', link: '/profile'},
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import {ProfileHeader} from "../../components/ProfileHeader/ProfileHeader";
|
import {ProfileHeader} from "../../components/ProfileHeader/ProfileHeader";
|
||||||
|
import { Navigation } from '../../components/Navigation/Navigation';
|
||||||
|
|
||||||
export const Payouts = () => {
|
export const Payouts = () => {
|
||||||
return (
|
return (
|
||||||
<div className='payouts'>
|
<div className='payouts'>
|
||||||
<ProfileHeader />
|
<ProfileHeader />
|
||||||
|
<Navigation />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
@ -5,6 +5,8 @@ import {Link} from "react-router-dom";
|
|||||||
import {ProfileHeader} from "../../components/ProfileHeader/ProfileHeader";
|
import {ProfileHeader} from "../../components/ProfileHeader/ProfileHeader";
|
||||||
import {ProfileBreadcrumbs} from "../../components/ProfileBreadcrumbs/ProfileBreadcrumbs"
|
import {ProfileBreadcrumbs} from "../../components/ProfileBreadcrumbs/ProfileBreadcrumbs"
|
||||||
import {Footer} from "../../components/Footer/Footer";
|
import {Footer} from "../../components/Footer/Footer";
|
||||||
|
import { CardControl } from '../../components/CardControl/CardControl';
|
||||||
|
import { Navigation } from '../../components/Navigation/Navigation';
|
||||||
|
|
||||||
import {getProfileInfo} from "../../redux/outstaffingSlice";
|
import {getProfileInfo} from "../../redux/outstaffingSlice";
|
||||||
|
|
||||||
@ -17,8 +19,6 @@ import paymentIcon from "../../images/paymentIcon.png"
|
|||||||
import settingIcon from "../../images/settingIcon.png"
|
import settingIcon from "../../images/settingIcon.png"
|
||||||
import avatarMok from "../PartnerTreaties/Images/avatarMok.png"
|
import avatarMok from "../PartnerTreaties/Images/avatarMok.png"
|
||||||
|
|
||||||
import rightArrow from "../../images/arrowRight.png"
|
|
||||||
|
|
||||||
import './profile.scss'
|
import './profile.scss'
|
||||||
|
|
||||||
export const Profile = () => {
|
export const Profile = () => {
|
||||||
@ -28,31 +28,31 @@ export const Profile = () => {
|
|||||||
const [profileItemsInfo] = useState({
|
const [profileItemsInfo] = useState({
|
||||||
developer: [
|
developer: [
|
||||||
{
|
{
|
||||||
path: '/calendar',
|
path: 'profile/calendar',
|
||||||
img: reportsIcon,
|
img: reportsIcon,
|
||||||
title: 'Ваша отчетность',
|
title: 'Ваша отчетность',
|
||||||
description: '<span></span>Отработанных в этом месяце часов'
|
description: '<span></span>Отработанных в этом месяце часов'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/summary',
|
path: 'profile/summary',
|
||||||
img: summaryIcon,
|
img: summaryIcon,
|
||||||
title: 'Данные и резюме',
|
title: 'Данные и резюме',
|
||||||
description: 'Ваше резюме<br/><span>заполнено</span>'
|
description: 'Ваше резюме<br/><span>заполнено</span>'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/tracker',
|
path: 'profile/tracker',
|
||||||
img: timerIcon,
|
img: timerIcon,
|
||||||
title: 'Трекер времени',
|
title: 'Трекер времени',
|
||||||
description: 'Сколько времени занимает<br/> выполнение задач'
|
description: 'Сколько времени занимает<br/> выполнение задач'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/payouts',
|
path: 'profile/payouts',
|
||||||
img: paymentIcon,
|
img: paymentIcon,
|
||||||
title: 'Выплаты',
|
title: 'Выплаты',
|
||||||
description: 'У вас <span>подтвержден</span><br/> статус самозанятого'
|
description: 'У вас <span>подтвержден</span><br/> статус самозанятого'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/settings',
|
path: 'profile/settings',
|
||||||
img: settingIcon,
|
img: settingIcon,
|
||||||
title: 'Настройки аккаунта',
|
title: 'Настройки аккаунта',
|
||||||
description: 'Перейдите чтобы начать<br/> редактирование'
|
description: 'Перейдите чтобы начать<br/> редактирование'
|
||||||
@ -60,31 +60,31 @@ export const Profile = () => {
|
|||||||
],
|
],
|
||||||
partner: [
|
partner: [
|
||||||
{
|
{
|
||||||
path: '/requests',
|
path: 'profile/requests',
|
||||||
img: reportsIcon,
|
img: reportsIcon,
|
||||||
title: 'Запросы и открытые позиции',
|
title: 'Запросы и открытые позиции',
|
||||||
description: '<span>У вас 2 вакансии<br/></span>открытые от лица компании'
|
description: '<span>У вас 2 вакансии<br/></span>открытые от лица компании'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/categories',
|
path: 'profile/categories',
|
||||||
img: summaryIcon,
|
img: summaryIcon,
|
||||||
title: 'Данные персонала',
|
title: 'Данные персонала',
|
||||||
description: 'Наши специалисты <br/><span>уже работающие у вас</span>'
|
description: 'Наши специалисты <br/><span>уже работающие у вас</span>'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/tracker',
|
path: 'profile/tracker',
|
||||||
img: timerIcon,
|
img: timerIcon,
|
||||||
title: 'Трекер времени',
|
title: 'Трекер времени',
|
||||||
description: 'Контроль времени и<br/> выполнение задач'
|
description: 'Контроль времени и<br/> выполнение задач'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/treaties',
|
path: 'profile/treaties',
|
||||||
img: paymentIcon,
|
img: paymentIcon,
|
||||||
title: 'Договора и отчетность',
|
title: 'Договора и отчетность',
|
||||||
description: 'Ключевые условия<br/> договора'
|
description: 'Ключевые условия<br/> договора'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/settings',
|
path: 'profile/settings',
|
||||||
img: settingIcon,
|
img: settingIcon,
|
||||||
title: 'Настройки аккаунта',
|
title: 'Настройки аккаунта',
|
||||||
description: 'Перейдите чтобы начать<br/> редактирование'
|
description: 'Перейдите чтобы начать<br/> редактирование'
|
||||||
@ -95,6 +95,7 @@ export const Profile = () => {
|
|||||||
return (
|
return (
|
||||||
<div className='profile'>
|
<div className='profile'>
|
||||||
<ProfileHeader/>
|
<ProfileHeader/>
|
||||||
|
<Navigation />
|
||||||
<div className='container'>
|
<div className='container'>
|
||||||
<ProfileBreadcrumbs links={[{name: 'Главная', link: '/profile'}]} />
|
<ProfileBreadcrumbs links={[{name: 'Главная', link: '/profile'}]} />
|
||||||
<h2 className='profile__title'>
|
<h2 className='profile__title'>
|
||||||
@ -119,18 +120,13 @@ export const Profile = () => {
|
|||||||
<div className='profile__items'>
|
<div className='profile__items'>
|
||||||
{
|
{
|
||||||
profileItemsInfo[user].map((item, index) => {
|
profileItemsInfo[user].map((item, index) => {
|
||||||
return <Link key={index} to={`/profile${item.path}`} className='item'>
|
return <CardControl
|
||||||
<div className='item__about'>
|
description={item.description}
|
||||||
<img src={item.img} alt='itemImg'/>
|
img={item.img}
|
||||||
<h3>{item.title}</h3>
|
path={item.path}
|
||||||
</div>
|
title={item.title}
|
||||||
<div className='item__info'>
|
key={index}
|
||||||
<p dangerouslySetInnerHTML={{__html: item.description}}></p>
|
/>
|
||||||
<div className='item__infoLink'>
|
|
||||||
<img src={rightArrow} alt='arrow'/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Link>
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
@ -49,79 +49,79 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.item {
|
// .item {
|
||||||
max-width: 353px;
|
// max-width: 353px;
|
||||||
width: 100%;
|
// width: 100%;
|
||||||
padding: 35px 45px 15px 30px;
|
// padding: 35px 45px 15px 30px;
|
||||||
background: #FFFFFF;
|
// background: #FFFFFF;
|
||||||
border-radius: 12px;
|
// border-radius: 12px;
|
||||||
text-decoration: none;
|
// text-decoration: none;
|
||||||
cursor: pointer;
|
// cursor: pointer;
|
||||||
transition: all 0.3s ease;
|
// transition: all 0.3s ease;
|
||||||
|
|
||||||
&:hover {
|
// &:hover {
|
||||||
box-shadow: 6px 5px 20px rgb(87 98 80 / 21%);
|
// box-shadow: 6px 5px 20px rgb(87 98 80 / 21%);
|
||||||
transform: scale(1.02);
|
// transform: scale(1.02);
|
||||||
}
|
// }
|
||||||
|
|
||||||
@media (max-width: 1175px) {
|
// @media (max-width: 1175px) {
|
||||||
width: 48%;
|
// width: 48%;
|
||||||
max-width: none;
|
// max-width: none;
|
||||||
}
|
// }
|
||||||
|
|
||||||
@media (max-width: 925px) {
|
// @media (max-width: 925px) {
|
||||||
width: 100%;
|
// width: 100%;
|
||||||
padding: 15px 25px;
|
// padding: 15px 25px;
|
||||||
}
|
// }
|
||||||
|
|
||||||
&__about {
|
// &__about {
|
||||||
display: flex;
|
// display: flex;
|
||||||
column-gap: 20px;
|
// column-gap: 20px;
|
||||||
align-items: center;
|
// align-items: center;
|
||||||
margin-bottom: 30px;
|
// margin-bottom: 30px;
|
||||||
|
|
||||||
@media (max-width: 925px) {
|
// @media (max-width: 925px) {
|
||||||
margin-bottom: 15px;
|
// margin-bottom: 15px;
|
||||||
}
|
// }
|
||||||
|
|
||||||
h3 {
|
// h3 {
|
||||||
color: #000000;
|
// color: #000000;
|
||||||
font-weight: 500;
|
// font-weight: 500;
|
||||||
font-size: 18px;
|
// font-size: 18px;
|
||||||
line-height: 22px;
|
// line-height: 22px;
|
||||||
max-width: 125px;
|
// max-width: 125px;
|
||||||
margin-bottom: 0;
|
// margin-bottom: 0;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
&__info {
|
// &__info {
|
||||||
display: flex;
|
// display: flex;
|
||||||
justify-content: space-between;
|
// justify-content: space-between;
|
||||||
align-items: center;
|
// align-items: center;
|
||||||
|
|
||||||
p {
|
// p {
|
||||||
font-weight: 700;
|
// font-weight: 700;
|
||||||
font-size: 12px;
|
// font-size: 12px;
|
||||||
line-height: 20px;
|
// line-height: 20px;
|
||||||
color: #000000;
|
// color: #000000;
|
||||||
margin-bottom: 0;
|
// margin-bottom: 0;
|
||||||
|
|
||||||
span {
|
// span {
|
||||||
color: #52B709;
|
// color: #52B709;
|
||||||
font-weight: 700;
|
// font-weight: 700;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
&Link {
|
// &Link {
|
||||||
width: 48px;
|
// width: 48px;
|
||||||
height: 48px;
|
// height: 48px;
|
||||||
background: #DDEEC6;
|
// background: #DDEEC6;
|
||||||
border-radius: 50px;
|
// border-radius: 50px;
|
||||||
display: flex;
|
// display: flex;
|
||||||
justify-content: center;
|
// justify-content: center;
|
||||||
align-items: center;
|
// align-items: center;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
|
94
src/pages/ProfileCandidate/ProfileCandidate.js
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
import React, { useState } from 'react'
|
||||||
|
import './ProfileCandidate.scss'
|
||||||
|
import { ProfileHeader } from "../../components/ProfileHeader/ProfileHeader";
|
||||||
|
import { ProfileBreadcrumbs } from '../../components/ProfileBreadcrumbs/ProfileBreadcrumbs';
|
||||||
|
import { CardControl } from '../../components/CardControl/CardControl';
|
||||||
|
import settingIcon from "../../images/settingIcon.png"
|
||||||
|
import reportsIcon from "../../images/reports.png"
|
||||||
|
import noteIcon from "../../images/note.png"
|
||||||
|
import questionIcon from "../../images/question.png"
|
||||||
|
import medium_male from "../../images/medium_male.png"
|
||||||
|
import { Footer } from '../../components/Footer/Footer';
|
||||||
|
import { HeadBottom } from '../../components/features/Candidate-lk/HeadBottom';
|
||||||
|
|
||||||
|
export const ProfileCandidate = () => {
|
||||||
|
const [candidatsCardsControl] = useState([
|
||||||
|
{
|
||||||
|
path: 'quiz',
|
||||||
|
img: reportsIcon,
|
||||||
|
title: 'Мои тесты',
|
||||||
|
description: '<span>У вас 122 часа<br/></span>отработанных в этом месяце'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'profile/settings',
|
||||||
|
img: settingIcon,
|
||||||
|
title: 'Настройки аккаунта',
|
||||||
|
description: 'Перейдите чтобы начать редактирование'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
return (
|
||||||
|
<div className='profile-candidate'>
|
||||||
|
<ProfileHeader />
|
||||||
|
<div className="profile-candidate__head-bottom bottom-head">
|
||||||
|
<HeadBottom />
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div className="profile-candidate__container">
|
||||||
|
<ProfileBreadcrumbs links={[{ name: 'Главная', link: '/profile-candidate' }]} />
|
||||||
|
<div className="profile-candidate__title main-title">Добрый день, <span>Дмитрий</span></div>
|
||||||
|
<div className="profile-candidate__row">
|
||||||
|
<div className="profile-candidate__tests">
|
||||||
|
|
||||||
|
<div className='info-candidate'>
|
||||||
|
<div className="info-candidate__img">
|
||||||
|
<img src={medium_male} alt="" />
|
||||||
|
</div>
|
||||||
|
<div className="info-candidate__info">
|
||||||
|
<div className="info-candidate__title">Открыто {3} теста из {12}</div>
|
||||||
|
<div className="info-candidate__decor"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="profile-candidate__cards">
|
||||||
|
{
|
||||||
|
candidatsCardsControl.map((item, index) => <CardControl
|
||||||
|
description={item.description}
|
||||||
|
img={item.img}
|
||||||
|
path={item.path}
|
||||||
|
title={item.title}
|
||||||
|
key={index}
|
||||||
|
/>)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div className="profile-candidate__instructions instructions-candidate">
|
||||||
|
<div className="instructions-candidate__container">
|
||||||
|
<div className="instructions-candidate___row">
|
||||||
|
<div className="instructions-candidate__title">Интсрукция:</div>
|
||||||
|
<div className="instructions-candidate__note">
|
||||||
|
<img className='instructions-candidate__icon' src={noteIcon} alt="" />
|
||||||
|
<div className="instructions-candidate__text">
|
||||||
|
Для подтверждения своих знаний - пройдите тестирование во вкладке
|
||||||
|
<span>“Мои тесты”</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="instructions-candidate___row">
|
||||||
|
<div className="instructions-candidate__title">Зачем?</div>
|
||||||
|
<div className="instructions-candidate__note">
|
||||||
|
<img className='instructions-candidate__icon' src={questionIcon} alt="" />
|
||||||
|
<div className="instructions-candidate__text">
|
||||||
|
Тесты itguild предназначены для того, чтобы подтверждать навыки, которые вы указали у себя.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
166
src/pages/ProfileCandidate/ProfileCandidate.scss
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
.profile-candidate{
|
||||||
|
background: #F1F1F1;
|
||||||
|
height: 100%;
|
||||||
|
min-height: 100vh;
|
||||||
|
font-family: "LabGrotesque", sans-serif;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
//max-width: 1200px;
|
||||||
|
&__container{
|
||||||
|
max-width: 1160px;
|
||||||
|
margin: 0 auto 42px auto;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
padding: 0 15px;
|
||||||
|
}
|
||||||
|
&__title{
|
||||||
|
margin: 0 0 31px 0;
|
||||||
|
}
|
||||||
|
&__row{
|
||||||
|
display: flex;
|
||||||
|
gap: 30px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
// &__column{
|
||||||
|
// flex: 1 1 60%;
|
||||||
|
// }
|
||||||
|
&__tests{
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: space-between;
|
||||||
|
flex: 1 1 60%;
|
||||||
|
gap: 30px;
|
||||||
|
}
|
||||||
|
&__cards{
|
||||||
|
display: flex;
|
||||||
|
gap: 29px;
|
||||||
|
width: 100%;
|
||||||
|
@media (max-width: 660px) {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&__head-bottom{
|
||||||
|
margin: 0 0 27px 0;
|
||||||
|
//max-width: 1160px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.instructions-candidate{
|
||||||
|
flex: 1 1 auto;
|
||||||
|
background: #FFFFFF;
|
||||||
|
border-radius: 12px;
|
||||||
|
&__container{
|
||||||
|
padding: 40px 18px 32px 36px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 29px;
|
||||||
|
@media (max-width: 660px) {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&__note{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 22px;
|
||||||
|
&:not(:last-child){
|
||||||
|
margin: 0 0 30px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
&__icon{
|
||||||
|
width: 25px;
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
|
&__title{
|
||||||
|
color: #52B709;
|
||||||
|
font-weight: 900;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 171%;
|
||||||
|
margin: 0 0 20px 0;
|
||||||
|
}
|
||||||
|
&__text{
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 200%;
|
||||||
|
color: #000000;
|
||||||
|
max-width: 235px;
|
||||||
|
span{
|
||||||
|
color: #406128;
|
||||||
|
font-weight: 700;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-candidate{
|
||||||
|
width: 100%;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 20px 45px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 47px;
|
||||||
|
@media (max-width:560px) {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
&__img{
|
||||||
|
flex: 0 0 88px;
|
||||||
|
height: 88px;
|
||||||
|
img{
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&__info{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
&__title{
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 200%;
|
||||||
|
color: #000000;
|
||||||
|
margin: 0 0 12px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__decor{
|
||||||
|
background: #52B709;
|
||||||
|
border-radius: 12px;
|
||||||
|
height: 8px;
|
||||||
|
width: 60%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-head{
|
||||||
|
margin: 0 0 40px 0;
|
||||||
|
height: 66px;
|
||||||
|
background: #FFF;
|
||||||
|
&__container{
|
||||||
|
max-width: 1160px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 15px;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
&__img{
|
||||||
|
flex: 0 0 37px;
|
||||||
|
height: 37px;
|
||||||
|
img{
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&__title{
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 178%;
|
||||||
|
color: #807777;
|
||||||
|
}
|
||||||
|
}
|
@ -12,6 +12,7 @@ import gitImgItem from "../../images/gitItemImg.png"
|
|||||||
|
|
||||||
import {apiRequest} from "../../api/request";
|
import {apiRequest} from "../../api/request";
|
||||||
import {Navigate} from "react-router-dom";
|
import {Navigate} from "react-router-dom";
|
||||||
|
import { Navigation } from '../../components/Navigation/Navigation';
|
||||||
|
|
||||||
import './summary.scss'
|
import './summary.scss'
|
||||||
|
|
||||||
@ -30,6 +31,7 @@ export const Summary = () => {
|
|||||||
return (
|
return (
|
||||||
<div className='summary'>
|
<div className='summary'>
|
||||||
<ProfileHeader/>
|
<ProfileHeader/>
|
||||||
|
<Navigation />
|
||||||
<div className='container'>
|
<div className='container'>
|
||||||
<div className='summary__content'>
|
<div className='summary__content'>
|
||||||
<ProfileBreadcrumbs links={[
|
<ProfileBreadcrumbs links={[
|
||||||
|
@ -24,6 +24,7 @@ import noProjects from "../../images/noProjects.png";
|
|||||||
import arrow from "../../images/arrowCalendar.png";
|
import arrow from "../../images/arrowCalendar.png";
|
||||||
|
|
||||||
import "./tracker.scss";
|
import "./tracker.scss";
|
||||||
|
import { Navigation } from "../../components/Navigation/Navigation";
|
||||||
|
|
||||||
export const Tracker = () => {
|
export const Tracker = () => {
|
||||||
const [toggleTab, setToggleTab] = useState(1);
|
const [toggleTab, setToggleTab] = useState(1);
|
||||||
@ -532,6 +533,7 @@ export const Tracker = () => {
|
|||||||
return (
|
return (
|
||||||
<div className="tracker">
|
<div className="tracker">
|
||||||
<ProfileHeader />
|
<ProfileHeader />
|
||||||
|
<Navigation />
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<div className="tracker__content">
|
<div className="tracker__content">
|
||||||
<ProfileBreadcrumbs
|
<ProfileBreadcrumbs
|
||||||
|
@ -16,6 +16,7 @@ import arrow from "../../images/right-arrow.png";
|
|||||||
import arrowSwitchDate from "../../images/arrowViewReport.png";
|
import arrowSwitchDate from "../../images/arrowViewReport.png";
|
||||||
|
|
||||||
import './viewReport.scss'
|
import './viewReport.scss'
|
||||||
|
import { Navigation } from '../../components/Navigation/Navigation';
|
||||||
|
|
||||||
export const ViewReport = () => {
|
export const ViewReport = () => {
|
||||||
if(localStorage.getItem('role_status') === '18') {
|
if(localStorage.getItem('role_status') === '18') {
|
||||||
@ -79,6 +80,7 @@ export const ViewReport = () => {
|
|||||||
return (
|
return (
|
||||||
<div className='viewReport'>
|
<div className='viewReport'>
|
||||||
<ProfileHeader/>
|
<ProfileHeader/>
|
||||||
|
<Navigation />
|
||||||
<div className='container'>
|
<div className='container'>
|
||||||
<div className='viewReport__info'>
|
<div className='viewReport__info'>
|
||||||
<ProfileBreadcrumbs links={[{name: 'Главная', link: '/profile'},
|
<ProfileBreadcrumbs links={[{name: 'Главная', link: '/profile'},
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
import {useNavigate} from "react-router-dom"
|
|
||||||
import {HeaderPageTestsQuiz} from "../../components/features/quiz/HeaderPageTests"
|
|
||||||
import {Instruction} from "../../components/features/quiz/Instructions"
|
|
||||||
import React from "react";
|
|
||||||
import {useSelector} from "react-redux";
|
|
||||||
import {selectedTest} from "../../redux/quizSlice";
|
|
||||||
|
|
||||||
|
|
||||||
export const InstructionPage = () => {
|
|
||||||
|
|
||||||
const test = useSelector(selectedTest)
|
|
||||||
|
|
||||||
let navigate = useNavigate();
|
|
||||||
if (!test) {
|
|
||||||
navigate('/quiz')
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<HeaderPageTestsQuiz isVisibilityButton={false}/>
|
|
||||||
<Instruction/>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
};
|
|
@ -1,26 +0,0 @@
|
|||||||
import React from "react";
|
|
||||||
import {useNavigate} from "react-router-dom"
|
|
||||||
import {useSelector} from "react-redux";
|
|
||||||
|
|
||||||
import {HeaderPageTestsQuiz} from "../../components/features/quiz/HeaderPageTests"
|
|
||||||
import {MyTestsQuiz} from "../../components/features/quiz/MyTestsQuiz"
|
|
||||||
|
|
||||||
import {selectedTest, selectPassedTests} from "../../redux/quizSlice";
|
|
||||||
|
|
||||||
|
|
||||||
export const InterjacentPage = () => {
|
|
||||||
|
|
||||||
const test = useSelector(selectedTest);
|
|
||||||
const passedTests = useSelector(selectPassedTests)
|
|
||||||
let navigate = useNavigate();
|
|
||||||
if (!test) {
|
|
||||||
navigate('/quiz')
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<HeaderPageTestsQuiz isVisibilityButton={true}/>
|
|
||||||
<MyTestsQuiz listTests={passedTests}/>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
};
|
|
83
src/pages/quiz/PassingTests.js
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
import React, { useState } from 'react'
|
||||||
|
import { ProfileHeader } from '../../components/ProfileHeader/ProfileHeader'
|
||||||
|
import { HeadBottom } from '../../components/features/Candidate-lk/HeadBottom'
|
||||||
|
import { ProfileBreadcrumbs } from '../../components/ProfileBreadcrumbs/ProfileBreadcrumbs'
|
||||||
|
import { Link } from 'react-router-dom'
|
||||||
|
import { Footer } from '../../components/Footer/Footer'
|
||||||
|
import { QuizPassingInformation } from '../../components/features/quiz/Quiz-passing-information'
|
||||||
|
import { CardIntroduction } from '../../components/features/quiz/Card-introduction'
|
||||||
|
import { TaskQuiz } from '../../components/features/quiz/Task'
|
||||||
|
import { BlockCompletedTest } from '../../components/features/quiz/BlockCompletedTest'
|
||||||
|
import { useSelector } from 'react-redux'
|
||||||
|
import { completedTestSelector, selectedTest } from '../../redux/quizSlice'
|
||||||
|
|
||||||
|
export const PassingTests = () => {
|
||||||
|
//const selectedTest = useSelector(selectedTest)
|
||||||
|
|
||||||
|
if(''){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const time = new Date();
|
||||||
|
time.setSeconds(time.getSeconds() + 600);//600 - кол-во секунд для прохождения теста
|
||||||
|
|
||||||
|
const [startTest, setStartTest] = useState(false)
|
||||||
|
const completedTest = useSelector(completedTestSelector)
|
||||||
|
|
||||||
|
const introduction = [
|
||||||
|
{
|
||||||
|
title: 'Зачем?',
|
||||||
|
description: 'Тесты itguild предназначены для того, чтобы подтверждать навыки, которые вы указали у себя.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Почему именно тестирование?',
|
||||||
|
description: 'Тесты itguild заменяют первое техническое собеседование по любой вакансии.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Какие тесты нужно проходить?',
|
||||||
|
description: 'Здесь все довольно просто — следует проходить тесты по инструментам и навыкам, которыми вы владеете.'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='passing-tests-page'>
|
||||||
|
<ProfileHeader />
|
||||||
|
<HeadBottom />
|
||||||
|
<div className="passing-tests-page__container">
|
||||||
|
<ProfileBreadcrumbs links={[
|
||||||
|
{ name: 'Главная', link: '/profile-candidate' },
|
||||||
|
{ name: 'Тестирование', link: '/quiz' },
|
||||||
|
{ name: 'Прохождение тестов', link: '/quiz/test' },
|
||||||
|
]} />
|
||||||
|
<div className="passing-tests-page__title main-title">Тестирование в позиции Junior разработчик </div>
|
||||||
|
<div className="passing-tests-page__passing-information">
|
||||||
|
<QuizPassingInformation expiryTimestamp={time} setStartTest={setStartTest} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{
|
||||||
|
!completedTest &&
|
||||||
|
<>
|
||||||
|
{startTest && <div className="passing-tests-page__block-green">Тестирование началось</div>}
|
||||||
|
{startTest ? <TaskQuiz /> : <div className='passing-tests-page__introduction'>
|
||||||
|
{
|
||||||
|
introduction.map((item, i) => <CardIntroduction description={item.description} title={item.title} key={i} />)
|
||||||
|
}
|
||||||
|
</div>}
|
||||||
|
{
|
||||||
|
!startTest && <div className="passing-tests-page__block-text block-text">
|
||||||
|
ИЛИ <Link to={''} >выполните тестове задание</Link> , без прохождения тестов
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
{
|
||||||
|
completedTest && <>
|
||||||
|
<div className="passing-tests-page__block-green">Тестирование завершено</div>
|
||||||
|
<BlockCompletedTest />
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
@ -1,17 +1,144 @@
|
|||||||
import React from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import {HeaderQuiz} from "../../components/features/quiz/HeaderQuiz"
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import {MyTestsQuiz} from "../../components/features/quiz/MyTestsQuiz"
|
import { questionnairesSelector, setQuestionnaires } from "../../redux/quizSlice";
|
||||||
import {useSelector} from "react-redux";
|
import { ProfileHeader } from '../../components/ProfileHeader/ProfileHeader';
|
||||||
import {selectQuestionnairesOfUser} from "../../redux/quizSlice";
|
import { HeadBottom } from '../../components/features/Candidate-lk/HeadBottom';
|
||||||
|
import { ProfileBreadcrumbs } from '../../components/ProfileBreadcrumbs/ProfileBreadcrumbs';
|
||||||
|
import './quiz-page.scss'
|
||||||
|
import { SelectedCategory } from '../../components/features/quiz/SelectedCategory';
|
||||||
|
import { Footer } from '../../components/Footer/Footer';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
import { CardAvailableTest } from '../../components/features/quiz/CardAviableTest';
|
||||||
|
import { apiRequest } from '../../api/request';
|
||||||
|
import CategoriesItem from '../../components/CategoriesItem/CategoriesItem';
|
||||||
|
|
||||||
|
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"
|
||||||
|
|
||||||
export const QuizPage = () => {
|
export const QuizPage = () => {
|
||||||
|
|
||||||
const allTests = useSelector(selectQuestionnairesOfUser)
|
const questionnaires = useSelector(questionnairesSelector)
|
||||||
|
const dispatch = useDispatch()
|
||||||
|
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
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
const userId = localStorage.getItem('id')
|
||||||
|
const [selectedCategory, setsetSelectedCategory] = useState(false)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
apiRequest(`/user-questionnaire/questionnaires-list?user_id=${userId}`)
|
||||||
|
.then(res => dispatch(setQuestionnaires(res)))
|
||||||
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div className='quiz-page'>
|
||||||
<HeaderQuiz header={true}/>
|
<ProfileHeader />
|
||||||
<MyTestsQuiz listTests={allTests}/>
|
<HeadBottom />
|
||||||
</>
|
<div className="quiz-page__container">
|
||||||
|
<ProfileBreadcrumbs links={[{ name: 'Главная', link: '/profile-candidate' }, { name: 'Тестирование', link: '/quiz' }]} />
|
||||||
|
<div className="quiz-page__title main-title">{!selectedCategory ? 'Тестирование' : 'Замена специализации'}</div>
|
||||||
|
{!selectedCategory && <>
|
||||||
|
<div className="quiz-page__specialization">
|
||||||
|
<SelectedCategory setSelectedCategory={setsetSelectedCategory} />
|
||||||
|
</div>
|
||||||
|
<div className="quiz-page__block">
|
||||||
|
Доступные тесты
|
||||||
|
</div>
|
||||||
|
<div className="quiz-page__cards-test">
|
||||||
|
{
|
||||||
|
questionnaires.length ? questionnaires.map((item, index) => (
|
||||||
|
<CardAvailableTest
|
||||||
|
description={'Вы новичок с реальным опытом работы до 1 года, или без опыта'}
|
||||||
|
path={'quiz/test'}
|
||||||
|
status={item.status}
|
||||||
|
title={item.questionnaire_title}
|
||||||
|
passedTest={item.passedTest}
|
||||||
|
key={index}
|
||||||
|
/>)) : <h1>Анкет нет</h1>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div className="block-text">
|
||||||
|
ИЛИ <Link to={''} >выполните тестове задание</Link> , без прохождения тестов
|
||||||
|
</div>
|
||||||
|
</>}
|
||||||
|
|
||||||
|
{selectedCategory && <div className="quiz-page__categories-items">
|
||||||
|
{personalInfoItems.map((item, index) => {
|
||||||
|
return <CategoriesItem link={item.link} key={index} title={item.title} img={item.img} skills={item.description} available={item.available} />
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</div>}
|
||||||
|
</div>
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
42
src/pages/quiz/QuizReportPage.js
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import { useNavigate } from "react-router-dom"
|
||||||
|
import { HeaderPageTestsQuiz } from "../../components/features/quiz/HeaderPageTests"
|
||||||
|
import { Results } from "../../components/features/quiz/Results";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
import { selectedTest } from "../../redux/quizSlice";
|
||||||
|
import React from "react";
|
||||||
|
import { ProfileHeader } from "../../components/ProfileHeader/ProfileHeader";
|
||||||
|
import { HeadBottom } from "../../components/features/Candidate-lk/HeadBottom";
|
||||||
|
import { ProfileBreadcrumbs } from "../../components/ProfileBreadcrumbs/ProfileBreadcrumbs";
|
||||||
|
import { QuizReport } from "../../components/features/quiz/QuizReport";
|
||||||
|
import { Footer } from "../../components/Footer/Footer";
|
||||||
|
import suucessIcon from '../../images/quiz/success.png'
|
||||||
|
import { AlertResult } from "../../components/features/quiz/AlertResult";
|
||||||
|
|
||||||
|
|
||||||
|
export const QuizReportPage = () => {
|
||||||
|
|
||||||
|
const test = useSelector(selectedTest)
|
||||||
|
|
||||||
|
let navigate = useNavigate();
|
||||||
|
if (!test) {
|
||||||
|
navigate('/quiz')
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="quiz-report-page">
|
||||||
|
<ProfileHeader />
|
||||||
|
<HeadBottom />
|
||||||
|
<div className="quiz-report-page__container">
|
||||||
|
<ProfileBreadcrumbs links={[{ name: 'Главная', link: '/profile-candidate' }, { name: 'Тестирование', link: '/quiz' },
|
||||||
|
{ name: 'Отчет по тестированию', link: '/quiz/report' }]} />
|
||||||
|
<div className="quiz-report-page__title main-title">Отчет по тестированию позиции Junior разработчик </div>
|
||||||
|
<div className="quiz-report-page__report-quiz">
|
||||||
|
<QuizReport />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<AlertResult />
|
||||||
|
</div>
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
};
|
@ -1,24 +0,0 @@
|
|||||||
import {useNavigate} from 'react-router-dom'
|
|
||||||
import {HeaderPageTestsQuiz} from '../../components/features/quiz/HeaderPageTests'
|
|
||||||
import {TaskQuiz} from '../../components/features/quiz/Task'
|
|
||||||
import {useSelector} from "react-redux";
|
|
||||||
import {selectedTest} from "../../redux/quizSlice";
|
|
||||||
import React, {useEffect} from "react";
|
|
||||||
|
|
||||||
export const QuizTestPage = () => {
|
|
||||||
let navigate = useNavigate();
|
|
||||||
const test = useSelector(selectedTest);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!test) {
|
|
||||||
navigate('/quiz')
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<HeaderPageTestsQuiz isVisibilityButton={false}/>
|
|
||||||
<TaskQuiz/>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
};
|
|
@ -1,24 +0,0 @@
|
|||||||
import {useNavigate} from "react-router-dom"
|
|
||||||
import {HeaderPageTestsQuiz} from "../../components/features/quiz/HeaderPageTests"
|
|
||||||
import {Results} from "../../components/features/quiz/Results";
|
|
||||||
import {useSelector} from "react-redux";
|
|
||||||
import {selectedTest} from "../../redux/quizSlice";
|
|
||||||
import React from "react";
|
|
||||||
|
|
||||||
|
|
||||||
export const ResultPage = () => {
|
|
||||||
|
|
||||||
const test = useSelector(selectedTest)
|
|
||||||
|
|
||||||
let navigate = useNavigate();
|
|
||||||
if (!test) {
|
|
||||||
navigate('/quiz')
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<HeaderPageTestsQuiz isVisibilityButton={false}/>
|
|
||||||
<Results/>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
};
|
|
143
src/pages/quiz/quiz-page.scss
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
.quiz-page{
|
||||||
|
background: #F1F1F1;
|
||||||
|
height: 100%;
|
||||||
|
min-height: 100vh;
|
||||||
|
font-family: "LabGrotesque", sans-serif;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
&__container{
|
||||||
|
max-width: 1160px;
|
||||||
|
margin: 0 auto 42px auto;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0 15px;
|
||||||
|
}
|
||||||
|
&__title{
|
||||||
|
margin: 0 0 39px 0;
|
||||||
|
}
|
||||||
|
&__block{
|
||||||
|
background: #E1FCCF;
|
||||||
|
border-radius: 12px 12px 0px 0px;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 178%;
|
||||||
|
color: #000000;
|
||||||
|
padding: 20px 51px;
|
||||||
|
margin: 0 0 16px 0;
|
||||||
|
}
|
||||||
|
&__cards-test{
|
||||||
|
display: grid;
|
||||||
|
grid-gap: 29px;
|
||||||
|
grid-template-columns: 1fr 1fr 1fr;
|
||||||
|
margin-bottom: 29px;
|
||||||
|
@media (max-width: 955px) {
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
}
|
||||||
|
@media (max-width: 668px) {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
&__specialization{
|
||||||
|
margin: 0 0 26px 0;
|
||||||
|
}
|
||||||
|
&__categories-items{
|
||||||
|
display: grid;
|
||||||
|
grid-gap: 24px;
|
||||||
|
grid-template-columns: 1fr 1fr 1fr;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
@media (max-width: 955px) {
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
}
|
||||||
|
@media (max-width: 668px) {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.interjacent-page-quiz{
|
||||||
|
|
||||||
|
background: #F1F1F1;
|
||||||
|
height: 100%;
|
||||||
|
min-height: 100vh;
|
||||||
|
font-family: "LabGrotesque", sans-serif;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
&__title{
|
||||||
|
margin: 0 0 39px 0;
|
||||||
|
}
|
||||||
|
&__passing-information{
|
||||||
|
margin: 0 0 32px 0;
|
||||||
|
}
|
||||||
|
&__container{
|
||||||
|
max-width: 1160px;
|
||||||
|
margin: 0 auto 42px auto;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0 15px;
|
||||||
|
}
|
||||||
|
&__introduction-items{
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin: 0px -25px -50px;
|
||||||
|
margin: 0 auto 54px auto;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.passing-tests-page{
|
||||||
|
background: #F1F1F1;
|
||||||
|
height: 100%;
|
||||||
|
min-height: 100vh;
|
||||||
|
font-family: "LabGrotesque", sans-serif;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
&__container{
|
||||||
|
max-width: 1160px;
|
||||||
|
margin: 0 auto 42px auto;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0 15px;
|
||||||
|
}
|
||||||
|
&__title{
|
||||||
|
margin: 0 0 39px 0;
|
||||||
|
}
|
||||||
|
&__passing-information{
|
||||||
|
margin: 0 0 29px 0;
|
||||||
|
}
|
||||||
|
&__block-green{
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 178%;
|
||||||
|
color: #000000;
|
||||||
|
background: #E1FCCF;
|
||||||
|
border-radius: 12px 12px 0px 0px;
|
||||||
|
padding: 20px 51px;
|
||||||
|
}
|
||||||
|
&__introduction{
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.quiz-report-page{
|
||||||
|
background: #F1F1F1;
|
||||||
|
height: 100%;
|
||||||
|
min-height: 100vh;
|
||||||
|
font-family: "LabGrotesque", sans-serif;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
&__container{
|
||||||
|
max-width: 1160px;
|
||||||
|
margin: 0 auto 42px auto;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0 15px;
|
||||||
|
}
|
||||||
|
&__title{
|
||||||
|
margin: 0 0 39px 0;
|
||||||
|
}
|
||||||
|
&__report-quiz{
|
||||||
|
margin: 0 0 28px 0;
|
||||||
|
}
|
||||||
|
}
|
@ -4,14 +4,76 @@ import {apiRequest} from "../api/request";
|
|||||||
|
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
// questions: [],
|
answers: [
|
||||||
answer: [],
|
{
|
||||||
|
"id": "12",
|
||||||
|
"question_id": "7",
|
||||||
|
"answer_body": "Нsdf sfd fds sdf sf sfsdf sdfеск вsdffsdfsdf sf sdf sdfsdfsdfsdfdsjknsdkf dssdjf sdfbsdhf sd hjdsfv sdhjvар1 отв1 истина"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "23",
|
||||||
|
"question_id": "7",
|
||||||
|
"answer_body": "Неск вар1 отв1 истина"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "233",
|
||||||
|
"question_id": "7",
|
||||||
|
"answer_body": "lorem sdfdsf dfs sdf "
|
||||||
|
},
|
||||||
|
],
|
||||||
|
questionnaires: [],
|
||||||
|
questions: [
|
||||||
|
{
|
||||||
|
"id": "4",
|
||||||
|
"question_type_id": "3",
|
||||||
|
"question_body": "Для чего в Python используется встроенная функция enumerate()?",
|
||||||
|
"question_priority": null,
|
||||||
|
"next_question": null,
|
||||||
|
"time_limit": "00:22:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "24",
|
||||||
|
"question_type_id": "3",
|
||||||
|
"question_body": "Для чего в Python dfsf троенная функция enumerate()?",
|
||||||
|
"question_priority": null,
|
||||||
|
"next_question": null,
|
||||||
|
"time_limit": "00:22:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "41",
|
||||||
|
"question_type_id": "3",
|
||||||
|
"question_body": "Для чегоsdfsdfя функция enumerate()?",
|
||||||
|
"question_priority": null,
|
||||||
|
"next_question": null,
|
||||||
|
"time_limit": "00:22:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "5",
|
||||||
|
"question_type_id": '2',
|
||||||
|
"question_body": "Один ответ2",
|
||||||
|
"question_priority": null,
|
||||||
|
"next_question": null,
|
||||||
|
"time_limit": "00:22:00"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
selectedTest: {
|
||||||
|
"user_id": 1,
|
||||||
|
"uuid": "d222f858-60fd-47fb-8731-dc9d5fc384c5",
|
||||||
|
"score": 11,
|
||||||
|
"status": 2,
|
||||||
|
"percent_correct_answers": 0.25,
|
||||||
|
"testing_date": "2022-03-17 11:14:22",
|
||||||
|
"questionnaire_title": "Кат1 Анкета 1 активна"
|
||||||
|
},
|
||||||
|
selectedAnswers:{},
|
||||||
|
completedTest: false,
|
||||||
result: null,
|
result: null,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
dataQuestionnairesOfUser: [],
|
dataQuestionnairesOfUser: [],
|
||||||
passedTests: [],
|
passedTests: [],
|
||||||
selectedTest: null,
|
|
||||||
userInfo: null
|
userInfo: null,
|
||||||
|
|
||||||
};
|
};
|
||||||
export const setUserInfo = createAsyncThunk(
|
export const setUserInfo = createAsyncThunk(
|
||||||
'userInfo',
|
'userInfo',
|
||||||
@ -47,13 +109,15 @@ export const quizSlice = createSlice({
|
|||||||
name: 'quiz',
|
name: 'quiz',
|
||||||
initialState,
|
initialState,
|
||||||
reducers: {
|
reducers: {
|
||||||
setQuestionnairesList: (state, action) => {
|
setQuestionnaires: (state, action) => {
|
||||||
state.dataQuestionnairesOfUser = action.payload;
|
state.questionnaires = action.payload;
|
||||||
state.passedTests = action.payload.filter(item => item.status === 2)
|
|
||||||
},
|
},
|
||||||
setSelectedTest: (state, action) => {
|
setSelectedTest: (state, action) => {
|
||||||
state.selectedTest = action.payload
|
state.selectedTest = action.payload
|
||||||
},
|
},
|
||||||
|
setCompleteTest: (state, action) => {
|
||||||
|
state.completedTest = true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
extraReducers: {
|
extraReducers: {
|
||||||
[setUserInfo.fulfilled]: (state, action) => {
|
[setUserInfo.fulfilled]: (state, action) => {
|
||||||
@ -68,16 +132,21 @@ export const quizSlice = createSlice({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const {setQuestionnairesList, setSelectedTest} = quizSlice.actions;
|
export const {setQuestionnaires, setSelectedTest, setCompleteTest} = quizSlice.actions;
|
||||||
|
|
||||||
|
|
||||||
export const selectAnswer = (state) => state.quiz.answer;
|
export const answersSelector = (state) => state.quiz.answers;
|
||||||
export const selectQuestionnairesOfUser = (state) => state.quiz.dataQuestionnairesOfUser;
|
export const questionnairesSelector = (state) => state.quiz.questionnaires;
|
||||||
|
export const selectedAnswersSelector = (state) => state.quiz.selectedAnswers
|
||||||
|
export const questionsSelector = (state) => state.quiz.questions
|
||||||
|
export const completedTestSelector = (state) => state.quiz.completedTest
|
||||||
|
|
||||||
export const selectResult = (state) => state.quiz.result;
|
export const selectResult = (state) => state.quiz.result;
|
||||||
export const selectedTest = (state) => state.quiz.selectedTest;
|
export const selectedTest = (state) => state.quiz.selectedTest;
|
||||||
export const selectPassedTests = (state) => state.quiz.passedTests;
|
export const selectPassedTests = (state) => state.quiz.passedTests;
|
||||||
export const selectUserInfo = (state) => state.quiz.userInfo;
|
export const selectUserInfo = (state) => state.quiz.userInfo;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default quizSlice.reducer;
|
export default quizSlice.reducer;
|
||||||
|
|
||||||
|