From 2747b0046a20383a9ca12eaf2a10871bce1e7468 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20P=C3=B6ttker?= Date: Fri, 29 May 2026 11:00:20 +0200 Subject: [PATCH] feat: redesign daily digest email with card layout and timezone fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace table layout with modern card-based design per dashboard area - Add icon, color accent, badge and "Öffnen" link per card - Show summary bar with total open items count - Fix cron timezone to Europe/Berlin Co-Authored-By: Claude Sonnet 4.6 --- .env.example | 2 +- .../src/daily-digest/daily-digest.service.ts | 181 ++++++++++++------ 2 files changed, 126 insertions(+), 57 deletions(-) diff --git a/.env.example b/.env.example index f7287a6..e62dd5b 100644 --- a/.env.example +++ b/.env.example @@ -66,4 +66,4 @@ AGRARMONITOR_UPLOAD_CHECK_CRON=0 * * * * * # Upload-Check-Intervall (Standard: # Basis-URL der App für klickbare Links in Digest-E-Mails (z.B. https://paperless.example.com) # Leer lassen: E-Mails werden ohne Links versendet APP_URL= -DAILY_DIGEST_CRON= # Standard: 0 7 * * * (täglich 07:00 Uhr) +DAILY_DIGEST_CRON= # Standard: 0 7 * * * (täglich 07:00 Uhr Europe/Berlin) diff --git a/paperless-backend/src/daily-digest/daily-digest.service.ts b/paperless-backend/src/daily-digest/daily-digest.service.ts index 84c91a3..82672ad 100644 --- a/paperless-backend/src/daily-digest/daily-digest.service.ts +++ b/paperless-backend/src/daily-digest/daily-digest.service.ts @@ -35,7 +35,7 @@ export class DailyDigestService { this.logger.log(`Manueller Digest gesendet an ${email} (userId: ${userId})`); } - @Cron(process.env.DAILY_DIGEST_CRON || '0 7 * * *') + @Cron(process.env.DAILY_DIGEST_CRON || '0 7 * * *', { timeZone: 'Europe/Berlin' }) async sendDailyDigests() { this.logger.log('Starte täglichen E-Mail-Digest...'); @@ -66,69 +66,138 @@ export class DailyDigestService { } } -function countColor(n: number): string { - if (n === 0) return '#16a34a'; - if (n <= 5) return '#d97706'; - return '#dc2626'; -} - function buildDigestHtml(counts: DashboardCounts, today: string, appUrl: string, agrarmonitorBaseUrl: string): string { - const rows: { label: string; count: number; url: string }[] = [ - { label: 'Eingangsbox (Scanner)', count: counts.inbox, url: appUrl ? `${appUrl}/inbox` : '' }, - { label: 'Posteingang', count: counts.posteingang, url: appUrl ? `${appUrl}/posteingang` : '' }, - { label: 'Manuell bearbeiten', count: counts.manuell, url: appUrl ? `${appUrl}/manuell` : '' }, - { label: 'Mailpostfach', count: counts.mailpostfach, url: appUrl ? `${appUrl}/mailpostfach` : '' }, - { label: 'In Agrarmonitor', count: counts.agrarmonitor, url: agrarmonitorBaseUrl ? `${agrarmonitorBaseUrl}/dateien/eingang#dateien` : '' }, + const tiles = [ + { + key: 'inbox' as const, + title: 'Eingangsbox', + description: 'Neu eingegangene Scans, Uploads und E-Mail-Anhänge prüfen.', + icon: '📥', + accent: '#1677ff', + accentSoft: '#e6f0ff', + url: appUrl ? `${appUrl}/inbox` : '', + count: counts.inbox, + }, + { + key: 'posteingang' as const, + title: 'Posteingang', + description: 'Verarbeitete Dokumente sichten und an Paperless übergeben.', + icon: '📄', + accent: '#13c2c2', + accentSoft: '#e6fffb', + url: appUrl ? `${appUrl}/posteingang` : '', + count: counts.posteingang, + }, + { + key: 'manuell' as const, + title: 'Manuell bearbeiten', + description: 'Dokumente mit fehlender Erkennung manuell ergänzen.', + icon: '✏️', + accent: '#fa8c16', + accentSoft: '#fff7e6', + url: appUrl ? `${appUrl}/manuell` : '', + count: counts.manuell, + }, + { + key: 'mailpostfach' as const, + title: 'Mailpostfach', + description: 'Eingehende E-Mails mit Anhängen durchsuchen und zuordnen.', + icon: '📬', + accent: '#722ed1', + accentSoft: '#f9f0ff', + url: appUrl ? `${appUrl}/mailpostfach` : '', + count: counts.mailpostfach, + }, + { + key: 'agrarmonitor' as const, + title: 'In Agrarmonitor', + description: 'Dokumente im Agrarmonitor-Eingang anzeigen und verwalten.', + icon: '🌱', + accent: '#52c41a', + accentSoft: '#f6ffed', + url: agrarmonitorBaseUrl ? `${agrarmonitorBaseUrl}/dateien/eingang#dateien` : '', + count: counts.agrarmonitor, + }, ]; - const tableRows = rows - .map(r => { - const labelCell = r.url - ? `${r.label}` - : r.label; - return ` - - ${labelCell} - ${r.url ? `${r.count}` : r.count} - `; - }) - .join(''); + const totalOpen = tiles.reduce((sum, t) => sum + t.count, 0); + const summaryText = totalOpen > 0 + ? `Sie haben ${totalOpen} offene Vorgänge in Ihren Bereichen.` + : 'Alle Bereiche sind auf dem aktuellen Stand. ✓'; + + const cards = tiles.map(t => { + const badge = t.count > 0 + ? `${t.count}` + : ''; + const footerCount = t.count > 0 + ? `${t.count} offen` + : `Keine offenen Vorgänge`; + const openLink = t.url + ? `Öffnen ›` + : ''; + + return ` + + + + +
+ + + + ${badge} + +
+ ${t.icon} +
+

${t.title}

+

${t.description}

+
+ + + + + +
${footerCount}${openLink}
+
+ `; + }).join(''); return ` - - + +
- - - - - - - - - - +
-

Paperless Manager

-

Tagesübersicht – ${today}

-
-

Hier ist Ihre aktuelle Übersicht der offenen Vorgänge:

- - - - - - - - ${tableRows} -
BereichOffen
-
-

- Diese E-Mail wird täglich automatisch von Paperless Manager versendet.
- Sie können den Digest in den Benutzereinstellungen deaktivieren. -

-
+ + + + + + + + + + + + +
+

Paperless Manager

+

Tagesübersicht

+

${today}

+
+

${summaryText}

+
+ + ${cards} +
+
+

+ Diese E-Mail wird täglich automatisch von Paperless Manager versendet.
+ Sie können den Digest in den Benutzereinstellungen deaktivieren. +

+