Content Calendar
Last updated on 2026-03-26
The content calendar provides a visual month-view calendar for scheduling, rescheduling, and managing social media posts across all platforms. It uses @hello-pangea/dnd for drag-and-drop post rescheduling and includes a day detail sheet for managing posts on a specific date. The calendar page is in the (dashboard) route group.
Calendar Overview
Route: /calendar
The content calendar displays scheduled, published, and draft posts on a month grid. Each post appears as a color-coded pill on its scheduled date.
- Month navigation -- previous/next month buttons with the current month and year displayed as a heading
- Calendar grid --
CalendarGridcomponent rendering a 7-column grid (Mon-Sun) withCalendarDayCellcomponents for each day - Post pills --
CalendarPostPillcomponents within each day cell, color-coded by platform (Instagram pink, Twitter blue, Facebook blue, LinkedIn blue, TikTok teal, YouTube red) with a truncated caption and media type icon - Drag-and-drop rescheduling -- drag a post pill from one day to another to reschedule it; uses
@hello-pangea/dndDragDropContext,Droppable(each day cell), andDraggable(each post pill) - Day detail sheet -- click a day cell to open the
DayDetailSheet(aSheetcomponent sliding in from the right) showing all posts for that day with full details, status, and quick actions - Today indicator -- the current date cell is highlighted with a teal ring
- Post count overflow -- days with more than 3 posts show a "+N more" indicator that opens the day detail sheet
import { CalendarGrid } from "@/components/calendar/calendar-grid"
import { CalendarDayCell } from "@/components/calendar/calendar-day-cell"
import { CalendarPostPill } from "@/components/calendar/calendar-post-pill"
import { DayDetailSheet } from "@/components/calendar/day-detail-sheet"
Calendar Layout
┌───────────────────────────────────────────┐
│ < March 2026 > [+ Post] │
├─────┬─────┬─────┬─────┬─────┬─────┬─────┤
│ Mon │ Tue │ Wed │ Thu │ Fri │ Sat │ Sun │
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│ │ │ 1 │ 2 │ 3 │ 4 │ 5 │
│ │ │ [IG]│ │ [TW]│ │ │
│ │ │ [FB]│ │ │ │ │
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│ 6 │ 7 │ 8 │ 9 │ 10 │ 11 │ 12 │
│ [LI]│ │ [IG]│ [TT]│ │ [YT]│ │
│ │ │ [TW]│ │ │ │ │
│ │ │ +1 │ │ │ │ │
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│ ... │ │ │ │ │ │ │
└─────┴─────┴─────┴─────┴─────┴─────┴─────┘
Post Pill Colors
Each CalendarPostPill uses the platform brand color as its background:
| Platform | Pill Color | Abbreviation |
|---|---|---|
#E1306C (pink) |
IG | |
| Twitter/X | #1DA1F2 (blue) |
TW |
#1877F2 (blue) |
FB | |
#0A66C2 (blue) |
LI | |
| TikTok | #00F2EA (teal) |
TT |
| YouTube | #FF0000 (red) |
YT |
Drag-and-Drop
The calendar uses @hello-pangea/dnd (a maintained fork of react-beautiful-dnd) for drag-and-drop post rescheduling.
How It Works
- Each
CalendarDayCellis aDroppablezone identified by its date string - Each
CalendarPostPillis aDraggableitem identified by its post ID - When a pill is dropped on a different day cell, the post's
scheduledAtdate is updated to the target date while preserving the original time - A toast notification confirms the reschedule with the old and new dates
Keyboard Accessibility
The drag-and-drop supports full keyboard interaction:
- Space -- lift and drop a post pill
- Arrow keys -- move a lifted pill between day cells
- Escape -- cancel a drag operation and return the pill to its original date
Data Flow
// CalendarPost type used for calendar display
interface CalendarPost {
id: string
postId: string
caption: string
platform: SocialPlatform
time: string
date: string
mediaType: PostType
status: PostStatus
}
Day Detail Sheet
The DayDetailSheet is a Sheet component that slides in from the right when a day cell is clicked. It provides a detailed view of all posts scheduled for that day.
- Date heading -- formatted date (e.g., "Wednesday, March 11, 2026")
- Post list -- each post shows platform badge, time, caption, media type, status badge, and engagement metrics (for published posts)
- Quick actions -- edit, reschedule, duplicate, and delete buttons for each post
- Add post button -- link to the composer with the selected date pre-filled
- Empty state -- message shown when no posts are scheduled for the day, with a prompt to create one
Day Detail Layout
┌─────────────────────────────┐
│ Wednesday, March 11, 2026 │
├─────────────────────────────┤
│ 9:00 AM [IG] Product shot │
│ Status: Scheduled │
│ [Edit] [Reschedule] [...] │
├─────────────────────────────┤
│ 2:00 PM [TW] Thread about │
│ Status: Draft │
│ [Edit] [Reschedule] [...] │
├─────────────────────────────┤
│ 5:30 PM [FB] Blog share │
│ Status: Scheduled │
│ [Edit] [Reschedule] [...] │
├─────────────────────────────┤
│ [+ Add Post for This Day] │
└─────────────────────────────┘
Data Sources
| Data | Source | Location |
|---|---|---|
| Calendar posts | calendarPosts |
data/seed.ts |
| Post details | posts (joined by postId) |
data/seed.ts |
Next Steps
- Content Management -- content hub and post composer
- Analytics -- post performance and audience insights
- Reports -- generate and export platform reports