"use client"; import { useState, useRef, useEffect } from "react"; import { useTranslations, useFormatter } from "next-intl"; import { Button } from "@/components/ui/button"; import { ChevronLeft, ChevronRight, Plus, Upload, CalendarDays, Globe, ChevronDown, ListTodo } from "lucide-react"; import { addDays, startOfWeek } from "date-fns"; import { cn } from "@/lib/utils"; import type { CalendarViewMode } from "@/stores/calendar-store"; import type { Calendar } from "@/lib/jmap/types"; interface CalendarToolbarProps { selectedDate: Date; viewMode: CalendarViewMode; onPrev: () => void; onNext: () => void; onToday: () => void; onViewModeChange: (mode: CalendarViewMode) => void; onCreateEvent: () => void; onImport?: () => void; onSubscribe?: () => void; isMobile?: boolean; firstDayOfWeek?: number; onNavigateBack?: () => void; calendars?: Calendar[]; selectedCalendarIds?: string[]; onToggleVisibility?: (id: string) => void; enableCalendarTasks?: boolean; } export function CalendarToolbar({ selectedDate, viewMode, onPrev, onNext, onToday, onViewModeChange, onCreateEvent, onImport, onSubscribe, isMobile, firstDayOfWeek = 1, calendars, selectedCalendarIds, onToggleVisibility, enableCalendarTasks, }: CalendarToolbarProps) { const t = useTranslations("calendar"); const formatter = useFormatter(); const views: CalendarViewMode[] = enableCalendarTasks ? ["month", "week", "day", "agenda", "tasks"] : ["month", "week", "day", "agenda"]; const [showCalendarDropdown, setShowCalendarDropdown] = useState(false); const dropdownRef = useRef(null); useEffect(() => { if (!showCalendarDropdown) return; function handleClickOutside(e: MouseEvent) { if (dropdownRef.current && !dropdownRef.current.contains(e.target as Node)) { setShowCalendarDropdown(false); } } document.addEventListener("mousedown", handleClickOutside); return () => document.removeEventListener("mousedown", handleClickOutside); }, [showCalendarDropdown]); const getDateLabel = (): string => { switch (viewMode) { case "month": return isMobile ? formatter.dateTime(selectedDate, { month: "short", year: "numeric" }) : formatter.dateTime(selectedDate, { month: "long", year: "numeric" }); case "week": { const ws = startOfWeek(selectedDate, { weekStartsOn: firstDayOfWeek as 0 | 1 }); const we = addDays(ws, 6); if (isMobile) { return `${formatter.dateTime(ws, { month: "short", day: "numeric" })} – ${formatter.dateTime(we, { day: "numeric" })}`; } const sameMonth = ws.getMonth() === we.getMonth(); if (sameMonth) { return `${formatter.dateTime(ws, { month: "short", day: "numeric" })} – ${formatter.dateTime(we, { day: "numeric" })}, ${we.getFullYear()}`; } return `${formatter.dateTime(ws, { month: "short", day: "numeric" })} – ${formatter.dateTime(we, { month: "short", day: "numeric" })}, ${we.getFullYear()}`; } case "day": return isMobile ? formatter.dateTime(selectedDate, { weekday: "short", month: "short", day: "numeric" }) : formatter.dateTime(selectedDate, { weekday: "long", month: "long", day: "numeric", year: "numeric" }); case "agenda": return isMobile ? formatter.dateTime(selectedDate, { month: "short", year: "numeric" }) : formatter.dateTime(selectedDate, { month: "long", year: "numeric" }); case "tasks": return t("views.tasks"); } }; const [showImportDropdown, setShowImportDropdown] = useState(false); const importDropdownRef = useRef(null); const [showViewDropdown, setShowViewDropdown] = useState(false); const viewDropdownRef = useRef(null); useEffect(() => { if (!showImportDropdown) return; function handleClickOutside(e: MouseEvent) { if (importDropdownRef.current && !importDropdownRef.current.contains(e.target as Node)) { setShowImportDropdown(false); } } document.addEventListener("mousedown", handleClickOutside); return () => document.removeEventListener("mousedown", handleClickOutside); }, [showImportDropdown]); useEffect(() => { if (!showViewDropdown) return; function handleClickOutside(e: MouseEvent) { if (viewDropdownRef.current && !viewDropdownRef.current.contains(e.target as Node)) { setShowViewDropdown(false); } } document.addEventListener("mousedown", handleClickOutside); return () => document.removeEventListener("mousedown", handleClickOutside); }, [showViewDropdown]); return (
{isMobile && (
{getDateLabel()}
)} {!isMobile && (
{getDateLabel()}
)} {isMobile && calendars && selectedCalendarIds && onToggleVisibility && (
{showCalendarDropdown && (

{t("my_calendars")}

{calendars.filter(c => !c.isShared).map((cal) => { const isVisible = selectedCalendarIds.includes(cal.id); const color = cal.color || "#3b82f6"; return ( ); })}
{(() => { const shared = calendars.filter(c => c.isShared); const groups = new Map(); for (const c of shared) { const key = c.accountId || c.accountName || c.id; if (!groups.has(key)) groups.set(key, { accountName: c.accountName || key, cals: [] }); groups.get(key)!.cals.push(c); } return Array.from(groups.values()).map((group) => (

{group.accountName}

{group.cals.map((cal) => { const isVisible = selectedCalendarIds.includes(cal.id); const color = cal.color || "#3b82f6"; return ( ); })}
)); })()}
)}
)} {isMobile && (
{showViewDropdown && (
{views.map((v) => ( ))}
)}
)}
{!isMobile && (
{views.map((v) => ( ))}
)} {(onImport || onSubscribe) && !isMobile && (
{showImportDropdown && (
{onImport && ( )} {onSubscribe && ( )}
)}
)} {!isMobile && ( )}
); }