"use client"; import { useState, useMemo, useRef, useEffect } from "react"; import Link from "next/link"; import { Card, CardContent } from "@/components/ui/card"; import { buttonVariants } from "@/components/ui/button"; import { ReadingSettings } from "@/components/reading-settings"; import { cn } from "@/lib/utils"; import { ChevronLeft, ChevronRight, Menu } from "lucide-react"; import { Drawer, DrawerClose, DrawerContent, DrawerHeader, DrawerTitle, DrawerTrigger, } from "@/components/ui/drawer"; // --------------------------------------------------------------------------- // Types // --------------------------------------------------------------------------- export type LetterItem = { slug: string; recipientDisplay: string; date: string | null; year: number | null; month: number | null; location: string | null; }; type MonthGroup = { month: number; label: string; shortLabel: string; count: number; letters: LetterItem[]; }; // --------------------------------------------------------------------------- // Constants // --------------------------------------------------------------------------- const MONTH_NAMES = [ "", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", ]; const MONTH_SHORT = [ "", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", ]; // --------------------------------------------------------------------------- // Build month groups from flat letter list // --------------------------------------------------------------------------- function buildMonthGroups(letters: LetterItem[]): MonthGroup[] { const map = new Map(); for (const letter of letters) { const m = letter.month && letter.month >= 1 && letter.month <= 12 ? letter.month : 0; if (!map.has(m)) map.set(m, []); map.get(m)!.push(letter); } const groups: MonthGroup[] = []; for (let m = 1; m <= 12; m++) { const items = map.get(m); if (items && items.length > 0) { groups.push({ month: m, label: MONTH_NAMES[m], shortLabel: MONTH_SHORT[m], count: items.length, letters: items, }); } } const unknown = map.get(0); if (unknown && unknown.length > 0) { groups.push({ month: 0, label: "Unknown Month", shortLabel: "Unknown", count: unknown.length, letters: unknown, }); } return groups; } // --------------------------------------------------------------------------- // Sidebar — matches book chapter sidebar // --------------------------------------------------------------------------- function MonthSidebar({ groups, activeMonth, onSelect, }: { groups: MonthGroup[]; activeMonth: number; onSelect: (month: number) => void; }) { return ( ); } // --------------------------------------------------------------------------- // Mobile drawer — matches MobileNav // --------------------------------------------------------------------------- function MonthMobileNav({ groups, activeMonth, onSelect, year, }: { groups: MonthGroup[]; activeMonth: number; onSelect: (month: number) => void; year: number; }) { const [open, setOpen] = useState(false); return ( Months Letters from {year} ); } // --------------------------------------------------------------------------- // Prev / Next nav — matches BbdNav // --------------------------------------------------------------------------- function MonthNav({ prev, next, groups, activeMonth, onSelect, year, }: { prev: MonthGroup | null; next: MonthGroup | null; groups: MonthGroup[]; activeMonth: number; onSelect: (month: number) => void; year: number; }) { return (
{prev ? ( ) : (
)}
{next ? ( ) : (
)}
); } // --------------------------------------------------------------------------- // Main component — renders header + sidebar + content (entire page layout) // --------------------------------------------------------------------------- export function YearMonthBrowser({ letters, year, totalCount, }: { letters: LetterItem[]; year: number; totalCount: number; }) { const allGroups = useMemo(() => buildMonthGroups(letters), [letters]); const [activeMonth, setActiveMonth] = useState( allGroups.length > 0 ? allGroups[0].month : 1, ); const contentRef = useRef(null); // Keep active month valid useEffect(() => { if ( allGroups.length > 0 && !allGroups.find((g) => g.month === activeMonth) ) { setActiveMonth(allGroups[0].month); } }, [allGroups, activeMonth]); const handleMonthSelect = (month: number) => { setActiveMonth(month); contentRef.current?.scrollIntoView({ behavior: "smooth", block: "start" }); }; // Active group + neighbors const activeIdx = allGroups.findIndex((g) => g.month === activeMonth); const activeGroup = activeIdx >= 0 ? allGroups[activeIdx] : null; const prev = activeIdx > 0 ? allGroups[activeIdx - 1] : null; const next = activeIdx >= 0 && activeIdx < allGroups.length - 1 ? allGroups[activeIdx + 1] : null; const activeLetters = activeGroup?.letters ?? []; const activeLabel = activeGroup?.label ?? "Unknown Month"; return ( <> {/* Header */}
← Letters by Year

Letters: {activeLabel} {year}

{activeGroup?.count ?? 0}{" "} {(activeGroup?.count ?? 0) === 1 ? "letter" : "letters"} ·{" "} {totalCount} total in {year}

{/* Sidebar + Main */}
{/* Left sidebar */} {/* Main content */}
{/* Top navigation */} {/* Content */} {activeLetters.length === 0 ? (

No letters for this month

) : (
    {activeLetters.map((letter) => (
  • To: {letter.recipientDisplay}

    {letter.date || "Undated"} {letter.location ? ` · ${letter.location}` : ""}

  • ))}
)} {/* Bottom navigation */}
); }