Full Calendar

repository·main·Indexed 19 days ago

https://github.com/yassir-jeraidi/full-calendar

A feature-rich, customizable calendar application built with React, TypeScript, and ShadCN UI. It supports multiple views (Day, Week, Month, Year, Agenda), drag-and-drop event management, and full CRUD operations for events. The library includes a centralized state management pattern via CalendarProvider and useCalendar hook, multi-user support with event filtering, and a DndProvider for spatial event manipulation.

Tokens
4.8K
Snippets
19
Records
24
Agent score
65%

What's inside full-calendar

  1. Introduction to Full Calendar

    main

    Full Calendar is a feature-rich calendar application built using React, TypeScript, and ShadCN UI components. It is designed to provide a customizable and interactive calendar experience suitable for personal scheduling or team collaboration.

    Key Capabilities

    • Multiple Views: Navigate through Day, Week, Month, Year, and Agenda views.
    • Event Management: Full CRUD (Create, Read, Update, Delete) operations for events, including support for recurring events and metadata like title, description, and attendees.
    • Interactivity: Supports drag-and-drop for moving events between time slots/dates and event resizing in day and week views.
    • Customization: Features include color-coding for events, toggling between 24-hour and 12-hour time formats, and full dark mode support.
    • Multi-User Support: Ability to filter events by user for collaborative environments.
  2. How the Full Calendar architecture works

    main

    The application is built around a centralized state management pattern using React Context.

    1. Initialization: The Calendar component acts as the entry point, fetching initial data (events and users) and initializing the CalendarProvider.
    2. State Management: CalendarContext manages the core application state, including the current view (Day, Week, Month, etc.), selected date, event list, and active filters. User preferences like time format (12h/24h) and view preferences are persisted via localStorage.
    3. Rendering: The CalendarHeader handles navigation and view switching. The CalendarBody reacts to changes in the view state to dynamically render the correct view component (e.g., MonthView).
    4. Interactions:
      • Drag & Drop: Enabled by a DndProvider that wraps the calendar. Moving an event triggers a context update to the event's start and end times.
      • Event CRUD: The context provides addEvent, updateEvent, and removeEvent functions to manage the event lifecycle and keep the UI in sync.
  3. Core Concepts of Full Calendar

    main

    The application's architecture and user experience are driven by three primary mental models:

    1. Event-Centric Design

    Events are the primary data entities. The system is optimized for managing event lifecycles, including:

    • Metadata: Storing details like title, description, time, and attendees.
    • Spatial Manipulation: Using drag-and-drop and resizing to adjust schedules visually.
    • Visual Organization: Using color coding to categorize and identify events quickly.

    2. Multi-View Navigation

    Users interact with data through different temporal lenses. The application provides context-aware interactions based on the selected view:

    • Day/Week Views: Optimized for granular interactions like event resizing.
    • Month/Year Views: Optimized for high-level overview and long-term planning.
    • Agenda View: Optimized for summarizing upcoming events in a list format.

    3. Interactive and Customizable UI

    Built on ShadCN UI, the interface is designed for high personalization and responsiveness:

    • Personalization: Users can switch between light/dark modes and 12/24-hour time formats.
    • Collaboration: Multi-user support allows for filtering views to focus on specific team members or shared calendars.
  4. Run the Full Calendar project locally

    main

    To run the full repository locally for development, follow these steps:

    1. Clone the repository:
      git clone https://github.com/yassir-jeraidi/full-calendar.git
      cd full-calendar
    2. Install dependencies using pnpm:
      pnpm install
    3. Start the development server:
      pnpm dev
    4. Access the app at http://localhost:3000.
    git clone https://github.com/yassir-jeraidi/full-calendar.git
    cd full-calendar
    pnpm install
    pnpm dev
  5. Initialize the calendar with CalendarProvider

    main

    To use the calendar features, wrap your component tree with the CalendarProvider. This provider manages the global state for events, users, view settings, and filters. It also persists certain settings (like view and time format) to local storage automatically.

    Props

    • children: React nodes to be wrapped.
    • users: An array of IUser objects.
    • events: An array of IEvent objects.
    • view (optional): The initial TCalendarView (e.g., 'day').
    • badge (optional): The initial badgeVariant ('dot' or 'colored').
    import { CalendarProvider } from '@/features/calendar/contexts/calendar-context';
    
    function App() {
      const users = [...]; // IUser[]
      const events = [...]; // IEvent[]
    
      return (
        <CalendarProvider users={users} events={events} view="day" badge="colored">
          <YourCalendarComponents />
        </CalendarProvider>
      );
    }
  6. Setup the DndProvider for drag-and-drop support

    main

    To enable drag-and-drop capabilities within your calendar application, you must wrap your component tree (or the specific calendar section) with the DndProvider. This provider manages the internal drag state and integrates with the useCalendar context to persist event updates.

    Note: DndProvider relies on useCalendar being available in the context tree to perform the actual event updates via updateEvent.

    import { DndProvider } from '@/features/calendar/contexts/dnd-context';
    import { CalendarProvider } from '@/features/calendar/contexts/calendar-context';
    
    function App() {
      return (
        <CalendarProvider>
          <DndProvider>
            <MyCalendar />
          </DndProvider>
        </CalendarProvider>
      );
    }
  7. Use the Calendar component in your application

    main

    After installation, import the Calendar component. It is recommended to wrap it in a Suspense boundary with a CalendarSkeleton to handle loading states during data fetching.

    import React, { Suspense } from "react";
    import { Calendar } from "@/features/calendar/calendar";
    import { CalendarSkeleton } from "@/features/calendar/skeletons/calendar-skeleton";
    
    export default function CalendarPage() {
      return (
        <Suspense fallback={<CalendarSkeleton />}>
          <Calendar />
        </Suspense>
      );
    }
  8. Implement the Calendar component in a React application

    main

    Once installed, you can use the Calendar component within your application. It is recommended to wrap the component in a Suspense boundary and provide a CalendarSkeleton as a fallback to handle loading states gracefully.

    import React, { Suspense } from "react";
    import { Calendar } from "@/components/calendar/calendar";
    import { CalendarSkeleton } from "@/components/calendar/skeletons/calendar-skeleton";
    
    export default function CalendarPage() {
      return (
        <Suspense fallback={<CalendarSkeleton />}>
          <Calendar />
        </Suspense>
      );
    }
  9. Validate event data with eventSchema

    main

    The eventSchema is a Zod schema used to validate event management form data. It ensures that all required fields are present and conform to the expected types and constraints. Use this schema to validate data before submitting event creation or update forms.

    import { eventSchema } from './path-to-schemas';
    
    const result = eventSchema.safeParse({
      title: "Meeting",
      description: "Project sync",
      startDate: new Date(),
      endDate: new Date(),
      color: "blue"
    });
    
    if (!result.success) {
      console.error(result.error.format());
    }
  10. Filter and manage events and users

    main

    The useCalendar hook allows you to filter the visible event list and perform CRUD operations on events.

    Filtering

    • filterEventsBySelectedColors(color: TEventColor): Toggles a color filter. Selecting a color adds it to the filter; selecting it again removes it. If no colors are selected, all events are shown.
    • filterEventsBySelectedUser(userId: IUser['id'] | 'all'): Filters events to show only those belonging to a specific user, or 'all' to show everything.
    • clearFilter(): Resets all filters (colors and user) and shows all events.

    Event CRUD

    • addEvent(event: IEvent): Adds a new event to the calendar.
    • updateEvent(event: IEvent): Updates an existing event by its id.
    • removeEvent(eventId: number): Removes an event from the calendar.

    Selection State

    • setSelectedDate(date: Date | undefined): Sets the currently selected date.
    • setSelectedUserId(userId: IUser['id'] | 'all'): Sets the active user filter state.