diff --git a/public/pages/calendar.js b/public/pages/calendar.js
index 4174ee4..4949046 100644
--- a/public/pages/calendar.js
+++ b/public/pages/calendar.js
@@ -8,17 +8,35 @@ import { api } from '/api.js';
import { renderRRuleFields, bindRRuleEvents, getRRuleValues } from '/rrule-ui.js';
import { openModal as openSharedModal, closeModal } from '/components/modal.js';
import { stagger } from '/utils/ux.js';
+import { t } from '/i18n.js';
// --------------------------------------------------------
// Konstanten
// --------------------------------------------------------
const VIEWS = ['month', 'week', 'day', 'agenda'];
-const VIEW_LABELS = { month: 'Monat', week: 'Woche', day: 'Tag', agenda: 'Agenda' };
-const DAY_NAMES_SHORT = ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'];
-const DAY_NAMES_LONG = ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'];
-const MONTH_NAMES = ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni',
- 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'];
+const VIEW_LABELS = () => ({
+ month: t('calendar.viewMonth'),
+ week: t('calendar.viewWeek'),
+ day: t('calendar.viewDay'),
+ agenda: t('calendar.viewAgenda'),
+});
+const DAY_NAMES_SHORT = () => [
+ t('calendar.dayShortSunday'), t('calendar.dayShortMonday'), t('calendar.dayShortTuesday'),
+ t('calendar.dayShortWednesday'), t('calendar.dayShortThursday'), t('calendar.dayShortFriday'),
+ t('calendar.dayShortSaturday'),
+];
+const DAY_NAMES_LONG = () => [
+ t('calendar.dayLongSunday'), t('calendar.dayLongMonday'), t('calendar.dayLongTuesday'),
+ t('calendar.dayLongWednesday'), t('calendar.dayLongThursday'), t('calendar.dayLongFriday'),
+ t('calendar.dayLongSaturday'),
+];
+const MONTH_NAMES = () => [
+ t('calendar.monthJanuary'), t('calendar.monthFebruary'), t('calendar.monthMarch'),
+ t('calendar.monthApril'), t('calendar.monthMay'), t('calendar.monthJune'),
+ t('calendar.monthJuly'), t('calendar.monthAugust'), t('calendar.monthSeptember'),
+ t('calendar.monthOctober'), t('calendar.monthNovember'), t('calendar.monthDecember'),
+];
const EVENT_COLORS = [
'#007AFF', '#34C759', '#FF9500', '#FF3B30',
@@ -73,9 +91,9 @@ function getMondayOf(dateStr) {
function formatDate(dateStr, { long = false, weekday = false } = {}) {
const d = new Date(dateStr + 'T00:00:00');
const day = d.getDate();
- const mon = MONTH_NAMES[d.getMonth()];
+ const mon = MONTH_NAMES()[d.getMonth()];
if (weekday) {
- const wd = long ? DAY_NAMES_LONG[d.getDay()] : DAY_NAMES_SHORT[d.getDay()];
+ const wd = long ? DAY_NAMES_LONG()[d.getDay()] : DAY_NAMES_SHORT()[d.getDay()];
return `${wd}, ${day}. ${mon}`;
}
return `${day}. ${mon} ${d.getFullYear()}`;
@@ -132,7 +150,7 @@ async function loadRange(from, to) {
} catch (err) {
console.error('[Calendar] loadRange Fehler:', err);
state.events = [];
- window.oikos?.showToast('Termine konnten nicht geladen werden.', 'danger');
+ window.oikos?.showToast(t('calendar.loadError'), 'danger');
}
state.rangeFrom = from;
state.rangeTo = to;
@@ -161,7 +179,7 @@ export async function render(container, { user }) {
@@ -185,26 +203,26 @@ function renderToolbar() {
if (!bar) return;
bar.innerHTML = `
- Kalender
+ ${t('calendar.title')}
-
- Heute
+ ${t('calendar.today')}
${VIEWS.map((v) => `
${VIEW_LABELS[v]}
+ data-view="${v}">${VIEW_LABELS()[v]}
`).join('')}
-
-
+
@@ -237,12 +255,12 @@ function updateLabel() {
if (!lbl) return;
const d = new Date(state.cursor + 'T00:00:00');
const year = d.getFullYear();
- const mon = MONTH_NAMES[d.getMonth()];
+ const mon = MONTH_NAMES()[d.getMonth()];
if (state.view === 'month') lbl.textContent = `${mon} ${year}`;
- if (state.view === 'week') lbl.textContent = `KW ${getWeekNumber(state.cursor)} · ${mon} ${year}`;
+ if (state.view === 'week') lbl.textContent = t('calendar.weekNumberLabel', { week: getWeekNumber(state.cursor), month: mon, year });
if (state.view === 'day') lbl.textContent = formatDate(state.cursor, { weekday: true, long: true });
- if (state.view === 'agenda') lbl.textContent = `Ab ${formatDate(state.cursor)}`;
+ if (state.view === 'agenda') lbl.textContent = t('calendar.agendaFrom', { date: formatDate(state.cursor) });
}
function getWeekNumber(dateStr) {
@@ -328,7 +346,7 @@ function renderMonthView(container) {
container.innerHTML = `
- ${['Mo','Di','Mi','Do','Fr','Sa','So'].map((n) => `
${n}
`).join('')}
+ ${[t('calendar.dayShortMonday'),t('calendar.dayShortTuesday'),t('calendar.dayShortWednesday'),t('calendar.dayShortThursday'),t('calendar.dayShortFriday'),t('calendar.dayShortSaturday'),t('calendar.dayShortSunday')].map((n) => `
${n}
`).join('')}
${days.map(({ date, inMonth }) => renderMonthDay(date, inMonth)).join('')}
@@ -376,7 +394,7 @@ function renderMonthDay(date, inMonth) {
${new Date(date + 'T00:00:00').getDate()}
${evHtml}
- ${extra > 0 ? `
+${extra} weitere
` : ''}
+ ${extra > 0 ? `
${t('calendar.moreEvents', { count: extra })}
` : ''}
`;
}
@@ -404,14 +422,14 @@ function renderWeekView(container) {
${days.map((d) => {
const dt = new Date(d + 'T00:00:00');
return ``;
}).join('')}
-
ganztg.
+
${t('calendar.allDayShort')}
${days.map((d, i) => `
${alldayEvs[i].map((ev) => `
@@ -523,7 +541,7 @@ function renderDayView(container) {
${allday.length ? `
-
ganztg.
+
${t('calendar.allDayShort')}
${allday.map((ev) => `
@@ -584,12 +602,12 @@ function renderAgendaView(container) {
container.innerHTML = `
${groups.length === 0
- ? `
Keine Termine im gewählten Zeitraum.
`
+ ? `
${t('calendar.noEvents')}
`
: groups.map(({ date, events }) => `
${events.map((ev) => renderAgendaEvent(ev)).join('')}
@@ -611,7 +629,7 @@ function renderAgendaView(container) {
function renderAgendaEvent(ev) {
const timeStr = ev.all_day
- ? 'Ganztägig'
+ ? t('calendar.allDay')
: formatTime(ev.start_datetime)
+ (ev.end_datetime ? ` – ${formatTime(ev.end_datetime)} Uhr` : ' Uhr');
@@ -650,7 +668,7 @@ function showEventPopup(ev, anchor) {
popup.className = 'event-popup';
const timeStr = ev.all_day
- ? 'Ganztägig'
+ ? t('calendar.allDay')
: formatDateTime(ev.start_datetime)
+ (ev.end_datetime ? ` – ${formatTime(ev.end_datetime)} Uhr` : '');
@@ -664,7 +682,7 @@ function showEventPopup(ev, anchor) {
${ev.assigned_name ? `
👤 ${escHtml(ev.assigned_name)}
` : ''}