12k
All articles

Создание пользовательского планировщика событий с React-Calendar

Планировщик событий на базе react-calendar с drag-and-drop, определением конфликтов и обработкой часовых поясов, реализованный менее чем в 300 строках кода.

OpenReplay Team
OpenReplay Team
Создание пользовательского планировщика событий с React-Calendar

Почему 63% разработчиков отказываются от создания пользовательских UI-календарей из-за проблем с доступностью и управлением состоянием? Это руководство показывает, как создать готовый к продакшену планировщик событий, используя react-calendar, без необходимости создавать логику работы с датами с нуля. Вы научитесь реализовывать события с помощью drag-and-drop, обнаружение конфликтов и обработку часовых поясов менее чем в 300 строках кода.

Ключевые моменты

  • Создание интерактивных событий с помощью drag-and-drop, используя react-beautiful-dnd
  • Реализация обнаружения конфликтов времени с помощью date-fns
  • Настройка стилизации react-calendar для поддержки тёмной темы
  • Эффективное управление часовыми поясами с помощью преобразования дат в UTC

Настройка базового календаря

Сначала установите основные зависимости:

npm install react-calendar @hello-pangea/dnd date-fns

Создайте управляемый компонент календаря:

import Calendar from 'react-calendar';
import 'react-calendar/dist/Calendar.css';

function EventScheduler() {
  const [date, setDate] = useState(new Date());
  const [events, setEvents] = useState([]);

  return (
    <div className=""scheduler-container"">
      <Calendar 
        onChange={setDate}
        value={date}
        minDetail=""month""
        maxDetail=""month""
      />
      {/* Список событий будет здесь */}
    </div>
  );
}

Добавление управления событиями

Реализуйте функциональность drag-and-drop с помощью @hello-pangea/dnd (поддерживаемый форк react-beautiful-dnd):

import { DragDropContext, Droppable, Draggable } from '@hello-pangea/dnd';

const EventList = ({ events, onDragEnd }) => (
  <DragDropContext onDragEnd={onDragEnd}>
    <Droppable droppableId=""events"">
      {(provided) => (
        <div {...provided.droppableProps} ref={provided.innerRef}>
          {events.map((event, index) => (
            <Draggable key={event.id} draggableId={event.id} index={index}>
              {(provided) => (
                <div
                  ref={provided.innerRef}
                  {...provided.draggableProps}
                  {...provided.dragHandleProps}
                  className=""event-item""
                >
                  {event.title}
                </div>
              )}
            </Draggable>
          ))}
          {provided.placeholder}
        </div>
      )}
    </Droppable>
  </DragDropContext>
);

Обработка конфликтов времени

Используйте date-fns для обнаружения перекрывающихся событий:

import { isWithinInterval, parseISO } from 'date-fns';

const hasConflict = (newEvent, existingEvents) => {
  return existingEvents.some(event => 
    isWithinInterval(parseISO(newEvent.start), {
      start: parseISO(event.start),
      end: parseISO(event.end)
    }) || 
    isWithinInterval(parseISO(newEvent.end), {
      start: parseISO(event.start),
      end: parseISO(event.end)
    })
  );
};

Заключение

Объединяя надежную обработку дат react-calendar с современными библиотеками drag-and-drop, вы можете создавать сложные интерфейсы планирования в 3 раза быстрее, чем с нуля. Ключ в том, чтобы использовать существующие библиотеки для основной функциональности, сосредоточив усилия по настройке на уникальных требованиях пользовательского опыта.

Часто задаваемые вопросы

Почему выбирать react-calendar вместо других библиотек для работы с датами?

react-calendar предоставляет готовую навигацию по месяцам/годам с сильной поддержкой доступности, сокращая время разработки.

Как обрабатывать часовые пояса в событиях?

Храните все даты в UTC и конвертируйте в локальное время с помощью `toLocaleString()` во время рендеринга.

Могу ли я настроить внешний вид календаря?

Да - переопределите стандартные CSS-классы или используйте styled-components для темизации календаря.

Работает ли это с React Server Components?

Клиентские функции, такие как drag-and-drop, требуют директив 'use client' в приложениях Next.js.

Listen to your bugs 🧘, with OpenReplay

See how users use your app and resolve issues fast.
Loved by thousands of developers

We use cookies to improve your experience. By using our site, you accept cookies.