Back

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

Создание пользовательского планировщика событий с 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 предоставляет готовую навигацию по месяцам/годам с сильной поддержкой доступности, сокращая время разработки.

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

Да - переопределите стандартные CSS-классы или используйте styled-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