refactor: convert admin panel to Tailwind CSS

- Convert admin layout, sidebar, and navigation to Tailwind classes
- Convert dashboard components (StatusCard, DiagnosticRow, etc.) to Tailwind
- Convert all ~48 admin page files from admin CSS classes to Tailwind
- Remove unused admin CSS from globals.css (973 → 712 lines)
- Convert developers page badges to Tailwind
- Remove <style jsx> block from OnlineUsersWidget
This commit is contained in:
remco committed 2026-07-02 15:23:07 +02:00
1 parent 64f50b2dde
commit bd299be55d
52 files changed
+277 -644

No files matched your search

+9 -9
View File
@@ -299,28 +299,28 @@ const GROUPS: Group[] = [
];
const METHOD_CLASS: Record<Method, string> = {
GET: "ok",
POST: "",
DELETE: "danger",
GET: "bg-green-600/20 text-[var(--color-text)]",
POST: "bg-[var(--color-primary)]/18 text-[var(--color-text)]",
DELETE: "bg-red-500/22 text-[var(--color-text)]",
};
function AuthTag({ endpoint }: { endpoint: Endpoint }) {
if (endpoint.bearer) {
return (
<span className="admin-badge" title="Requires Authorization: Bearer <token>">
<span className="inline-block text-[0.72rem] font-bold px-2 py-0.5 rounded-full bg-[var(--color-primary)]/18 text-[var(--color-text)]" title="Requires Authorization: Bearer <token>">
🔒 Bearer
</span>
);
}
if (endpoint.session) {
return (
<span className="admin-badge" title="Requires a signed-in web session">
<span className="inline-block text-[0.72rem] font-bold px-2 py-0.5 rounded-full bg-[var(--color-primary)]/18 text-[var(--color-text)]" title="Requires a signed-in web session">
🔒 Session
</span>
);
}
return (
<span className="admin-badge ok" title="No authentication required">
<span className="inline-block text-[0.72rem] font-bold px-2 py-0.5 rounded-full bg-green-600/20 text-[var(--color-text)]" title="No authentication required">
Public
</span>
);
@@ -355,7 +355,7 @@ function EndpointRow({ endpoint }: { endpoint: Endpoint }) {
overflowX: "auto",
}}
>
<span className={`admin-badge ${METHOD_CLASS[endpoint.method]}`}>{endpoint.method}</span>
<span className={`inline-block text-[0.72rem] font-bold px-2 py-0.5 rounded-full ${METHOD_CLASS[endpoint.method]}`}>{endpoint.method}</span>
<span>{endpoint.path}</span>
</code>
<span className="muted" style={{ flex: "1 1 14rem", minWidth: "12rem" }}>
@@ -387,7 +387,7 @@ export default function DevelopersPage() {
<div style={{ display: "grid", gap: "0.75rem" }}>
<p className="muted" style={{ margin: 0 }}>
Most reads are <strong>open</strong> and need no credentials. Endpoints marked{" "}
<span className="admin-badge">🔒 Bearer</span> require a personal access token sent in
<span className="inline-block text-[0.72rem] font-bold px-2 py-0.5 rounded-full bg-[var(--color-primary)]/18 text-[var(--color-text)]">🔒 Bearer</span> require a personal access token sent in
the request header:
</p>
<code
@@ -411,7 +411,7 @@ export default function DevelopersPage() {
<code>POST</code> to <code>/api/tokens</code> — the plaintext token is returned{" "}
<strong>once</strong> and never shown again, so store it safely. You can list and revoke
your tokens at <code>/api/me/tokens</code>. These token-management endpoints are marked{" "}
<span className="admin-badge">🔒 Session</span> because they use your signed-in web
<span className="inline-block text-[0.72rem] font-bold px-2 py-0.5 rounded-full bg-[var(--color-primary)]/18 text-[var(--color-text)]">🔒 Session</span> because they use your signed-in web
session rather than a Bearer token.
</p>
<p className="muted" style={{ margin: 0 }}>