Commit 91e2ce16 authored by Ermolaev Timur's avatar Ermolaev Timur

Merge branch 'task-35-enhance/optimize-code' into 'development'

Task 35 enhance/optimize code

See merge request !20
parents f89b7a3f f5e10dd8
import { Grid } from "@mui/material";
import { memo } from "react";
const CalendarRow = ({children}) => {
return <>
......@@ -12,6 +13,6 @@ const CalendarRow = ({children}) => {
</>
};
export default CalendarRow;
export default memo(CalendarRow);
import { Grid } from "@mui/material";
import { memo } from "react";
const CalendarSmallCell = ({children, xs}) => {
return <>
......@@ -8,4 +9,4 @@ const CalendarSmallCell = ({children, xs}) => {
</>
};
export default CalendarSmallCell;
\ No newline at end of file
export default memo(CalendarSmallCell);
\ No newline at end of file
import { Grid, TextField, Typography } from "@mui/material";
import { useEffect, useState } from "react";
import { memo, useEffect, useState } from "react";
const CalendarStandartCell = ({children, xs, currentTask, hours, dayNumber, createTaskInCellHandler, handleOpen, modal}) => {
const CalendarStandartCell = ({children, xs, hours, dayNumber, createTaskInCellHandler, handleOpen, modal}) => {
const [isThisCell, setIsThisCell] = useState(false)
useEffect(()=>{
if(!modal) {
......@@ -19,11 +19,14 @@ const CalendarStandartCell = ({children, xs, currentTask, hours, dayNumber, cre
sx={{backgroundColor: 'lightgreen', padding: '10px', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis'}}
>
<span>
{currentTask.title}
Задача
</span>
</Grid> : null}
</Grid>
</>
};
export default CalendarStandartCell;
\ No newline at end of file
export default memo(CalendarStandartCell, (prevProps, nextProps)=>{
if(!prevProps.modal) return false
if(nextProps.modal) return true
});
\ No newline at end of file
import { Grid, TextField, Typography } from "@mui/material";
import React, { useEffect, useState } from "react";
import React, { memo, useState, useEffect} from "react";
const CalendarTask = ({year, month, tasks, day, hours, setCurrentTask, hourFormat, handleOpen, currentTask}) => {
const [thisCellCurrentTask, setThisCellCurrentTask] = useState({})
......@@ -27,20 +27,13 @@ const CalendarTask = ({year, month, tasks, day, hours, setCurrentTask, hourForma
return tasksCell
}
const tasksCell = getTaskInDayCell(tasks, day, hours)
useEffect(()=>{
if (!currentTask.title) {
setThisCellCurrentTask({})
}
}, [currentTask])
const renderText = (i, task) => {
if (thisCellCurrentTask && i === thisCellCurrentTask.i) {
return (<>{currentTask.title}</>)
} else {
return (<>{task.title}</>)
}
}
return (<>
{tasksCell.length ? tasksCell.map((task, i)=>
......@@ -49,9 +42,9 @@ const CalendarTask = ({year, month, tasks, day, hours, setCurrentTask, hourForma
<Grid
key={task.id}
sx={{backgroundColor: 'lightgreen', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', padding: '10px', borderBottom: '1px solid rgb(29, 161, 51);;'}}
onClick={(e)=>{e.stopPropagation(); setCurrentTask(task); handleOpen(e); setThisCellCurrentTask({...task, i: i})}}
onClick={(e)=>{e.stopPropagation(); setCurrentTask(task); handleOpen(e)}}
>
{renderText(i, task)}
{task.title}
</Grid>
)}
)
......@@ -59,4 +52,4 @@ const CalendarTask = ({year, month, tasks, day, hours, setCurrentTask, hourForma
</>)
};
export default CalendarTask;
\ No newline at end of file
export default memo(CalendarTask);
\ No newline at end of file
import { FormControlLabel, Switch} from "@mui/material";
import { useEffect, useState } from "react";
import { memo, useEffect, useState } from "react";
import CalendarRow from "./CalendarRow/CalendarRow";
import CalendarSmallCell from "./CalendarSmallCell/CalendarSmallCell";
import CalendarStandartCell from "./CalendarStandartCell.js/CalendarStandartCell";
......@@ -7,11 +7,8 @@ import CalendarTask from "./CalendarTask/CalendarTask";
import ModalTask from "../UI/ModalTask/ModalTask";
import MonthCalendarModalContent from "../MonthCalendarModalContent/MonthCalendarModalContent";
function MonthCalendarBody({month, year, tasks, createTaskInCellHandler, currentTask, setCurrentTask, hourFormat, setHourFormat, onChangeCurrentTaskHandler, sendNewTaskHandler, deleteTaskHandler}) {
const [hoursInDay, setHoursInDay] = useState(['8:00', '10:00', '12:00', '14:00', '16:00', '18:00', '20:00', '22:00'])
const [daysInMonth, setDaysInMonth] = useState([])
const [cellSizes, setCellSizes] = useState({})
function MonthCalendarBody({month, year, tasks, createTaskInCellHandler, currentTask, setCurrentTask, hourFormat, setHourFormat, onChangeCurrentTaskHandler, sendNewTaskHandler, deleteTaskHandler, cellSizes, hoursInDay, daysInMonth}) {
const [modal, setModal] = useState({open:false, y: 0, x: 0,});
const handleOpen = (e) => {
setModal( {
......@@ -30,58 +27,6 @@ function MonthCalendarBody({month, year, tasks, createTaskInCellHandler, current
};
useEffect(()=>{
const cells = hoursInDay.length
const xs = 10.8/cells
setCellSizes(()=>{
return {smallCell: 0.6, standarCell: xs}
})
}, [])
useEffect(()=>{
if (hourFormat) {
const arr = ['8:00', '9:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00', '19:00', '20:00','21:00','22:00']
const cells = arr.length
const xs = 10.8/cells
setCellSizes(()=>{
return {smallCell: 0.6, standarCell: xs}
})
setHoursInDay(()=>arr)
} else {
const arr = ['8:00', '10:00', '12:00', '14:00', '16:00', '18:00', '20:00', '22:00']
const cells = arr.length
const xs = 10.8/cells
setCellSizes(()=>{
return {smallCell: 0.6, standarCell: xs}
})
setHoursInDay(()=>arr)
}
}, [hourFormat])
useEffect(()=>{
setNewMonthDays()
}, [month])
const getDaysInMonth = () => {
return new Date(year, month + 1, 0).getDate();
}
const getDayOfWeekString = (day) => {
return ["ВС","ПН","ВТ","СР","ЧТ","ПТ","СБ"][day];
}
const getDayOfWeekNumber = (day) => {
return new Date(year, month, day).getDay()
}
const setNewMonthDays = () => {
const newDaysInMonth = []
for (let i = 1; i <= getDaysInMonth(); i++) {
const dayOfWeekNumber = getDayOfWeekNumber(i)
newDaysInMonth.push({dayNumber: i, dayOfWeek: getDayOfWeekString(dayOfWeekNumber)})
}
setDaysInMonth(prevState=>newDaysInMonth)
}
return (
<>
......@@ -94,7 +39,7 @@ function MonthCalendarBody({month, year, tasks, createTaskInCellHandler, current
labelPlacement="end"
/>
</CalendarSmallCell>
{hoursInDay.map((hours, i)=>{
{hoursInDay?.map((hours, i)=>{
return (
<CalendarStandartCell key={i} xs={cellSizes.standarCell}>
{hours}
......@@ -102,7 +47,7 @@ function MonthCalendarBody({month, year, tasks, createTaskInCellHandler, current
)
})}
</CalendarRow>
{daysInMonth.map((day, i)=>{
{daysInMonth?.map((day, i)=>{
return (
<CalendarRow
key={i}
......
import { Box, Typography } from '@mui/material';
import { memo } from 'react';
import MonthDecrementButton from './MonthDecrementButton/MonthDecrementButton';
import MonthIncrementButton from './MonthIncrementButton/MonthIncrementButton';
function MonthAndYearInfo({getCurrentMonthString, year, incrementMonth, decrementMonth}) {
return (
<>
<Box
sx={{
flexGrow: 1,
display: 'flex',
alignItems: 'center',
gap: '10px'
}}
>
<MonthDecrementButton
decrementMonth={decrementMonth}
/>
<Box sx={{ flexBasis: '150px' }}>
<Typography
variant="h6"
sx={{
display: 'flex',
justifyContent: 'center',
}}
>
{getCurrentMonthString}
</Typography>
<Typography align='center'>{year}</Typography>
</Box>
<MonthIncrementButton
incrementMonth={incrementMonth}
/>
</Box>
</> );
}
export default memo(MonthAndYearInfo);
\ No newline at end of file
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
import { memo } from 'react';
const arrowClass = {
borderRadius: '50%',
cursor: 'pointer',
transition: '0.5s',
"&:hover": {
background: 'rgb(48, 154, 252, 0.65)',
transition: '0.5s',
transform: 'scale(1.2)'
}
}
function MonthDecrementButton({decrementMonth}) {
return (
<>
<ArrowBackIcon
sx={arrowClass}
onClick={decrementMonth}
/>
</> );
}
export default memo(MonthDecrementButton);
\ No newline at end of file
import ArrowForwardIcon from '@mui/icons-material/ArrowForward';
import { memo } from 'react';
const arrowClass = {
borderRadius: '50%',
cursor: 'pointer',
transition: '0.5s',
"&:hover": {
background: 'rgb(48, 154, 252, 0.65)',
transition: '0.5s',
transform: 'scale(1.2)'
}
}
function MonthIncrementButton({incrementMonth}) {
return (
<>
<ArrowForwardIcon
sx={arrowClass}
onClick={incrementMonth}
/>
</> );
}
export default memo(MonthIncrementButton);
\ No newline at end of file
import { AppBar, FormControl, InputLabel, MenuItem, Select, Toolbar, Typography } from '@mui/material';
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
import ArrowForwardIcon from '@mui/icons-material/ArrowForward';
import { AppBar, Toolbar} from '@mui/material';
import { Box } from '@mui/system';
import MonthAndYearInfo from './MonthAndYearInfo/MonthAndYearInfo';
import СustomSelect from '../UI/СustomSelect/СustomSelect'
const arrowClass = {
borderRadius: '50%',
cursor: 'pointer',
transition: '0.5s',
"&:hover": {
background: 'rgb(48, 154, 252, 0.65)',
transition: '0.5s',
transform: 'scale(1.2)'
}
}
const workers = [{value: '', text: '--выберите сотрудника'}, {value: 'Василий', text: 'Василий'}, {value: 'Никита', text: 'Никита'}]
const types = [{value: 'Месяц', text: 'Месяц'}, {value: 'Неделя', text: 'Неделя'}]
function MonthCalendarHeader({month, getCurrentMonthString, decrementMonth, incrementMonth, calendarType, onChangeWorkerHandler, onChangeCalendarTypeHandler, worker, year}) {
function MonthCalendarHeader({ getCurrentMonthString, decrementMonth, incrementMonth, calendarType, onChangeWorkerHandler, onChangeCalendarTypeHandler, worker, year}) {
return (
<>
<Box sx={{ flexGrow: 1 }}>
<AppBar position="static">
<Toolbar>
<Box
sx={{
flexGrow: 1,
display: 'flex',
alignItems: 'center',
gap: '10px'
}}
>
<ArrowBackIcon
onClick={()=>{decrementMonth()}}
sx={arrowClass}
/>
<Box sx={{ flexBasis: '150px' }}>
<Typography
variant="h6"
sx={{
display: 'flex',
justifyContent: 'center',
}}
>
{getCurrentMonthString(month)}
</Typography>
<Typography align='center'>{year}</Typography>
</Box>
<ArrowForwardIcon
sx={arrowClass}
onClick={()=>{incrementMonth()}}
/>
</Box>
<FormControl variant="standard" sx={{ m: 1, minWidth: 120 }}>
<InputLabel id="worker-select-label">Сотрудник</InputLabel>
<Select
labelId="worker-select-label"
id="worker-select"
value={worker}
onChange={(e)=>{onChangeWorkerHandler(e)}}
label="Worker"
>
<MenuItem value="">
<em>-- Выберите сотрудника --</em>
</MenuItem>
<MenuItem value={"Василий"}>Василий</MenuItem>
<MenuItem value={"Никита"}>Никита</MenuItem>
<MenuItem value={"Артем"}>Артем</MenuItem>
</Select>
</FormControl>
<FormControl variant="standard" sx={{ m: 1, minWidth: 120 }}>
<InputLabel id="calendar-type-label">Календарь</InputLabel>
<Select
labelId="calendar-type-label"
id="calendar-type"
value={calendarType}
onChange={(e)=>{onChangeCalendarTypeHandler(e)}}
label="Type"
>
<MenuItem value={"Месяц"}>Месяц</MenuItem>
<MenuItem value={"Неделя"}>Неделя</MenuItem>
</Select>
</FormControl>
<MonthAndYearInfo
getCurrentMonthString={getCurrentMonthString}
decrementMonth={decrementMonth}
incrementMonth={incrementMonth}
year={year}
/>
<СustomSelect
value={worker}
onChange={(e)=>{onChangeWorkerHandler(e)}}
label={'Сотрудник'}
id={'worker'}
items={workers}
/>
<СustomSelect
value={calendarType}
onChange={(e)=>{onChangeCalendarTypeHandler(e)}}
label={'Календарь'}
id={'calendar-type'}
items={types}
/>
</Toolbar>
</AppBar>
</Box>
......
import { FormControl, InputLabel, MenuItem, Select} from '@mui/material';
import { memo } from 'react';
function СustomSelect({value, onChange, label, variant='standard', items, id}) {
return (
<>
<FormControl variant={variant} sx={{ m: 1, minWidth: 120 }}>
<InputLabel id={id + '-select' + '-label'}>{label}</InputLabel>
<Select
labelId={id + '-select'+ '-label'}
id={id + '-select'}
value={value}
onChange={onChange}
label={label}
>
{items.map((item, i)=>{
return (
<MenuItem
key={i}
value={item?.value}
>{item?.text}</MenuItem>
)
})}
</Select>
</FormControl>
</> );
}
export default memo(СustomSelect, (prevProps, nextProps)=>{
if(prevProps.value !== nextProps.value) {
return false
} else {
return true
}
});
\ No newline at end of file
import { useEffect, useState } from 'react';
import { useEffect, useCallback, useState, useMemo } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import MonthCalendarBody from '../../components/MonthCalendarBody/MonthCalendarBody';
import MonthCalendarHeader from '../../components/MonthCalendarHeader/MonthCalendarHeader';
......@@ -9,58 +9,84 @@ function MonthCalendar() {
const { calendarTasks } = useSelector(state => state.tasks);
const [hourFormat, setHourFormat] = useState(false);
const [month, setMonth] = useState('')
const [year, setYear] = useState('')
const [dateNow, setDateNow] = useState({month: '', year: ''})
const [worker, setWorker] = useState('');
const [calendarType, setCalendarType] = useState('Месяц');
const [currentTask, setCurrentTask] = useState({title: '', description: '', priority: null, dateTimeStart: '', dateTimeDue:''})
const [currentTask, setCurrentTask] = useState({title: '', description: '', priority: ''})
const [cellSizes, setCellSizes] = useState({})
useEffect(()=>{
setMonth(new Date().getMonth())
setYear(new Date().getFullYear())
setDateNow({
month: new Date().getMonth(),
year: new Date().getFullYear(),
})
dispatch(fetchCalendarTasks())
}, [dispatch])
const onChangeWorkerHandler = (event) => {
const hoursInDay = useMemo(()=>{
if (hourFormat) {
const arr = ['8:00', '9:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00', '19:00', '20:00','21:00','22:00']
const cells = arr.length
const xs = 10.8/cells
setCellSizes(()=>{
return {smallCell: 0.6, standarCell: xs}
})
return arr
} else {
const arr = ['8:00', '10:00', '12:00', '14:00', '16:00', '18:00', '20:00', '22:00']
const cells = arr.length
const xs = 10.8/cells
setCellSizes(()=>{
return {smallCell: 0.6, standarCell: xs}
})
return arr
}
}, [hourFormat])
const daysInMonth = useMemo(() => {
const newDaysInMonth = []
const daysInMonthNumber = new Date(dateNow.year, dateNow.month + 1, 0).getDate()
for (let i = 1; i <= daysInMonthNumber; i++) {
const dayOfWeekNumber = new Date(dateNow.year, dateNow.month, i).getDay()
const getDayOfWeekString = ["ВС","ПН","ВТ","СР","ЧТ","ПТ","СБ"][dayOfWeekNumber]
newDaysInMonth.push({dayNumber: i, dayOfWeek: getDayOfWeekString})
}
return newDaysInMonth
}, [dateNow.month, dateNow.year])
const onChangeWorkerHandler = useCallback((event) => {
setWorker(event.target.value);
};
}, []);
const onChangeCalendarTypeHandler = (event) => {
const onChangeCalendarTypeHandler = useCallback((event) => {
setCalendarType(event.target.value);
};
}, []);
const getCurrentMonthString = (month) => {
return ["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь", "Декабрь"][month];
}
const getCurrentMonthString = useMemo(() => {
return ["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь", "Декабрь"][dateNow.month];
}, [dateNow.month])
const incrementMonth = () => {
setMonth((prevState)=>{
if (prevState + 1 === 12 ) {
setYear(prevState=>prevState+1)
return 0
const incrementMonth = useCallback(() => {
setDateNow((prevState)=>{
if (prevState.month + 1 === 12 ) {
return { month: 0, year: prevState.year + 1}
}
return prevState + 1
return {...prevState, month: prevState.month + 1}
})
}
}, [])
const decrementMonth = () => {
setMonth((prevState)=>{
if (prevState - 1 === -1) {
setYear(prevState=>prevState-1)
return 11
const decrementMonth = useCallback(() => {
setDateNow((prevState)=>{
if (prevState.month - 1 === -1) {
return { month: 11, year: prevState.year - 1}
}
return prevState - 1
return {...prevState, month: prevState.month - 1}
})
}
function dateToISOLikeButLocal(date) {
const offsetMs = date.getTimezoneOffset() * 60 * 1000;
const msLocal = date.getTime() - offsetMs;
const dateLocal = new Date(msLocal);
const iso = dateLocal.toISOString();
return iso;
}
}, [])
const onChangeCurrentTaskHandler = (e) => {
const onChangeCurrentTaskHandler = useCallback((e) => {
const {name, value} = e.target;
setCurrentTask((prevState) => {
return {
......@@ -68,8 +94,14 @@ function MonthCalendar() {
[name]: value
}
});
};
}, []);
function dateToISOLikeButLocal(date) {
const offsetMs = date.getTimezoneOffset() * 60 * 1000;
const msLocal = date.getTime() - offsetMs;
const dateLocal = new Date(msLocal);
const iso = dateLocal.toISOString();
return iso;
}
const createTaskInCellHandler = (dayNumber, dayHour) => {
const hour = parseInt(dayHour.split(':')[0])
let hourDue
......@@ -82,14 +114,13 @@ function MonthCalendar() {
title:"Задача",
description:"описание",
priority: null,
dateTimeStart: dateToISOLikeButLocal(new Date(year, month, dayNumber, hour, 0)),
dateTimeDue: dateToISOLikeButLocal(new Date(year, month, dayNumber, hourDue, 59)),
dateTimeStart: dateToISOLikeButLocal(new Date(dateNow.year, dateNow.month, dayNumber, hour, 0)),
dateTimeDue: dateToISOLikeButLocal(new Date(dateNow.year, dateNow.month, dayNumber, hourDue, 59)),
}
setCurrentTask((newTask))
}
const sendNewTaskHandler = async () => {
if (currentTask.id) {
setCurrentTask(() => {
return{
......@@ -104,6 +135,7 @@ function MonthCalendar() {
...currentTask,
}}
)
console.log(currentTask)
delete currentTask.infoForCell
await dispatch(addTask(currentTask))
}
......@@ -116,8 +148,7 @@ function MonthCalendar() {
return (
<>
<MonthCalendarHeader
month={month}
year={year}
year={dateNow.year}
getCurrentMonthString={getCurrentMonthString}
decrementMonth={decrementMonth}
incrementMonth={incrementMonth}
......@@ -127,8 +158,8 @@ function MonthCalendar() {
calendarType={calendarType}
/>
<MonthCalendarBody
month={month}
year={year}
month={dateNow.month}
year={dateNow.year}
tasks={calendarTasks}
createTaskInCellHandler={createTaskInCellHandler}
setCurrentTask={setCurrentTask}
......@@ -138,7 +169,11 @@ function MonthCalendar() {
onChangeCurrentTaskHandler={onChangeCurrentTaskHandler}
sendNewTaskHandler={sendNewTaskHandler}
deleteTaskHandler={deleteTaskHandler}
cellSizes={cellSizes}
hoursInDay={hoursInDay}
daysInMonth={daysInMonth}
/>
</>
);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment