reports create, refactoring
This commit is contained in:
@ -1,78 +1,96 @@
|
||||
import React, { useState } from 'react';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
import style from './Outstaffing.module.css';
|
||||
import OutstaffingBlock from './OutstaffingBlock';
|
||||
import TagSelect from '../Select/TagSelect';
|
||||
import { selectTags, getPositionId, setPositionId } from '../../redux/outstaffingSlice';
|
||||
import front from '../../images/front_end.png';
|
||||
import back from '../../images/back_end.png';
|
||||
import design from '../../images/design.png';
|
||||
import React, { useState } from 'react'
|
||||
import { useSelector, useDispatch } from 'react-redux'
|
||||
import OutstaffingBlock from '../OutstaffingBlock/OutstaffingBlock'
|
||||
import TagSelect from '../Select/TagSelect'
|
||||
import {
|
||||
selectTags,
|
||||
getPositionId,
|
||||
setPositionId
|
||||
} from '../../redux/outstaffingSlice'
|
||||
import front from '../../images/front_end.png'
|
||||
import back from '../../images/back_end.png'
|
||||
import design from '../../images/design.png'
|
||||
|
||||
import './outstaffing.scss'
|
||||
|
||||
|
||||
const createSelectPositionHandler = ({ positionId, setPositionId, dispatch }) => id => {
|
||||
if(id===positionId) {
|
||||
dispatch(setPositionId(null));
|
||||
} else {
|
||||
dispatch(setPositionId(id));
|
||||
const createSelectPositionHandler =
|
||||
({ positionId, setPositionId, dispatch }) =>
|
||||
(id) => {
|
||||
if (id === positionId) {
|
||||
dispatch(setPositionId(null))
|
||||
} else {
|
||||
dispatch(setPositionId(id))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const Outstaffing = () => {
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useDispatch()
|
||||
const positionId = useSelector(getPositionId)
|
||||
const tagsArr = useSelector(selectTags);
|
||||
const tagsArr = useSelector(selectTags)
|
||||
|
||||
const onSelectPosition = createSelectPositionHandler({ positionId, setPositionId, dispatch });
|
||||
const onSelectPosition = createSelectPositionHandler({
|
||||
positionId,
|
||||
setPositionId,
|
||||
dispatch
|
||||
})
|
||||
return (
|
||||
<>
|
||||
<section className={style.outstaffing}>
|
||||
<div className="row">
|
||||
<div className="col-12">
|
||||
<div className={style.outstaffing__title}>
|
||||
<h2>
|
||||
<span>Аутстаффинг</span> it-персонала
|
||||
</h2>
|
||||
</div>
|
||||
<section className='outstaffing'>
|
||||
<div className='row'>
|
||||
<div className='col-12'>
|
||||
<div className='outstaffing__title'>
|
||||
<h2>
|
||||
<span>Аутстаффинг</span> it-персонала
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="row">
|
||||
<div className="col-12 col-xl-4">
|
||||
<OutstaffingBlock
|
||||
dataTags={tagsArr && tagsArr.flat().filter((tag) => tag.name === 'skills_front')}
|
||||
img={front}
|
||||
header="Frontend"
|
||||
positionId='2'
|
||||
isSelected={positionId==='2'}
|
||||
onSelect={id=>onSelectPosition(id)}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-12 col-xl-4">
|
||||
<OutstaffingBlock
|
||||
dataTags={tagsArr.flat().filter((tag) => tag.name === 'skills_back')}
|
||||
img={back}
|
||||
header="Backend"
|
||||
positionId='1'
|
||||
isSelected={positionId==='1'}
|
||||
onSelect={id=>onSelectPosition(id)}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-12 col-xl-4">
|
||||
<OutstaffingBlock
|
||||
dataTags={tagsArr.flat().filter((tag) => tag.name === 'skills_design')}
|
||||
img={design}
|
||||
header="Дизайн"
|
||||
positionId='5'
|
||||
isSelected={positionId==='5'}
|
||||
onSelect={id=>onSelectPosition(id)}
|
||||
/>
|
||||
</div>
|
||||
<div className='row'>
|
||||
<div className='col-12 col-xl-4'>
|
||||
<OutstaffingBlock
|
||||
dataTags={
|
||||
tagsArr &&
|
||||
tagsArr.flat().filter((tag) => tag.name === 'skills_front')
|
||||
}
|
||||
img={front}
|
||||
header='Frontend'
|
||||
positionId='2'
|
||||
isSelected={positionId === '2'}
|
||||
onSelect={(id) => onSelectPosition(id)}
|
||||
/>
|
||||
</div>
|
||||
<div className='col-12 col-xl-4'>
|
||||
<OutstaffingBlock
|
||||
dataTags={
|
||||
tagsArr &&
|
||||
tagsArr.flat().filter((tag) => tag.name === 'skills_back')
|
||||
}
|
||||
img={back}
|
||||
header='Backend'
|
||||
positionId='1'
|
||||
isSelected={positionId === '1'}
|
||||
onSelect={(id) => onSelectPosition(id)}
|
||||
/>
|
||||
</div>
|
||||
<div className='col-12 col-xl-4'>
|
||||
<OutstaffingBlock
|
||||
dataTags={
|
||||
tagsArr &&
|
||||
tagsArr.flat().filter((tag) => tag.name === 'skills_design')
|
||||
}
|
||||
img={design}
|
||||
header='Дизайн'
|
||||
positionId='5'
|
||||
isSelected={positionId === '5'}
|
||||
onSelect={(id) => onSelectPosition(id)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<TagSelect />
|
||||
</>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
export default Outstaffing;
|
||||
export default Outstaffing
|
||||
|
@ -1,174 +0,0 @@
|
||||
.outstaffing__box__selected .outstaffing__box__img {
|
||||
background-color: #52b70999;
|
||||
color: #f9f9f9;
|
||||
}
|
||||
|
||||
.outstaffing__title {
|
||||
margin-top: 60px;
|
||||
}
|
||||
.outstaffing__title > h2 {
|
||||
text-align: center;
|
||||
color: #52b709;
|
||||
font-family: 'GT Eesti Pro Display';
|
||||
font-size: 5em;
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
letter-spacing: normal;
|
||||
line-height: 77.81px;
|
||||
}
|
||||
|
||||
@media (max-width: 375.98px) {
|
||||
.outstaffing__title > h2 {
|
||||
font-size: 4.5em;
|
||||
line-height: normal;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 376px) {
|
||||
.outstaffing__title > h2 {
|
||||
font-size: 5em;
|
||||
line-height: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.outstaffing__title > h2 > span {
|
||||
color: #282828;
|
||||
font-style: normal;
|
||||
letter-spacing: 0.56px;
|
||||
line-height: normal;
|
||||
}
|
||||
.outstaffing__box {
|
||||
margin-top: 60px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@media (max-width: 575.98px) {
|
||||
.outstaffing__box {
|
||||
margin-top: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.outstaffing__box__img {
|
||||
min-width: 260px;
|
||||
min-height: 120px;
|
||||
background-color: #f9f9f9;
|
||||
border-radius: 20px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.outstaffing__box__img > h3 {
|
||||
position: absolute;
|
||||
right: 25%;
|
||||
top: 40%;
|
||||
font-family: 'GT Eesti Pro Display';
|
||||
font-size: 18px;
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
letter-spacing: normal;
|
||||
line-height: normal;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.outstaffing__box__img > img {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.outstaffing__box > div {
|
||||
margin-top: 60px;
|
||||
}
|
||||
|
||||
.outstaffing__box > p {
|
||||
font-family: 'GT Eesti Pro Display';
|
||||
font-size: 1.2em;
|
||||
font-weight: 300;
|
||||
font-style: normal;
|
||||
letter-spacing: normal;
|
||||
line-height: 36px;
|
||||
text-align: left;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
@media (max-width: 575.98px) {
|
||||
.outstaffing__box__text {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.front {
|
||||
left: -5%;
|
||||
}
|
||||
|
||||
.back {
|
||||
top: 11%;
|
||||
left: -9%;
|
||||
}
|
||||
|
||||
.des {
|
||||
top: 24%;
|
||||
left: -9%;
|
||||
}
|
||||
|
||||
@media (max-width: 575.98px) {
|
||||
.mobile__none {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.mobile__block {
|
||||
display: block;
|
||||
animation: fadeInFromNone 0.5s ease-out;
|
||||
}
|
||||
|
||||
@media (max-width: 575.98px) {
|
||||
@keyframes fadeInFromNone {
|
||||
0% {
|
||||
display: none;
|
||||
opacity: 0;
|
||||
transform: translateY(-100px);
|
||||
}
|
||||
|
||||
10% {
|
||||
display: block;
|
||||
opacity: 0;
|
||||
transform: translateY(-50px);
|
||||
}
|
||||
|
||||
100% {
|
||||
display: block;
|
||||
opacity: 1;
|
||||
transform: translateY(0px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.outstaffing__box > div > ul {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.border {
|
||||
border: 2px solid #cdeaba;
|
||||
}
|
||||
|
||||
.items > li {
|
||||
font-family: 'GT Eesti Pro Display';
|
||||
font-size: 1.8em;
|
||||
font-weight: 100;
|
||||
font-style: normal;
|
||||
letter-spacing: normal;
|
||||
line-height: 36px;
|
||||
text-align: left;
|
||||
list-style: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@media (max-width: 1199px) {
|
||||
.outstaffing__box {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.outstaffing__box>div {
|
||||
margin-top: 32px;
|
||||
}
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
import React from 'react';
|
||||
import OutsideClickHandler from 'react-outside-click-handler';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { selectItems, selectedItems, filteredCandidates, auth } from '../../redux/outstaffingSlice';
|
||||
import { fetchItemsForId } from '../../server/server';
|
||||
import style from './Outstaffing.module.css';
|
||||
|
||||
import { fetchProfile } from '../../server/server';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { getRole } from '../../redux/roleSlice';
|
||||
|
||||
const handlePositionClick = ({dispatch, positionId, isSelected, onSelect, history, role}) => {
|
||||
if(isSelected) {
|
||||
fetchProfile({ link: `${process.env.REACT_APP_API_URL}/api/profile?limit=`, index: 4, history, role, logout: dispatch(auth(false)) }).then((profileArr) => {
|
||||
dispatch(filteredCandidates(profileArr));
|
||||
dispatch(selectedItems([]));
|
||||
onSelect(positionId);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
fetchItemsForId({ link: `${process.env.REACT_APP_API_URL}/api/profile?position_id=`, index: positionId, history, role, logout: dispatch(auth(false)) }).then((el) => {
|
||||
dispatch(filteredCandidates(el));
|
||||
dispatch(selectedItems([]));
|
||||
onSelect(positionId);
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const OutstaffingBlock = ({ dataTags = [], selected, img, header, positionId, isSelected, onSelect }) => {
|
||||
const history = useHistory();
|
||||
const role = useSelector(getRole);
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const itemsArr = useSelector(selectItems);
|
||||
|
||||
const handleBlockClick = (item, id) => {
|
||||
if (!itemsArr.find((el) => item === el.value)) {
|
||||
dispatch(selectedItems([...itemsArr, { id, value: item, label: item }]));
|
||||
}
|
||||
};
|
||||
|
||||
let classes;
|
||||
|
||||
dataTags.forEach((el) => {
|
||||
if (el.name === 'skills_back') {
|
||||
classes = style.back;
|
||||
} else if (el.name === 'skills_design') {
|
||||
classes = style.des;
|
||||
} else if (el.name === 'skills_front') {
|
||||
classes = style.front;
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<OutsideClickHandler
|
||||
onOutsideClick={() => {
|
||||
isSelected && onSelect(null)
|
||||
}}
|
||||
>
|
||||
<div className={`${style.outstaffing__box} ${isSelected?style.outstaffing__box__selected:''}`} >
|
||||
<div className={`${style.outstaffing__box__img} ${selected ? style.border : ''}`} onClick={()=>handlePositionClick({dispatch, positionId, isSelected, onSelect, history, role})}>
|
||||
<h3>{header}</h3>
|
||||
<img className={classes} src={img} alt="img" />
|
||||
</div>
|
||||
<div className={`${selected ? style.mobile__block : style.mobile__none}`}>
|
||||
<p className={style.outstaffing__box__text}># Популярный стек</p>
|
||||
{dataTags && (
|
||||
<ul className={style.items}>
|
||||
{dataTags.map((item) => (
|
||||
<li key={item.id} onClick={() => handleBlockClick(item.value, item.id)}>
|
||||
{item.value}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</OutsideClickHandler>
|
||||
);
|
||||
};
|
||||
|
||||
export default OutstaffingBlock;
|
73
src/components/Outstaffing/outstaffing.scss
Normal file
73
src/components/Outstaffing/outstaffing.scss
Normal file
@ -0,0 +1,73 @@
|
||||
.outstaffing {
|
||||
&__title {
|
||||
margin-top: 60px;
|
||||
|
||||
h2 {
|
||||
text-align: center;
|
||||
color: #52b709;
|
||||
font-family: 'GT Eesti Pro Display';
|
||||
font-size: 5em;
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
letter-spacing: normal;
|
||||
line-height: 77.81px;
|
||||
|
||||
span {
|
||||
color: #282828;
|
||||
font-style: normal;
|
||||
letter-spacing: 0.56px;
|
||||
line-height: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 375.98px) {
|
||||
.outstaffing__title > h2 {
|
||||
font-size: 4.5em;
|
||||
line-height: normal;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 376px) {
|
||||
.outstaffing__title > h2 {
|
||||
font-size: 5em;
|
||||
line-height: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.front {
|
||||
left: -5%;
|
||||
}
|
||||
|
||||
.back {
|
||||
top: 11%;
|
||||
left: -9%;
|
||||
}
|
||||
|
||||
.des {
|
||||
top: 24%;
|
||||
left: -9%;
|
||||
}
|
||||
|
||||
@media (max-width: 575.98px) {
|
||||
@keyframes fadeInFromNone {
|
||||
0% {
|
||||
display: none;
|
||||
opacity: 0;
|
||||
transform: translateY(-100px);
|
||||
}
|
||||
|
||||
10% {
|
||||
display: block;
|
||||
opacity: 0;
|
||||
transform: translateY(-50px);
|
||||
}
|
||||
|
||||
100% {
|
||||
display: block;
|
||||
opacity: 1;
|
||||
transform: translateY(0px);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user