Merge branch 'profileCalendar' into profilePage

# Conflicts:
#	src/App.js
#	src/components/ProfileCalendar/ProfileCalendar.js
#	src/components/ReportForm/ReportForm.js
#	src/pages/Profile.js
This commit is contained in:
Дмитрий Савенко 2023-01-16 19:20:49 +03:00
commit 794a5fa44e
14 changed files with 316 additions and 113 deletions

View File

@ -44,16 +44,17 @@ const App = () => {
<Route exact path='quiz'> <Route exact path='quiz'>
<Route index element={<QuizPage/>}/> <Route index element={<QuizPage/>}/>
<Route path='interjacent' element={<InterjacentPage/>}/> <Route exact path='interjacent' element={<InterjacentPage/>}/>
<Route path='test' element={<QuizTestPage/>}/> <Route exact path='test' element={<QuizTestPage/>}/>
<Route path='instruction' element={<InstructionPage/>}/> <Route exact path='instruction' element={<InstructionPage/>}/>
<Route path='result' element={<ResultPage/>}/> <Route exact path='result' element={<ResultPage/>}/>
</Route> </Route>
<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={<ProfileCalendarPage/>}/>
<Route exact path='summary' element={<Summary/>}/> <Route exact path='summary' element={<Summary/>}/>
<Route exact path='calendar' element={ProfileCalendarPage} />
</Route> </Route>
<Route path="*" element={<Navigate to="/" replace/>}/> <Route path="*" element={<Navigate to="/" replace/>}/>

View File

@ -64,7 +64,6 @@
&__btn { &__btn {
width: 280px; width: 280px;
height: 62px; height: 62px;
box-shadow: 6px 5px 20px rgba(82, 151, 34, 0.21);
border-radius: 31px; border-radius: 31px;
background-color: #ffffff; background-color: #ffffff;
background-image: linear-gradient(to top, #6aaf5c 0%, #52b709 100%), background-image: linear-gradient(to top, #6aaf5c 0%, #52b709 100%),
@ -81,6 +80,12 @@
font-size: 1.6em; font-size: 1.6em;
letter-spacing: normal; letter-spacing: normal;
text-align: center; text-align: center;
transition: all 0.3s ease;
&:hover {
box-shadow: 6px 5px 20px rgb(87 98 80 / 21%);
transform: scale(1.02);
}
} }
&__hours { &__hours {

View File

@ -1,6 +1,6 @@
.calendar-component { .calendar-component {
position: relative; position: relative;
margin-top: 80px; margin-top: 30px;
margin-bottom: 60px; margin-bottom: 60px;
background-color: #f9f9f9; background-color: #f9f9f9;
padding-left: 68px; padding-left: 68px;
@ -92,6 +92,11 @@
letter-spacing: normal; letter-spacing: normal;
line-height: normal; line-height: normal;
text-align: center; text-align: center;
a {
text-decoration: none;
color: #000000;
}
} }
} }
} }
@ -263,3 +268,7 @@
.selected { .selected {
background-color: #f9f9c3 !important; background-color: #f9f9c3 !important;
} }
.block {
pointer-events: none;
}

View File

