'use client' import { useState, useMemo, useCallback } from 'react' import { ChevronLeft, ChevronRight } from 'lucide-react' import { useLanguage } from '@/lib/i18n' import { cn } from '@/lib/utils' import type { Note } from '@/lib/types' import type { NotebookSchemaPayload, NotePropertyValues } from '@/lib/structured-views/types' type NotesCalendarViewProps = { notes: Note[] schema: NotebookSchemaPayload noteValues: Record notebookColor?: string | null onOpen: (note: Note) => void onPropertyChange: (noteId: string, propertyId: string, value: unknown) => void } const WEEKDAYS_FR = ['Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam', 'Dim'] const WEEKDAYS_EN = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] const MONTHS_FR = ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'] const MONTHS_EN = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] function getDateString(value: unknown): string | null { if (!value || typeof value !== 'string') return null const d = new Date(value) if (isNaN(d.getTime())) return null return d.toISOString().slice(0, 10) } export function NotesCalendarView({ notes, schema, noteValues, notebookColor, onOpen, onPropertyChange, }: NotesCalendarViewProps) { const { t, language } = useLanguage() const isFR = language === 'fr' const weekdays = isFR ? WEEKDAYS_FR : WEEKDAYS_EN const months = isFR ? MONTHS_FR : MONTHS_EN const [currentMonth, setCurrentMonth] = useState(() => { const now = new Date() return new Date(now.getFullYear(), now.getMonth(), 1) }) const dateProperty = useMemo(() => { return schema.properties.find(p => p.type === 'date') }, [schema.properties]) const notesByDate = useMemo(() => { const map = new Map() if (!dateProperty) return map for (const note of notes) { const vals = noteValues[note.id] if (!vals) continue const raw = vals[dateProperty.id] const dateStr = getDateString(raw) if (!dateStr) continue const existing = map.get(dateStr) || [] existing.push(note) map.set(dateStr, existing) } return map }, [notes, noteValues, dateProperty]) const calendarDays = useMemo(() => { const year = currentMonth.getFullYear() const month = currentMonth.getMonth() const firstDay = new Date(year, month, 1) const lastDay = new Date(year, month + 1, 0) const startWeekday = (firstDay.getDay() + 6) % 7 const daysInMonth = lastDay.getDate() const days: Array<{ date: string | null; day: number | null; isToday: boolean }> = [] for (let i = 0; i < startWeekday; i++) { days.push({ date: null, day: null, isToday: false }) } const todayStr = new Date().toISOString().slice(0, 10) for (let d = 1; d <= daysInMonth; d++) { const dateStr = new Date(year, month, d).toISOString().slice(0, 10) days.push({ date: dateStr, day: d, isToday: dateStr === todayStr }) } const remaining = (7 - (days.length % 7)) % 7 for (let i = 0; i < remaining; i++) { days.push({ date: null, day: null, isToday: false }) } return days }, [currentMonth]) const prevMonth = useCallback(() => { setCurrentMonth(m => new Date(m.getFullYear(), m.getMonth() - 1, 1)) }, []) const nextMonth = useCallback(() => { setCurrentMonth(m => new Date(m.getFullYear(), m.getMonth() + 1, 1)) }, []) const todayMonth = useCallback(() => { const now = new Date() setCurrentMonth(new Date(now.getFullYear(), now.getMonth(), 1)) }, []) if (!dateProperty) { return (

{t('structuredViews.calendarNoDateProperty')}

) } return (

{months[currentMonth.getMonth()]} {currentMonth.getFullYear()}

{weekdays.map(wd => (
{wd}
))} {calendarDays.map((day, i) => { const dayNotes = day.date ? (notesByDate.get(day.date) || []) : [] return (
{day.day && ( {day.day} )} {dayNotes.slice(0, 3).map(note => ( ))} {dayNotes.length > 3 && ( +{dayNotes.length - 3} )}
) })}
) }