Adapt + improve all admin pages to the new design system
Swept the whole housekeeping panel (34 pages) so it's a consistent, improved adaptation of the old Filament admin rather than bare tables: - Live status tiles (StatusCard) summarising each page's data — counts and stateful metrics (users online, active/permanent bans, pending applications, settings, radio shouts, etc.). - Status pills (admin-badge ok/danger) replacing ad-hoc text: online/ offline, account/ip ban types, permanent vs timed, command OK/FAIL, alert severity & read/new, enabled/disabled, open/closed. - Sections wrapped in .admin-section with h2 headers; redundant inline table styling removed (the global .admin layer handles it). - alerts/logs/emulator hand-built as the reference pattern; the rest via parallel agents that read the schema and preserved every server action, query and field name. Behaviour unchanged (same actions, queries, field names). Verified in a real authed admin session (prod, amx_test): pages render with live data (Users tiles show 7 real accounts + online/offline pills), no errors. tsc 0, vitest 49/49, next build 0.
This commit is contained in:
1 parent
d419731566
commit
0de0ac6a3c
34 files changed
+2357
-1396
No files matched your search
@@ -1,6 +1,7 @@
|
||||
import Link from 'next/link';
|
||||
import { saveRadioSetting, saveRadioSettings } from '@/actions/admin-radio-extra';
|
||||
import { prisma } from '@/lib/prisma';
|
||||
import { StatusCard } from '@/components/admin/dashboard';
|
||||
|
||||
export const dynamic = 'force-dynamic';
|
||||
|
||||
@@ -208,17 +209,26 @@ export default async function AdminRadioSettingsPage() {
|
||||
|
||||
const allKeys = [...CURATED_KEYS, ...extra.map((e) => e.key)].join(',');
|
||||
|
||||
const totalKeys = CURATED_KEYS.size + extra.length;
|
||||
// Curated keys that already have a non-empty stored value.
|
||||
const configuredKeys = [...CURATED_KEYS].filter((k) => {
|
||||
const v = values.get(k);
|
||||
return v != null && v !== '';
|
||||
}).length;
|
||||
const radioEnabled = (values.get('radio_enabled') ?? '') === '1';
|
||||
|
||||
return (
|
||||
<main>
|
||||
<nav className="muted" style={{ marginBottom: '0.5rem' }}>
|
||||
<Link href="/admin/radio">Radio</Link> ·{' '}
|
||||
<Link href="/admin/radio/settings">Settings</Link> ·{' '}
|
||||
<Link href="/admin/radio/banners">Banners</Link> ·{' '}
|
||||
<Link href="/admin/radio/ranks">Ranks</Link>
|
||||
<Link href="/admin/radio/ranks">Ranks</Link> ·{' '}
|
||||
<Link href="/admin/radio/history">History</Link>
|
||||
</nav>
|
||||
|
||||
<h1>Radio Settings</h1>
|
||||
<p className="muted">
|
||||
<p className="muted" style={{ marginTop: '-0.4rem' }}>
|
||||
Edits write to <code>website_settings</code> (radio_* keys) and bust the
|
||||
runtime settings cache. Booleans use <code>0</code> / <code>1</code>.
|
||||
</p>
|
||||
@@ -230,7 +240,29 @@ export default async function AdminRadioSettingsPage() {
|
||||
created on save.
|
||||
</p>
|
||||
</div>
|
||||
) : null}
|
||||
) : (
|
||||
<div className="admin-stats">
|
||||
<StatusCard
|
||||
label="Radio"
|
||||
value={radioEnabled ? 'Enabled' : 'Disabled'}
|
||||
state={radioEnabled ? 'ok' : 'danger'}
|
||||
icon="📻"
|
||||
/>
|
||||
<StatusCard label="Total keys" value={totalKeys} icon="🔑" />
|
||||
<StatusCard
|
||||
label="Configured"
|
||||
value={`${configuredKeys}/${CURATED_KEYS.size}`}
|
||||
hint="curated keys with a value"
|
||||
icon="⚙️"
|
||||
/>
|
||||
<StatusCard
|
||||
label="Custom keys"
|
||||
value={extra.length}
|
||||
state={extra.length > 0 ? 'warn' : 'neutral'}
|
||||
icon="➕"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<form action={saveRadioSettings}>
|
||||
<input type="hidden" name="__keys" value={allKeys} />
|
||||
|
||||
Reference in new issue
Block a user