@ -8,6 +8,7 @@ import moment from "moment";
import rectangle from '../../images/rectangle_secondPage.png' import rectangle from '../../images/rectangle_secondPage.png'
import {currentMonth, getReports} from '../Calendar/calendarHelper' import {currentMonth, getReports} from '../Calendar/calendarHelper'
import {ProfileCalendarComponent} from "./ProfileCalendarComponent"; import {ProfileCalendarComponent} from "./ProfileCalendarComponent";
import { ProfileHeader } from "../Profile/ProfileHeader";
import { Footer } from '../Footer/Footer' import { Footer } from '../Footer/Footer'
import './profileCalendar.scss' import './profileCalendar.scss'
@ -48,42 +49,29 @@ export const ProfileCalendar = () => {
}, [month]); }, [month]);
return ( return (
<section className='calendar'> <div className='profile__calendar'>
<div className='profile__calendar'> <ProfileHeader/>
<Link className='calendar__back' to={`/profile`}> <div className='container'>
<div><img src={arrow} alt=''/>Вернуться назад</div> <h2 className='summary__title'>Ваши отчеты</h2>
</Link> <div className='summary__info'>
<h2 className='calendar__profile'> <div className='summary__person'>
Добрый день, <span>{profileInfo.fio}</span> <img src={profileInfo.photo} className='summary__avatar' alt='avatar'/>
</h2> <p className='summary__name'>{profileInfo.fio} {profileInfo.specification}</p>
<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={profileInfo.photo} alt='img' />
<h3 className='calendar__info-name'>{}</h3>
</div>
<div className='calendar__title'>
<h3 className='calendar__title-text'>{profileInfo.position_name}</h3>
<img className='calendar__title-img' src={rectangle} alt='img' />
</div>
<div>
<Link to='/report'>
<button className='calendar__btn' onClick={() => {
dispatch(setReportDate(moment()))
}}>Заполнить отчет за день</button>
</Link>
</div> </div>
<Link to='/profile/report'>
<button className="calendar__btn">Заполнить отчет за день</button>
</Link>
</div> </div>
</div> <div className='row'>
<div className='col-12 col-xl-12'>
<div className='row'> <ProfileCalendarComponent reportsDates={reports} />
<div className='col-12 col-xl-12'> <p className='calendar__hours'>
<ProfileCalendarComponent reportsDates={reports} /> {month} : <span> {totalHours} часов </span>
<p className='calendar__hours'> </p>
{month} : <span> {totalHours} часов </span> </div>
</p>
</div> </div>
</div> </div>
<Footer /> <Footer />
</section> </div>
) )
}; };

View File

