Переписываю спорные решения
Фикс отправки отчета, проверка на массив в map в Description.js
This commit is contained in:
@ -1,22 +1,27 @@
|
||||
import React, {useEffect, useState} from 'react'
|
||||
import {useSelector} from 'react-redux'
|
||||
import {selectCurrentCandidate} from '../../redux/outstaffingSlice'
|
||||
import {Link} from 'react-router-dom'
|
||||
import {Link, useNavigate} from 'react-router-dom'
|
||||
|
||||
import CalendarComponent from './CalendarComponent'
|
||||
import {currentMonth} from './calendarHelper'
|
||||
import {Footer} from '../Footer/Footer'
|
||||
import {LogoutButton} from "../LogoutButton/LogoutButton";
|
||||
|
||||
import {selectCurrentCandidate} from '../../redux/outstaffingSlice'
|
||||
|
||||
import rectangle from '../../images/rectangle_secondPage.png'
|
||||
|
||||
import './calendar.scss'
|
||||
|
||||
const Calendar = ({onSelect}) => {
|
||||
|
||||
const Calendar = () => {
|
||||
|
||||
const candidateForCalendar = useSelector(selectCurrentCandidate);
|
||||
|
||||
const [month, setMonth] = useState('');
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
setMonth(currentMonth)
|
||||
}, [month]);
|
||||
@ -26,38 +31,43 @@ const Calendar = ({onSelect}) => {
|
||||
const abbreviatedName = name && name.substring(0, name.lastIndexOf(' '));
|
||||
|
||||
return (
|
||||
<section className='calendar'>
|
||||
<div className='row'>
|
||||
<h2 className='calendar__profile'>
|
||||
Добрый день, <span>Александр !</span>
|
||||
</h2>
|
||||
<div className='col-12 col-xl-12 d-flex justify-content-between align-items-center flex-column flex-sm-row'>
|
||||
<div className='calendar__info'>
|
||||
<img className='calendar__info-img' src={photo} alt='img'/>
|
||||
<h3 className='calendar__info-name'>{abbreviatedName}</h3>
|
||||
<div className='container'>
|
||||
<section className='calendar'>
|
||||
<div className='row'>
|
||||
<div className='calendar__header'>
|
||||
<h2 className='calendar__profile'>
|
||||
Добрый день, <span>Александр !</span>
|
||||
</h2>
|
||||
<LogoutButton />
|
||||
</div>
|
||||
<div className='calendar__title'>
|
||||
<h3 className='calendar__title-text'>{skillsName} разработчик</h3>
|
||||
<img className='calendar__title-img' src={rectangle} alt='img'/>
|
||||
</div>
|
||||
<div>
|
||||
<Link to='/report'>
|
||||
<button className='calendar__btn'>Заполнить отчет за день</button>
|
||||
</Link>
|
||||
<div className='col-12 col-xl-12 d-flex justify-content-between align-items-center flex-column flex-sm-row'>
|
||||
<div className='calendar__info'>
|
||||
<img className='calendar__info-img' src={photo} alt='img'/>
|
||||
<h3 className='calendar__info-name'>{abbreviatedName}</h3>
|
||||
</div>
|
||||
<div className='calendar__title'>
|
||||
<h3 className='calendar__title-text'>{skillsName} разработчик</h3>
|
||||
<img className='calendar__title-img' src={rectangle} alt='img'/>
|
||||
</div>
|
||||
<div>
|
||||
<Link to='/report'>
|
||||
<button className='calendar__btn'>Заполнить отчет за день</button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='row'>
|
||||
<div className='col-12 col-xl-12'>
|
||||
<CalendarComponent onSelect={onSelect}/>
|
||||
<p className='calendar__hours'>
|
||||
{month} : <span> 60 часов </span>
|
||||
</p>
|
||||
<div className='row'>
|
||||
<div className='col-12 col-xl-12'>
|
||||
<CalendarComponent onSelect={() => { navigate('/report/0') }}/>
|
||||
<p className='calendar__hours'>
|
||||
{month} : <span> 60 часов </span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Footer/>
|
||||
</section>
|
||||
<Footer/>
|
||||
</section>
|
||||
</div>
|
||||
)
|
||||
};
|
||||
|
||||
|
@ -2,6 +2,17 @@
|
||||
margin-bottom: 40px;
|
||||
font-family: 'LabGrotesque', sans-serif;
|
||||
|
||||
&__header {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
padding: 0 20px;
|
||||
h2 {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&__profile {
|
||||
color: #282828;
|
||||
font-size: 3.4em;
|
||||
@ -45,8 +56,6 @@
|
||||
position: absolute;
|
||||
width: 132px;
|
||||
height: 132px;
|
||||
left: -40px;
|
||||
top: -10px;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ const Description = ({ onLoadMore, isLoadingMore }) => {
|
||||
<section className='description'>
|
||||
<div className='container'>
|
||||
<div className='description__wrapper'>
|
||||
{candidatesListArr && candidatesListArr.length > 0 ? (
|
||||
{candidatesListArr && Array.isArray(candidatesListArr) && candidatesListArr.length > 0 ? (
|
||||
candidatesListArr.map((el) => (
|
||||
<div className='row' key={el.id}>
|
||||
<div className='col-2 col-xs-12'>
|
||||
@ -56,7 +56,7 @@ const Description = ({ onLoadMore, isLoadingMore }) => {
|
||||
<div className='col-xl-2'></div>
|
||||
<div className='col-12 col-xl-6'>
|
||||
<ul className='description__list'>
|
||||
{el.skillValues.map((e) => (
|
||||
{Array.isArray(el?.skillValues) && el.skillValues.map((e) => (
|
||||
<li key={e.id} className='description__list-item'>
|
||||
{e.skill.name}
|
||||
</li>
|
||||
@ -104,7 +104,7 @@ const Description = ({ onLoadMore, isLoadingMore }) => {
|
||||
<section className='description'>
|
||||
<div className='container'>
|
||||
<div className='description__wrapper'>
|
||||
{filteredListArr && filteredListArr.length > 0
|
||||
{filteredListArr && Array.isArray(filteredListArr) && filteredListArr.length > 0
|
||||
? filteredListArr.map((el) => (
|
||||
<div className='row' key={el.id}>
|
||||
<div className='col-2'>
|
||||
@ -139,7 +139,7 @@ const Description = ({ onLoadMore, isLoadingMore }) => {
|
||||
<div className='col-xl-2'></div>
|
||||
<div className='col-12 col-xl-6'>
|
||||
<ul className='description__list'>
|
||||
{el.skillValues.map((e) => (
|
||||
{Array.isArray(el?.skillValues) && el.skillValues?.map((e) => (
|
||||
<li key={e.id} className='description__list-item'>
|
||||
{e.skill.name}
|
||||
</li>
|
||||
@ -155,7 +155,7 @@ const Description = ({ onLoadMore, isLoadingMore }) => {
|
||||
</div>
|
||||
))
|
||||
: /* : <div className={style.description__empty}>В данный момент в категории нет свободных специалистов</div> } */
|
||||
candidatesListArr &&
|
||||
candidatesListArr && Array.isArray(candidatesListArr) &&
|
||||
candidatesListArr.map((el) => (
|
||||
<div className='row' key={el.id}>
|
||||
<div className='col-2'>
|
||||
@ -186,7 +186,7 @@ const Description = ({ onLoadMore, isLoadingMore }) => {
|
||||
<div className='col-xl-2'></div>
|
||||
<div className='col-12 col-xl-6'>
|
||||
<ul className='description__list'>
|
||||
{el.skillValues.map((e) => (
|
||||
{Array.isArray(el?.skillValues) && el.skillValues?.map((e) => (
|
||||
<li key={e.id} className='description__list-item'>
|
||||
{e.skill.name}
|
||||
</li>
|
||||
@ -207,8 +207,7 @@ const Description = ({ onLoadMore, isLoadingMore }) => {
|
||||
<div className='col-12'>
|
||||
<div className='description__footer'>
|
||||
<div className='description__footer-btn'>
|
||||
{
|
||||
candidatesListArr &&
|
||||
{candidatesListArr &&
|
||||
filteredListArr.length === 0 ? (
|
||||
<button onClick={() => onLoadMore(2)}>Загрузить еще</button>
|
||||
) : null}
|
||||
|
@ -8,6 +8,7 @@ import {Footer} from '../Footer/Footer'
|
||||
import {profiles, tags} from '../../redux/outstaffingSlice'
|
||||
|
||||
import {useRequest} from "../../hooks/useRequest";
|
||||
import {LogoutButton} from "../LogoutButton/LogoutButton";
|
||||
|
||||
|
||||
const Home = () => {
|
||||
@ -53,11 +54,12 @@ const Home = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='container'>
|
||||
|
||||
<Outstaffing/>
|
||||
<Description onLoadMore={loadMore} isLoadingMore={isLoadingMore}/>
|
||||
<Footer/>
|
||||
</>
|
||||
</div>
|
||||
)
|
||||
};
|
||||
|
||||
|
@ -14,18 +14,17 @@ export const LogoutButton = () => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
<div className='logout-button'>
|
||||
<button
|
||||
onClick={() => {
|
||||
setIsLoggingOut(true);
|
||||
localStorage.clear();
|
||||
dispatch(auth(false));
|
||||
setIsLoggingOut(false);
|
||||
navigate(userRole === 'ROLE_DEV' ? '/authdev' : '/auth')
|
||||
}}
|
||||
>
|
||||
{isLoggingOut ? <Loader/> : 'Выйти'}{' '}
|
||||
</button>
|
||||
</div>
|
||||
<button
|
||||
className='logout-button'
|
||||
onClick={() => {
|
||||
setIsLoggingOut(true);
|
||||
localStorage.clear();
|
||||
dispatch(auth(false));
|
||||
setIsLoggingOut(false);
|
||||
navigate(userRole === 'ROLE_DEV' ? '/authdev' : '/auth')
|
||||
}}
|
||||
>
|
||||
{isLoggingOut ? <Loader/> : 'Выйти'}
|
||||
</button>
|
||||
)
|
||||
};
|
||||
|
@ -1,40 +1,27 @@
|
||||
.logout-button {
|
||||
position: absolute;
|
||||
top: 70px;
|
||||
right: 2.5rem;
|
||||
z-index: 100;
|
||||
|
||||
button {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin: 0;
|
||||
width: 131px;
|
||||
height: 40px;
|
||||
border-radius: 10px;
|
||||
font-family: 'Muller';
|
||||
font-size: 1.6em;
|
||||
letter-spacing: 0.8px;
|
||||
background-color: #6aaf5c;
|
||||
color: #ffffff;
|
||||
border: 3px solid #6aaf5c;
|
||||
font-family: 'Muller';
|
||||
text-align: center;
|
||||
}
|
||||
position: relative;
|
||||
z-index: 100;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin: 0;
|
||||
width: 131px;
|
||||
height: 40px;
|
||||
border-radius: 10px;
|
||||
font-size: 1.6em;
|
||||
letter-spacing: 0.8px;
|
||||
background-color: #6aaf5c;
|
||||
color: #ffffff;
|
||||
border: 3px solid #6aaf5c;
|
||||
font-family: 'Muller', sans-serif;
|
||||
text-align: center;
|
||||
|
||||
&:hover {
|
||||
button {
|
||||
background-color: #ffffff;
|
||||
color: #6aaf5c;
|
||||
border: 3px solid #6aaf5c;
|
||||
box-shadow: 3px 2px 5px rgba(82, 151, 34, 0.21);
|
||||
transition: 0.3s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1199px) {
|
||||
.logout-button {
|
||||
top: 16px !important;
|
||||
background-color: #ffffff;
|
||||
color: #6aaf5c;
|
||||
border: 3px solid #6aaf5c;
|
||||
box-shadow: 3px 2px 5px rgba(82, 151, 34, 0.21);
|
||||
transition: 0.3s;
|
||||
}
|
||||
}
|
||||
|
@ -1,26 +1,27 @@
|
||||
import React from 'react'
|
||||
import { useSelector, useDispatch } from 'react-redux'
|
||||
import React 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 {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'
|
||||
import {LogoutButton} from "../LogoutButton/LogoutButton";
|
||||
|
||||
const createSelectPositionHandler =
|
||||
({ positionId, setPositionId, dispatch }) =>
|
||||
(id) => {
|
||||
if (id === positionId) {
|
||||
dispatch(setPositionId(null))
|
||||
} else {
|
||||
dispatch(setPositionId(id))
|
||||
}
|
||||
};
|
||||
({positionId, setPositionId, dispatch}) =>
|
||||
(id) => {
|
||||
if (id === positionId) {
|
||||
dispatch(setPositionId(null))
|
||||
} else {
|
||||
dispatch(setPositionId(id))
|
||||
}
|
||||
};
|
||||
|
||||
const Outstaffing = () => {
|
||||
const dispatch = useDispatch();
|
||||
@ -33,62 +34,58 @@ const Outstaffing = () => {
|
||||
dispatch
|
||||
});
|
||||
return (
|
||||
<>
|
||||
<section className='outstaffing'>
|
||||
<div className='row'>
|
||||
<div className='col-12'>
|
||||
<div className='outstaffing__title'>
|
||||
<h2>
|
||||
<span>Аутстаффинг</span> it-персонала
|
||||
</h2>
|
||||
<>
|
||||
<section className='outstaffing'>
|
||||
<div className='outstaffing__title'>
|
||||
<h2>
|
||||
<span>Аутстаффинг</span> it-персонала
|
||||
</h2>
|
||||
<LogoutButton/>
|
||||
</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>
|
||||
</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 />
|
||||
</>
|
||||
</section>
|
||||
<TagSelect/>
|
||||
</>
|
||||
)
|
||||
};
|
||||
|
||||
|
@ -1,11 +1,15 @@
|
||||
.outstaffing {
|
||||
&__title {
|
||||
margin-top: 60px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
h2 {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
color: #52b709;
|
||||
font-family: 'GT Eesti Pro Display';
|
||||
font-family: 'GT Eesti Pro Display', sans-serif;
|
||||
font-size: 5em;
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
|
@ -58,7 +58,7 @@ const ReportForm = () => {
|
||||
const handler = () => {
|
||||
apiRequest('/reports/create', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
data: {
|
||||
tasks: inputs,
|
||||
difficulties: troublesInputValue,
|
||||
tomorrow: scheduledInputValue,
|
||||
|
Reference in New Issue
Block a user