Сделать календарь и встречи с React Hooks - PullRequest
0 голосов
/ 09 января 2020

Я пытаюсь создать календарь для каждого пользователя, который выглядит следующим образом (игнорируйте стили, это не окончательный результат):

enter image description here

У меня есть ряд встреч, приходящих из бэкэнда, я хочу отобразить их там, где они должны быть основаны на дате и времени.

Я не могу найти хорошую практику для этого, я думал использовать атрибуты данных и измените их после загрузки назначений, но веб-сайт React говорит, чтобы этого избежать. Так что я могу думать только о том, чтобы каждый раз выполнять рендеринг ячейки в массиве встреч (я использую не таблицу, а div) и проверять, равняется ли время. Я стараюсь избегать этого, потому что это кажется мне плохой практикой, каждый визуализированный DIV должен будет запускаться в массиве встреч и проверять, совпадает ли один из них по метке времени.

Есть ли способ визуализировать их после календарь отображается? вот так я могу изменить указанные c ячейки и избежать ненужных циклов.

Я использую React Hooks & Redux для внешнего интерфейса.

Редактировать: Вот мой код

import React, { useEffect, useState, useMemo } from 'react';
import { useSelector } from 'react-redux';
import moment from 'moment';

function Calendar() {
    const calendarFromStore = useSelector(state => state.calendar);
    const [calendar, setCalendar] = useState({});
    const [settings, setSettings] = useState({
        currentWeek: [],
        diffWeeks: 0,
        totalAppointments: []
}); 

useEffect(() => {
    setCalendar(calendarFromStore);
    setSettings({ ...settings, currentWeek: getCurrentWeek })
}, [calendarFromStore]);

useEffect(() => {
    setSettings({ ...settings, currentWeek: getCurrentWeek })
}, [settings.diffWeeks])

const getCurrentWeek = useMemo(() => {
    let currentDate = moment().add(settings.diffWeeks, 'weeks');
    let days = [];
    for (let i = 3; i >= 0; i--) {
        days.push(moment(currentDate).subtract(i, 'days').format('dddd DD/MM/YY'));
    }
    for (let i = 1; i <= 3; i++) {
        days.push(moment(currentDate).add(i, 'days').format('dddd DD/MM/YY'));
    }
    return days;
}, [settings.diffWeeks])

const daysHeader = useMemo(() => {
    if (!settings.currentWeek) return;
    return settings.currentWeek.map((day, i) =>
        <div className={`day-title ${i === 3 && !settings.diffWeeks ? 'today' : ''}`} key={day}>
            <span className="day">{day.substring(0, day.indexOf(' '))}</span>
            <span className="date">{day.substring(day.indexOf(' '))}</span>
        </div>)
}, [settings.currentWeek, settings.diffWeeks]);

const timeline = useMemo(() => {
    let currTime = '10:00';
    const stopTime = '19:00';
    const interval = 15;
    let timesArr = [];
    while (currTime !== stopTime) {
        timesArr.push(currTime);
        currTime = moment(currTime, 'HH:mm').add(interval, 'minute').format('HH:mm');
    }
    setSettings({ ...settings, totalAppointments: timesArr })
    return timesArr;
}, [])

const convertStringToTimestamp = (day, time) => {
    const fixedDay = day.substring(day.indexOf(' '));
    return moment(`${fixedDay} ${time}`, 'DD/MM/YY HH:mm').unix();
}

const calendarApts = useMemo(() => {
    if (!settings.currentWeek) return;
    return settings.currentWeek.map(day =>
        <div className="line" key={day}>
            {timeline.map(time =>
                <div key={`${day} ${time}`}
                    time={convertStringToTimestamp(day, time)} onClick={() => console.log(day, time)}>
                </div>)
            }
        </div>
    )
}, [settings.currentWeek, timeline])

useMemo(() => {
    calendar.appointments && calendar.appointments.map(apt => apt);
}, [calendar.appointments])

const changeWeeks = val => {
    setSettings({ ...settings, diffWeeks: !val ? 0 : settings.diffWeeks + val })
}

return (
    <div className="calendar-container">
        <div className="navigation">
            <div className="last-buttons">
                <button onClick={() => changeWeeks(-5)}>Last month</button>
                <button onClick={() => changeWeeks(-1)}>Last week</button>
            </div>
            <button onClick={() => changeWeeks(0)}>Current Week</button>
            <div className="next-buttons">
                <button onClick={() => changeWeeks(1)}>Next week</button>
                <button onClick={() => changeWeeks(5)}>Next month</button>
            </div>
        </div>
        <div className="calendar-header">
            {daysHeader}
        </div>
        <div className="calendar-content">
            <div className="calendar-timeline">
                {timeline.map(time => <div key={time}><span>{time}</span></div>)}
            </div>
            <div className="calendar-vertical-lines">
                {calendarApts}
            </div>
        </div>
    </div>
)
}

export default Calendar;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...