diff --git a/frontend/css/app.css b/frontend/css/app.css index e3f6e06..403fb09 100644 --- a/frontend/css/app.css +++ b/frontend/css/app.css @@ -302,6 +302,10 @@ a { color: var(--primary); text-decoration: none; } .color-swatch.active { border-color: var(--text-1); } .ev-color-row { display: flex; align-items: center; gap: 8px; } +.ev-reminders-list { display: flex; flex-direction: column; gap: 6px; margin-bottom: 6px; } +.ev-reminder-row { display: flex; align-items: center; gap: 8px; } +.ev-reminder-row select { flex: 1; } +.ev-reminder-remove { flex-shrink: 0; } .ev-color-hex { flex: 1; height: 36px; padding: 0 10px; background: var(--bg-hover); border: 1px solid var(--border); @@ -539,6 +543,11 @@ a { color: var(--primary); text-decoration: none; } width and only truncates while the button is visible. */ .cal-item-remove { display: none; } .cal-item:hover .cal-item-remove { display: inline-flex; } +/* Reminder bell: only shown on hover when enabled, but always shown (dimmed) + when disabled so the muted state is visible at a glance. */ +.cal-item-bell { display: none; flex-shrink: 0; } +.cal-item:hover .cal-item-bell { display: inline-flex; } +.cal-item-bell.off { display: inline-flex; color: var(--text-3); opacity: .75; } /* ── Month View ─────────────────────────────────────────── */ .month-view { display: flex; flex-direction: column; flex: 1; min-height: 0; } @@ -574,7 +583,7 @@ a { color: var(--primary); text-decoration: none; } } .month-col:last-child { border-right: none; } .month-col:hover { background: var(--bg-hover); } -.month-col.today { background: rgba(66,133,244,.08); } +.month-col.today { background: color-mix(in srgb, var(--today-color) 10%, transparent); } .month-col.month-selected { background: var(--primary-dim); } .month-col.month-selected .cell-day { border: 2px solid var(--primary); color: var(--primary); font-weight: 700; } .month-col.month-selected .cell-day.today { background: var(--today-color); color: #fff; border: none; } diff --git a/frontend/index.html b/frontend/index.html index 49f0b92..9a91336 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -364,6 +364,11 @@
+ ` ).join(''); @@ -825,6 +836,37 @@ function renderCalendarList() { }); }); + // ── Reminder bell handlers (toggle reminders_enabled per calendar) ── + container.querySelectorAll('.cal-item-bell').forEach(btn => { + btn.addEventListener('click', async e => { + e.stopPropagation(); + const source = btn.dataset.source; + const id = parseInt(btn.dataset.calId || btn.dataset.subId); + let cal = null; + if (source === 'caldav') { + for (const acc of state.accounts) { const c = acc.calendars.find(c => c.id === id); if (c) cal = c; } + } else if (source === 'local') { + cal = state.localCalendars.find(c => c.id === id); + } else if (source === 'ical') { + cal = state.icalSubscriptions.find(s => s.id === id); + } else if (source === 'google') { + for (const acc of state.googleAccounts) { const c = acc.calendars.find(c => c.id === id); if (c) cal = c; } + } else if (source === 'homeassistant') { + for (const acc of state.haAccounts) { const c = acc.calendars.find(c => c.id === id); if (c) cal = c; } + } + if (!cal) return; + const newVal = cal.reminders_enabled === false; // toggle + const path = source === 'ical' + ? `/ical/subscriptions/${id}` + : `/${source}/calendars/${id}`; + try { + await api.put(path, { reminders_enabled: newVal }); + cal.reminders_enabled = newVal; + renderCalendarList(); + } catch (err) { showToast(err.message, true); } + }); + }); + // ── Color dot handlers ───────────────────────────────── container.querySelectorAll('.cal-item-dot').forEach(dot => { dot.addEventListener('click', async e => { @@ -1463,15 +1505,24 @@ function populateCalendarSelect(selectedId) { sel.appendChild(opt); }); }); - // Local calendars (group calendars marked with 👥 so group events can be - // created from anywhere, not just the group view). - state.localCalendars.filter(c => !c.sidebar_hidden).forEach(cal => { + // Local calendars. Group calendars are collected under a "Groups" optgroup + // (no emoji — a native