diff --git a/src/App.js b/src/App.js
index b70c438c..d00ea2fe 100644
--- a/src/App.js
+++ b/src/App.js
@@ -18,6 +18,7 @@ import {InstructionPage} from './pages/quiz/InstructionPage'
import {ResultPage} from './pages/quiz/ResultPage'
import {Profile} from './pages/Profile/Profile.js'
import {Summary} from './pages/Summary/Summary'
+import {ViewReport} from './pages/ViewReport/ViewReport'
import './fonts/stylesheet.css'
import 'bootstrap/dist/css/bootstrap.min.css'
@@ -56,6 +57,7 @@ const App = () => {
}/>
}/>
}/>
+ }/>
}/>
diff --git a/src/components/ProfileCalendar/ProfileCalendar.js b/src/components/ProfileCalendar/ProfileCalendar.js
index fbbe1232..dd40b413 100644
--- a/src/components/ProfileCalendar/ProfileCalendar.js
+++ b/src/components/ProfileCalendar/ProfileCalendar.js
@@ -1,13 +1,14 @@
import React, { useEffect, useState } from 'react'
import {useDispatch, useSelector} from 'react-redux'
+import {currentMonth, getReports} from '../Calendar/calendarHelper'
import { Link } from 'react-router-dom'
import moment from "moment";
-import {currentMonth, getReports} from '../Calendar/calendarHelper'
import {ProfileCalendarComponent} from "./ProfileCalendarComponent";
-import { Footer } from '../Footer/Footer'
+import {Loader} from "../Loader/Loader";
import {ProfileHeader} from "../ProfileHeader/ProfileHeader";
+import { Footer } from '../Footer/Footer'
import {urlForLocal} from "../../helper";
@@ -25,6 +26,7 @@ export const ProfileCalendar = () => {
const [reports, setReports] = useState([]);
const [totalHours, setTotalHours] = useState(0);
const [requestDates, setRequestDates] = useState('');
+ const [loader, setLoader] = useState(false)
useEffect(() => {
@@ -32,19 +34,23 @@ export const ProfileCalendar = () => {
},[]);
useEffect( () => {
+ setLoader(true)
if (!requestDates) {
return
}
- apiRequest(`/reports/reports-by-date?${requestDates}&user_id=${localStorage.getItem('id')}`)
+ apiRequest(`/reports/reports-by-date?${requestDates}&user_card_id=${localStorage.getItem('cardId')}`)
.then((reports) => {
let spendTime = 0;
- reports.map((report) => {
- if (report.spendTime) {
- spendTime += Number(report.spendTime)
- }
- });
+ for (const report of reports) {
+ report.task.map((task) => {
+ if(task.hours_spent) {
+ spendTime += Number(task.hours_spent)
+ }
+ })
+ }
setTotalHours(spendTime);
setReports(reports)
+ setLoader(false)
})
}, [requestDates]);
@@ -68,14 +74,18 @@ export const ProfileCalendar = () => {
}}>Заполнить отчет за день
-
-
-
-
- {month} : {totalHours} часов
-
+ {loader ?
+
+ :
+
+
+
+
+ {month} : {totalHours} часов
+
+
-
+ }
diff --git a/src/components/ProfileCalendar/ProfileCalendarComponent.js b/src/components/ProfileCalendar/ProfileCalendarComponent.js
index b2307e14..2c574863 100644
--- a/src/components/ProfileCalendar/ProfileCalendarComponent.js
+++ b/src/components/ProfileCalendar/ProfileCalendarComponent.js
@@ -37,7 +37,7 @@ export const ProfileCalendarComponent = ({reportsDates}) => {
function dayStyles(day) {
if (value < day) return `block`
for (const date of reportsDates) {
- if (`${new Date(day).getFullYear()}-${correctDay(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.created_at) {
return `before`
}
}
@@ -48,8 +48,8 @@ export const ProfileCalendarComponent = ({reportsDates}) => {
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`
+ if (`${new Date(day).getFullYear()}-${correctDay(new Date(day).getMonth() + 1)}-${correctDay(new Date(day).getDate())}` === date.created_at) {
+ return `../view`
}
}
return '../../report'
diff --git a/src/components/ProfileCalendar/profileCalendar.scss b/src/components/ProfileCalendar/profileCalendar.scss
index 45d98c4e..d9101e99 100644
--- a/src/components/ProfileCalendar/profileCalendar.scss
+++ b/src/components/ProfileCalendar/profileCalendar.scss
@@ -16,6 +16,15 @@
.summary__info {
padding-right: 25px;
}
+
+ .loader {
+ margin: 20px 0 50px;
+ &:hover {
+ path {
+ fill: #ffffff;
+ }
+ }
+ }
.profile__calendar {
margin-top: 20px;
}
diff --git a/src/components/ReportForm/ReportForm.js b/src/components/ReportForm/ReportForm.js
index 70756a05..7c8bbda1 100644
--- a/src/components/ReportForm/ReportForm.js
+++ b/src/components/ReportForm/ReportForm.js
@@ -1,6 +1,6 @@
import React, {useState} from 'react'
import {useSelector} from 'react-redux'
-import {Link} from 'react-router-dom'
+import {Link, useNavigate} from 'react-router-dom'
import {Loader} from '../Loader/Loader'
import {currentMonthAndDay} from '../Calendar/calendarHelper'
@@ -33,10 +33,11 @@ const getCreatedDate = (day) => {
};
const ReportForm = () => {
+ const navigate= useNavigate();
const reportDate = useSelector(getReportDate);
const [isFetching, setIsFetching] = useState(false);
- const [reportSuccess, setReportSuccess] = useState(false);
+ const [reportSuccess, setReportSuccess] = useState('');
const [inputs, setInputs] = useState([{task: '', hours_spent: '', minutes_spent: 0}]);
const [troublesInputValue, setTroublesInputValue] = useState('');
@@ -55,6 +56,11 @@ const ReportForm = () => {
};
const handler = () => {
+ if(!inputs[0].task) {
+ setReportSuccess('Заполните задачи');
+ setTimeout(() => setReportSuccess(''), 1000)
+ return
+ }
apiRequest('/reports/create', {
method: 'POST',
data: {
@@ -65,10 +71,11 @@ const ReportForm = () => {
status: 1,
},
}).then((res) => {
- if (res.status === 200) {
- setReportSuccess(true);
- setTimeout(() => setReportSuccess(false), 2000)
- }
+ setReportSuccess('Отчет отправлен');
+ setTimeout(() => {
+ setReportSuccess('')
+ navigate('/profile/calendar');
+ }, 1000)
setInputs(() => []);
setTroublesInputValue('');
setScheduledInputValue('');
@@ -188,7 +195,7 @@ const ReportForm = () => {
Всего за день : {totalHours} часов
{reportSuccess &&
- Отчет отправлен
+ {reportSuccess}
}
diff --git a/src/components/ReportForm/reportForm.scss b/src/components/ReportForm/reportForm.scss
index 71d62d02..89ca5205 100644
--- a/src/components/ReportForm/reportForm.scss
+++ b/src/components/ReportForm/reportForm.scss
@@ -314,6 +314,11 @@
font-weight: 500;
margin-left: 20px;
}
+
+ .errorText {
+ color: #bf3c3c;
+ font-weight: 600;
+ }
}
&__form {
diff --git a/src/hooks/useRequest.js b/src/hooks/useRequest.js
new file mode 100644
index 00000000..e69de29b
diff --git a/src/images/arrowViewReport.png b/src/images/arrowViewReport.png
new file mode 100644
index 00000000..5730f025
Binary files /dev/null and b/src/images/arrowViewReport.png differ
diff --git a/src/images/arrowViewReport.svg b/src/images/arrowViewReport.svg
new file mode 100644
index 00000000..80de657d
--- /dev/null
+++ b/src/images/arrowViewReport.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/pages/Summary/Summary.js b/src/pages/Summary/Summary.js
index 36c645b3..4e4e4f43 100644
--- a/src/pages/Summary/Summary.js
+++ b/src/pages/Summary/Summary.js
@@ -67,7 +67,7 @@ export const Summary = () => {
- {gitInfo.length && gitInfo.map((itemGit) => {
+ {Boolean(gitInfo.length) && gitInfo.map((itemGit) => {
return
diff --git a/src/pages/ViewReport/ViewReport.js b/src/pages/ViewReport/ViewReport.js
new file mode 100644
index 00000000..7a601274
--- /dev/null
+++ b/src/pages/ViewReport/ViewReport.js
@@ -0,0 +1,175 @@
+import React, {useEffect, useState} from 'react'
+import {Link} from "react-router-dom";
+import {useRequest} from "../../hooks/useRequest";
+import {useSelector} from "react-redux";
+import {getReportDate} from "../../redux/reportSlice";
+import SVG from 'react-inlinesvg'
+
+import {Loader} from "../../components/Loader/Loader"
+import {ProfileHeader} from "../../components/ProfileHeader/ProfileHeader";
+import {Footer} from "../../components/Footer/Footer";
+
+import arrow from "../../images/right-arrow.png";
+import arrowSwitchDate from "../../images/arrowViewReport.png";
+
+import './viewReport.scss'
+
+export const ViewReport = () => {
+ const getCreatedDate = (day) => {
+ if (day) {
+ return `${new Date(day).getFullYear()}-${new Date(day).getMonth() + 1}-${new Date(day).getDate()}`
+ } else {
+ const date = new Date();
+ const dd = String(date.getDate()).padStart(2, '0');
+ const mm = String(date.getMonth() + 1).padStart(2, '0');
+ const yyyy = date.getFullYear();
+ return `${yyyy}-${mm}-${dd}`
+ }
+ };
+ const {apiRequest} = useRequest();
+ const reportDate = useSelector(getReportDate);
+
+ const [taskText, setTaskText] = useState([]);
+ const [difficulties, setDifficulties] = useState([])
+ const [tomorrowTask, setTomorrowTask] = useState([])
+ const [totalHours, setTotalHours] = useState(0);
+ const [reportDay] = useState(new Date (getCreatedDate(reportDate)))
+ const [currentDay] = useState(new Date ())
+ const [loader, setLoader] = useState(false)
+
+ function getReportFromDate(day) {
+ setLoader(true)
+ setTaskText([])
+ setDifficulties([])
+ setTomorrowTask([])
+ apiRequest(`reports/find-by-date?user_card_id=${localStorage.getItem('cardId')}&date=${day}`)
+ .then(res => {
+ let spendTime = 0
+ for (const item of res) {
+ if(item.difficulties) {
+ setDifficulties(prevArray => [...prevArray, item.difficulties])
+ }
+ if(item.tomorrow) {
+ setTomorrowTask(prevArray => [...prevArray, item.tomorrow])
+ }
+ item.task.map((task) => {
+ const taskInfo = {
+ hours: task.hours_spent,
+ task: task.task,
+ id: task.id
+ }
+ if(task.hours_spent) {
+ spendTime += Number(task.hours_spent)
+ }
+ setTaskText(prevArray => [...prevArray, taskInfo])
+ })
+ }
+ setTotalHours(spendTime)
+ setLoader(false)
+ })
+ }
+
+ function nextDay() {
+ reportDay.setDate(reportDay.getDate() + 1);
+ getReportFromDate(getCreatedDate(reportDay))
+ }
+
+ function previousDay() {
+ reportDay.setDate(reportDay.getDate() - 1);
+ getReportFromDate(getCreatedDate(reportDay))
+ }
+
+ useEffect(() => {
+ getReportFromDate(getCreatedDate(reportDate))
+ }, []);
+ return (
+
+
+
+
+
Ваши отчеты - просмотр отчета за день
+
+
Вернуться
+
+
+
{getCreatedDate(reportDay)}
+
Вами потрачено на работу : {totalHours} часов
+ {/*
*/}
+ {/* */}
+ {/*
*/}
+ {/*
122 часа из 160
*/}
+
+
+
+
previousDay()}>
+
+
+
{getCreatedDate(reportDay)}
+
nextDay()}>
+
+
+
+ {loader &&
+
+ }
+ {Boolean(taskText.length) &&
+
+
+
+
+
+ Какие задачи были выполнены? |
+ Время |
+
+
+
+ {taskText.length && taskText.map((task) => {
+ return
+
+ {task.task}
+ |
+
+
+ {task.hours}
+ часа на задачу
+
+ |
+
+ })}
+
+ |
+ Всего: {totalHours} часов |
+
+
+
+
+ {Boolean(difficulties.length) &&
+
+
Какие сложности возникли?
+ {difficulties.map((item, index) => {
+ return
{item}
+ }
+ )}
+
+ }
+ {Boolean(tomorrowTask.length) &&
+
+
Что планируется сделать завтра?
+ {tomorrowTask.map((item, index) => {
+ return
{item}
+ }
+ )}
+
+ }
+
+ }
+ {!Boolean(taskText.length) && !loader &&
+
+
В этот день вы не заполняли отчет
+
+ }
+
+
+
+ )
+};
diff --git a/src/pages/ViewReport/viewReport.scss b/src/pages/ViewReport/viewReport.scss
new file mode 100644
index 00000000..f4ec5da6
--- /dev/null
+++ b/src/pages/ViewReport/viewReport.scss
@@ -0,0 +1,308 @@
+.viewReport {
+ 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;
+ }
+ }
+
+ &__info {
+ display: flex;
+ flex-direction: column;
+ margin-top: 23px;
+ }
+
+ &__title {
+ font-weight: 700;
+ font-size: 22px;
+ line-height: 32px;
+ color: #000000;
+ span {
+ color: #52B709;
+ }
+ }
+
+ &__back {
+ display: flex;
+ align-items: center;
+ column-gap: 30px;
+ margin-top: 20px;
+ cursor: pointer;
+
+ &:hover {
+ text-decoration: none;
+ }
+ p {
+ margin-bottom: 0;
+ font-weight: 400;
+ font-size: 14px;
+ line-height: 32px;
+ color: #000000;
+ text-decoration: none;
+ }
+ }
+
+ &__bar {
+ display: flex;
+ margin-top: 20px;
+ background: #FFFFFF;
+ border-radius: 12px;
+ padding: 20px 33px;
+ align-items: center;
+ column-gap: 60px;
+ height: 72px;
+ justify-content: space-between;
+
+ &__date {
+ font-weight: 500;
+ font-size: 22px;
+ line-height: 32px;
+ color: #000000;
+ }
+
+ &__hours {
+ font-weight: 400;
+ font-size: 12px;
+ line-height: 32px;
+ color: #000000;
+
+ span {
+ color: #52B709;
+ font-weight: 700;
+ }
+ }
+
+ &__progressBar {
+ max-width: 390px;
+ width: 100%;
+ background: #F1F1F1;
+ border-radius: 12px;
+ height: 8px;
+ position: relative;
+
+ span {
+ position: absolute;
+ height: 100%;
+ left: 0;
+ width: 60%;
+ background: #52B709;
+ border-radius: 12px;
+ }
+ }
+
+ &__total {
+ font-weight: 400;
+ font-size: 12px;
+ line-height: 32px;
+ }
+
+ }
+
+ h3 {
+ margin-bottom: 0;
+ }
+
+ p {
+ margin-bottom: 0;
+ }
+
+ &__switchDate {
+ display: flex;
+ margin: 30px 0;
+ justify-content: center;
+ column-gap: 140px;
+ align-items: center;
+
+ p {
+ font-weight: 400;
+ font-size: 18px;
+ line-height: 32px;
+ color: #000000;
+ }
+
+ .switchDate {
+ width: 48px;
+ height: 48px;
+ background: #8DC63F;
+ border-radius: 50px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ cursor: pointer;
+
+ img {
+ margin-left: 3px;
+ }
+ }
+
+ &__prev {
+ transform: rotate(180deg);
+ }
+ }
+
+ .disable {
+ pointer-events: none;
+ opacity: 0.3;
+ }
+
+ .loader {
+ &:hover {
+ path {
+ fill: #ffffff;
+ }
+ }
+ }
+
+ .table__container {
+ margin: 0 -28px;
+ overflow: hidden;
+ position: relative;
+ }
+
+ &__done {
+ width: 100%;
+ border-collapse: separate;
+ border-spacing: 28px 0;
+
+ th {
+ padding: 32px 40px;
+ background: white;
+ border-radius: 12px 12px 0 0;
+ font-weight: 500;
+ font-size: 22px;
+ line-height: 32px;
+ color: #000000;
+ }
+
+ td {
+ padding: 15px 40px;
+ background: white;
+
+ p {
+ font-weight: 400;
+ font-size: 12px;
+ line-height: 24px;
+ color: #000000;
+ }
+ }
+
+ tr:last-child {
+ td {
+ border-radius: 0 0 12px 12px;
+ }
+
+ td:last-child {
+ font-weight: 500;
+ font-size: 17px;
+ line-height: 32px;
+ color: #000000;
+ }
+ }
+
+ &__hours {
+ width: 25%;
+ background: #FFFFFF;
+ border-radius: 12px;
+ padding: 32px 40px 18px;
+ display: flex;
+ flex-direction: column;
+ row-gap: 30px;
+
+ h3 {
+ font-weight: 500;
+ font-size: 22px;
+ line-height: 32px;
+ color: #000000;
+ }
+
+ &__item {
+ display: flex;
+ column-gap: 25px;
+ align-items: center;
+ min-width: 155px;
+
+ span {
+ width: 48px;
+ height: 48px;
+ background: #8DC63F;
+ border-radius: 50px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-weight: 700;
+ font-size: 22px;
+ line-height: 32px;
+ color: #000000;
+ }
+
+ p {
+ font-weight: 400;
+ font-size: 12px;
+ line-height: 32px;
+ }
+ }
+
+ &__total {
+ font-weight: 500;
+ font-size: 17px;
+ line-height: 32px;
+ }
+ }
+ }
+
+ &__item {
+ display: flex;
+ flex-direction: column;
+ row-gap: 22px;
+ background: #FFFFFF;
+ border-radius: 12px;
+ margin: 25px 0;
+ padding: 25px 35px;
+
+ h3 {
+ font-weight: 500;
+ font-size: 22px;
+ line-height: 32px;
+ }
+
+ p {
+ font-weight: 400;
+ font-size: 12px;
+ line-height: 24px;
+ }
+ }
+
+ &__item:last-child {
+ margin-bottom: 0;
+ }
+
+ &__noTask {
+ padding: 25px 10px;
+ background: #FFFFFF;
+ border-radius: 12px;
+ text-align: center;
+
+ p {
+ font-weight: 400;
+ font-size: 22px;
+ line-height: 32px;
+ color: #000000;
+
+ span {
+ color: #8BCC60;
+ font-weight: 500;
+ }
+ }
+ }
+
+ footer {
+ margin-top: 70px;
+ }
+}