Build a live status dashboard for Commandocentrum + admin home
The Commandocentrum (AtomCMS's verification/diagnostics hub) was just RCON buttons + an error table. Rebuilt it as a real status dashboard, and gave the admin home the same treatment, with reusable StatusCard / DiagnosticRow / InfoItem components and a scoped CSS layer: Commandocentrum now shows: - Live status tiles: players online, emulator (RCON ping), database, emulator error count — colour-accented by state. - Server info: Node version, platform, app/host uptime, heap/RSS, load, CPUs (from node:os / process). - System diagnostics: DB, emulator RCON, RCON config, APP_KEY (2FA), SMTP, maintenance mode — each with an ok/warn/error dot + pill. - Existing RCON controls + hotel alert, a recent staff-activity feed (staff_activities, now a real table), and the emulator error log. Admin home: four status tiles (online/articles/active bans/database) + recent staff activity, replacing the three plain count cards. Verified in a real authed admin session (prod, amx_test): both pages render the tiles/diagnostics with live data (Node v22, real memory/uptime, APP_KEY/SMTP correctly flagged WARN). tsc 0, vitest 49/49, next build 0.
This commit is contained in:
1 parent
f4e0924e71
commit
d419731566
4 files changed
+433
-25
No files matched your search
@@ -0,0 +1,66 @@
|
||||
import type { ReactNode } from "react";
|
||||
|
||||
type State = "ok" | "warn" | "danger" | "neutral";
|
||||
|
||||
/** A single live-status tile (online users, emulator, DB, …). */
|
||||
export function StatusCard({
|
||||
label,
|
||||
value,
|
||||
hint,
|
||||
state = "neutral",
|
||||
icon,
|
||||
}: {
|
||||
label: string;
|
||||
value: ReactNode;
|
||||
hint?: string;
|
||||
state?: State;
|
||||
icon?: string;
|
||||
}) {
|
||||
return (
|
||||
<div className={`admin-stat-card ${state}`}>
|
||||
<div className="admin-stat-top">
|
||||
<span className="admin-stat-label">{label}</span>
|
||||
{icon ? (
|
||||
<span className="admin-stat-icon" aria-hidden>
|
||||
{icon}
|
||||
</span>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="admin-stat-value">{value}</div>
|
||||
{hint ? <div className="admin-stat-hint">{hint}</div> : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/** A row in the system-diagnostics list with an ok/warn/error pill. */
|
||||
export function DiagnosticRow({
|
||||
label,
|
||||
detail,
|
||||
state,
|
||||
}: {
|
||||
label: string;
|
||||
detail: string;
|
||||
state: Exclude<State, "neutral">;
|
||||
}) {
|
||||
const text = state === "ok" ? "OK" : state === "warn" ? "WARN" : "ERROR";
|
||||
return (
|
||||
<div className="admin-diag-row">
|
||||
<span className={`admin-dot ${state}`} aria-hidden />
|
||||
<span className="admin-diag-label">{label}</span>
|
||||
<span className="admin-diag-detail muted">{detail}</span>
|
||||
<span className={`admin-badge ${state === "ok" ? "ok" : state === "danger" ? "danger" : ""}`}>
|
||||
{text}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/** Small labelled key/value used in the server-info card. */
|
||||
export function InfoItem({ label, value }: { label: string; value: ReactNode }) {
|
||||
return (
|
||||
<div className="admin-info-item">
|
||||
<span className="muted">{label}</span>
|
||||
<strong>{value}</strong>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user