Files
deardiary/todo/calendar.md
lotherk 0bdd71a4ed feat: v0.1.0 - geolocation capture, calendar, search, Starlight docs site
- Automatic browser geolocation capture on event creation
- Reverse geocoding via Nominatim API for place names
- Full-text search with SQLite FTS5
- Calendar view for browsing past entries
- DateNavigator component for day navigation
- SearchModal with Ctrl+K shortcut
- QuickAddWidget with Ctrl+J shortcut
- Starlight documentation site with GitHub Pages deployment
- Multiple AI provider support (Groq, OpenAI, Anthropic, Ollama, LM Studio)
- Multi-user registration support

BREAKING: Events now include latitude/longitude/placeName fields
2026-03-27 02:27:55 +00:00

8.8 KiB

Calendar View Feature Research

Overview

This document outlines research and implementation ideas for adding a calendar view to DearDiary, enabling users to visualize their journaling activity across days, weeks, and months at a glance.

Current State Analysis

Existing Navigation & Data Flow

  • Routes: / (Dashboard), /today, /history, /diary, /day/:date, /journal/:date, /settings
  • API: getDays() returns Array<{ date, eventCount, hasJournal, journalTitle?, journalExcerpt? }>
  • History page: Currently a simple list showing all days chronologically

Key Data Points Per Day

  • date: ISO date string (YYYY-MM-DD)
  • eventCount: Number of events captured
  • hasJournal: Whether diary page has been generated
  • journalTitle: Title from AI-generated diary
  • journalExcerpt: Preview text from diary content

Feature Description

1. Monthly Calendar View

Primary use case: Overview of journaling activity at a glance

  • Grid layout (7 columns for weekdays)
  • Each day cell shows:
    • Date number
    • Visual indicator(s) for presence of events/diary
    • Event count (optional, on hover or expanded)

Visual Indicators

State Indicator
No events Empty cell, muted styling
Events only (draft) Small blue/gray dot
Diary generated Small purple dot
Both (events + diary) Two dots or colored dot with indicator
Today Highlighted cell (border/background)
Selected day Different background/border

Event Density Visualization

  • Option to show density heat map (more events = darker shade)
  • Scale: 1-2 events (light), 3-5 (medium), 6+ (dark)

2. Weekly Calendar View

Primary use case: Detailed look at recent activity

  • Horizontal 7-day strip
  • Each day shows expanded content:
    • Event count
    • Mini event list (first 2-3 events)
    • Diary status badge

3. Daily Mini Calendar

  • Fixed position in header or sidebar
  • Shows current month
  • Click to navigate to specific date
  • Quick navigation (prev/next month arrows)

UI Component Suggestions

Library Pros Cons
react-big-calendar Full-featured, customizable, well-maintained Requires styling, may be heavy
react-calendar Lightweight, simple API, good theming Limited customization
react-datepicker Easy to integrate, accessible More input-focused than display
fullcalendar-react Enterprise-grade, many views Complex, may be overkill
Custom CSS Grid Full control, lightweight More implementation work

Recommendation: Custom CSS Grid + react-calendar hybrid

For DearDiary's needs, a custom implementation using CSS Grid provides:

  • Full Tailwind integration (matches existing style)
  • Lightweight bundle
  • Complete control over visual indicators
  • No dependency on heavy calendar libraries

Fallback: If ready-made needed, react-calendar is lightweight (~50KB) and sufficient for monthly view.

Tailwind CSS Implementation (Custom)

// Monthly calendar grid
<div className="grid grid-cols-7 gap-1">
  {days.map(day => (
    <button className={cn(
      "relative p-2 rounded-lg text-center",
      day.isToday && "ring-2 ring-purple-500",
      day.hasEvents && "bg-slate-800",
      day.hasJournal && "bg-purple-900/30"
    )}>
      <span>{day.dateNumber}</span>
      {day.hasEvents && (
        <span className="absolute bottom-1 left-1/2 -translate-x-1/2 w-1.5 h-1.5 rounded-full bg-blue-400" />
      )}
    </button>
  ))}
</div>

Integration with Existing Pages

1. Standalone Calendar Page (/calendar)

New route added to App.tsx:

  • Full monthly calendar view
  • Navigation to previous/next months
  • Click on day navigates to /day/:date or /journal/:date
  • Toggle between month/week views

2. Integration with Dashboard

Replace or supplement "Recent Diary Pages" with mini calendar:

  • Show current month
  • Click date to navigate
  • Compact version (fewer details per cell)

3. Integration with History Page

Replace list view with calendar as default:

  • Toggle between calendar and list views
  • Calendar shows activity overview
  • List remains available for detailed browsing

