327 lines
11 KiB
React
Raw Normal View History

2023-05-31 08:36:15 +03:00
import ru from "date-fns/locale/ru";
import React, { useEffect, useState } from "react";
import DatePicker, { registerLocale } from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
2023-05-24 15:34:43 +03:00
import { useSelector } from "react-redux";
import { Link, Navigate, useNavigate } from "react-router-dom";
2023-05-31 08:36:15 +03:00
import { getReportDate } from "@redux/reportSlice";
2023-05-30 10:10:34 +03:00
import { apiRequest } from "@api/request";
2023-05-31 08:36:15 +03:00
import { Footer } from "@components/Common/Footer/Footer";
import { Loader } from "@components/Common/Loader/Loader";
2023-05-30 10:10:34 +03:00
import { Navigation } from "@components/Navigation/Navigation";
2023-05-31 08:36:15 +03:00
import { ProfileBreadcrumbs } from "@components/ProfileBreadcrumbs/ProfileBreadcrumbs";
import { ProfileHeader } from "@components/ProfileHeader/ProfileHeader";
2023-05-31 08:36:15 +03:00
import arrow from "assets/icons/arrows/left-arrow.png";
2023-05-30 10:10:34 +03:00
import calendarIcon from "assets/icons/calendar.svg";
import ellipse from "assets/icons/ellipse.png";
import remove from "assets/icons/remove.svg";
2023-05-31 08:36:15 +03:00
import {
getCorrectDate,
getCreatedDate,
hourOfNum,
} from "../Calendar/calendarHelper";
2023-05-24 15:34:43 +03:00
import "./reportForm.scss";
2023-05-31 08:36:15 +03:00
registerLocale("ru", ru);
2021-06-21 17:41:26 +03:00
const ReportForm = () => {
2023-05-24 15:34:43 +03:00
if (localStorage.getItem("role_status") === "18") {
return <Navigate to="/profile" replace />;
2023-02-27 16:50:32 +03:00
}
2023-05-24 15:34:43 +03:00
const navigate = useNavigate();
2023-01-09 20:53:23 +03:00
const reportDate = useSelector(getReportDate);
2022-10-19 15:41:11 +03:00
2023-02-07 15:11:11 +03:00
useEffect(() => {
2023-05-24 15:34:43 +03:00
initListeners();
}, []);
2023-02-07 15:11:11 +03:00
2023-01-09 20:53:23 +03:00
const [isFetching, setIsFetching] = useState(false);
2023-05-24 15:34:43 +03:00
const [reportSuccess, setReportSuccess] = useState("");
const [startDate, setStartDate] = useState(
2023-12-04 18:01:04 +03:00
reportDate ? new Date(reportDate._d) : new Date(),
2023-05-24 15:34:43 +03:00
);
2023-02-07 15:11:11 +03:00
const [datePickerOpen, setDatePickerOpen] = useState(false);
2021-06-22 18:00:52 +03:00
2023-05-24 15:34:43 +03:00
const [inputs, setInputs] = useState([
{ task: "", hours_spent: "", minutes_spent: 0 },
]);
const [troublesInputValue, setTroublesInputValue] = useState("");
const [scheduledInputValue, setScheduledInputValue] = useState("");
2021-06-22 18:00:52 +03:00
2021-11-30 16:00:58 +02:00
const addInput = () => {
2023-05-24 15:34:43 +03:00
setInputs((prev) => [
...prev,
{ task: "", hours_spent: "", minutes_spent: 0 },
]);
2023-01-09 20:53:23 +03:00
};
2021-06-22 18:00:52 +03:00
2023-02-07 15:11:11 +03:00
const initListeners = () => {
2023-05-24 15:34:43 +03:00
document.addEventListener("click", closeByClickingOut);
};
2023-02-07 15:11:11 +03:00
const closeByClickingOut = (event) => {
2023-05-24 15:34:43 +03:00
const path = event.path || (event.composedPath && event.composedPath());
2023-02-07 15:11:11 +03:00
2023-05-24 15:34:43 +03:00
if (
event &&
!path.find(
(div) =>
div.classList &&
(div.classList.contains("report-form__block-img") ||
2023-12-04 18:01:04 +03:00
div.classList.contains("react-datepicker-popper")),
2023-05-24 15:34:43 +03:00
)
) {
setDatePickerOpen(false);
2023-02-07 15:11:11 +03:00
}
2023-05-24 15:34:43 +03:00
};
2023-02-07 15:11:11 +03:00
2023-01-09 20:53:23 +03:00
const totalHours = inputs.reduce((a, b) => a + b.hours_spent, 0);
2022-10-19 15:41:11 +03:00
2021-11-30 16:00:58 +02:00
const deleteInput = (indexRemove) => {
2023-05-24 15:34:43 +03:00
setInputs((prev) => prev.filter((el, index) => index !== indexRemove));
2023-01-09 20:53:23 +03:00
};
2021-06-22 18:00:52 +03:00
const handler = () => {
2023-03-01 00:28:58 +03:00
for (let input of inputs) {
2023-05-24 15:34:43 +03:00
if (!input.task || !input.hours_spent) {
setReportSuccess("Заполните задачи");
setTimeout(() => setReportSuccess(""), 2000);
return;
2023-03-01 00:28:58 +03:00
}
2023-01-24 19:11:24 +03:00
}
2023-05-24 15:34:43 +03:00
apiRequest("/reports/create", {
method: "POST",
data: {
tasks: inputs,
difficulties: troublesInputValue,
tomorrow: scheduledInputValue,
2023-02-07 15:11:11 +03:00
created_at: getCreatedDate(startDate),
status: 1,
},
2023-05-31 11:24:46 +03:00
}).then(() => {
2023-05-24 15:34:43 +03:00
setReportSuccess("Отчет отправлен");
2023-01-24 19:11:24 +03:00
setTimeout(() => {
2023-05-24 15:34:43 +03:00
setReportSuccess("");
navigate("/profile/calendar");
}, 1000);
setInputs(() => []);
2023-05-24 15:34:43 +03:00
setTroublesInputValue("");
setScheduledInputValue("");
setIsFetching(false);
2023-05-24 15:34:43 +03:00
setInputs(() => [{ task: "", hours_spent: "", minutes_spent: 0 }]);
});
};
2021-06-21 17:41:26 +03:00
return (
2023-05-24 15:34:43 +03:00
<section className="report-form">
<ProfileHeader />
<Navigation />
<div className="container">
<ProfileBreadcrumbs
links={[
{ name: "Главная", link: "/profile" },
{ name: "Ваша отчетность", link: "/profile/calendar" },
{ name: "Страница добавления нового отчета", link: "/report" },
]}
/>
<h2 className="summary__title">
Ваши отчеты - <span>добавить отчет</span>
</h2>
<div>
<div className="report__head">
<Link className="calendar__back" to={`/profile/calendar`}>
<img src={arrow} alt="" />
<p>Вернуться</p>
</Link>
2023-01-13 15:53:07 +03:00
</div>
2023-05-24 15:34:43 +03:00
</div>
2023-01-13 15:53:07 +03:00
2023-05-24 15:34:43 +03:00
<div className="report-form__content">
<div className="report-form__block">
<div className="report-form__block-title">
<h2>Добавление отчета за день</h2>
<h3>Дата заполнения отчета:</h3>
</div>
<div
className="report-form__block-img"
onClick={() => setDatePickerOpen(true)}
>
<img
className="report-form__calendar-icon"
src={calendarIcon}
alt=""
2023-02-07 15:11:11 +03:00
/>
2023-05-24 15:34:43 +03:00
{getCorrectDate(startDate)}
</div>
<DatePicker
className="datePicker"
open={datePickerOpen}
locale="ru"
selected={startDate}
onChange={(date) => {
setDatePickerOpen(false);
setStartDate(date);
}}
/>
<div className="report-form__task-list">
<img src={ellipse} alt="" />
<span>Какие задачи были выполнены?</span>
2021-06-21 17:41:26 +03:00
</div>
2023-05-24 15:34:43 +03:00
</div>
2021-06-22 18:00:52 +03:00
2023-05-24 15:34:43 +03:00
<div className="row">
<div className="col-8">
<div className="report-form__task-header">
<p className="report-form__task-title--description">
Краткое описание задачи
</p>
<p className="report-form__task-title--hours">
Количество часов
</p>
</div>
2021-11-30 16:00:58 +02:00
2023-05-24 15:34:43 +03:00
{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
value={inputs[index].task}
className={
!input.task && reportSuccess === "Заполните задачи"
? "checkTask"
: ""
}
name="text"
type="text"
onChange={(e) =>
setInputs(
inputs.map((input, inputIndex) => {
return index === inputIndex
? {
...input,
task: e.target.value,
}
: input;
2023-12-04 18:01:04 +03:00
}),
2023-05-24 15:34:43 +03:00
)
}
/>
</div>
<div className="report-form__task-input report-form__task-input--hours">
<input
value={inputs[index].hours_spent}
className={
!input.hours_spent &&
reportSuccess === "Заполните задачи"
? "checkTask"
: ""
}
name="number"
type="number"
min="1"
onChange={(e) =>
setInputs(
inputs.map((input, inputIndex) => {
return index === inputIndex
2023-01-13 15:53:07 +03:00
? {
2023-05-24 15:34:43 +03:00
...input,
hours_spent: Number(e.target.value),
}
: input;
2023-12-04 18:01:04 +03:00
}),
2023-05-24 15:34:43 +03:00
)
2023-02-17 15:19:49 +03:00
}
2023-05-24 15:34:43 +03:00
/>
</div>
{index > 0 && (
<div className="report-form__task-remove">
<img
onClick={() => deleteInput(index)}
src={remove}
alt=""
/>
</div>
)}
</form>
);
})}
2021-11-30 16:00:58 +02:00
2023-05-24 15:34:43 +03:00
<div className="report-form__form-add">
<p className="addMore" onClick={addInput}>
+
</p>
2023-12-04 18:00:12 +03:00
<span>Добавить ещё</span>
2023-01-13 15:53:07 +03:00
</div>
2023-01-09 20:53:23 +03:00
</div>
2023-05-24 15:34:43 +03:00
</div>
2021-06-22 18:00:52 +03:00
2023-05-24 15:34:43 +03:00
<div className="row">
<div className="col-12">
<div className="report-form__input-box">
<div className="report-form__troubles">
<img src={ellipse} alt="" />
<span>Какие сложности возникли?</span>
</div>
<input
type="text"
value={troublesInputValue}
onChange={(e) => setTroublesInputValue(e.target.value)}
/>
<div className="report-form__scheduled">
<img src={ellipse} alt="" />
<span>Что планируется сделать завтра?</span>
</div>
<input
type="text"
value={scheduledInputValue}
onChange={(e) => setScheduledInputValue(e.target.value)}
/>
2023-01-09 20:53:23 +03:00
</div>
</div>
2021-06-22 18:00:52 +03:00
</div>
2023-05-24 15:34:43 +03:00
<div className="row">
<div className="col-12">
<div className="report-form__footer">
<button
className="report-form__footer-btn"
onClick={() => handler()}
>
{isFetching ? <Loader /> : "Отправить"}
</button>
<p className="report-form__footer-text">
Всего за день :{" "}
<span>
{totalHours} {hourOfNum(totalHours)}
</span>
</p>
{reportSuccess && (
<p
className={`report-form__footer-done ${
reportSuccess === "Заполните задачи" ? "errorText" : ""
}`}
>
{reportSuccess}
</p>
)}
</div>
2023-01-09 20:53:23 +03:00
</div>
2021-06-22 18:00:52 +03:00
</div>
</div>
2023-05-24 15:34:43 +03:00
</div>
<Footer />
</section>
);
2023-01-09 20:53:23 +03:00
};
2021-06-21 17:41:26 +03:00
2023-05-24 15:34:43 +03:00
export default ReportForm;