diff --git a/app/(app)/analytics/report/ReportClient.tsx b/app/(app)/analytics/report/ReportClient.tsx index a18ba9a..a581240 100644 --- a/app/(app)/analytics/report/ReportClient.tsx +++ b/app/(app)/analytics/report/ReportClient.tsx @@ -33,200 +33,532 @@ type ReportData = { generatedAt: number; }; -export function ReportClient({ data, logo }: { data: ReportData; logo: React.ReactNode }) { +const NR_LOGO = ( + +); + +export function ReportClient({ data }: { data: ReportData; logo?: React.ReactNode }) { useEffect(() => { const url = new URL(window.location.href); if (url.searchParams.get("print") === "1") { - setTimeout(() => window.print(), 800); + setTimeout(() => window.print(), 1200); } }, []); const s = data.sections; + const generatedDate = new Date(data.generatedAt).toLocaleDateString("de-DE", { day: "2-digit", month: "long", year: "numeric" }); + const periodFrom = new Date(Date.now() - data.days * 24 * 60 * 60 * 1000).toLocaleDateString("de-DE"); + const periodTo = new Date().toLocaleDateString("de-DE"); return ( -
- Zeitraum: letzte {data.days} Tage • Erstellt: {new Date(data.generatedAt).toLocaleString("de-DE")} -
+ {/* COVER */} ++ Übersicht über Domain-Aktivität und Nutzung im Zeitraum vom {periodFrom} bis {periodTo}. + Die Daten basieren auf der lokalen Hit-Datenbank des NexRedirect-Servers. +
+ ++ Bot-Traffic und automatisierte Anfragen sind herausgefiltert; eindeutige Besucher werden über + täglich rotierende IP-Hashes ermittelt (DSGVO-konform). +
+ + + +| Berichtszeitraum | letzte {data.days} Tage ({periodFrom} – {periodTo}) |
| Domains gesamt | {data.totalDomains.toLocaleString("de-DE")} ({data.activeDomains} aktiv) |
| Hits im Zeitraum | {data.totalHits.toLocaleString("de-DE")} |
| Eindeutige Besucher | {data.uniqueIps.toLocaleString("de-DE")} |
| Erstellt am | {generatedDate} |
Inhalt
+
+ {[
+ s.summary && "1. Zusammenfassung",
+ s.daily && "2. Hits pro Tag",
+ s.top && "3. Top Domains",
+ s.country && "4. Geografische Verteilung",
+ s.dead && "5. Tote Domains",
+ s.perDomain && "6. Detail pro Domain",
+ s.hits && "7. Letzte Aufrufe",
+ ].filter(Boolean).map((line, i) => (
+ {line}
+ ))}
+
Die meistgenutzten Domains im Berichtszeitraum, sortiert nach Hit-Count.
+ +| Domain | Hits | % gesamt |
|---|
| Domain | Hits | Anteil | |||
|---|---|---|---|---|---|
| {r.domain} | -{r.hits.toLocaleString("de-DE")} | -{data.totalHits ? ((r.hits / data.totalHits) * 100).toFixed(1) : "0"}% | +{r.domain} | +{r.hits.toLocaleString("de-DE")} | +{data.totalHits ? ((r.hits / data.totalHits) * 100).toFixed(1) : "0"}% |
| Land | Hits |
|---|---|
| {c.country} | {c.hits.toLocaleString("de-DE")} |
Aufschlüsselung der Hits nach Herkunftsland (über lokale GeoLite2-Datenbank).
+ +| Land | Hits | Anteil |
|---|---|---|
| {c.country} | +{c.hits.toLocaleString("de-DE")} | +{data.totalHits ? ((c.hits / data.totalHits) * 100).toFixed(1) : "0"}% | +
Aktive Domains ohne Hits in den letzten 90 Tagen — Kandidaten zum Kündigen.
-| Domain | Ziel | Angelegt |
|---|
| Domain | Ziel | Angelegt | |||
|---|---|---|---|---|---|
| {d.domain} | -{d.target_url || "—"} | -{new Date(d.created_at).toLocaleDateString("de-DE")} | +{d.domain} | +{d.target_url || "—"} | +{new Date(d.created_at).toLocaleDateString("de-DE")} |
| Domain | -Status | -Code | -Ziel | -Hits ({data.days}d) | -Hits gesamt | -Letzter Hit | +Domain | +Status | +Code | +Hits ({data.days}d) | +Hits gesamt | +Letzter Hit |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| {d.domain} | -{d.status} | -{d.redirect_code} | -{d.target_url || "—"} | -{d.hits_period.toLocaleString("de-DE")} | -{d.hits_total.toLocaleString("de-DE")} | -{d.last_hit ? new Date(d.last_hit).toLocaleString("de-DE") : "—"} | +{d.domain} | +{d.status} | +{d.redirect_code} | +{d.hits_period.toLocaleString("de-DE")} | +{d.hits_total.toLocaleString("de-DE")} | +{d.last_hit ? new Date(d.last_hit).toLocaleString("de-DE") : "—"} |
Bis zu 200 jüngste Hits im Berichts-Zeitraum.
-| Zeit | Domain | Land | Pfad |
|---|
| Zeit | +Domain | +Land | +Pfad | +||||
|---|---|---|---|---|---|---|---|
| {new Date(h.ts).toLocaleString("de-DE")} | -{h.domain} | -{h.country || "—"} | -{(h.path || "/").slice(0, 60)} | +{new Date(h.ts).toLocaleString("de-DE")} | +{h.domain} | +{h.country || "—"} | +{(h.path || "/").slice(0, 50)} |
{label}
-{value.toLocaleString("de-DE")}
- {sub &&{sub}
} -