4. Navigation Updates

Update Navbar to include calendar link:

// App.tsx Navbar
<a href="/calendar" className="text-slate-300 hover:text-white transition">Calendar</a>

5. Quick Date Navigation

Mini calendar in header (optional):

  • Always visible month view
  • Click date = navigate to /day/:date

Implementation Complexity

Phase 1: Basic Monthly Calendar (Priority: High)

  • Create Calendar.tsx component
  • Add /calendar route
  • Fetch days data for current month
  • Render grid with visual indicators
  • Click to navigate

Complexity: ~2-3 hours Files: frontend/src/components/Calendar.tsx, route in App.tsx

Phase 2: Dashboard Integration (Priority: Medium)

  • Add mini calendar to Dashboard
  • Show current month
  • Click date navigates to day

Complexity: ~1-2 hours

Phase 3: Week View (Priority: Low)

  • Add week view toggle
  • Horizontal 7-day strip
  • Expanded content per day

Complexity: ~2-3 hours

Phase 4: Advanced Features (Priority: Low)

  • Event density heat map
  • Drag to select date range
  • Export calendar as image
  • iCal integration

Complexity: Varies


API Requirements

Current API Sufficiency

getDays() returns all days - filtering by month happens on client. For larger datasets:

Potential enhancement:

// Get days for specific month (optional optimization)
async getDaysByMonth(year: number, month: number): Promise<DayInfo[]>

Current workaround sufficient: Fetch all days, filter in React (acceptable for < 365 entries).


Accessibility Considerations

WCAG 2.1 AA Compliance

  1. Keyboard Navigation

    • Arrow keys to move between days
    • Enter/Space to select
    • Escape to close calendar
  2. Screen Reader Support

    • aria-label on each day cell: "March 15, 2026 - 3 events, diary generated"
    • aria-current for today
    • role="grid" with proper row/cell structure
  3. Visual Indicators

    • Don't rely solely on color
    • Use icons/shapes + color
    • Sufficient contrast ratios (4.5:1 minimum)
  4. Focus Management

    • Focus visible on calendar open
    • Return focus to trigger element on close

Example ARIA Implementation

<button
  aria-label={`${dateString} - ${eventCount} events${hasJournal ? ', diary generated' : ''}`}
  aria-current={isToday ? 'date' : undefined}
  className="..."
>
  <span aria-hidden="true">{dayNumber}</span>
  {hasEvents && <span className="sr-only">Has events</span>}
</button>

Mobile-Friendly Considerations

Responsive Design

  1. Viewport Adaptation

    • Desktop: Full monthly grid (35 cells visible)
    • Tablet: Scrollable or condensed
    • Mobile: Week view default, swipe between weeks
  2. Touch Targets

    • Minimum 44x44px tap targets
    • Adequate spacing between dates
  3. Interaction Patterns

    • Swipe left/right for month navigation
    • Tap to select, long-press for context menu

Library Considerations

If using react-big-calendar:

<Calendar
  views={['month', 'week', 'day']}
  defaultView="week" // Default to week on mobile
  popup
  selectable
  style={{ height: 'auto' }}
/>

Priority 1: Calendar Page

  1. Create frontend/src/components/Calendar.tsx
    • Monthly grid using CSS Grid
    • Visual dots for event/diary status
    • Click navigates to /day/:date
  2. Add route /calendar in App.tsx
  3. Add nav link in Navbar
  4. Test with existing data

Priority 2: Dashboard Integration

  1. Add mini calendar above recent entries
  2. Show current month
  3. Highlight today, clickable dates

Priority 3: History Enhancement

  1. Add toggle between list/calendar views
  2. Calendar as default

Priority 4: Week View (Optional)

  1. Add view switcher
  2. Horizontal week strip with event previews

Summary

Aspect Recommendation
Implementation Custom CSS Grid (Tailwind)
First placement New /calendar page
View types Monthly default, week as secondary
Indicators Dots (blue=events, purple=diary)
Navigation Click to /day/:date or /journal/:date
Accessibility Full ARIA, keyboard nav
Mobile Default to week view, touch-friendly

Estimated Timeline

  • Phase 1 (Calendar page): 2-3 hours
  • Phase 2 (Dashboard): 1-2 hours
  • Phase 3 (Week view): 2-3 hours
  • Total: ~5-8 hours

Questions for Further Research

  1. Should calendar support date range selection for bulk operations?
  2. Export to iCal/Google Calendar desired?
  3. Sync with external calendars (Google, Apple)?
  4. Recurring event support?
  5. Need to show time-of-day heat map?