a11y: aria-hidden auf allen Icons + aria-label auf icon-only Buttons (Redesign Phase F)
- Alle data-lucide Icons: aria-hidden="true" (dekorativ) - Icon-only Buttons/Links: title→aria-label (Screenreader-zugänglich) - Betrifft: modal.js, contacts, meals, budget, calendar, notes, tasks, shopping, dashboard Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -93,7 +93,7 @@ export function openModal({ title, content, onSave, onDelete, size = 'md' } = {}
|
|||||||
<div class="modal-panel__header">
|
<div class="modal-panel__header">
|
||||||
<h2 class="modal-panel__title" id="shared-modal-title">${title}</h2>
|
<h2 class="modal-panel__title" id="shared-modal-title">${title}</h2>
|
||||||
<button class="modal-panel__close" data-action="close-modal" aria-label="Schließen">
|
<button class="modal-panel__close" data-action="close-modal" aria-label="Schließen">
|
||||||
<i data-lucide="x" style="width:18px;height:18px"></i>
|
<i data-lucide="x" style="width:18px;height:18px" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-panel__body">
|
<div class="modal-panel__body">
|
||||||
|
|||||||
+10
-10
@@ -86,22 +86,22 @@ export async function render(container, { user }) {
|
|||||||
<h1 class="sr-only">Budget</h1>
|
<h1 class="sr-only">Budget</h1>
|
||||||
<div class="budget-nav">
|
<div class="budget-nav">
|
||||||
<button class="btn btn--icon" id="budget-prev" aria-label="Vorheriger Monat">
|
<button class="btn btn--icon" id="budget-prev" aria-label="Vorheriger Monat">
|
||||||
<i data-lucide="chevron-left"></i>
|
<i data-lucide="chevron-left" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
<button class="budget-nav__today" id="budget-today">Aktuell</button>
|
<button class="budget-nav__today" id="budget-today">Aktuell</button>
|
||||||
<span class="budget-nav__label" id="budget-label"></span>
|
<span class="budget-nav__label" id="budget-label"></span>
|
||||||
<button class="btn btn--primary btn--icon" id="budget-add" aria-label="Eintrag hinzufügen">
|
<button class="btn btn--primary btn--icon" id="budget-add" aria-label="Eintrag hinzufügen">
|
||||||
<i data-lucide="plus"></i>
|
<i data-lucide="plus" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn--icon" id="budget-next" aria-label="Nächster Monat">
|
<button class="btn btn--icon" id="budget-next" aria-label="Nächster Monat">
|
||||||
<i data-lucide="chevron-right"></i>
|
<i data-lucide="chevron-right" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="budget-body" style="flex:1;display:flex;flex-direction:column;overflow:hidden;">
|
<div id="budget-body" style="flex:1;display:flex;flex-direction:column;overflow:hidden;">
|
||||||
<div style="padding:2rem;text-align:center;color:var(--color-text-disabled);">Lade…</div>
|
<div style="padding:2rem;text-align:center;color:var(--color-text-disabled);">Lade…</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="page-fab" id="fab-new-budget" aria-label="Neuer Eintrag">
|
<button class="page-fab" id="fab-new-budget" aria-label="Neuer Eintrag">
|
||||||
<i data-lucide="plus" style="width:24px;height:24px"></i>
|
<i data-lucide="plus" style="width:24px;height:24px" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
@@ -192,7 +192,7 @@ function renderBody() {
|
|||||||
${state.entries.length ? `
|
${state.entries.length ? `
|
||||||
<a href="/api/v1/budget/export?month=${state.month}" class="btn btn--secondary"
|
<a href="/api/v1/budget/export?month=${state.month}" class="btn btn--secondary"
|
||||||
style="font-size:var(--text-sm);padding:var(--space-1) var(--space-3);">
|
style="font-size:var(--text-sm);padding:var(--space-1) var(--space-3);">
|
||||||
<i data-lucide="download" style="width:14px;height:14px;margin-right:4px;"></i>CSV
|
<i data-lucide="download" style="width:14px;height:14px;margin-right:4px;" aria-hidden="true"></i>CSV
|
||||||
</a>` : ''}
|
</a>` : ''}
|
||||||
</div>
|
</div>
|
||||||
<div class="budget-list" id="budget-list">
|
<div class="budget-list" id="budget-list">
|
||||||
@@ -240,7 +240,7 @@ function renderCategoryBars(byCategory) {
|
|||||||
function renderEntries() {
|
function renderEntries() {
|
||||||
if (!state.entries.length) {
|
if (!state.entries.length) {
|
||||||
return `<div class="budget-empty">
|
return `<div class="budget-empty">
|
||||||
<i data-lucide="receipt" style="width:48px;height:48px;color:var(--color-text-disabled);margin-bottom:var(--space-3);"></i>
|
<i data-lucide="receipt" style="width:48px;height:48px;color:var(--color-text-disabled);margin-bottom:var(--space-3);" aria-hidden="true"></i>
|
||||||
<div style="font-size:var(--text-base);font-weight:600;">Keine Einträge</div>
|
<div style="font-size:var(--text-base);font-weight:600;">Keine Einträge</div>
|
||||||
<div style="font-size:var(--text-sm);margin-top:var(--space-1);">Noch keine Transaktionen für diesen Monat.</div>
|
<div style="font-size:var(--text-sm);margin-top:var(--space-1);">Noch keine Transaktionen für diesen Monat.</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
@@ -261,8 +261,8 @@ function renderEntries() {
|
|||||||
<div class="budget-entry__meta">${date} · ${escHtml(e.category)}${e.is_recurring ? ' 🔁' : ''}</div>
|
<div class="budget-entry__meta">${date} · ${escHtml(e.category)}${e.is_recurring ? ' 🔁' : ''}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="budget-entry__amount ${amtClass}">${sign}${formatAmount(e.amount)}</div>
|
<div class="budget-entry__amount ${amtClass}">${sign}${formatAmount(e.amount)}</div>
|
||||||
<button class="budget-entry__delete" data-action="delete" data-id="${e.id}" title="Löschen">
|
<button class="budget-entry__delete" data-action="delete" data-id="${e.id}" aria-label="Eintrag löschen">
|
||||||
<i data-lucide="trash-2" style="width:14px;height:14px;"></i>
|
<i data-lucide="trash-2" style="width:14px;height:14px;" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
@@ -329,8 +329,8 @@ function openBudgetModal({ mode, entry = null }) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="modal-panel__footer" style="border:none;padding:0;margin-top:var(--space-4)">
|
<div class="modal-panel__footer" style="border:none;padding:0;margin-top:var(--space-4)">
|
||||||
${isEdit ? `<button class="btn btn--danger btn--icon" id="bm-delete" title="Löschen">
|
${isEdit ? `<button class="btn btn--danger btn--icon" id="bm-delete" aria-label="Eintrag löschen">
|
||||||
<i data-lucide="trash-2" style="width:16px;height:16px;"></i>
|
<i data-lucide="trash-2" style="width:16px;height:16px;" aria-hidden="true"></i>
|
||||||
</button>` : '<div></div>'}
|
</button>` : '<div></div>'}
|
||||||
<div style="display:flex;gap:var(--space-3)">
|
<div style="display:flex;gap:var(--space-3)">
|
||||||
<button class="btn btn--secondary" id="bm-cancel">Abbrechen</button>
|
<button class="btn btn--secondary" id="bm-cancel">Abbrechen</button>
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ export async function render(container, { user }) {
|
|||||||
<div class="cal-toolbar" id="cal-toolbar"></div>
|
<div class="cal-toolbar" id="cal-toolbar"></div>
|
||||||
<div id="cal-body" style="flex:1;display:flex;flex-direction:column;overflow:hidden;"></div>
|
<div id="cal-body" style="flex:1;display:flex;flex-direction:column;overflow:hidden;"></div>
|
||||||
<button class="page-fab" id="fab-new-event" aria-label="Neuer Termin">
|
<button class="page-fab" id="fab-new-event" aria-label="Neuer Termin">
|
||||||
<i data-lucide="plus" style="width:24px;height:24px"></i>
|
<i data-lucide="plus" style="width:24px;height:24px" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
@@ -187,7 +187,7 @@ function renderToolbar() {
|
|||||||
<h1 class="sr-only">Kalender</h1>
|
<h1 class="sr-only">Kalender</h1>
|
||||||
<div class="cal-toolbar__nav">
|
<div class="cal-toolbar__nav">
|
||||||
<button class="btn btn--icon" id="cal-prev" aria-label="Zurück">
|
<button class="btn btn--icon" id="cal-prev" aria-label="Zurück">
|
||||||
<i data-lucide="chevron-left"></i>
|
<i data-lucide="chevron-left" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<button class="cal-toolbar__today" id="cal-today">Heute</button>
|
<button class="cal-toolbar__today" id="cal-today">Heute</button>
|
||||||
@@ -200,11 +200,11 @@ function renderToolbar() {
|
|||||||
</div>
|
</div>
|
||||||
<button class="btn btn--primary btn--icon" id="cal-add" aria-label="Termin hinzufügen"
|
<button class="btn btn--primary btn--icon" id="cal-add" aria-label="Termin hinzufügen"
|
||||||
style="margin-left:auto;">
|
style="margin-left:auto;">
|
||||||
<i data-lucide="plus"></i>
|
<i data-lucide="plus" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
<div class="cal-toolbar__nav">
|
<div class="cal-toolbar__nav">
|
||||||
<button class="btn btn--icon" id="cal-next" aria-label="Weiter">
|
<button class="btn btn--icon" id="cal-next" aria-label="Weiter">
|
||||||
<i data-lucide="chevron-right"></i>
|
<i data-lucide="chevron-right" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
@@ -620,7 +620,7 @@ function renderAgendaEvent(ev) {
|
|||||||
<div class="agenda-event" data-id="${ev.id}">
|
<div class="agenda-event" data-id="${ev.id}">
|
||||||
<div class="agenda-event__color" style="background-color:${escHtml(ev.color)};"></div>
|
<div class="agenda-event__color" style="background-color:${escHtml(ev.color)};"></div>
|
||||||
<div class="agenda-event__body">
|
<div class="agenda-event__body">
|
||||||
<div class="agenda-event__title">${escHtml(ev.title)}${ev.recurrence_rule ? ' <i data-lucide="repeat" style="width:12px;height:12px;display:inline;vertical-align:middle;opacity:0.5"></i>' : ''}</div>
|
<div class="agenda-event__title">${escHtml(ev.title)}${ev.recurrence_rule ? ' <i data-lucide="repeat" style="width:12px;height:12px;display:inline;vertical-align:middle;opacity:0.5" aria-hidden="true"></i>' : ''}</div>
|
||||||
<div class="agenda-event__meta">
|
<div class="agenda-event__meta">
|
||||||
<span>${timeStr}</span>
|
<span>${timeStr}</span>
|
||||||
${ev.location ? `<span>📍 ${escHtml(ev.location)}</span>` : ''}
|
${ev.location ? `<span>📍 ${escHtml(ev.location)}</span>` : ''}
|
||||||
@@ -663,7 +663,7 @@ function showEventPopup(ev, anchor) {
|
|||||||
<div class="event-popup__actions">
|
<div class="event-popup__actions">
|
||||||
<button class="btn btn--secondary" style="flex:1;" id="popup-edit">Bearbeiten</button>
|
<button class="btn btn--secondary" style="flex:1;" id="popup-edit">Bearbeiten</button>
|
||||||
<button class="btn btn--danger" id="popup-delete">
|
<button class="btn btn--danger" id="popup-delete">
|
||||||
<i data-lucide="trash-2" style="width:16px;height:16px;"></i>
|
<i data-lucide="trash-2" style="width:16px;height:16px;" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
@@ -850,8 +850,8 @@ function buildEventModalContent({ mode, event, date }) {
|
|||||||
${renderRRuleFields('event', isEdit ? event.recurrence_rule : null)}
|
${renderRRuleFields('event', isEdit ? event.recurrence_rule : null)}
|
||||||
|
|
||||||
<div class="modal-panel__footer" style="border:none;padding:0;margin-top:var(--space-4)">
|
<div class="modal-panel__footer" style="border:none;padding:0;margin-top:var(--space-4)">
|
||||||
${isEdit ? `<button class="btn btn--danger btn--icon" id="modal-delete" title="Löschen">
|
${isEdit ? `<button class="btn btn--danger btn--icon" id="modal-delete" aria-label="Termin löschen">
|
||||||
<i data-lucide="trash-2" style="width:16px;height:16px;"></i>
|
<i data-lucide="trash-2" style="width:16px;height:16px;" aria-hidden="true"></i>
|
||||||
</button>` : '<div></div>'}
|
</button>` : '<div></div>'}
|
||||||
<div style="display:flex;gap:var(--space-3)">
|
<div style="display:flex;gap:var(--space-3)">
|
||||||
<button class="btn btn--secondary" id="modal-cancel">Abbrechen</button>
|
<button class="btn btn--secondary" id="modal-cancel">Abbrechen</button>
|
||||||
|
|||||||
+11
-11
@@ -46,13 +46,13 @@ export async function render(container, { user }) {
|
|||||||
<h1 class="sr-only">Kontakte</h1>
|
<h1 class="sr-only">Kontakte</h1>
|
||||||
<div class="contacts-toolbar">
|
<div class="contacts-toolbar">
|
||||||
<div class="contacts-toolbar__search">
|
<div class="contacts-toolbar__search">
|
||||||
<i data-lucide="search" class="contacts-toolbar__search-icon"></i>
|
<i data-lucide="search" class="contacts-toolbar__search-icon" aria-hidden="true"></i>
|
||||||
<input type="search" class="contacts-toolbar__search-input"
|
<input type="search" class="contacts-toolbar__search-input"
|
||||||
id="contacts-search" placeholder="Name, Telefon oder E-Mail suchen…"
|
id="contacts-search" placeholder="Name, Telefon oder E-Mail suchen…"
|
||||||
autocomplete="off">
|
autocomplete="off">
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn--primary" id="contacts-add-btn">
|
<button class="btn btn--primary" id="contacts-add-btn">
|
||||||
<i data-lucide="plus" style="width:16px;height:16px;margin-right:4px;"></i>
|
<i data-lucide="plus" style="width:16px;height:16px;margin-right:4px;" aria-hidden="true"></i>
|
||||||
Neu
|
Neu
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -64,7 +64,7 @@ export async function render(container, { user }) {
|
|||||||
</div>
|
</div>
|
||||||
<div id="contacts-list" class="contacts-list"></div>
|
<div id="contacts-list" class="contacts-list"></div>
|
||||||
<button class="page-fab" id="fab-new-contact" aria-label="Neuer Kontakt">
|
<button class="page-fab" id="fab-new-contact" aria-label="Neuer Kontakt">
|
||||||
<i data-lucide="plus" style="width:24px;height:24px"></i>
|
<i data-lucide="plus" style="width:24px;height:24px" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
@@ -134,7 +134,7 @@ function renderList() {
|
|||||||
if (!contacts.length) {
|
if (!contacts.length) {
|
||||||
container.innerHTML = `
|
container.innerHTML = `
|
||||||
<div class="contacts-empty">
|
<div class="contacts-empty">
|
||||||
<i data-lucide="users" style="width:48px;height:48px;color:var(--color-text-disabled);margin-bottom:var(--space-3);"></i>
|
<i data-lucide="users" style="width:48px;height:48px;color:var(--color-text-disabled);margin-bottom:var(--space-3);" aria-hidden="true"></i>
|
||||||
<div style="font-size:var(--text-base);font-weight:600;">Keine Kontakte gefunden</div>
|
<div style="font-size:var(--text-base);font-weight:600;">Keine Kontakte gefunden</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
@@ -176,9 +176,9 @@ function renderList() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function renderContactItem(c) {
|
function renderContactItem(c) {
|
||||||
const phone = c.phone ? `<a href="tel:${escHtml(c.phone)}" class="contact-action-btn contact-action-btn--call" title="Anrufen"><i data-lucide="phone" style="width:16px;height:16px;"></i></a>` : '';
|
const phone = c.phone ? `<a href="tel:${escHtml(c.phone)}" class="contact-action-btn contact-action-btn--call" aria-label="Anrufen"><i data-lucide="phone" style="width:16px;height:16px;" aria-hidden="true"></i></a>` : '';
|
||||||
const email = c.email ? `<a href="mailto:${escHtml(c.email)}" class="contact-action-btn contact-action-btn--mail" title="E-Mail"><i data-lucide="mail" style="width:16px;height:16px;"></i></a>` : '';
|
const email = c.email ? `<a href="mailto:${escHtml(c.email)}" class="contact-action-btn contact-action-btn--mail" aria-label="E-Mail"><i data-lucide="mail" style="width:16px;height:16px;" aria-hidden="true"></i></a>` : '';
|
||||||
const maps = c.address ? `<a href="https://maps.google.com/?q=${encodeURIComponent(c.address)}" target="_blank" rel="noopener" class="contact-action-btn contact-action-btn--maps" title="In Maps öffnen"><i data-lucide="map-pin" style="width:16px;height:16px;"></i></a>` : '';
|
const maps = c.address ? `<a href="https://maps.google.com/?q=${encodeURIComponent(c.address)}" target="_blank" rel="noopener" class="contact-action-btn contact-action-btn--maps" aria-label="In Maps öffnen"><i data-lucide="map-pin" style="width:16px;height:16px;" aria-hidden="true"></i></a>` : '';
|
||||||
const meta = [c.phone, c.email].filter(Boolean).join(' · ');
|
const meta = [c.phone, c.email].filter(Boolean).join(' · ');
|
||||||
|
|
||||||
return `
|
return `
|
||||||
@@ -190,8 +190,8 @@ function renderContactItem(c) {
|
|||||||
</div>
|
</div>
|
||||||
<div class="contact-item__actions">
|
<div class="contact-item__actions">
|
||||||
${phone}${email}${maps}
|
${phone}${email}${maps}
|
||||||
<button class="contact-action-btn" data-action="delete" data-id="${c.id}" title="Löschen">
|
<button class="contact-action-btn" data-action="delete" data-id="${c.id}" aria-label="Kontakt löschen">
|
||||||
<i data-lucide="trash-2" style="width:16px;height:16px;"></i>
|
<i data-lucide="trash-2" style="width:16px;height:16px;" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -237,8 +237,8 @@ function openContactModal({ mode, contact = null }) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="modal-panel__footer" style="border:none;padding:0;margin-top:var(--space-4)">
|
<div class="modal-panel__footer" style="border:none;padding:0;margin-top:var(--space-4)">
|
||||||
${isEdit ? `<button class="btn btn--danger btn--icon" id="cm-delete" title="Löschen">
|
${isEdit ? `<button class="btn btn--danger btn--icon" id="cm-delete" aria-label="Kontakt löschen">
|
||||||
<i data-lucide="trash-2" style="width:16px;height:16px;"></i>
|
<i data-lucide="trash-2" style="width:16px;height:16px;" aria-hidden="true"></i>
|
||||||
</button>` : '<div></div>'}
|
</button>` : '<div></div>'}
|
||||||
<div style="display:flex;gap:var(--space-3);">
|
<div style="display:flex;gap:var(--space-3);">
|
||||||
<button class="btn btn--secondary" id="cm-cancel">Abbrechen</button>
|
<button class="btn btn--secondary" id="cm-cancel">Abbrechen</button>
|
||||||
|
|||||||
@@ -118,17 +118,17 @@ function renderGreeting(user, stats = {}) {
|
|||||||
const statChips = [];
|
const statChips = [];
|
||||||
if (urgentCount > 0)
|
if (urgentCount > 0)
|
||||||
statChips.push(`<span class="greeting-chip greeting-chip--warn">
|
statChips.push(`<span class="greeting-chip greeting-chip--warn">
|
||||||
<i data-lucide="alert-circle" style="${chipIcon}"></i>
|
<i data-lucide="alert-circle" style="${chipIcon}" aria-hidden="true"></i>
|
||||||
${urgentCount} dring. Aufgabe${urgentCount > 1 ? 'n' : ''}
|
${urgentCount} dring. Aufgabe${urgentCount > 1 ? 'n' : ''}
|
||||||
</span>`);
|
</span>`);
|
||||||
if (todayEventCount > 0)
|
if (todayEventCount > 0)
|
||||||
statChips.push(`<span class="greeting-chip">
|
statChips.push(`<span class="greeting-chip">
|
||||||
<i data-lucide="calendar" style="${chipIcon}"></i>
|
<i data-lucide="calendar" style="${chipIcon}" aria-hidden="true"></i>
|
||||||
${todayEventCount} Termin${todayEventCount > 1 ? 'e' : ''} heute
|
${todayEventCount} Termin${todayEventCount > 1 ? 'e' : ''} heute
|
||||||
</span>`);
|
</span>`);
|
||||||
if (todayMealTitle)
|
if (todayMealTitle)
|
||||||
statChips.push(`<span class="greeting-chip">
|
statChips.push(`<span class="greeting-chip">
|
||||||
<i data-lucide="utensils" style="${chipIcon}"></i>
|
<i data-lucide="utensils" style="${chipIcon}" aria-hidden="true"></i>
|
||||||
Heute: ${todayMealTitle}
|
Heute: ${todayMealTitle}
|
||||||
</span>`);
|
</span>`);
|
||||||
|
|
||||||
@@ -148,7 +148,7 @@ function renderUrgentTasks(tasks) {
|
|||||||
return `<div class="widget">
|
return `<div class="widget">
|
||||||
${widgetHeader('check-square', 'Aufgaben', 0, '/tasks')}
|
${widgetHeader('check-square', 'Aufgaben', 0, '/tasks')}
|
||||||
<div class="widget__empty">
|
<div class="widget__empty">
|
||||||
<i data-lucide="check-circle" class="empty-state__icon" style="color:var(--color-success)"></i>
|
<i data-lucide="check-circle" class="empty-state__icon" style="color:var(--color-success)" aria-hidden="true"></i>
|
||||||
<div>Alles erledigt</div>
|
<div>Alles erledigt</div>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
@@ -181,7 +181,7 @@ function renderUpcomingEvents(events) {
|
|||||||
return `<div class="widget">
|
return `<div class="widget">
|
||||||
${widgetHeader('calendar', 'Termine', 0, '/calendar')}
|
${widgetHeader('calendar', 'Termine', 0, '/calendar')}
|
||||||
<div class="widget__empty">
|
<div class="widget__empty">
|
||||||
<i data-lucide="calendar-check" class="empty-state__icon"></i>
|
<i data-lucide="calendar-check" class="empty-state__icon" aria-hidden="true"></i>
|
||||||
<div>Keine Termine</div>
|
<div>Keine Termine</div>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
@@ -238,7 +238,7 @@ function renderPinnedNotes(notes) {
|
|||||||
return `<div class="widget">
|
return `<div class="widget">
|
||||||
${widgetHeader('pin', 'Pinnwand', 0, '/notes')}
|
${widgetHeader('pin', 'Pinnwand', 0, '/notes')}
|
||||||
<div class="widget__empty">
|
<div class="widget__empty">
|
||||||
<i data-lucide="sticky-note" class="empty-state__icon"></i>
|
<i data-lucide="sticky-note" class="empty-state__icon" aria-hidden="true"></i>
|
||||||
<div>Keine angepinnten Notizen</div>
|
<div>Keine angepinnten Notizen</div>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|||||||
+11
-11
@@ -107,12 +107,12 @@ export async function render(container, { user }) {
|
|||||||
<h1 class="sr-only">Essensplan</h1>
|
<h1 class="sr-only">Essensplan</h1>
|
||||||
<div class="week-nav">
|
<div class="week-nav">
|
||||||
<button class="btn btn--icon" id="week-prev" aria-label="Vorherige Woche">
|
<button class="btn btn--icon" id="week-prev" aria-label="Vorherige Woche">
|
||||||
<i data-lucide="chevron-left"></i>
|
<i data-lucide="chevron-left" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
<span class="week-nav__label" id="week-label"></span>
|
<span class="week-nav__label" id="week-label"></span>
|
||||||
<button class="week-nav__today" id="week-today">Heute</button>
|
<button class="week-nav__today" id="week-today">Heute</button>
|
||||||
<button class="btn btn--icon" id="week-next" aria-label="Nächste Woche">
|
<button class="btn btn--icon" id="week-next" aria-label="Nächste Woche">
|
||||||
<i data-lucide="chevron-right"></i>
|
<i data-lucide="chevron-right" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="week-grid" id="week-grid">
|
<div class="week-grid" id="week-grid">
|
||||||
@@ -179,7 +179,7 @@ function renderSlot(date, type, mealsForDay) {
|
|||||||
data-type="${type.key}"
|
data-type="${type.key}"
|
||||||
aria-label="${type.label} hinzufügen"
|
aria-label="${type.label} hinzufügen"
|
||||||
>
|
>
|
||||||
<i data-lucide="plus" style="width:16px;height:16px;"></i>
|
<i data-lucide="plus" style="width:16px;height:16px;" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
@@ -206,13 +206,13 @@ function renderSlot(date, type, mealsForDay) {
|
|||||||
${canTransfer ? `<button class="meal-card__action-btn meal-card__action-btn--shopping"
|
${canTransfer ? `<button class="meal-card__action-btn meal-card__action-btn--shopping"
|
||||||
data-action="transfer-meal"
|
data-action="transfer-meal"
|
||||||
data-meal-id="${meal.id}"
|
data-meal-id="${meal.id}"
|
||||||
title="Zutaten auf Einkaufsliste"
|
aria-label="Zutaten auf Einkaufsliste"
|
||||||
><i data-lucide="shopping-cart" style="width:14px;height:14px;"></i></button>` : ''}
|
><i data-lucide="shopping-cart" style="width:14px;height:14px;" aria-hidden="true"></i></button>` : ''}
|
||||||
<button class="meal-card__action-btn"
|
<button class="meal-card__action-btn"
|
||||||
data-action="delete-meal"
|
data-action="delete-meal"
|
||||||
data-meal-id="${meal.id}"
|
data-meal-id="${meal.id}"
|
||||||
title="Löschen"
|
aria-label="Mahlzeit löschen"
|
||||||
><i data-lucide="trash-2" style="width:14px;height:14px;"></i></button>
|
><i data-lucide="trash-2" style="width:14px;height:14px;" aria-hidden="true"></i></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -427,7 +427,7 @@ function buildModalContent({ mode, date, mealType, meal }) {
|
|||||||
<label class="form-label">Zutaten</label>
|
<label class="form-label">Zutaten</label>
|
||||||
<div class="ingredient-list" id="ingredient-list">${ingRows}</div>
|
<div class="ingredient-list" id="ingredient-list">${ingRows}</div>
|
||||||
<button class="add-ingredient-btn" id="add-ingredient-btn" type="button">
|
<button class="add-ingredient-btn" id="add-ingredient-btn" type="button">
|
||||||
<i data-lucide="plus" style="width:14px;height:14px;"></i>
|
<i data-lucide="plus" style="width:14px;height:14px;" aria-hidden="true"></i>
|
||||||
Zutat hinzufügen
|
Zutat hinzufügen
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -435,7 +435,7 @@ function buildModalContent({ mode, date, mealType, meal }) {
|
|||||||
${isEdit && hasIngOpen ? `
|
${isEdit && hasIngOpen ? `
|
||||||
<div class="shopping-transfer">
|
<div class="shopping-transfer">
|
||||||
<div class="shopping-transfer__label">
|
<div class="shopping-transfer__label">
|
||||||
<i data-lucide="shopping-cart" style="width:14px;height:14px;"></i>
|
<i data-lucide="shopping-cart" style="width:14px;height:14px;" aria-hidden="true"></i>
|
||||||
Zutaten auf Einkaufsliste übertragen
|
Zutaten auf Einkaufsliste übertragen
|
||||||
</div>
|
</div>
|
||||||
<select class="shopping-transfer__select" id="transfer-list-select">${listOpts}</select>
|
<select class="shopping-transfer__select" id="transfer-list-select">${listOpts}</select>
|
||||||
@@ -455,8 +455,8 @@ function ingredientRowHTML(name, qty, id) {
|
|||||||
<div class="ingredient-row" data-ing-id="${id ?? ''}">
|
<div class="ingredient-row" data-ing-id="${id ?? ''}">
|
||||||
<input type="text" class="form-input ingredient-row__name" placeholder="Zutat" value="${escHtml(name)}">
|
<input type="text" class="form-input ingredient-row__name" placeholder="Zutat" value="${escHtml(name)}">
|
||||||
<input type="text" class="form-input ingredient-row__qty" placeholder="Menge" value="${escHtml(qty)}">
|
<input type="text" class="form-input ingredient-row__qty" placeholder="Menge" value="${escHtml(qty)}">
|
||||||
<button class="ingredient-row__remove" data-action="remove-ingredient" type="button" title="Entfernen">
|
<button class="ingredient-row__remove" data-action="remove-ingredient" type="button" aria-label="Zutat entfernen">
|
||||||
<i data-lucide="x" style="width:14px;height:14px;"></i>
|
<i data-lucide="x" style="width:14px;height:14px;" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -49,13 +49,13 @@ export async function render(container, { user }) {
|
|||||||
<div class="notes-toolbar">
|
<div class="notes-toolbar">
|
||||||
<h1 class="notes-toolbar__title">Pinnwand</h1>
|
<h1 class="notes-toolbar__title">Pinnwand</h1>
|
||||||
<button class="btn btn--primary" id="notes-add-btn">
|
<button class="btn btn--primary" id="notes-add-btn">
|
||||||
<i data-lucide="plus" style="width:16px;height:16px;margin-right:4px;"></i>
|
<i data-lucide="plus" style="width:16px;height:16px;margin-right:4px;" aria-hidden="true"></i>
|
||||||
Neue Notiz
|
Neue Notiz
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="notes-grid" class="notes-grid"></div>
|
<div id="notes-grid" class="notes-grid"></div>
|
||||||
<button class="page-fab" id="fab-new-note" aria-label="Neue Notiz">
|
<button class="page-fab" id="fab-new-note" aria-label="Neue Notiz">
|
||||||
<i data-lucide="plus" style="width:24px;height:24px"></i>
|
<i data-lucide="plus" style="width:24px;height:24px" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
@@ -88,7 +88,7 @@ function renderGrid() {
|
|||||||
if (!state.notes.length) {
|
if (!state.notes.length) {
|
||||||
grid.innerHTML = `
|
grid.innerHTML = `
|
||||||
<div class="notes-empty">
|
<div class="notes-empty">
|
||||||
<i data-lucide="sticky-note" class="notes-empty__icon"></i>
|
<i data-lucide="sticky-note" class="notes-empty__icon" aria-hidden="true"></i>
|
||||||
<div style="font-size:var(--text-lg);font-weight:600;margin-bottom:var(--space-2);">Noch keine Notizen</div>
|
<div style="font-size:var(--text-lg);font-weight:600;margin-bottom:var(--space-2);">Noch keine Notizen</div>
|
||||||
<div style="font-size:var(--text-sm);">Klicke auf „Neue Notiz" um loszulegen.</div>
|
<div style="font-size:var(--text-sm);">Klicke auf „Neue Notiz" um loszulegen.</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -130,8 +130,8 @@ function renderNoteCard(note) {
|
|||||||
data-id="${note.id}"
|
data-id="${note.id}"
|
||||||
style="background-color:${escHtml(note.color)};color:${textColor};">
|
style="background-color:${escHtml(note.color)};color:${textColor};">
|
||||||
<button class="note-card__pin" data-action="pin" data-id="${note.id}"
|
<button class="note-card__pin" data-action="pin" data-id="${note.id}"
|
||||||
title="${note.pinned ? 'Anpinnen aufheben' : 'Anpinnen'}">
|
aria-label="${note.pinned ? 'Anpinnen aufheben' : 'Anpinnen'}">
|
||||||
<i data-lucide="${note.pinned ? 'pin-off' : 'pin'}" style="width:12px;height:12px;"></i>
|
<i data-lucide="${note.pinned ? 'pin-off' : 'pin'}" style="width:12px;height:12px;" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
${note.title ? `<div class="note-card__title">${escHtml(note.title)}</div>` : ''}
|
${note.title ? `<div class="note-card__title">${escHtml(note.title)}</div>` : ''}
|
||||||
<div class="note-card__content">${renderMarkdownLight(note.content)}</div>
|
<div class="note-card__content">${renderMarkdownLight(note.content)}</div>
|
||||||
@@ -141,8 +141,8 @@ function renderNoteCard(note) {
|
|||||||
style="background-color:${escHtml(note.creator_color || '#8E8E93')}">${initials}</span>
|
style="background-color:${escHtml(note.creator_color || '#8E8E93')}">${initials}</span>
|
||||||
<span>${escHtml(note.creator_name || '')}</span>
|
<span>${escHtml(note.creator_name || '')}</span>
|
||||||
</div>
|
</div>
|
||||||
<button class="note-card__delete" data-action="delete" data-id="${note.id}" title="Löschen">
|
<button class="note-card__delete" data-action="delete" data-id="${note.id}" aria-label="Notiz löschen">
|
||||||
<i data-lucide="trash-2" style="width:12px;height:12px;"></i>
|
<i data-lucide="trash-2" style="width:12px;height:12px;" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+13
-13
@@ -75,7 +75,7 @@ function renderTabs(container) {
|
|||||||
bar.innerHTML = `
|
bar.innerHTML = `
|
||||||
${tabsHtml}
|
${tabsHtml}
|
||||||
<button class="list-tab__new" data-action="new-list" aria-label="Neue Liste erstellen">
|
<button class="list-tab__new" data-action="new-list" aria-label="Neue Liste erstellen">
|
||||||
<i data-lucide="plus" style="width:18px;height:18px"></i>
|
<i data-lucide="plus" style="width:18px;height:18px" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
`;
|
`;
|
||||||
if (window.lucide) window.lucide.createIcons();
|
if (window.lucide) window.lucide.createIcons();
|
||||||
@@ -88,7 +88,7 @@ function renderListContent(container) {
|
|||||||
if (!state.activeList) {
|
if (!state.activeList) {
|
||||||
content.innerHTML = `
|
content.innerHTML = `
|
||||||
<div class="no-lists">
|
<div class="no-lists">
|
||||||
<i data-lucide="shopping-cart" style="width:56px;height:56px;color:var(--color-text-disabled)"></i>
|
<i data-lucide="shopping-cart" style="width:56px;height:56px;color:var(--color-text-disabled)" aria-hidden="true"></i>
|
||||||
<div style="font-size:var(--text-lg);font-weight:var(--font-weight-semibold)">Keine Listen</div>
|
<div style="font-size:var(--text-lg);font-weight:var(--font-weight-semibold)">Keine Listen</div>
|
||||||
<div style="font-size:var(--text-sm);color:var(--color-text-secondary)">
|
<div style="font-size:var(--text-sm);color:var(--color-text-secondary)">
|
||||||
Erstelle eine Liste mit dem + Button.
|
Erstelle eine Liste mit dem + Button.
|
||||||
@@ -106,19 +106,19 @@ function renderListContent(container) {
|
|||||||
<span class="list-header__name" data-action="rename-list" data-id="${state.activeList.id}"
|
<span class="list-header__name" data-action="rename-list" data-id="${state.activeList.id}"
|
||||||
role="button" tabindex="0" aria-label="Liste umbenennen">
|
role="button" tabindex="0" aria-label="Liste umbenennen">
|
||||||
${state.activeList.name}
|
${state.activeList.name}
|
||||||
<i data-lucide="pencil" class="list-header__edit-icon"></i>
|
<i data-lucide="pencil" class="list-header__edit-icon" aria-hidden="true"></i>
|
||||||
</span>
|
</span>
|
||||||
<div class="list-header__actions">
|
<div class="list-header__actions">
|
||||||
${checkedCount > 0 ? `
|
${checkedCount > 0 ? `
|
||||||
<button class="btn btn--ghost" data-action="clear-checked"
|
<button class="btn btn--ghost" data-action="clear-checked"
|
||||||
style="font-size:var(--text-sm);color:var(--color-text-secondary)">
|
style="font-size:var(--text-sm);color:var(--color-text-secondary)">
|
||||||
<i data-lucide="trash-2" style="width:15px;height:15px"></i>
|
<i data-lucide="trash-2" style="width:15px;height:15px" aria-hidden="true"></i>
|
||||||
Abgehakt löschen (${checkedCount})
|
Abgehakt löschen (${checkedCount})
|
||||||
</button>` : ''}
|
</button>` : ''}
|
||||||
<button class="btn btn--ghost btn--icon" data-action="delete-list"
|
<button class="btn btn--ghost btn--icon" data-action="delete-list"
|
||||||
data-id="${state.activeList.id}" aria-label="Liste löschen"
|
data-id="${state.activeList.id}" aria-label="Liste löschen"
|
||||||
style="color:var(--color-text-secondary)">
|
style="color:var(--color-text-secondary)">
|
||||||
<i data-lucide="trash" style="width:18px;height:18px"></i>
|
<i data-lucide="trash" style="width:18px;height:18px" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -139,7 +139,7 @@ function renderListContent(container) {
|
|||||||
).join('')}
|
).join('')}
|
||||||
</select>
|
</select>
|
||||||
<button class="quick-add__btn" type="submit" aria-label="Artikel hinzufügen">
|
<button class="quick-add__btn" type="submit" aria-label="Artikel hinzufügen">
|
||||||
<i data-lucide="plus" style="width:20px;height:20px"></i>
|
<i data-lucide="plus" style="width:20px;height:20px" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@@ -159,7 +159,7 @@ function renderItems() {
|
|||||||
if (!state.items.length) {
|
if (!state.items.length) {
|
||||||
return `
|
return `
|
||||||
<div class="shopping-empty">
|
<div class="shopping-empty">
|
||||||
<i data-lucide="check-circle" class="shopping-empty__icon"></i>
|
<i data-lucide="check-circle" class="shopping-empty__icon" aria-hidden="true"></i>
|
||||||
<div class="shopping-empty__title">Liste ist leer</div>
|
<div class="shopping-empty__title">Liste ist leer</div>
|
||||||
<div class="shopping-empty__desc">Füge Artikel mit dem Eingabefeld oben hinzu.</div>
|
<div class="shopping-empty__desc">Füge Artikel mit dem Eingabefeld oben hinzu.</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
@@ -169,7 +169,7 @@ function renderItems() {
|
|||||||
return groups.map(([cat, items]) => `
|
return groups.map(([cat, items]) => `
|
||||||
<div class="item-category">
|
<div class="item-category">
|
||||||
<div class="item-category__header">
|
<div class="item-category__header">
|
||||||
<i data-lucide="${CATEGORY_ICONS[cat] ?? 'tag'}" class="item-category__icon"></i>
|
<i data-lucide="${CATEGORY_ICONS[cat] ?? 'tag'}" class="item-category__icon" aria-hidden="true"></i>
|
||||||
${cat}
|
${cat}
|
||||||
</div>
|
</div>
|
||||||
${items.map(renderItem).join('')}
|
${items.map(renderItem).join('')}
|
||||||
@@ -183,7 +183,7 @@ function renderItem(item) {
|
|||||||
<button class="item-check ${item.is_checked ? 'item-check--checked' : ''}"
|
<button class="item-check ${item.is_checked ? 'item-check--checked' : ''}"
|
||||||
data-action="toggle-item" data-id="${item.id}" data-checked="${item.is_checked}"
|
data-action="toggle-item" data-id="${item.id}" data-checked="${item.is_checked}"
|
||||||
aria-label="${item.name} ${item.is_checked ? 'als nicht erledigt markieren' : 'abhaken'}">
|
aria-label="${item.name} ${item.is_checked ? 'als nicht erledigt markieren' : 'abhaken'}">
|
||||||
<i data-lucide="check" class="item-check__icon"></i>
|
<i data-lucide="check" class="item-check__icon" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
<div class="item-body">
|
<div class="item-body">
|
||||||
<div class="item-name">${item.name}</div>
|
<div class="item-name">${item.name}</div>
|
||||||
@@ -191,7 +191,7 @@ function renderItem(item) {
|
|||||||
</div>
|
</div>
|
||||||
<button class="item-delete" data-action="delete-item" data-id="${item.id}"
|
<button class="item-delete" data-action="delete-item" data-id="${item.id}"
|
||||||
aria-label="${item.name} löschen">
|
aria-label="${item.name} löschen">
|
||||||
<i data-lucide="x" style="width:16px;height:16px"></i>
|
<i data-lucide="x" style="width:16px;height:16px" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>`;
|
</div>`;
|
||||||
}
|
}
|
||||||
@@ -321,7 +321,7 @@ function updateItemsList(container) {
|
|||||||
header.insertAdjacentHTML('afterbegin', `
|
header.insertAdjacentHTML('afterbegin', `
|
||||||
<button class="btn btn--ghost" data-action="clear-checked"
|
<button class="btn btn--ghost" data-action="clear-checked"
|
||||||
style="font-size:var(--text-sm);color:var(--color-text-secondary)">
|
style="font-size:var(--text-sm);color:var(--color-text-secondary)">
|
||||||
<i data-lucide="trash-2" style="width:15px;height:15px"></i>
|
<i data-lucide="trash-2" style="width:15px;height:15px" aria-hidden="true"></i>
|
||||||
Abgehakt löschen (${checkedCount})
|
Abgehakt löschen (${checkedCount})
|
||||||
</button>`);
|
</button>`);
|
||||||
if (window.lucide) window.lucide.createIcons();
|
if (window.lucide) window.lucide.createIcons();
|
||||||
@@ -330,7 +330,7 @@ function updateItemsList(container) {
|
|||||||
clearBtn.remove();
|
clearBtn.remove();
|
||||||
} else {
|
} else {
|
||||||
clearBtn.innerHTML = `
|
clearBtn.innerHTML = `
|
||||||
<i data-lucide="trash-2" style="width:15px;height:15px"></i>
|
<i data-lucide="trash-2" style="width:15px;height:15px" aria-hidden="true"></i>
|
||||||
Abgehakt löschen (${checkedCount})`;
|
Abgehakt löschen (${checkedCount})`;
|
||||||
if (window.lucide) window.lucide.createIcons();
|
if (window.lucide) window.lucide.createIcons();
|
||||||
}
|
}
|
||||||
@@ -557,7 +557,7 @@ export async function render(container, { user }) {
|
|||||||
<div class="list-tabs-bar" id="list-tabs-bar"></div>
|
<div class="list-tabs-bar" id="list-tabs-bar"></div>
|
||||||
<div id="list-content" style="flex:1;display:flex;flex-direction:column;overflow:hidden"></div>
|
<div id="list-content" style="flex:1;display:flex;flex-direction:column;overflow:hidden"></div>
|
||||||
<button class="page-fab" id="fab-new-item" aria-label="Artikel hinzufügen">
|
<button class="page-fab" id="fab-new-item" aria-label="Artikel hinzufügen">
|
||||||
<i data-lucide="plus" style="width:24px;height:24px"></i>
|
<i data-lucide="plus" style="width:24px;height:24px" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|||||||
+13
-13
@@ -99,7 +99,7 @@ function renderDueDate(dateStr) {
|
|||||||
const d = formatDueDate(dateStr);
|
const d = formatDueDate(dateStr);
|
||||||
if (!d) return '';
|
if (!d) return '';
|
||||||
return `<span class="due-date ${d.cls}">
|
return `<span class="due-date ${d.cls}">
|
||||||
<i data-lucide="clock" style="width:11px;height:11px"></i> ${d.label}
|
<i data-lucide="clock" style="width:11px;height:11px" aria-hidden="true"></i> ${d.label}
|
||||||
</span>`;
|
</span>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,11 +108,11 @@ function renderSwipeRow(task, innerHtml) {
|
|||||||
return `
|
return `
|
||||||
<div class="swipe-row" data-swipe-id="${task.id}" data-swipe-status="${task.status}">
|
<div class="swipe-row" data-swipe-id="${task.id}" data-swipe-status="${task.status}">
|
||||||
<div class="swipe-reveal swipe-reveal--done" aria-hidden="true">
|
<div class="swipe-reveal swipe-reveal--done" aria-hidden="true">
|
||||||
<i data-lucide="${isDone ? 'rotate-ccw' : 'check'}" style="width:22px;height:22px"></i>
|
<i data-lucide="${isDone ? 'rotate-ccw' : 'check'}" style="width:22px;height:22px" aria-hidden="true"></i>
|
||||||
<span>${isDone ? 'Öffnen' : 'Erledigt'}</span>
|
<span>${isDone ? 'Öffnen' : 'Erledigt'}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="swipe-reveal swipe-reveal--edit" aria-hidden="true">
|
<div class="swipe-reveal swipe-reveal--edit" aria-hidden="true">
|
||||||
<i data-lucide="pencil" style="width:22px;height:22px"></i>
|
<i data-lucide="pencil" style="width:22px;height:22px" aria-hidden="true"></i>
|
||||||
<span>Bearbeiten</span>
|
<span>Bearbeiten</span>
|
||||||
</div>
|
</div>
|
||||||
${innerHtml}
|
${innerHtml}
|
||||||
@@ -133,7 +133,7 @@ function renderTaskCard(task, opts = {}) {
|
|||||||
<button class="subtask-item__checkbox ${s.status === 'done' ? 'subtask-item__checkbox--done' : ''}"
|
<button class="subtask-item__checkbox ${s.status === 'done' ? 'subtask-item__checkbox--done' : ''}"
|
||||||
data-action="toggle-subtask" data-id="${s.id}"
|
data-action="toggle-subtask" data-id="${s.id}"
|
||||||
data-status="${s.status}" aria-label="${s.title} als erledigt markieren">
|
data-status="${s.status}" aria-label="${s.title} als erledigt markieren">
|
||||||
${s.status === 'done' ? '<i data-lucide="check" style="width:10px;height:10px;color:#fff"></i>' : ''}
|
${s.status === 'done' ? '<i data-lucide="check" style="width:10px;height:10px;color:#fff" aria-hidden="true"></i>' : ''}
|
||||||
</button>
|
</button>
|
||||||
<span class="subtask-item__title">${s.title}</span>
|
<span class="subtask-item__title">${s.title}</span>
|
||||||
</div>`).join('')
|
</div>`).join('')
|
||||||
@@ -145,7 +145,7 @@ function renderTaskCard(task, opts = {}) {
|
|||||||
<button class="task-status-btn task-status-btn--${task.status}"
|
<button class="task-status-btn task-status-btn--${task.status}"
|
||||||
data-action="toggle-status" data-id="${task.id}" data-status="${task.status}"
|
data-action="toggle-status" data-id="${task.id}" data-status="${task.status}"
|
||||||
aria-label="${task.title} als erledigt markieren">
|
aria-label="${task.title} als erledigt markieren">
|
||||||
<i data-lucide="check" class="task-status-btn__check"></i>
|
<i data-lucide="check" class="task-status-btn__check" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div class="task-card__body">
|
<div class="task-card__body">
|
||||||
@@ -155,7 +155,7 @@ function renderTaskCard(task, opts = {}) {
|
|||||||
<div class="task-card__meta">
|
<div class="task-card__meta">
|
||||||
${renderPriorityBadge(task.priority)}
|
${renderPriorityBadge(task.priority)}
|
||||||
${renderDueDate(task.due_date)}
|
${renderDueDate(task.due_date)}
|
||||||
${task.is_recurring ? '<span class="due-date" title="Wiederkehrend"><i data-lucide="repeat" style="width:12px;height:12px"></i></span>' : ''}
|
${task.is_recurring ? '<span class="due-date" aria-label="Wiederkehrend"><i data-lucide="repeat" style="width:12px;height:12px" aria-hidden="true"></i></span>' : ''}
|
||||||
${task.category !== 'Sonstiges' ? `<span class="due-date">${task.category}</span>` : ''}
|
${task.category !== 'Sonstiges' ? `<span class="due-date">${task.category}</span>` : ''}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -168,7 +168,7 @@ function renderTaskCard(task, opts = {}) {
|
|||||||
|
|
||||||
<button class="btn btn--ghost btn--icon" data-action="edit-task" data-id="${task.id}"
|
<button class="btn btn--ghost btn--icon" data-action="edit-task" data-id="${task.id}"
|
||||||
aria-label="Aufgabe bearbeiten" style="min-height:unset;width:36px;height:36px">
|
aria-label="Aufgabe bearbeiten" style="min-height:unset;width:36px;height:36px">
|
||||||
<i data-lucide="pencil" style="width:16px;height:16px"></i>
|
<i data-lucide="pencil" style="width:16px;height:16px" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -195,7 +195,7 @@ function renderTaskCard(task, opts = {}) {
|
|||||||
function renderTaskGroups(tasks, groupMode) {
|
function renderTaskGroups(tasks, groupMode) {
|
||||||
if (!tasks.length) {
|
if (!tasks.length) {
|
||||||
return `<div class="tasks-empty">
|
return `<div class="tasks-empty">
|
||||||
<i data-lucide="check-circle-2" class="tasks-empty__icon"></i>
|
<i data-lucide="check-circle-2" class="tasks-empty__icon" aria-hidden="true"></i>
|
||||||
<div class="tasks-empty__title">Keine Aufgaben</div>
|
<div class="tasks-empty__title">Keine Aufgaben</div>
|
||||||
<div class="tasks-empty__desc">Erstelle eine neue Aufgabe mit dem + Button.</div>
|
<div class="tasks-empty__desc">Erstelle eine neue Aufgabe mit dem + Button.</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
@@ -467,7 +467,7 @@ function renderKanbanCard(task) {
|
|||||||
<div class="kanban-card__title">${task.title}</div>
|
<div class="kanban-card__title">${task.title}</div>
|
||||||
<div class="kanban-card__meta">
|
<div class="kanban-card__meta">
|
||||||
${renderPriorityBadge(task.priority)}
|
${renderPriorityBadge(task.priority)}
|
||||||
${due ? `<span class="due-date ${due.cls}"><i data-lucide="clock" style="width:10px;height:10px"></i> ${due.label}</span>` : ''}
|
${due ? `<span class="due-date ${due.cls}"><i data-lucide="clock" style="width:10px;height:10px" aria-hidden="true"></i> ${due.label}</span>` : ''}
|
||||||
</div>
|
</div>
|
||||||
${task.assigned_color ? `
|
${task.assigned_color ? `
|
||||||
<div class="kanban-card__footer">
|
<div class="kanban-card__footer">
|
||||||
@@ -915,11 +915,11 @@ export async function render(container, { user }) {
|
|||||||
<div class="group-toggle" id="view-toggle">
|
<div class="group-toggle" id="view-toggle">
|
||||||
<button class="group-toggle__btn group-toggle__btn--active" data-view="list"
|
<button class="group-toggle__btn group-toggle__btn--active" data-view="list"
|
||||||
title="Listenansicht" aria-label="Listenansicht">
|
title="Listenansicht" aria-label="Listenansicht">
|
||||||
<i data-lucide="list" style="width:14px;height:14px;pointer-events:none"></i>
|
<i data-lucide="list" style="width:14px;height:14px;pointer-events:none" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
<button class="group-toggle__btn" data-view="kanban"
|
<button class="group-toggle__btn" data-view="kanban"
|
||||||
title="Kanban-Ansicht" aria-label="Kanban-Ansicht">
|
title="Kanban-Ansicht" aria-label="Kanban-Ansicht">
|
||||||
<i data-lucide="columns" style="width:14px;height:14px;pointer-events:none"></i>
|
<i data-lucide="columns" style="width:14px;height:14px;pointer-events:none" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="group-toggle" id="group-mode-toggle">
|
<div class="group-toggle" id="group-mode-toggle">
|
||||||
@@ -927,7 +927,7 @@ export async function render(container, { user }) {
|
|||||||
<button class="group-toggle__btn" data-mode="due">Fälligkeit</button>
|
<button class="group-toggle__btn" data-mode="due">Fälligkeit</button>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn--primary" id="btn-new-task" style="gap:var(--space-1)">
|
<button class="btn btn--primary" id="btn-new-task" style="gap:var(--space-1)">
|
||||||
<i data-lucide="plus" style="width:18px;height:18px"></i> Neu
|
<i data-lucide="plus" style="width:18px;height:18px" aria-hidden="true"></i> Neu
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -943,7 +943,7 @@ export async function render(container, { user }) {
|
|||||||
</div>`).join('')}
|
</div>`).join('')}
|
||||||
</div>
|
</div>
|
||||||
<button class="page-fab" id="fab-new-task" aria-label="Neue Aufgabe">
|
<button class="page-fab" id="fab-new-task" aria-label="Neue Aufgabe">
|
||||||
<i data-lucide="plus" style="width:24px;height:24px"></i>
|
<i data-lucide="plus" style="width:24px;height:24px" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|||||||
Reference in New Issue
Block a user