import type { Metadata } from "next"; import Link from "next/link"; import { notFound } from "next/navigation"; import { Icon } from "@/components/icons"; import { Card } from "@/components/ui"; import { requirePageActor } from "@/lib/auth/guard"; import { can } from "@/lib/auth/policy"; import { prisma } from "@/lib/db"; import { FEEDBACK_SCALES, feedbackDataSchema } from "@/lib/qr/types/feedback"; export const dynamic = "force-dynamic"; export const metadata: Metadata = { title: "Rückmeldungen" }; type PageProps = { params: Promise<{ id: string }> }; function formatDate(value: Date): string { return new Intl.DateTimeFormat("de-DE", { dateStyle: "medium", timeStyle: "short", }).format(value); } export default async function FeedbackResultsPage({ params }: PageProps) { const { id } = await params; const actor = await requirePageActor(); const code = await prisma.qrCode.findUnique({ where: { id }, include: { feedback: { orderBy: { createdAt: "desc" }, take: 200 }, }, }); if (!code || code.type !== "feedback") notFound(); if (!can(actor, "codes:read", { groupId: code.groupId })) notFound(); const daten = feedbackDataSchema.safeParse(code.data); const skala = daten.success ? daten.data.scale : "stars"; const titel = daten.success ? daten.data.title : (code.label ?? "Feedback"); const eintraege = code.feedback; const anzahl = eintraege.length; const schnitt = anzahl > 0 ? eintraege.reduce((summe, eintrag) => summe + eintrag.rating, 0) / anzahl : 0; // Verteilung von 5 nach 1 — so liest man eine Bewertungsübersicht. const verteilung = [5, 4, 3, 2, 1].map((note) => ({ note, anzahl: eintraege.filter((eintrag) => eintrag.rating === note).length, })); const groesste = Math.max(1, ...verteilung.map((zeile) => zeile.anzahl)); const kommentare = eintraege.filter((eintrag) => eintrag.comment); return (
{anzahl === 0 ? "Es ist noch keine Rückmeldung eingegangen." : `${anzahl} ${anzahl === 1 ? "Rückmeldung" : "Rückmeldungen"} · ${code.scans} ${code.scans === 1 ? "Scan" : "Scans"}`}
{anzahl > 0 ? ( <>{schnitt.toFixed(1).replace(".", ",")}
von 5 im Schnitt
{eintrag.comment}
Angezeigt werden die 200 jüngsten Rückmeldungen.
) : null}Bisher hat niemand etwas dazugeschrieben.
)} > ) : (Sobald jemand den Code scannt und eine Bewertung abgibt, steht sie hier. Die Rückmeldungen enthalten keinen Namen und keine IP-Adresse.