@ -28,23 +28,33 @@ export const ProfileCalendarComponent = ({reportsDates}) => {
return day.isSame(new Date(), 'day') return day.isSame(new Date(), 'day')
} }
function correctDay(day) {
if (day < 10) {
return `0${day}`
} return day
}
function dayStyles(day) { function dayStyles(day) {
if (value < day) return `` if (value < day) return `block`
if (day.day() === 6 || day.day() === 0) return `selected`
function correctDay(day) {
if (day < 10) {
return `0${day}`
} return day
}
for (const date of reportsDates) { for (const date of reportsDates) {
if (`${new Date(day).getFullYear()}-${new Date(day).getMonth() + 1}-${correctDay(new Date(day).getDate())}` === date.date) { if (`${new Date(day).getFullYear()}-${correctDay(new Date(day).getMonth() + 1)}-${correctDay(new Date(day).getDate())}` === date.date) {
return `before` return `before`
} }
} }
if (day.day() === 6 || day.day() === 0) return `selected`
if (isToday(day)) return `today` if (isToday(day)) return `today`
return 'pass' return 'pass'
} }
function correctRoute(day) {
for (const date of reportsDates) {
if (`${new Date(day).getFullYear()}-${correctDay(new Date(day).getMonth() + 1)}-${correctDay(new Date(day).getDate())}` === date.date) {
return `/view/report`
}
}
return '/profile/report'
}
// function prevMonth() { // function prevMonth() {
// return value.clone().subtract(1, 'month') // return value.clone().subtract(1, 'month')
// } // }
@ -85,7 +95,6 @@ export const ProfileCalendarComponent = ({reportsDates}) => {
<div className='calendar-component__form'> <div className='calendar-component__form'>
{calendar.map((week) => {calendar.map((week) =>
week.map((day) => ( week.map((day) => (
<Link to='/report'>
<button <button
onClick={() => { onClick={() => {
dispatch(setReportDate(day)) dispatch(setReportDate(day))
@ -95,10 +104,11 @@ export const ProfileCalendarComponent = ({reportsDates}) => {
name={day.format('dddd')} name={day.format('dddd')}
id='btn' id='btn'
> >
<img className={'calendar__icon'} src={calendarIcon} alt='' /> <Link to={() => correctRoute(day)}>
{currentMonthAndDay(day)} <img className={'calendar__icon'} src={calendarIcon} alt='' />
{currentMonthAndDay(day)}
</Link>
</button> </button>
</Link>
)) ))
)} )}
</div> </div>

View File

@ -1,5 +1,21 @@
.calendar { .profile__calendar {
font-family: 'LabGrotesque', sans-serif; background: #F1F1F1;
height: 100%;
min-height: 100vh;
font-family: "LabGrotesque", sans-serif;
.container {
max-width: 1160px;
margin-top: 23px;
@media (max-width: 570px) {
margin-top: 0;
}
}
.summary__info {
padding-right: 25px;
}
.profile__calendar { .profile__calendar {
margin-top: 20px; margin-top: 20px;
} }
@ -17,4 +33,11 @@
&__profile { &__profile {
margin-top: 42px; margin-top: 42px;
} }
&__btn {
transition: all 0.3s ease;
&:hover {
transform: scale(1.02);
}
}
} }

View File

@ -57,6 +57,11 @@
font-size: 18px; font-size: 18px;
line-height: 32px; line-height: 32px;
color: #807777 !important; color: #807777 !important;
transition: all 0.3s ease;
&:hover {
color: #261a1a !important;
}
} }
@media (max-width: 800px) { @media (max-width: 800px) {

View File

@ -8,6 +8,9 @@ import ellipse from '../../images/ellipse.png'
import remove from '../../images/remove.png' import remove from '../../images/remove.png'
import addIcon from '../../images/addIcon.png' import addIcon from '../../images/addIcon.png'
import {currentMonthAndDay} from '../Calendar/calendarHelper' import {currentMonthAndDay} from '../Calendar/calendarHelper'
import {currentMonthAndDay, getReports} from '../Calendar/calendarHelper'
import {ProfileHeader} from "../Profile/ProfileHeader";
import {Footer} from "../Footer/Footer";
import './reportForm.scss' import './reportForm.scss'
import arrow from "../../images/right-arrow.png"; import arrow from "../../images/right-arrow.png";
import {useRequest} from "../../hooks/useRequest"; import {useRequest} from "../../hooks/useRequest";
@ -72,14 +75,21 @@ const ReportForm = () => {
return ( return (
<section className='report-form'> <section className='report-form'>
<div className='row'> <ProfileHeader/>
<div className='col-xl-12 report__head'> <div className='container'>
<Link className='calendar__back' to={`/ProfileCalendar`}> <h2 className='summary__title'>Ваши отчеты - <span>добавить отчет</span></h2>
<div><img src={arrow} alt=''/>Вернуться назад</div> <div>
</Link> <div className='report__head'>
<Link className='calendar__back' to={`/profile/profilecalendar`}>
<img src={arrow} alt=''/><p>Вернуться</p>
</Link>
</div>
</div>
<div className='report-form__content'>
<div className='report-form__block'> <div className='report-form__block'>
<div className='report-form__block-title'> <div className='report-form__block-title'>
<h2>Добавить отчет</h2> <h2>Добавление отчета за день</h2>
<h3>Дата заполнения отчета:</h3> <h3>Дата заполнения отчета:</h3>
</div> </div>
<div className='report-form__block-img'> <div className='report-form__block-img'>
@ -96,60 +106,58 @@ const ReportForm = () => {
<span>Какие задачи были выполнены?</span> <span>Какие задачи были выполнены?</span>
</div> </div>
</div> </div>
</div>
</div>
<div className='row'> <div className='row'>
<div className='col-8'> <div className='col-8'>
<div className='report-form__task-header'> <div className='report-form__task-header'>
<p className='report-form__task-title--description'> <p className='report-form__task-title--description'>
Краткое описание задачи Краткое описание задачи
</p> </p>
<p className='report-form__task-title--hours'>Количество часов</p> <p className='report-form__task-title--hours'>Количество часов</p>
</div>
{inputs.map((input, index) => {
return (
<form id={'input'} key={`input__${index}`} className='report-form__task-form'>
<div className='report-form__task-number'>
{index + 1}.
</div>
<div className='report-form__task-input report-form__task-input--description'>
<input name='text' type='text' onChange={e => setInputs(inputs.map((input, inputIndex) => {
return index === inputIndex
? {
...input,
task: e.target.value
}
: input
}))}/>
</div>
<div className='report-form__task-input report-form__task-input--hours'>
<input name='number' type='number' min='1'
onChange={e => setInputs(inputs.map((input, inputIndex) => {
return index === inputIndex
? {
...input,
hours_spent: Number(e.target.value)
}
: input
}))}/>
</div>
<div className='report-form__task-remove'>
<img onClick={() => deleteInput(index)} src={remove} alt=''/>
</div>
</form>
)
})}
<div className='report-form__form-add'>
<img onClick={addInput} src={addIcon} alt=''/>
<span>Добавить еще </span>
</div>
</div>
<div className='col-4'></div>
</div> </div>
{inputs.map((input, index) => {
return (
<form id={'input'} key={`input__${index}`} className='report-form__task-form'>
<div className='report-form__task-number'>
{index + 1}.
</div>
<div className='report-form__task-input report-form__task-input--description'>
<input name='text' type='text' onChange={e => setInputs(inputs.map((input, inputIndex) => {
return index === inputIndex
? {
...input,
task: e.target.value
}
: input
}))}/>
</div>
<div className='report-form__task-input report-form__task-input--hours'>
<input name='number' type='number' min='1'
onChange={e => setInputs(inputs.map((input, inputIndex) => {
return index === inputIndex
? {
...input,
hours_spent: Number(e.target.value)
}
: input
}))}/>
</div>
<div className='report-form__task-remove'>
<img onClick={() => deleteInput(index)} src={remove} alt=''/>
</div>
</form>
)
})}
<div className='report-form__form-add'>
<img onClick={addInput} src={addIcon} alt=''/>
<span>Добавить еще </span>
</div>
</div>
<div className='col-4'></div>
</div>
<div className='row'> <div className='row'>
<div className='col-12'> <div className='col-12'>
<div className='report-form__input-box'> <div className='report-form__input-box'>
@ -180,7 +188,10 @@ const ReportForm = () => {
} }
</div> </div>
</div> </div>
</div>
</div>
</div> </div>
<Footer/>
</section> </section>
) )
}; };

View File

@ -1,14 +1,51 @@
.report-form { .report-form {
background: #F1F1F1;
height: 100%;
min-height: 100vh;
font-family: "LabGrotesque", sans-serif;
.container {
max-width: 1160px;
margin-top: 23px;
@media (max-width: 570px) {
margin-top: 0;
}
}
&__content {
background: #FFFFFF;
border-radius: 12px;
margin: 25px 0 80px;
padding: 50px 40px;
}
.report__head { .report__head {
margin-top: 20px; margin-top: 20px;
a {
display: flex;
align-items: center;
grid-column-gap: 30px;
column-gap: 30px;
margin-top: 20px;
cursor: pointer;
text-decoration: none;
p {
margin-bottom: 0;
font-size: 14px;
line-height: 32px;
font-weight: 500;
color: black;
}
}
} }
&__block-title { &__block-title {
margin-top: 15px;
h2 { h2 {
color: #282828; color: #52B709;
font-family: 'GT Eesti Pro Display'; font-family: 'GT Eesti Pro Display';
font-size: 3.3em; font-size: 3.3em;
font-weight: 700; font-weight: 700;

96
src/pages/Profile.js Normal file
View File

@ -0,0 +1,96 @@
import React from 'react';
import {useSelector} from "react-redux";
import {getProfileInfo} from "../redux/outstaffingSlice";
import {ProfileHeader} from "../components/Profile/ProfileHeader";
import {Link} from "react-router-dom";
import {Footer} from "../components/Footer/Footer";
import reportsIcon from "../images/reports.png"
import summaryIcon from "../images/summaryIcon.png"
import timerIcon from "../images/timerIcon.png"
import paymentIcon from "../images/paymentIcon.png"
import settingIcon from "../images/settingIcon.png"
import rightArrow from "../images/arrowRight.png"
import '../components/Profile/profile.scss'
export const Profile = () => {
const profileInfo = useSelector(getProfileInfo);
return(
<div className='profile'>
<ProfileHeader/>
<div className='container'>
<h2 className='profile__title'>Добрый день, <span>{profileInfo.fio}</span></h2>
<div className='summary__info'>
<div className='summary__person'>
<img src={profileInfo.photo} className='summary__avatar' alt='avatar'/>
<p className='summary__name'>{profileInfo.fio} {profileInfo.specification}</p>
</div>
</div>
<div className='profile__items'>
<Link to={'/profile/profilecalendar'} className='item'>
<div className='item__about'>
<img src={reportsIcon} alt='report'/>
<h3>Ваша отчетность</h3>
</div>
<div className='item__info'>
<p><span></span>Отработанных в этом месяце часов</p>
<div className='item__infoLink'>
<img src={rightArrow} alt='arrow'/>
</div>
</div>
</Link>
<Link to={'/summary'} className='item'>
<div className='item__about'>
<img src={summaryIcon} alt='summary'/>
<h3>Данные и резюме</h3>
</div>
<div className='item__info'>
<p>Ваше резюме<br/><span>заполнено</span></p>
<div className='item__infoLink'>
<img src={rightArrow} alt='arrow'/>
</div>
</div>
</Link>
<Link to={'/profile'} className='item'>
<div className='item__about'>
<img src={timerIcon} alt='timer'/>
<h3>Трекер времени</h3>
</div>
<div className='item__info'>
<p>Сколько времени занимает<br/> выполнение задач</p>
<div className='item__infoLink'>
<img src={rightArrow} alt='arrow'/>
</div>
</div>
</Link>
<Link to={'/profile'} className='item'>
<div className='item__about'>
<img src={paymentIcon} alt='payment'/>
<h3>Выплаты</h3>
</div>
<div className='item__info'>
<p>У вас <span>подтвержден</span><br/> статус самозанятого</p>
<div className='item__infoLink'>
<img src={rightArrow} alt='arrow'/>
</div>
</div>
</Link>
<Link to={'/profile'} className='item'>
<div className='item__about'>
<img src={settingIcon} alt='settings'/>
<h3>Настройки аккаунта</h3>
</div>
<div className='item__info'>
<p>Перейдите чтобы начать<br/> редактирование</p>
<div className='item__infoLink'>
<img src={rightArrow} alt='arrow'/>
</div>
</div>
</Link>
</div>
</div>
<Footer/>
</div>
)
};

View File

@ -49,6 +49,12 @@
border-radius: 12px; border-radius: 12px;
text-decoration: none; text-decoration: none;
cursor: pointer; 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) { @media (max-width: 1175px) {
width: 48%; width: 48%;

View File

@ -3,7 +3,7 @@ import { WithLogout } from '../hoc/withLogout';
import { ProfileCalendar } from '../../src/components/ProfileCalendar/ProfileCalendar'; import { ProfileCalendar } from '../../src/components/ProfileCalendar/ProfileCalendar';
const ProfileCalendarPage = () => { const ProfileCalendarPage = () => {
return <WithLogout><ProfileCalendar/></WithLogout>; return <ProfileCalendar/>;
}; };
export default ProfileCalendarPage; export default ProfileCalendarPage;

View File

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

View File

@ -121,6 +121,12 @@
line-height: 32px; line-height: 32px;
color: white; color: white;
border: none; border: none;
transition: all 0.3s ease;
&:hover {
box-shadow: 6px 5px 20px rgb(87 98 80 / 21%);
transform: scale(1.02);
}
@media (max-width: 690px) { @media (max-width: 690px) {
width: 120px; width: 120px;
@ -257,6 +263,12 @@
background: #FFFFFF; background: #FFFFFF;
border-radius: 12px; border-radius: 12px;
padding: 35px 30px 30px 45px; padding: 35px 30px 30px 45px;
transition: all 0.3s ease;
&:hover {
box-shadow: 6px 5px 20px rgb(87 98 80 / 21%);
transform: scale(1.02);
}
@media (max-width: 825px) { @media (max-width: 825px) {
width: 100%; width: 100%;