65 lines
2.0 KiB
TypeScript
65 lines
2.0 KiB
TypeScript
import Link from "next/link";
|
|
import { prisma } from "@/lib/prisma";
|
|
import { formatMoney, billingLabel } from "@/lib/format";
|
|
|
|
export default async function AdminCoursesPage() {
|
|
const courses = await prisma.course.findMany({
|
|
orderBy: { updatedAt: "desc" },
|
|
include: { _count: { select: { enrollments: true, modules: true } } },
|
|
});
|
|
|
|
return (
|
|
<div>
|
|
<div className="stack" style={{ justifyContent: "space-between", marginBottom: "1rem" }}>
|
|
<div>
|
|
<h1 className="page-title">Kurse</h1>
|
|
<p className="muted subtitle">Alle Kurse inkl. Entwürfe</p>
|
|
</div>
|
|
<Link href="/admin/courses/new" className="btn btn-primary">
|
|
Neuer Kurs
|
|
</Link>
|
|
</div>
|
|
|
|
<div className="table-wrap">
|
|
<table className="simple">
|
|
<thead>
|
|
<tr>
|
|
<th>Titel</th>
|
|
<th>Slug</th>
|
|
<th>Status</th>
|
|
<th>Preis</th>
|
|
<th>Module</th>
|
|
<th>Einschreibungen</th>
|
|
<th />
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{courses.map((c) => (
|
|
<tr key={c.id}>
|
|
<td>{c.title}</td>
|
|
<td className="muted">{c.slug}</td>
|
|
<td>{c.published ? "Live" : "Entwurf"}</td>
|
|
<td>
|
|
{c.priceCents === 0 ? (
|
|
"kostenlos"
|
|
) : (
|
|
<>
|
|
{formatMoney(c.priceCents, c.currency)}
|
|
{billingLabel(c.billingInterval) ? ` ${billingLabel(c.billingInterval)}` : ""}
|
|
</>
|
|
)}
|
|
</td>
|
|
<td>{c._count.modules}</td>
|
|
<td>{c._count.enrollments}</td>
|
|
<td>
|
|
<Link href={`/admin/courses/${c.id}/edit`}>Bearbeiten</Link>
|
|
</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|