since3-portal/modules/templates/ui/views/templates-view.tsx
2026-10-10 02:38:50 +02:00

79 lines
4.3 KiB
TypeScript

import Link from "next/link"
import { Badge } from "@/components/ui/badge"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { getClients } from "@/modules/admin/queries/clients"
import { dateFormat, shareState, type ShareState } from "../../lib/preview"
import { getTemplate } from "../../lib/registry"
import { getVariants } from "../../queries/variants"
import { TemplateGrid } from "../components/template-grid"
const shareBadge: Record<ShareState, { label: string; variant: "success" | "warning" | "neutral" }> = {
shared: { label: "Geteilt", variant: "success" },
expired: { label: "Abgelaufen", variant: "warning" },
private: { label: "Privat", variant: "neutral" },
}
const TemplatesView = async () => {
const [variants, clients] = await Promise.all([getVariants(), getClients()])
const clientNames = new Map(clients.map((client) => [client.id, client.name]))
return (
<div className="flex w-full flex-col gap-10">
<div className="flex flex-col gap-2">
<h1 className="text-2xl font-semibold md:text-3xl">Vorlagen</h1>
<p className="max-w-2xl text-sm text-muted-foreground">
Demo-Webseiten für Pitches: Vorlage wählen, für den Kunden anpassen (Inhalte, Farben, Schriften, Reihenfolge) und als Link teilen.
</p>
</div>
<TemplateGrid />
<section className="flex flex-col gap-4">
<h2 className="text-lg font-semibold">Varianten</h2>
{variants.length === 0 ? (
<p className="rounded-xl border border-dashed p-8 text-center text-sm text-muted-foreground">
Noch keine Varianten. Wähle oben eine Vorlage und klicke auf „Anpassen“.
</p>
) : (
<div className="overflow-hidden rounded-xl border">
<Table>
<TableHeader>
<TableRow>
<TableHead>Name</TableHead>
<TableHead>Vorlage</TableHead>
<TableHead className="hidden md:table-cell">Client</TableHead>
<TableHead>Link</TableHead>
<TableHead className="hidden md:table-cell">Geändert</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{variants.map((variant) => {
const badge = shareBadge[shareState(variant.share_token, variant.share_expires_at)]
return (
<TableRow key={variant.id}>
<TableCell>
<Link href={`/admin/templates/${variant.id}`} className="font-medium hover:underline">
{variant.name}
</Link>
</TableCell>
<TableCell>{getTemplate(variant.template_key)?.name ?? variant.template_key}</TableCell>
<TableCell className="hidden md:table-cell">
{(variant.client_id && clientNames.get(variant.client_id)) ?? "—"}
</TableCell>
<TableCell><Badge variant={badge.variant}>{badge.label}</Badge></TableCell>
<TableCell className="hidden text-muted-foreground md:table-cell">
{dateFormat.format(new Date(variant.updated_at))}
</TableCell>
</TableRow>
)
})}
</TableBody>
</Table>
</div>
)}
</section>
</div>
)
}
export default TemplatesView