# Phase 4 — Visual Content Calendar
## Week 8

---

## STEP 4.1 — Calendar Views

**Package:** FullCalendar.js (via CDN in Vite)

**Route:** `GET /calendar` → `CalendarController@index`

**Livewire Component:** `Calendar\ContentCalendar`

### Backend: `CalendarController@events` (JSON endpoint)
```
GET /calendar/events?start={date}&end={date}&platform={platform}&type={type}
Returns: [{id, title, start, end, color, extendedProps: {status, platform, caption, media_url}}]
```

Color coding:
- Scheduled: `#3b82f6` (blue)
- Published: `#22c55e` (green)
- Failed: `#ef4444` (red)
- Draft: `#9ca3af` (gray)
- Needs Review: `#f59e0b` (amber)

### FullCalendar.js Configuration:
```javascript
new Calendar(el, {
  plugins: [dayGridPlugin, timeGridPlugin, listPlugin, interactionPlugin],
  initialView: 'dayGridMonth',
  headerToolbar: {
    left: 'prev,next today',
    center: 'title',
    right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
  },
  editable: true,  // enables drag-drop
  eventDrop: function(info) {
    // Call /calendar/events/{id}/move via fetch
    // $wire.reschedule(info.event.id, info.event.start)
  },
  eventClick: function(info) {
    // Open quick-preview panel (Livewire component)
  },
  dateClick: function(info) {
    // Open composer pre-filled with clicked date
  },
  // Best time slots: background events with className 'best-time'
})
```

### Calendar Filters (top bar above calendar):
- Platform multi-select pills (Instagram, Twitter, etc.) — Alpine.js
- Content type filter (Images, Videos, Drafts)
- Filters passed as query params to `/calendar/events`

### Quick Preview Panel (Alpine.js side drawer):
When clicking a post card:
```
Post caption (truncated)
Platform icon + account name
Status badge
Scheduled time
Thumbnail preview
[Edit Post] [Delete] [Duplicate] buttons
```

---

## STEP 4.2 — Calendar Intelligence

### Livewire Component: `Calendar\CalendarIntelligence`

1. **Posting Frequency Heatmap:** Day-of-week × hour grid showing scheduled post density (darker = more posts)

2. **Gap Alert:** Laravel command runs daily, finds 3+ consecutive days with no scheduled content, creates notification

3. **Over-posting Warning:** If >5 posts on same day, show orange warning banner on that calendar day

4. **Campaign Grouping:**
   - Add `campaign_tag` column to `posts` table
   - Color-code all posts in same campaign
   - Filter by campaign

5. **Public Holidays:** Hardcode 20 major holidays as background events on calendar

---

## COMPLETION CHECKLIST
- [ ] FullCalendar.js month/week/day/list views working
- [ ] Color-coded post cards per status
- [ ] Drag-drop reschedule working
- [ ] Click date → open composer with pre-filled date
- [ ] Click post card → quick preview panel
- [ ] Platform + content type filters working
- [ ] Best time slot highlights (soft green bg events)
- [ ] Heatmap overlay toggle
- [ ] Gap alert notification
- [ ] Campaign grouping + filter

When done: update to `5`, commit `feat(phase4): complete visual content calendar`, stop.
