feat(ux): kontextuelle Onboarding-Tipps in Empty-States aller Module
This commit is contained in:
@@ -892,6 +892,17 @@
|
||||
"offline": {
|
||||
"banner": "Offline – Verbindung wird wiederhergestellt…"
|
||||
},
|
||||
"emptyHint": {
|
||||
"tasks": "Tippe auf + um deine erste Aufgabe zu erstellen. Wische eine Karte nach links zum Löschen.",
|
||||
"calendar": "Verbinde Google Kalender unter Einstellungen → Integrationen für automatische Synchronisation.",
|
||||
"shopping": "Füge Artikel hinzu und wische zum Abhaken oder Löschen.",
|
||||
"notes": "Tippe auf + für eine neue Notiz. Notizen werden im Volltext durchsucht.",
|
||||
"contacts": "Lege wichtige Kontakte an — Arzt, Schule, Notfall — für Schnellzugriff.",
|
||||
"budget": "Erstelle Kategorien und trage Einnahmen und Ausgaben ein.",
|
||||
"meals": "Plane Mahlzeiten für die Woche und verknüpfe Rezepte.",
|
||||
"birthdays": "Trage Geburtstage ein — du erhältst eine Erinnerung rechtzeitig.",
|
||||
"recipes": "Lege Rezepte an und verknüpfe sie mit deiner Mahlzeitenplanung."
|
||||
},
|
||||
"shortcuts": {
|
||||
"search": "Suche öffnen",
|
||||
"new": "Neuen Eintrag erstellen",
|
||||
|
||||
@@ -882,5 +882,16 @@
|
||||
"goCal": "Calendar",
|
||||
"goShop": "Shopping list",
|
||||
"goNotes": "Notes"
|
||||
},
|
||||
"emptyHint": {
|
||||
"tasks": "Tap + to create your first task. Swipe a card left to delete.",
|
||||
"calendar": "Connect Google Calendar under Settings → Integrations for automatic sync.",
|
||||
"shopping": "Add items and swipe to check off or delete.",
|
||||
"notes": "Tap + for a new note. Notes are full-text searchable.",
|
||||
"contacts": "Add important contacts — doctor, school, emergency — for quick access.",
|
||||
"budget": "Create categories and track income and expenses.",
|
||||
"meals": "Plan meals for the week and link recipes.",
|
||||
"birthdays": "Add birthdays — you will receive a reminder in time.",
|
||||
"recipes": "Create recipes and link them to your meal planner."
|
||||
}
|
||||
}
|
||||
@@ -121,6 +121,7 @@ function renderList() {
|
||||
host.insertAdjacentHTML('beforeend', `<div class="empty-state">
|
||||
<div class="empty-state__title">${t('birthdays.emptyTitle')}</div>
|
||||
<div class="empty-state__description">${t('birthdays.emptyDescription')}</div>
|
||||
<p class="empty-state__hint">${t('emptyHint.birthdays')}</p>
|
||||
</div>`);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -377,6 +377,7 @@ function renderEntries() {
|
||||
</svg>
|
||||
<div class="empty-state__title">${t('budget.emptyTitle')}</div>
|
||||
<div class="empty-state__description">${t('budget.emptyDescription')}</div>
|
||||
<p class="empty-state__hint">${t('emptyHint.budget')}</p>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
|
||||
@@ -180,6 +180,7 @@ function renderList() {
|
||||
</svg>
|
||||
<div class="empty-state__title">${t('contacts.emptyTitle')}</div>
|
||||
<div class="empty-state__description">${t('contacts.emptyDescription')}</div>
|
||||
<p class="empty-state__hint">${t('emptyHint.contacts')}</p>
|
||||
</div>
|
||||
`;
|
||||
if (window.lucide) lucide.createIcons();
|
||||
|
||||
@@ -146,6 +146,7 @@ function renderGrid() {
|
||||
</svg>
|
||||
<div class="empty-state__title">${isFiltered ? t('notes.noResultsTitle') : t('notes.emptyTitle')}</div>
|
||||
<div class="empty-state__description">${isFiltered ? t('notes.noResultsDescription', { query: state.filterQuery }) : t('notes.emptyDescription')}</div>
|
||||
${!isFiltered ? `<p class="empty-state__hint">${t('emptyHint.notes')}</p>` : ''}
|
||||
</div>
|
||||
`;
|
||||
if (window.lucide) lucide.createIcons();
|
||||
|
||||
@@ -126,7 +126,10 @@ function renderRecipeList() {
|
||||
emptyDesc.className = 'empty-state__description';
|
||||
emptyDesc.textContent = t('recipes.emptyDescription');
|
||||
|
||||
empty.append(emptyTitle, emptyDesc);
|
||||
const emptyHint = document.createElement('p');
|
||||
emptyHint.className = 'empty-state__hint';
|
||||
emptyHint.textContent = t('emptyHint.recipes');
|
||||
empty.append(emptyTitle, emptyDesc, emptyHint);
|
||||
list.appendChild(empty);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -170,6 +170,7 @@ function renderItems() {
|
||||
</svg>
|
||||
<div class="empty-state__title">${t('shopping.emptyList')}</div>
|
||||
<div class="empty-state__description">${t('shopping.emptyListDescription')}</div>
|
||||
<p class="empty-state__hint">${t('emptyHint.shopping')}</p>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
|
||||
@@ -261,6 +261,7 @@ function renderTaskGroups(tasks, groupMode) {
|
||||
</svg>
|
||||
<div class="empty-state__title">${t('tasks.emptyTitle')}</div>
|
||||
<div class="empty-state__description">${t('tasks.emptyDescription')}</div>
|
||||
<p class="empty-state__hint">${t('emptyHint.tasks')}</p>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
|
||||
@@ -1370,6 +1370,18 @@
|
||||
line-height: var(--line-height-base);
|
||||
}
|
||||
|
||||
.empty-state__hint {
|
||||
font-size: var(--text-xs);
|
||||
color: var(--color-text-tertiary);
|
||||
max-width: 280px;
|
||||
line-height: var(--line-height-relaxed);
|
||||
padding: var(--space-2) var(--space-3);
|
||||
background-color: var(--color-surface-2);
|
||||
border-radius: var(--radius-sm);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.empty-state--compact {
|
||||
padding: var(--space-4) var(--space-3);
|
||||
gap: var(--space-2);
|
||||
|
||||
Reference in New Issue
Block a user