122 lines
5.1 KiB
TypeScript
122 lines
5.1 KiB
TypeScript
import { CheckCircle2 } from "lucide-react";
|
|
|
|
import type { PublicAuditRenderState } from "@/lib/audits/public-audit-types";
|
|
import { RybbitTracking } from "./rybbit-tracking";
|
|
import { PublicAuditScreenshot } from "./public-audit-screenshot";
|
|
import { TrackedPublicAuditLink } from "./tracked-public-audit-link";
|
|
|
|
type PublicAuditPageProps = {
|
|
audit: Extract<PublicAuditRenderState, { kind: "published" }>["audit"];
|
|
};
|
|
|
|
export function PublicAuditPage({ audit }: PublicAuditPageProps) {
|
|
return (
|
|
<main className="min-h-dvh bg-slate-50 text-slate-950">
|
|
<RybbitTracking domain={audit.domain} />
|
|
<section className="border-b border-slate-200 bg-white">
|
|
<div className="mx-auto grid min-h-[72dvh] w-full max-w-6xl content-center gap-10 px-6 py-14 md:grid-cols-[minmax(0,1.1fr)_minmax(320px,0.9fr)] md:px-8">
|
|
<div className="max-w-3xl">
|
|
<p className="text-sm font-semibold uppercase tracking-normal text-emerald-700">
|
|
Öffentliche Audit-Kurzfassung
|
|
</p>
|
|
<h1 className="mt-4 text-4xl font-semibold tracking-normal text-slate-950 md:text-5xl">
|
|
{audit.headline}
|
|
</h1>
|
|
<p className="mt-5 text-lg leading-8 text-slate-700">{audit.intro}</p>
|
|
<dl className="mt-8 grid gap-4 text-sm text-slate-700 sm:grid-cols-2">
|
|
<div>
|
|
<dt className="font-semibold text-slate-950">Unternehmen</dt>
|
|
<dd className="mt-1">{audit.companyName}</dd>
|
|
</div>
|
|
<div>
|
|
<dt className="font-semibold text-slate-950">Geprüfte Domain</dt>
|
|
<dd className="mt-1">{audit.domain}</dd>
|
|
</div>
|
|
</dl>
|
|
</div>
|
|
|
|
<aside className="self-end border-l-4 border-emerald-600 bg-emerald-50 px-5 py-4 text-sm leading-6 text-emerald-950">
|
|
Diese Fassung enthält nur freigegebene Beobachtungen und keine internen Scores,
|
|
Skills oder Rohdaten.
|
|
</aside>
|
|
</div>
|
|
</section>
|
|
|
|
<section className="mx-auto w-full max-w-6xl px-6 py-12 md:px-8">
|
|
<div className="grid gap-5">
|
|
{audit.observations.map((observation, index) => (
|
|
<article
|
|
key={`${observation.title}-${index}`}
|
|
className="rounded-lg border border-slate-200 bg-white p-6 shadow-sm"
|
|
>
|
|
<div className="flex items-start gap-3">
|
|
<CheckCircle2 className="mt-1 h-5 w-5 shrink-0 text-emerald-700" aria-hidden />
|
|
<div>
|
|
<h2 className="text-xl font-semibold tracking-normal text-slate-950">
|
|
{observation.title}
|
|
</h2>
|
|
<div className="mt-5 grid gap-5 md:grid-cols-3">
|
|
<div>
|
|
<h3 className="text-sm font-semibold text-slate-950">Beobachtung</h3>
|
|
<p className="mt-2 text-sm leading-6 text-slate-700">
|
|
{observation.observation}
|
|
</p>
|
|
</div>
|
|
<div>
|
|
<h3 className="text-sm font-semibold text-slate-950">Auswirkung</h3>
|
|
<p className="mt-2 text-sm leading-6 text-slate-700">
|
|
{observation.impact}
|
|
</p>
|
|
</div>
|
|
<div>
|
|
<h3 className="text-sm font-semibold text-slate-950">Vorschlag</h3>
|
|
<p className="mt-2 text-sm leading-6 text-slate-700">
|
|
{observation.suggestion}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</article>
|
|
))}
|
|
</div>
|
|
</section>
|
|
|
|
{audit.screenshots.length > 0 ? (
|
|
<section className="border-y border-slate-200 bg-white">
|
|
<div className="mx-auto w-full max-w-6xl px-6 py-12 md:px-8">
|
|
<h2 className="text-2xl font-semibold tracking-normal text-slate-950">
|
|
Screenshots aus der Prüfung
|
|
</h2>
|
|
<div className="mt-6 grid gap-5 md:grid-cols-2">
|
|
{audit.screenshots.map((screenshot) => (
|
|
<PublicAuditScreenshot key={screenshot.id} screenshot={screenshot} />
|
|
))}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
) : null}
|
|
|
|
<section className="mx-auto w-full max-w-6xl px-6 py-12 md:px-8">
|
|
<div className="rounded-lg border border-slate-200 bg-white p-6 shadow-sm md:flex md:items-center md:justify-between md:gap-8">
|
|
<div>
|
|
<h2 className="text-2xl font-semibold tracking-normal text-slate-950">
|
|
Nächster sinnvoller Schritt
|
|
</h2>
|
|
<p className="mt-3 max-w-3xl text-sm leading-6 text-slate-700">
|
|
{audit.finalOffer.body}
|
|
</p>
|
|
</div>
|
|
{audit.finalOffer.ctaHref ? (
|
|
<TrackedPublicAuditLink
|
|
domain={audit.domain}
|
|
href={audit.finalOffer.ctaHref}
|
|
label={audit.finalOffer.ctaLabel ?? "Audit besprechen"}
|
|
/>
|
|
) : null}
|
|
</div>
|
|
</section>
|
|
</main>
|
|
);
|
|
}
|