feat(admin): server-safe StatusCard and Import hub polish
CI / check (push) Failing after 8s
CI / release (push) Skipped
CI / deploy (push) Skipped

Split OnlineUsersWidget from StatusCard, decouple ad delete button, sync badge import to ExternalTexts+WebsiteBadges, add Import section hub with cancelable SSE jobs and upload SQL option.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
SimoandCursor committed 2026-08-01 15:48:21 +02:00
1 parent db957d7fb1
commit 9c4949186c
21 files changed
+576 -249

No files matched your search

+5 -11
View File
@@ -2,7 +2,7 @@ import { count, desc, eq, gt, inArray, or } from "drizzle-orm";
import {
Activity,
ArrowRight,
Ban,
Ban as BanIcon,
Database,
Newspaper,
Users,
@@ -11,13 +11,7 @@ import Link from "next/link";
import { getTranslations } from "next-intl/server";
import { StatusCard } from "@/components/admin/dashboard";
import { unixNow } from "@/lib/bans";
import {
Ban as BanTable,
db,
StaffActivities,
User,
WebsiteArticles,
} from "@/lib/db";
import { Ban, db, StaffActivities, User, WebsiteArticles } from "@/lib/db";
import { formatDate } from "@/lib/format-date";
type RankCount = { rank: number; count: number };
@@ -36,8 +30,8 @@ export default async function AdminDashboard() {
db.select({ total: count() }).from(WebsiteArticles),
db
.select({ total: count() })
.from(BanTable)
.where(or(eq(BanTable.banExpire, 0), gt(BanTable.banExpire, now))),
.from(Ban)
.where(or(eq(Ban.banExpire, 0), gt(Ban.banExpire, now))),
]);
users = usersRow[0]?.total ?? 0;
online = onlineRow[0]?.total ?? 0;
@@ -119,7 +113,7 @@ export default async function AdminDashboard() {
label={t("activeBans")}
value={dbOk ? bans : "—"}
state={bans > 0 ? "warn" : "neutral"}
icon={<Ban size={18} />}
icon={<BanIcon size={18} />}
/>
<StatusCard
label={t("database")}