Переписываю спорные решения

Фикс отправки отчета, проверка на массив в map в Description.js
This commit is contained in:
Дмитрий Савенко 2023-01-17 22:14:05 +03:00
parent 42e2d0e181
commit 6b0b5e991c
21 changed files with 220 additions and 231 deletions

View File

@ -1,4 +1,4 @@
# Getting Started with Create React App nvm# Getting Started with Create React App
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).

View File

@ -4,13 +4,13 @@ import {BrowserRouter as Router, Route, Routes, Navigate} from 'react-router-dom
import AuthForPartners from "./pages/AuthForPartners/AuthForPartners"; import AuthForPartners from "./pages/AuthForPartners/AuthForPartners";
import AuthForDevelopers from "./pages/AuthForDevelopers/AuthForDevelopers"; import AuthForDevelopers from "./pages/AuthForDevelopers/AuthForDevelopers";
import HomePage from './pages/HomePage' import Home from "./components/Home/Home";
import CandidatePage from './pages/CandidatePage' import CandidatePage from './pages/CandidatePage'
import CalendarPage from './pages/CalendarPage' import Calendar from "./components/Calendar/Calendar";
import ReportPage from './pages/ReportFormPage.js' import ReportForm from "./components/ReportForm/ReportForm";
import ProfileCalendarPage from './pages/ProfileCalendarPage.js' import {ProfileCalendar} from "./components/ProfileCalendar/ProfileCalendar";
import FormPage from './pages/FormPage.js' import FormPage from './pages/FormPage/FormPage.js'
import SingleReportPage from './pages/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 {InterjacentPage} from './pages/quiz/InterjacentPage'
import {QuizTestPage} from './pages/quiz/QuizTestPage' import {QuizTestPage} from './pages/quiz/QuizTestPage'
@ -23,23 +23,24 @@ import './fonts/stylesheet.css'
import 'bootstrap/dist/css/bootstrap.min.css' import 'bootstrap/dist/css/bootstrap.min.css'
const App = () => { const App = () => {
return ( return (
<> <>
<h1>IT Аутстаффинг в России</h1>
<Router> <Router>
<Routes> <Routes>
<Route exact path='/' element={<HomePage/>}/>
<Route exact path='/' element={<Home/>}/>
<Route exact path='/authdev' element={<AuthForDevelopers/>}/> <Route exact path='/authdev' element={<AuthForDevelopers/>}/>
<Route exact path='/auth' element={<AuthForPartners/>}/> <Route exact path='/auth' element={<AuthForPartners/>}/>
<Route exact path='/candidate/:id' element={<CandidatePage/>}/> <Route exact path='/candidate/:id' element={<CandidatePage/>}/>
<Route exact path='/candidate/:id/form' element={<FormPage/>}/> <Route exact path='/candidate/:id/form' element={<FormPage/>}/>
<Route path='/:userId/calendar' element={<CalendarPage/>}/> <Route path='/:userId/calendar' element={<Calendar/>}/>
<Route exact path='/report' element={<ReportPage/>}/> <Route exact path='/report' element={<ReportForm/>}/>
<Route path='/report/:id' element={<SingleReportPage/>}/> <Route path='/report/:id' element={<SingleReportPage/>}/>
<Route exact path='quiz'> <Route exact path='quiz'>
@ -52,7 +53,7 @@ const App = () => {
<Route exact path='profile'> <Route exact path='profile'>
<Route index element={<Profile/>}/> <Route index element={<Profile/>}/>
<Route exact path='calendar' element={<ProfileCalendarPage/>}/> <Route exact path='calendar' element={<ProfileCalendar/>}/>
<Route exact path='summary' element={<Summary/>}/> <Route exact path='summary' element={<Summary/>}/>
</Route> </Route>

View File

@ -1,22 +1,27 @@
import React, {useEffect, useState} from 'react' import React, {useEffect, useState} from 'react'
import {useSelector} from 'react-redux' import {useSelector} from 'react-redux'
import {selectCurrentCandidate} from '../../redux/outstaffingSlice' import {Link, useNavigate} from 'react-router-dom'
import {Link} from 'react-router-dom'
import CalendarComponent from './CalendarComponent' import CalendarComponent from './CalendarComponent'
import {currentMonth} from './calendarHelper' import {currentMonth} from './calendarHelper'
import {Footer} from '../Footer/Footer' import {Footer} from '../Footer/Footer'
import {LogoutButton} from "../LogoutButton/LogoutButton";
import {selectCurrentCandidate} from '../../redux/outstaffingSlice'
import rectangle from '../../images/rectangle_secondPage.png' import rectangle from '../../images/rectangle_secondPage.png'
import './calendar.scss' import './calendar.scss'
const Calendar = ({onSelect}) => {
const Calendar = () => {
const candidateForCalendar = useSelector(selectCurrentCandidate); const candidateForCalendar = useSelector(selectCurrentCandidate);
const [month, setMonth] = useState(''); const [month, setMonth] = useState('');
const navigate = useNavigate();
useEffect(() => { useEffect(() => {
setMonth(currentMonth) setMonth(currentMonth)
}, [month]); }, [month]);
@ -26,11 +31,15 @@ const Calendar = ({onSelect}) => {
const abbreviatedName = name && name.substring(0, name.lastIndexOf(' ')); const abbreviatedName = name && name.substring(0, name.lastIndexOf(' '));
return ( return (
<div className='container'>
<section className='calendar'> <section className='calendar'>
<div className='row'> <div className='row'>
<div className='calendar__header'>
<h2 className='calendar__profile'> <h2 className='calendar__profile'>
Добрый день, <span>Александр !</span> Добрый день, <span>Александр !</span>
</h2> </h2>
<LogoutButton />
</div>
<div className='col-12 col-xl-12 d-flex justify-content-between align-items-center flex-column flex-sm-row'> <div className='col-12 col-xl-12 d-flex justify-content-between align-items-center flex-column flex-sm-row'>
<div className='calendar__info'> <div className='calendar__info'>
<img className='calendar__info-img' src={photo} alt='img'/> <img className='calendar__info-img' src={photo} alt='img'/>
@ -50,7 +59,7 @@ const Calendar = ({onSelect}) => {
<div className='row'> <div className='row'>
<div className='col-12 col-xl-12'> <div className='col-12 col-xl-12'>
<CalendarComponent onSelect={onSelect}/> <CalendarComponent onSelect={() => { navigate('/report/0') }}/>
<p className='calendar__hours'> <p className='calendar__hours'>
{month} : <span> 60 часов </span> {month} : <span> 60 часов </span>
</p> </p>
@ -58,6 +67,7 @@ const Calendar = ({onSelect}) => {
</div> </div>
<Footer/> <Footer/>
</section> </section>
</div>
) )
}; };

View File

@ -2,6 +2,17 @@
margin-bottom: 40px; margin-bottom: 40px;
font-family: 'LabGrotesque', sans-serif; font-family: 'LabGrotesque', sans-serif;
&__header {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
padding: 0 20px;
h2 {
flex: 1;
}
}
&__profile { &__profile {
color: #282828; color: #282828;
font-size: 3.4em; font-size: 3.4em;
@ -45,8 +56,6 @@
position: absolute; position: absolute;
width: 132px; width: 132px;
height: 132px; height: 132px;
left: -40px;
top: -10px;
} }
} }

View File

@ -22,7 +22,7 @@ const Description = ({ onLoadMore, isLoadingMore }) => {
<section className='description'> <section className='description'>
<div className='container'> <div className='container'>
<div className='description__wrapper'> <div className='description__wrapper'>
{candidatesListArr && candidatesListArr.length > 0 ? ( {candidatesListArr && Array.isArray(candidatesListArr) && candidatesListArr.length > 0 ? (
candidatesListArr.map((el) => ( candidatesListArr.map((el) => (
<div className='row' key={el.id}> <div className='row' key={el.id}>
<div className='col-2 col-xs-12'> <div className='col-2 col-xs-12'>
@ -56,7 +56,7 @@ const Description = ({ onLoadMore, isLoadingMore }) => {
<div className='col-xl-2'></div> <div className='col-xl-2'></div>
<div className='col-12 col-xl-6'> <div className='col-12 col-xl-6'>
<ul className='description__list'> <ul className='description__list'>
{el.skillValues.map((e) => ( {Array.isArray(el?.skillValues) && el.skillValues.map((e) => (
<li key={e.id} className='description__list-item'> <li key={e.id} className='description__list-item'>
{e.skill.name} {e.skill.name}
</li> </li>
@ -104,7 +104,7 @@ const Description = ({ onLoadMore, isLoadingMore }) => {
<section className='description'> <section className='description'>
<div className='container'> <div className='container'>
<div className='description__wrapper'> <div className='description__wrapper'>
{filteredListArr && filteredListArr.length > 0 {filteredListArr && Array.isArray(filteredListArr) && filteredListArr.length > 0
? filteredListArr.map((el) => ( ? filteredListArr.map((el) => (
<div className='row' key={el.id}> <div className='row' key={el.id}>
<div className='col-2'> <div className='col-2'>
@ -139,7 +139,7 @@ const Description = ({ onLoadMore, isLoadingMore }) => {
<div className='col-xl-2'></div> <div className='col-xl-2'></div>
<div className='col-12 col-xl-6'> <div className='col-12 col-xl-6'>
<ul className='description__list'> <ul className='description__list'>
{el.skillValues.map((e) => ( {Array.isArray(el?.skillValues) && el.skillValues?.map((e) => (
<li key={e.id} className='description__list-item'> <li key={e.id} className='description__list-item'>
{e.skill.name} {e.skill.name}
</li> </li>
@ -155,7 +155,7 @@ const Description = ({ onLoadMore, isLoadingMore }) => {
</div> </div>
)) ))
: /* : <div className={style.description__empty}>В данный момент в категории нет свободных специалистов</div> } */ : /* : <div className={style.description__empty}>В данный момент в категории нет свободных специалистов</div> } */
candidatesListArr && candidatesListArr && Array.isArray(candidatesListArr) &&
candidatesListArr.map((el) => ( candidatesListArr.map((el) => (
<div className='row' key={el.id}> <div className='row' key={el.id}>
<div className='col-2'> <div className='col-2'>
@ -186,7 +186,7 @@ const Description = ({ onLoadMore, isLoadingMore }) => {
<div className='col-xl-2'></div> <div className='col-xl-2'></div>
<div className='col-12 col-xl-6'> <div className='col-12 col-xl-6'>
<ul className='description__list'> <ul className='description__list'>
{el.skillValues.map((e) => ( {Array.isArray(el?.skillValues) && el.skillValues?.map((e) => (
<li key={e.id} className='description__list-item'> <li key={e.id} className='description__list-item'>
{e.skill.name} {e.skill.name}
</li> </li>
@ -207,8 +207,7 @@ const Description = ({ onLoadMore, isLoadingMore }) => {
<div className='col-12'> <div className='col-12'>
<div className='description__footer'> <div className='description__footer'>
<div className='description__footer-btn'> <div className='description__footer-btn'>
{ {candidatesListArr &&
candidatesListArr &&
filteredListArr.length === 0 ? ( filteredListArr.length === 0 ? (
<button onClick={() => onLoadMore(2)}>Загрузить еще</button> <button onClick={() => onLoadMore(2)}>Загрузить еще</button>
) : null} ) : null}

View File

@ -8,6 +8,7 @@ import {Footer} from '../Footer/Footer'
import {profiles, tags} from '../../redux/outstaffingSlice' import {profiles, tags} from '../../redux/outstaffingSlice'
import {useRequest} from "../../hooks/useRequest"; import {useRequest} from "../../hooks/useRequest";
import {LogoutButton} from "../LogoutButton/LogoutButton";
const Home = () => { const Home = () => {
@ -53,11 +54,12 @@ const Home = () => {
}; };
return ( return (
<> <div className='container'>
<Outstaffing/> <Outstaffing/>
<Description onLoadMore={loadMore} isLoadingMore={isLoadingMore}/> <Description onLoadMore={loadMore} isLoadingMore={isLoadingMore}/>
<Footer/> <Footer/>
</> </div>
) )
}; };

View File

@ -14,8 +14,8 @@ export const LogoutButton = () => {
const navigate = useNavigate(); const navigate = useNavigate();
return ( return (
<div className='logout-button'>
<button <button
className='logout-button'
onClick={() => { onClick={() => {
setIsLoggingOut(true); setIsLoggingOut(true);
localStorage.clear(); localStorage.clear();
@ -24,8 +24,7 @@ export const LogoutButton = () => {
navigate(userRole === 'ROLE_DEV' ? '/authdev' : '/auth') navigate(userRole === 'ROLE_DEV' ? '/authdev' : '/auth')
}} }}
> >
{isLoggingOut ? <Loader/> : 'Выйти'}{' '} {isLoggingOut ? <Loader/> : 'Выйти'}
</button> </button>
</div>
) )
}; };

View File

@ -1,10 +1,7 @@
.logout-button { .logout-button {
position: absolute;
top: 70px;
right: 2.5rem;
z-index: 100;
button { position: relative;
z-index: 100;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
@ -12,18 +9,15 @@
width: 131px; width: 131px;
height: 40px; height: 40px;
border-radius: 10px; border-radius: 10px;
font-family: 'Muller';
font-size: 1.6em; font-size: 1.6em;
letter-spacing: 0.8px; letter-spacing: 0.8px;
background-color: #6aaf5c; background-color: #6aaf5c;
color: #ffffff; color: #ffffff;
border: 3px solid #6aaf5c; border: 3px solid #6aaf5c;
font-family: 'Muller'; font-family: 'Muller', sans-serif;
text-align: center; text-align: center;
}
&:hover { &:hover {
button {
background-color: #ffffff; background-color: #ffffff;
color: #6aaf5c; color: #6aaf5c;
border: 3px solid #6aaf5c; border: 3px solid #6aaf5c;
@ -31,10 +25,3 @@
transition: 0.3s; transition: 0.3s;
} }
} }
}
@media (max-width: 1199px) {
.logout-button {
top: 16px !important;
}
}

View File

@ -11,6 +11,7 @@ import back from '../../images/back_end.png'
import design from '../../images/design.png' import design from '../../images/design.png'
import './outstaffing.scss' import './outstaffing.scss'
import {LogoutButton} from "../LogoutButton/LogoutButton";
const createSelectPositionHandler = const createSelectPositionHandler =
({positionId, setPositionId, dispatch}) => ({positionId, setPositionId, dispatch}) =>
@ -35,16 +36,12 @@ const Outstaffing = () => {
return ( return (
<> <>
<section className='outstaffing'> <section className='outstaffing'>
<div className='row'>
<div className='col-12'>
<div className='outstaffing__title'> <div className='outstaffing__title'>
<h2> <h2>
<span>Аутстаффинг</span> it-персонала <span>Аутстаффинг</span> it-персонала
</h2> </h2>
<LogoutButton/>
</div> </div>
</div>
</div>
<div className='row'> <div className='row'>
<div className='col-12 col-xl-4'> <div className='col-12 col-xl-4'>
<OutstaffingBlock <OutstaffingBlock

View File

@ -1,11 +1,15 @@
.outstaffing { .outstaffing {
&__title { &__title {
margin-top: 60px; margin-top: 60px;
display: flex;
justify-content: center;
align-items: center;
h2 { h2 {
flex: 1;
text-align: center; text-align: center;
color: #52b709; color: #52b709;
font-family: 'GT Eesti Pro Display'; font-family: 'GT Eesti Pro Display', sans-serif;
font-size: 5em; font-size: 5em;
font-weight: 700; font-weight: 700;
font-style: normal; font-style: normal;

View File

@ -58,7 +58,7 @@ const ReportForm = () => {
const handler = () => { const handler = () => {
apiRequest('/reports/create', { apiRequest('/reports/create', {
method: 'POST', method: 'POST',
body: { data: {
tasks: inputs, tasks: inputs,
difficulties: troublesInputValue, difficulties: troublesInputValue,
tomorrow: scheduledInputValue, tomorrow: scheduledInputValue,

View File

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { ActContent } from "../components/features/bookkeeping/ActContent/ActContent" import { ActContent } from "../../components/features/bookkeeping/ActContent/ActContent"
import { BookkeepingTemplete } from "../components/features/bookkeeping/BookkeepingTemplete/BookkeepingTemplete" import { BookkeepingTemplete } from "../../components/features/bookkeeping/BookkeepingTemplete/BookkeepingTemplete"
export const ActPage = () => { export const ActPage = () => {
return ( return (

View File

@ -4,8 +4,8 @@ import { WithLogout } from '../hoc/withLogout';
import Calendar from '../components/Calendar/Calendar'; import Calendar from '../components/Calendar/Calendar';
const CalendarPage = () => { const CalendarPage = () => {
const navigate = useNavigate();
return <WithLogout><Calendar onSelect={() => { navigate('/report/0') }} /></WithLogout>; return <WithLogout><Calendar onSelect={} /></WithLogout>;
}; };
export default CalendarPage; export default CalendarPage;

View File

@ -4,14 +4,14 @@ import { a11yDark } from 'react-syntax-highlighter/dist/esm/styles/prism';
export const CodeSnippetlighter = () => { export const CodeSnippetlighter = () => {
const [codeString, setCodeString] = useState(``) const [codeString, setCodeString] = useState(``)
//
useEffect(()=>{ // useEffect(()=>{
fetch('/code.txt') // fetch('/code.txt')
.then((r) => r.text()) // .then((r) => r.text())
.then(text => { // .then(text => {
setCodeString(text) // setCodeString(text)
}) // })
}, []) // }, [])
return ( return (
<SyntaxHighlighter language={"javascript"} style={a11yDark} wrapLongLines={false} customStyle={{fontSize:14}} showLineNumbers={true}> <SyntaxHighlighter language={"javascript"} style={a11yDark} wrapLongLines={false} customStyle={{fontSize:14}} showLineNumbers={true}>

View File

@ -1,22 +1,25 @@
import React from 'react' import React from 'react'
import {useDispatch, useSelector} from 'react-redux' import {useDispatch, useSelector} from 'react-redux'
import {useParams, useNavigate} from 'react-router-dom' import {useParams, useNavigate} from 'react-router-dom'
import {
currentCandidate,
selectCurrentCandidate,
} from '../redux/outstaffingSlice'
import SVG from 'react-inlinesvg' import SVG from 'react-inlinesvg'
import {WithLogout} from '../hoc/withLogout'
import Form from '../components/Form/Form'
import {LEVELS, SKILLS} from '../constants/constants'
import {Footer} from '../components/Footer/Footer'
import arrow from '../images/right-arrow.png' import {useRequest} from "../../hooks/useRequest";
import rectangle from '../images/rectangle_secondPage.png' import {WithLogout} from '../../hoc/withLogout'
import telegramIcon from '../images/telegram-icon.svg'
import Form from '../../components/Form/Form'
import {Footer} from '../../components/Footer/Footer'
import arrow from '../../images/right-arrow.png'
import rectangle from '../../images/rectangle_secondPage.png'
import telegramIcon from '../../images/telegram-icon.svg'
import {LEVELS, SKILLS} from '../../constants/constants'
import {currentCandidate, selectCurrentCandidate} from '../../redux/outstaffingSlice'
import './formPage.scss' import './formPage.scss'
import {useRequest} from "../hooks/useRequest";
const FormPage = () => { const FormPage = () => {

View File

@ -1,7 +0,0 @@
import React from 'react';
import { WithLogout } from '../hoc/withLogout';
import Home from '../components/Home/Home';
const HomePage = () => <WithLogout><Home /></WithLogout>;
export default HomePage;

View File

@ -1,8 +0,0 @@
import React from 'react';
import { ProfileCalendar } from '../../src/components/ProfileCalendar/ProfileCalendar';
const ProfileCalendarPage = () => {
return <ProfileCalendar/>;
};
export default ProfileCalendarPage;

View File

@ -1,7 +0,0 @@
import React from 'react';
import { WithLogout } from '../hoc/withLogout';
import ReportForm from '../components/ReportForm/ReportForm';
const ReportFormPage = () => <ReportForm />;
export default ReportFormPage;

View File

@ -1,15 +1,17 @@
import React from 'react' import React from 'react'
import { WithLogout } from '../hoc/withLogout' import { WithLogout } from '../../hoc/withLogout'
import arrowLeft from '../images/right-arrow.png' import arrowLeft from '../../images/right-arrow.png'
import SVG from 'react-inlinesvg' import SVG from 'react-inlinesvg'
import dateArrowIcon from '../images/dateArrow.svg' import dateArrowIcon from '../../images/dateArrow.svg'
import calendarIcon from '../images/calendar.svg' import calendarIcon from '../../images/calendar.svg'
import { TaskItem } from '../components/TaskItem/TaskItem' import { TaskItem } from '../../components/TaskItem/TaskItem'
import './singleReportPage.scss' import './singleReportPage.scss'
import {useNavigate} from "react-router";
import {LogoutButton} from "../../components/LogoutButton/LogoutButton";
const tasks = [ const tasks = [
{ {
@ -25,10 +27,13 @@ const tasks = [
]; ];
const SingleReportPage = () => { const SingleReportPage = () => {
const navigate= useNavigate();
return ( return (
<WithLogout>
<div className='single-report-page'> <div className='single-report-page'>
<div className='single-report-page__back'> <div onClick={()=> {navigate(-1)}} className='single-report-page__back'>
<div className='single-report-page__back-arrow'> <div className='single-report-page__back-arrow'>
<img src={arrowLeft} alt='arrowLeft'/> <img src={arrowLeft} alt='arrowLeft'/>
</div> </div>
@ -100,8 +105,9 @@ const SingleReportPage = () => {
<div className='single-report-page__hours-text'></div> <div className='single-report-page__hours-text'></div>
</div> </div>
</div> </div>
<LogoutButton />
</div> </div>
</WithLogout>
) )
}; };

View File

@ -1,15 +1,14 @@
.single-report-page { .single-report-page {
padding-top: 4.6rem; padding: 4.6rem 20px 0;
font-family: 'GT Eesti Pro Display', sans-serif;
&__back { &__back {
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-start;
align-items: center; align-items: center;
cursor: pointer;
&-text { &-text {
margin-left: 3.1rem; margin-left: 3.1rem;
color: #000000; color: #000000;
font-family: 'GT Eesti Pro Display';
font-size: 18px; font-size: 18px;
font-weight: 300; font-weight: 300;
letter-spacing: normal; letter-spacing: normal;
@ -26,7 +25,6 @@
&-text { &-text {
color: #282828; color: #282828;
font-family: 'GT Eesti Pro Display';
font-size: 33px; font-size: 33px;
font-weight: 700; font-weight: 700;
line-height: 48.74px; line-height: 48.74px;
@ -52,7 +50,6 @@
border-radius: 5px; border-radius: 5px;
border: 1px solid #c4c4c4; border: 1px solid #c4c4c4;
background-color: #f0f7e0; background-color: #f0f7e0;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
@ -63,7 +60,6 @@
margin-left: 10px; margin-left: 10px;
margin-bottom: 0; margin-bottom: 0;
color: #000000; color: #000000;
font-family: "GT Eesti Pro Display";
font-size: 13px; font-size: 13px;
font-weight: 300; font-weight: 300;
font-style: normal; font-style: normal;
@ -104,7 +100,6 @@
align-items: center; align-items: center;
h3 { h3 {
color: #18586e; color: #18586e;
font-family: 'GT Eesti Pro Display';
font-size: 20px; font-size: 20px;
font-weight: 500; font-weight: 500;
letter-spacing: normal; letter-spacing: normal;
@ -117,7 +112,6 @@
margin-top: 2.4rem; margin-top: 2.4rem;
width: 580px; width: 580px;
color: #000000; color: #000000;
font-family: 'GT Eesti Pro Display';
font-size: 15px; font-size: 15px;
font-weight: 400; font-weight: 400;
letter-spacing: normal; letter-spacing: normal;