latest changes

This commit is contained in:
remco committed 2026-07-01 15:06:52 +02:00
1 parent 56cd6fd058
commit 1de72863db
40 files changed
+3837 -568

No files matched your search

+5 -7
View File
@@ -12,12 +12,10 @@ export default async function EditArticle({
params: Promise<{ id: string }>;
}) {
const { id } = await params;
let article: Awaited<ReturnType<typeof prisma.websiteArticles.findUnique>> = null;
try {
article = await prisma.websiteArticles.findUnique({ where: { id: BigInt(id) } });
} catch {
notFound();
}
const article = await prisma.websiteArticles.findUnique({
where: { id: BigInt(id) },
select: { id: true, slug: true, title: true, shortStory: true, fullStory: true, image: true, createdAt: true, updatedAt: true },
}).catch(() => null);
if (!article) notFound();
return (
@@ -36,7 +34,7 @@ export default async function EditArticle({
</form>
<form action={deleteArticle} style={{ marginTop: "1rem" }}>
<input type="hidden" name="id" value={String(article.id)} />
<button type="submit">Delete article</button>
<button type="submit" className="btn btn-primary">Delete article</button>
</form>
</main>
);
+22 -3
View File
@@ -1,12 +1,11 @@
import Link from "next/link";
import { StatusCard } from "@/components/admin/dashboard";
import { deleteArticle } from "@/actions/admin-articles";
import { prisma } from "@/lib/prisma";
export const dynamic = "force-dynamic";
export default async function AdminArticles() {
// .catch(() => []) keeps the precise selected-row type while falling back to
// an empty list when the DB is unavailable (instead of a 500).
const articles = await prisma.websiteArticles
.findMany({
orderBy: { createdAt: "desc" },
@@ -47,13 +46,16 @@ export default async function AdminArticles() {
<th>Title</th>
<th>Slug</th>
<th>Created</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{articles.map((a) => (
<tr key={String(a.id)}>
<td>
<Link href={`/admin/articles/${a.id}`}>{a.title}</Link>
<Link href={`/admin/articles/${a.id}`} style={{ color: "var(--link-color)" }}>
{a.title}
</Link>
</td>
<td className="muted">
<code>{a.slug}</code>
@@ -61,6 +63,23 @@ export default async function AdminArticles() {
<td className="muted" style={{ whiteSpace: "nowrap" }}>
{a.createdAt ? a.createdAt.toISOString().slice(0, 10) : "—"}
</td>
<td>
<div style={{ display: "flex", gap: "0.5rem" }}>
<Link href={`/admin/articles/${a.id}`} className="btn btn-primary" style={{ fontSize: "0.8rem", padding: "0.3rem 0.6rem" }}>
Edit
</Link>
<form action={deleteArticle} style={{ margin: 0 }}>
<input type="hidden" name="id" value={String(a.id)} />
<button
type="submit"
className="btn btn-danger"
style={{ fontSize: "0.8rem", padding: "0.3rem 0.6rem" }}
>
Delete
</button>
</form>
</div>
</td>
</tr>
))}
</tbody>
+4 -4
View File
@@ -58,20 +58,20 @@ export default async function AdminDashboard() {
value={online}
hint={dbOk ? `${users} accounts` : "DB unavailable"}
state={dbOk ? "neutral" : "danger"}
icon="\u{1F464}"
icon="👤"
/>
<StatusCard label="Articles" value={dbOk ? articles : "—"} icon="\u{1F4F0}" />
<StatusCard label="Articles" value={dbOk ? articles : "—"} icon="📰" />
<StatusCard
label="Active bans"
value={dbOk ? bans : "—"}
state={bans > 0 ? "warn" : "neutral"}
icon="\u{1F528}"
icon="🔧"
/>
<StatusCard
label="Database"
value={dbOk ? "Connected" : "Down"}
state={dbOk ? "ok" : "danger"}
icon="\u{1F5C4}️"
icon="🗄️"
/>
</div>