# 46 - Calendar that displays events and allows scheduling

### Description

Create a calendar that displays events and allows scheduling, rendering a calendar grid with days, weeks, or months customizable based on user preferences, fetching and displaying events from a data source (e.g., local array, external API), allowing users to create new events by selecting dates and times and providing event details, and enabling editing and deleting existing events.

### **Algorithm**

1. Render a calendar grid with days, weeks, or months based on user preferences
2. Fetch events from a data source (e.g., local array, external API)
3. Display events on the calendar grid
4. Allow users to create new events by selecting dates and times and providing event details
5. Enable editing and deleting existing events
6. Update the calendar grid and data source accordingly

### Classes

* `Calendar`: The main calendar component
* `CalendarGrid`: The calendar grid component
* `Event`: The event component
* `EventForm`: The event form component for creating and editing events
* `EventData`: The event data component for fetching and storing events

### Code

Calendar.js

```javascript
import React, { useState, useEffect } from 'react';
import CalendarGrid from './CalendarGrid';
import Event from './Event';
import EventForm from './EventForm';
import EventData from './EventData';

const Calendar = () => {
  const [events, setEvents] = useState([]);
  const [selectedDate, setSelectedDate] = useState(new Date());
  const [showEventForm, setShowEventForm] = useState(false);

  useEffect(() => {
    EventData.fetchEvents().then((events) => setEvents(events));
  }, []);

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

  const handleCreateEvent = (event) => {
    EventData.createEvent(event).then((event) => setEvents((prevEvents) => [...prevEvents, event]));
  };

  const handleEditEvent = (event) => {
    EventData.editEvent(event).then((event) => setEvents((prevEvents) => prevEvents.map((prevEvent) => ((link unavailable) === (link unavailable) ? event : prevEvent)));
  };

  const handleDeleteEvent = (event) => {
    EventData.deleteEvent(event).then(() => setEvents((prevEvents) => prevEvents.filter((prevEvent) => (link unavailable) !== (link unavailable))));
  };

  return (
    <div>
      <CalendarGrid
        selectedDate={selectedDate}
        handleSelectDate={handleSelectDate}
      >
        {events.map((event) => (
          <Event
            key={(link unavailable)}
            event={event}
            handleEditEvent={handleEditEvent}
            handleDeleteEvent={handleDeleteEvent}
          />
        ))}
      </CalendarGrid>
      {showEventForm && (
        <EventForm
          onCreateEvent={handleCreateEvent}
          onClose={() => setShowEventForm(false)}
        />
      )}
    </div>
  );
};

export default Calendar;

```

CalendarGrid.js

```javascript
import React from 'react';

const CalendarGrid = ({ selectedDate, handleSelectDate }) => {
  const days = [];
  for (let i = 0; i < 7; i++) {
    days.push(
      <div key={i}>
        {i === 0 ? 'Sun' : i === 1 ? 'Mon' : i === 2 ? 'Tue' : i === 3 ? 'Wed' : i === 4 ? 'Thu' : i === 5 ? 'Fri' : 'Sat'}
      </div>
    );
  }

  const weeks = [];
  for (let i = 0; i < 5; i++) {
    weeks.push(
      <div key={i}>
        {days.slice(i * 7, (i + 1) * 7)}
      </div>
    );
  }

  return (
    <div>
      {weeks}
      <div>
        <button onClick={() => handleSelectDate(selectedDate.getDate() - 1)}>
          Prev
        </button>
        <button onClick={() => handleSelectDate(selectedDate.getDate() + 1)}>
          Next
        </button>
      </div>
    </div>
  );
};

export default CalendarGrid;
```

Event.js

```javascript
import React from 'react';

const Event = ({ event, handleEditEvent, handleDeleteEvent }) => {
  return (
    <div>
      <h2>{event.title}</h2>
      <p>{event.description}</p>
      <p>{event.startDate} - {event.endDate}</p>
      <button onClick={() => handleEditEvent(event)}>Edit</button>
      <button onClick={() => handleDeleteEvent(event)}>Delete</button>
    </div>
  );
};

export default Event;
```

EventForm.js

```javascript
import React from 'react';

const EventForm = ({ onCreateEvent, onClose }) => {
  const [title, setTitle] = useState('');
  const [description, setDescription] = useState('');
  const [startDate, setStartDate] = useState(new Date());
  const [endDate, setEndDate] = useState(new Date());

  const handleSubmit = (event) => {
    event.preventDefault();
    onCreateEvent({ title, description, startDate, endDate });
    onClose();
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>Title:</label>
      <input type="text" value={title} onChange={(e) => setTitle(e.target.value)} />
      <br />
      <label>Description:</label>
      <textarea value={description} onChange={(e) => setDescription(e.target.value)} />
      <br />
      <label>Start Date:</label>
      <input type="date" value={startDate} onChange={(e) => setStartDate(e.target.value)} />
      <br />
      <label>End Date:</label>
      <input type="date" value={endDate} onChange={(e) => setEndDate(e.target.value)} />
      <br />
      <button type="submit">Create Event</button>
      <button onClick={onClose}>Cancel</button>
    </form>
  );
};

export default EventForm;
```

EventData.js

```javascript
const events = [];

const fetchEvents = () => {
  return Promise.resolve(events);
};

const createEvent = (event) => {
  events.push(event);
  return Promise.resolve(event);
};

const editEvent = (event) => {
  const index = events.findIndex((e) => (link unavailable) === (link unavailable));
  if (index !== -1) {
    events[index] = event;
  }
  return Promise.resolve(event);
};

const deleteEvent = (event) => {
  const index = events.findIndex((e) => (link unavailable) === (link unavailable));
  if (index !== -1) {
    events.splice(index, 1);
  }
  return Promise.resolve();
};

export { fetchEvents, createEvent, editEvent, deleteEvent };
```

### **Explanation**

This code creates a calendar that displays events and allows scheduling. It 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, and enables editing and deleting existing events

### **Possible future enhancements**

* *Customizable calendar views*: Offer customizable calendar views, such as a list view or a agenda view, to cater to different user preferences.
* *Time zone support*: Add support for different time zones, to accommodate users from diverse geographical locations.
* *Accessibility features*: Implement accessibility features, such as screen reader support, to make the calendar usable by everyone.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://choubey.gitbook.io/react-coding-puzzles/46-calendar-that-displays-events-and-allows-scheduling.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
