diff --git a/public/pages/calendar.js b/public/pages/calendar.js index b022744..dc591b4 100644 --- a/public/pages/calendar.js +++ b/public/pages/calendar.js @@ -9,7 +9,7 @@ import { renderRRuleFields, bindRRuleEvents, getRRuleValues } from '/rrule-ui.js import { openModal as openSharedModal, closeModal, confirmModal } from '/components/modal.js'; import { stagger } from '/utils/ux.js'; import { t, formatTime } from '/i18n.js'; -import { esc } from '/utils/html.js'; +import { esc, fmtLocation } from '/utils/html.js'; import { refresh as refreshReminders } from '/reminders.js'; // -------------------------------------------------------- @@ -48,6 +48,22 @@ const EVENT_COLORS = [ const HOUR_HEIGHT = 56; // px pro Stunde in Wochen-/Tagesansicht +/** + * Gibt eine lesbare Textfarbe für eine Hintergrundfarbe zurück. + * Helle Hintergründe (z.B. Hellgelb, Hellgrün) → dunkles Grau statt Weiß. + */ +function getContrastColor(hex) { + if (!hex || hex.length < 7) return null; + try { + const r = parseInt(hex.slice(1, 3), 16) / 255; + const g = parseInt(hex.slice(3, 5), 16) / 255; + const b = parseInt(hex.slice(5, 7), 16) / 255; + const lin = (c) => c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4); + const L = 0.2126 * lin(r) + 0.7152 * lin(g) + 0.0722 * lin(b); + return L > 0.30 ? '#3D3D3D' : null; // null → CSS-Standard (weiß) bleibt + } catch { return null; } +} + // -------------------------------------------------------- // State // -------------------------------------------------------- @@ -379,13 +395,17 @@ function renderMonthDay(date, inMonth) { const shown = evs.slice(0, MAX_SHOW); const extra = evs.length - MAX_SHOW; - const evHtml = shown.map((ev) => ` + const evHtml = shown.map((ev) => { + const bg = ev.cal_color || ev.color; + const fg = getContrastColor(bg); + return `
${esc(ev.title)}
- `).join(''); + `; + }).join(''); return `
@@ -430,8 +450,9 @@ function renderWeekView(container) { ${days.map((d, i) => `
${alldayEvs[i].map((ev) => ` -
${esc(ev.title)}
+
${esc(ev.title)}
`).join('')}
`).join('')} @@ -502,7 +523,7 @@ function renderWeekEvent(ev) { return `
+ style="top:${top}px;height:${height}px;${ev.cal_color || ev.color ? `background-color:${esc(ev.cal_color || ev.color)};` : ''}${getContrastColor(ev.cal_color || ev.color) ? `color:${getContrastColor(ev.cal_color || ev.color)};` : ''}">
${esc(ev.title)}
${formatTime(ev.start_datetime)}${ev.end_datetime ? '–' + formatTime(ev.end_datetime) : ''}
@@ -541,9 +562,9 @@ function renderDayView(container) {
${t('calendar.allDayShort')}
${allday.map((ev) => ` -
- ${esc(ev.title)} -
`).join('')} +
${esc(ev.title)}
`).join('')}
` : ''}
@@ -634,14 +655,16 @@ function renderAgendaEvent(ev) { ? ev.assigned_name.split(' ').map((w) => w[0]).join('').toUpperCase().slice(0, 2) : ''; + const displayColor = ev.cal_color || ev.color; return `
-
+
${esc(ev.title)}${(ev.recurrence_rule || ev.is_recurring_instance) ? ' ' : ''}
${timeStr} - ${ev.location ? `📍 ${esc(ev.location)}` : ''} + ${ev.location ? `📍 ${esc(fmtLocation(ev.location))}` : ''} + ${ev.cal_name ? `${esc(ev.cal_name)}` : ''} ${ev.assigned_name ? ` ${initials} @@ -669,12 +692,14 @@ function showEventPopup(ev, anchor) { : formatDateTime(ev.start_datetime) + (ev.end_datetime ? ` – ${formatTime(ev.end_datetime)}${t('calendar.timeSuffix') ? ' ' + t('calendar.timeSuffix') : ''}`.trim() : ''); + const displayColor = ev.cal_color || ev.color; popup.innerHTML = ` -
+
${esc(ev.title)}
+ ${ev.cal_name ? `
${esc(ev.cal_name)}
` : ''}
${timeStr}
- ${ev.location ? `
📍 ${esc(ev.location)}
` : ''} + ${ev.location ? `
📍 ${esc(fmtLocation(ev.location))}
` : ''} ${ev.description ? `
${esc(ev.description)}
` : ''} ${ev.assigned_name ? `
👤 ${esc(ev.assigned_name)}
` : ''}