46 - Calendar that displays events and allows scheduling

Description

Develop a React component that visualizes a calendar, displays events, and enables users to add, edit, and delete events, effectively managing schedules and appointments.

  • Renders a calendar grid with days, weeks, or months, customizable based on user preferences.

  • Fetches and displays events from a data source (e.g., local array, external API).

  • Allows users to create new events by selecting dates and times and providing event details.

  • Enables editing and deleting existing events.

Algorithm

  1. Component Structure:

    • Define a functional component named Calendar.

    • Accept props for:

      • events: Array of event objects with properties like title, start date/time, end date/time.

      • initialView: Optional initial view to display (day, week, month).

  2. Calendar Grid Generation:

    • Use a library like react-calendar or implement custom logic to create the calendar grid:

      • Generate days, weeks, or months based on the current view.

      • Handle navigation between different views.

  3. Event Display:

    • Render events on their corresponding dates within the calendar grid.

    • Consider styling, event durations, and overlapping events.

  4. Event Scheduling:

    • Implement event creation functionality:

      • Allow users to select dates and times.

      • Prompt for event details (title, description, etc.).

      • Add new events to the events state and trigger re-rendering.

    • Provide options for editing and deleting existing events.

Code

import React, { useState, useEffect } from 'react';
import Calendar from 'react-calendar';
import 'react-calendar/dist/Calendar.css';

// Assuming a local array of events for simplicity
const events = [
  { id: 1, title: 'Meeting', start: new Date(2024, 0, 10, 9, 0) },
  // ... more events
];

const MyCalendar = ({ initialView = 'month', onEventChange = () => {} }) => {
  const [view, setView] = useState(initialView);
  const [currentDate, setCurrentDate] = useState(new Date());
  const [selectedDate, setSelectedDate] = useState(null);
  const [eventsToDisplay, setEventsToDisplay] = useState([]);

  useEffect(() => {
    // Filter events based on current view and date
    setEventsToDisplay(events.filter((event) => {
      const eventDate = new Date(event.start);
      const isSameMonth = eventDate.getMonth() === currentDate.getMonth();
      const isSameWeek = eventDate.getWeek() === currentDate.getWeek();
      const isSameDay = eventDate.getDate() === currentDate.getDate();
      return (
        (view === 'month' && isSameMonth) ||
        (view === 'week' && isSameWeek) ||
        (view === 'day' && isSameDay)
      );
    }));
  }, [events, view, currentDate]);

  const handleDateSelect = (date) => {
    setSelectedDate(date);
  };

  const handleEventCreate = (eventData) => {
    // Add new event to the events array (implementation depends on data source)
    const newEvents = [...events, eventData];
    setEventsToDisplay(newEvents);
    onEventChange(newEvents); // Notify parent component for persistence
  };

  const handleEventEdit = (eventId, updatedEventData) => {
    // Update existing event in the events array (implementation depends on data source)
    const updatedEvents = events.map((event) =>
      event.id === eventId ? { ...event, ...updatedEventData } : event
    );
    setEventsToDisplay(updatedEvents);
    onEventChange(updatedEvents); // Notify parent component for persistence
  };

  const handleEventDelete = (eventId) => {
    const updatedEvents = events.filter((event) => event.id !== eventId);
    setEventsToDisplay(updatedEvents);
    onEventChange(updatedEvents); // Notify parent component for persistence
  };

  return (
    <div className="calendar-container">
      <Calendar
        view={view}
        locale="en-US"
        value={currentDate}
        onChange={setCurrentDate}
        onViewChange={setView}
        onSelect={handleDateSelect}
        onClickDay={(date) => setSelectedDate(date)}
      />
      {selectedDate && (
        <div className="event-details">
          {/* Display event details for selected date */}
          {eventsToDisplay.map((event) => (
            <div key={event.id}>
              {event.title}
              <button onClick={() => handleEventEdit(event.id, { start: selectedDate })}>
                Edit
              </button>
              <button onClick={() => handleEventDelete(event.id)}>Delete</button>
            </div>
          ))}
          <button onClick={() => handleEventCreate({ start: selectedDate })}>
            Create Event
          </button>
        </div>
      )}
    </div>
  );
};

export default MyCalendar;

Explanation

  • Imports:

    • React for component creation and state management.

    • useState and useEffect hooks for managing component state and side effects.

    • Calendar component from the react-calendar library for calendar rendering.

  • Data Source:

    • A local array of events is used for simplicity, but you can adapt it to any data source.

  • State Variables:

    • view: Stores the current calendar view (month, week, or day).

    • currentDate: Stores the current displayed date.

    • selectedDate: Stores the selected date for event details and creation.

    • eventsToDisplay: Stores filtered events based on current view and date.

  • useEffect Hook:

    • Runs on component render and when dependencies change.

    • Filters events based on current view and date, updating eventsToDisplay.

  • Event Handling Functions:

    • handleDateSelect: Sets the selected date when a user clicks a day.

    • handleEventCreate: Adds a new event to the events array and triggers onEventChange for persistence.

    • handleEventEdit: Updates an existing event in the events array and triggers onEventChange.

    • handleEventDelete: Removes an event from the events array and triggers onEventChange.

  • Component Rendering:

    • Renders the Calendar component with props for view, date, and event selection.

    • Conditionally renders event details and creation UI when a date is selected.

Additional Notes

  • Data Source Interactions:

    • Adapt the code to interact with your chosen data source (API, database, etc.).

    • Handle potential errors or conflicts during data interactions.

  • State Management:

    • Consider using a state management library for complex data handling in larger applications.

  • User Interface:

    • Add input fields and UI elements for event details and editing.

  • Additional Features:

    • Implement recurring events, reminders, integrations, or other enhancements as needed.

Last updated