UX-Welle nach User-Feedback aus dem ersten Live-Test der Mail-Page: Page-Hierarchie neu (top → bottom): 1. HALF-DONUT als HERO-Karte — bisherige "BLOCKIERT XX über N Postfächer Live"- Banner-Card weg, Inhalt ist jetzt Title-Zeile innerhalb der Donut-Karte (rendert nur ab ≥2 Connections; Fallback-Stats-Row für 0-1 Connections) 2. Postfach-Liste (Account-Cards aus letztem Refactor — schlanker Header) 3. NEU: "Mehr Infos"-Collapsible — Bar-Chart "Blockiert letzte 30 Tage" liegt jetzt versteckt drin (default collapsed) 4. Activity-Log "Kürzlich blockiert" (unverändert) 5. NEU: FAB unten rechts — 56pt brandOrange Kreis mit "+"-Icon, öffnet ConnectMailSheet. Section-Header-Plus-Button entfällt. Half-Donut Legend-Truncation: - ≤3 Connections → alle anzeigen - =4 Connections → alle anzeigen - ≥5 Connections → Top-3 by blocked-count + "Sonstige"-Bucket · Donut: 4 Segmente (Top-3 + OTHER_COLOR grau) · Legend: 4 Zeilen (Top-3 fett, "weitere"-Zeile in regular grau) Backend: GET /api/mail/stats/blocked-by-day?connectionId=<uuid> als optionaler Filter (für per-Connection-Bar-Chart in expanded Account-Card, in dieser Welle noch nicht im UI verdrahtet — Erweiterung kommt wenn gewünscht). FAB-Details (iOS-diskreter Shadow statt Material-Glow): - position absolute, right 24, bottom = tabBarHeight + insets.bottom + 16 - 56pt, borderRadius 28, brandOrange BG, weißes Plus-Icon - ScrollView paddingBottom angehoben damit kein Content unter dem FAB clipped Edge-Cases: - 0 Accounts → FAB sichtbar, Donut/Stats/Charts/Log versteckt + EmptyState - 1 Account → Donut hidden (nur mit ≥2 Connections sinnvoll), Fallback-Stats-Row - limitReached + FAB-Tap → bestehender Plan-Alert (FAB ist visuell nicht disabled) Memory: Pull-to-refresh + bestehendes 30s-Status-Polling reichen für "wartet auf erste verbindung"→"aktiv"-Übergang nach OAuth-Connect (Daemon-Heartbeat braucht initial 2-9min, mo-Befund). UX-Polish-Option für später: in der Initial-Phase einen freundlicheren "Verbinde gerade…"-Status anzeigen. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
30 lines
1.1 KiB
TypeScript
30 lines
1.1 KiB
TypeScript
import { getBlockedMailsByDay } from "../../../db/mail";
|
|
|
|
/**
|
|
* GET /api/mail/stats/blocked-by-day?days=30[&connectionId=<uuid>]
|
|
*
|
|
* Blockierte Mails pro Tag (UTC) — Bar-Chart-Datenquelle.
|
|
*
|
|
* Query params:
|
|
* days? number — Anzahl Tage zurück (default 30, max 90)
|
|
* connectionId? uuid — Wenn angegeben: nur diese Connection. Gehört die UUID
|
|
* einem fremden User, kommen 0-Rows zurück (implizit 404).
|
|
*
|
|
* Response: { date: 'YYYY-MM-DD', count: number }[]
|
|
* — Alle N Tage sind enthalten, auch wenn count=0 (Frontend zeichnet flatline statt Lücken).
|
|
* — Timestamps sind UTC.
|
|
*/
|
|
export default defineEventHandler(async (event) => {
|
|
const user = await requireUser(event);
|
|
|
|
const query = getQuery(event);
|
|
const rawDays = parseInt((query.days as string) || "30");
|
|
const days = Math.min(Math.max(1, isNaN(rawDays) ? 30 : rawDays), 90);
|
|
|
|
const connectionId = (query.connectionId as string | undefined) || undefined;
|
|
|
|
const data = await getBlockedMailsByDay(user.id, days, connectionId);
|
|
|
|
return { success: true, data };
|
|
});
|