/* calendar.jsx — Календарь: месяц с напоминаниями + список на выбранный день. */ function _pad(n) { return String(n).padStart(2, "0"); } function _dayKey(d) { return `${d.getFullYear()}-${_pad(d.getMonth() + 1)}-${_pad(d.getDate())}`; } function _buildMonth(base) { // base — первое число месяца. Возвращает 6 недель по 7 дат (Пн-первый). const first = new Date(base.getFullYear(), base.getMonth(), 1); const offset = (first.getDay() + 6) % 7; // Пн=0 const start = new Date(first); start.setDate(1 - offset); const weeks = []; for (let w = 0; w < 6; w++) { const row = []; for (let d = 0; d < 7; d++) { row.push(new Date(start.getFullYear(), start.getMonth(), start.getDate() + w * 7 + d)); } weeks.push(row); } return weeks; } function CalendarScreen({ onOpenNote }) { const [base, setBase] = React.useState(() => { const d = new Date(); return new Date(d.getFullYear(), d.getMonth(), 1); }); const [items, setItems] = React.useState([]); const [sel, setSel] = React.useState(() => _dayKey(new Date())); const [loading, setLoading] = React.useState(true); React.useEffect(() => { setLoading(true); api.getReminders().then((r) => { setItems(r || []); setLoading(false); }).catch(() => setLoading(false)); }, []); const byDay = React.useMemo(() => { const m = {}; items.forEach((r) => { const k = _dayKey(new Date(r.remind_at)); (m[k] = m[k] || []).push(r); }); return m; }, [items]); const weeks = _buildMonth(base); const todayKey = _dayKey(new Date()); const selItems = (byDay[sel] || []).slice().sort((a, b) => new Date(a.remind_at) - new Date(b.remind_at)); const openNote = async (r) => { if (!r.note_id) return; try { const list = await api.getNotes({}); const n = list.find((x) => x.id === r.note_id); if (n) onOpenNote(n); } catch (e) {} }; const prev = () => setBase(new Date(base.getFullYear(), base.getMonth() - 1, 1)); const next = () => setBase(new Date(base.getFullYear(), base.getMonth() + 1, 1)); const goToday = () => { const d = new Date(); setBase(new Date(d.getFullYear(), d.getMonth(), 1)); setSel(_dayKey(d)); }; const dows = ["Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс"]; return (
{MONTHS_FULL[base.getMonth()]} {base.getFullYear()}
{dows.map((d) =>
{d}
)}
{weeks.flat().map((d) => { const k = _dayKey(d); const inMonth = d.getMonth() === base.getMonth(); const isToday = k === todayKey; const isSel = k === sel; const dayItems = byDay[k] || []; const hasPending = dayItems.some((r) => r.status === "pending"); return ( ); })}
{/* список выбранного дня */}

{(() => { const [y, m, dd] = sel.split("-").map(Number); const dt = new Date(y, m - 1, dd); return `${dt.getDate()} ${MONTHS_FULL[dt.getMonth()]}`; })()} · {selItems.length}

{loading ? (
{[0, 1].map((i) =>
)}
) : selItems.length === 0 ? (

На этот день напоминаний нет.

) : (
{selItems.map((r) => { const f = formatRemind(r.remind_at); const done = r.status !== "pending"; return ( ); })}
)}
); } Object.assign(window, { CalendarScreen });