"use client"; import { useMemo } from "react"; import { useQuery } from "convex/react"; import type { Id } from "@/convex/_generated/dataModel"; import { api } from "@/convex/_generated/api"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Globe } from "lucide-react"; type UsedSkill = { name: string; purpose?: string; category?: string; source?: string; version?: string; }; type LeadContext = { _id: Id<"leads">; companyName?: string; websiteDomain?: string; websiteUrl?: string; city?: string; niche?: string; }; type SkillAwareAudit = { _id: Id<"audits">; slug: string; checkedDomain: string; status: "draft" | "approved" | "published" | "deactivated"; checkedPages: string[]; createdAt?: number; updatedAt?: number; usedSkills?: UsedSkill[]; internalSummary?: string | null; }; type CheckedPageScreenshot = { id: Id<"_storage">; url: string; viewport: "desktop" | "mobile"; sourceUrl: string; width: number; height: number; createdAt: number; }; type CheckedPageEvidence = { url: string; sourceUrl: string | null; finalUrl: string | null; pageKind: string | null; title: string | null; metaDescription: string | null; headings: string[]; visibleTextExcerpt: string | null; hasContactFormSignal: boolean | null; hasContactCtaSignal: boolean | null; usesHttps: boolean | null; missingMetaDescription: boolean | null; brokenInternalLinkCount: number | null; screenshots: CheckedPageScreenshot[]; createdAt: number | null; }; type AuditDetailResult = { audit: SkillAwareAudit; lead: LeadContext | null; sourceSummaries: { checkedPages: CheckedPageEvidence[]; }; } | null; const statusText: Record = { draft: "Entwurf", approved: "Freigegeben", published: "Veröffentlicht", deactivated: "Deaktiviert", }; function getStatusLabel(status: SkillAwareAudit["status"]) { return statusText[status] ?? "Unbekannt"; } function getPageKindLabel(pageKind: string | null) { const labels: Record = { contact: "Kontakt", homepage: "Startseite", imprint: "Impressum", other: "Unterseite", service: "Leistung", }; return pageKind ? labels[pageKind] ?? pageKind : "Geprüft"; } function signalText(value: boolean | null, positive: string, negative: string) { if (value === null) { return "Unbekannt"; } return value ? positive : negative; } function metaSignalText(page: CheckedPageEvidence) { if (page.metaDescription) { return "Vorhanden"; } if (page.missingMetaDescription === true) { return "Fehlt"; } if (page.missingMetaDescription === false) { return "Vorhanden"; } return "Unbekannt"; } function leadSummary(lead: LeadContext | null | undefined) { if (!lead) { return "Kein Lead-Kontext gespeichert"; } const detail = [lead.city, lead.niche].filter(Boolean).join(" • "); let leadDomain = lead.websiteDomain ?? "—"; if (!leadDomain && lead.websiteUrl) { try { leadDomain = new URL(lead.websiteUrl).hostname; } catch { leadDomain = lead.websiteUrl; } } return ( <>

{lead.companyName ?? "Lead ohne Name"}

{detail || "Kein Kontext textlich"}

{leadDomain}

); } export function AuditDetail({ id }: { id: string | Id<"audits"> }) { const result = useQuery(api.audits.getDetail, { id: id as Id<"audits">, }) as AuditDetailResult | undefined; const audit = result?.audit; const lead = result?.lead; const usedSkills = useMemo(() => audit?.usedSkills ?? [], [audit]); const checkedPageEvidence = useMemo( () => result?.sourceSummaries.checkedPages ?? [], [result], ); if (result === null) { return ( Audit nicht gefunden Der gewünschte Audit-Datensatz konnte nicht geladen werden. ); } if (audit === undefined) { return ( Audit wird geladen... ); } return (
Audit-Detail #{audit.slug}

{audit.checkedDomain}

Status

{getStatusLabel(audit.status)}

Seitenanzahl

{audit.checkedPages.length}

Lead-Kontext

{leadSummary(lead)}
{audit.internalSummary ? (

Interne Notiz

{audit.internalSummary}

) : null}
Geprüfte Seiten Kompakte Evidence aus Website-Enrichment und Screenshot-Erfassung. {checkedPageEvidence.length === 0 ? (

Keine Seiten-Evidence gespeichert

) : (
    {checkedPageEvidence.map((page, index) => (
  • {page.title ?? page.finalUrl ?? page.sourceUrl ?? page.url}

    {page.finalUrl ?? page.sourceUrl ?? page.url}

    {getPageKindLabel(page.pageKind)}
    {page.visibleTextExcerpt ? (

    {page.visibleTextExcerpt}

    ) : null}
    Meta: {metaSignalText(page)} Kontaktformular:{" "} {signalText(page.hasContactFormSignal, "Signal", "Kein Signal")} CTA: {signalText(page.hasContactCtaSignal, "Signal", "Kein Signal")} Interne Links: {page.brokenInternalLinkCount ?? "Unbekannt"}
    {page.screenshots.length > 0 ? (
    {page.screenshots.map((screenshot) => (
    {/* eslint-disable-next-line @next/next/no-img-element */} {`${screenshot.viewport
    {screenshot.viewport === "desktop" ? "Desktop" : "Mobil"} {screenshot.sourceUrl}
    ))}
    ) : null}
  • ))}
)}
Verwendete Skills Skills, die an diesem Audit beteiligt wurden. {usedSkills.length === 0 ? (

Keine Skills gespeichert

) : (
    {usedSkills.map((skill, index) => (
  • {skill.name}

    {skill.purpose ?? "Keine Zweckbeschreibung"}

    {skill.category ? {skill.category} : null} {skill.version ? {skill.version} : null} {skill.source ? {skill.source} : null}

  • ))}
)}
); }