fix(admin): P0 integrity — permanent bans, ACL sidebar, rank guards
Deploy / release (push) Skipped
Deploy / deploy (push) Successful in 1m36s

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
SimoandCursor committed 2026-07-22 19:01:59 +02:00
1 parent 11004626c7
commit 75cdfdebe4
14 files changed
+458 -68

No files matched your search

+31 -3
View File
@@ -2,6 +2,7 @@
import Image from "next/image";
import type { ReactNode } from "react";
import { cn } from "@/lib/utils";
export interface OnlineUser {
id: number;
@@ -14,12 +15,29 @@ export interface OnlineUser {
type State = "ok" | "warn" | "danger" | "neutral";
const STATE_RING: Record<State, string> = {
ok: "ring-1 ring-[var(--admin-success-subtle)]/50 border-[var(--admin-success-subtle)]/40",
warn: "ring-1 ring-[var(--admin-accent)]/40 border-[var(--admin-accent)]/35",
danger:
"ring-1 ring-[var(--admin-error-subtle)]/50 border-[var(--admin-error-subtle)]/45",
neutral: "border-[var(--admin-border)]",
};
const STATE_ICON_BG: Record<State, string> = {
ok: "from-[var(--admin-success-subtle)]/25 to-[var(--admin-success-subtle)]/5 text-[var(--admin-success)]",
warn: "from-[var(--admin-accent)]/20 to-[var(--admin-accent)]/5 text-[var(--admin-accent)]",
danger:
"from-[var(--admin-error-subtle)]/25 to-[var(--admin-error-subtle)]/5 text-[var(--admin-error)]",
neutral:
"from-[var(--admin-accent)]/15 to-[var(--admin-accent)]/5 text-[var(--admin-accent)]",
};
/** A single live-status tile (online users, emulator, DB, …). */
export function StatusCard({
label,
value,
hint,
state: _state = "neutral",
state = "neutral",
icon,
}: {
label: string;
@@ -29,13 +47,23 @@ export function StatusCard({
icon?: ReactNode;
}) {
return (
<div className="bg-[var(--admin-surface)] border border-[var(--admin-border)] rounded-2xl p-5 shadow-card hover:shadow-card-hover transition-shadow duration-200">
<div
className={cn(
"bg-[var(--admin-surface)] border rounded-2xl p-5 shadow-card hover:shadow-card-hover transition-shadow duration-200",
STATE_RING[state],
)}
>
<div className="flex items-center justify-between gap-3 mb-3">
<span className="text-[0.65rem] font-bold uppercase tracking-widest text-[var(--admin-text-muted)]">
{label}
</span>
{icon ? (
<span className="w-8 h-8 rounded-xl bg-gradient-to-br from-[var(--admin-accent)]/15 to-[var(--admin-accent)]/5 grid place-items-center text-[var(--admin-accent)] flex-none">
<span
className={cn(
"w-8 h-8 rounded-xl bg-gradient-to-br grid place-items-center flex-none",
STATE_ICON_BG[state],
)}
>
{icon}
</span>
) : null}