Skip to content

Admin Panel Overview

React-based control plane for QS-Bridge — real-time cluster management via SpacetimeDB subscriptions.


Overview

The QS-Bridge admin panel is a React 19 single-page application that provides a complete control plane for managing game server clusters. It connects to SpacetimeDB over WebSocket for live data subscriptions and routes admin mutations through an API Gateway with Steam OpenID 2.0 authentication.

Live at: panel.qs-zuq.com

Technology Stack

Technology Version Role
React 19 UI framework
Vite 6 Build tool and dev server
TypeScript 5.6 Type safety (strict: true)
Tailwind CSS v4 Utility-first styling
framer-motion latest Animations and transitions
@tanstack/react-table latest Sortable, filterable data tables
recharts latest Data visualization charts
Monaco Editor latest SQL console with custom theme
cmdk latest Command palette
sonner latest Toast notifications
vaul latest Drawer components

Panel Pages

The panel has 13 pages organized into Platform and Developer navigation groups:

Platform Group (accessible to all admin roles)

Page Route Description
Dashboard / Cluster overview: stat cards, 3-column live feed (bans/events/chat)
Servers /servers Server fleet management with hosting API controls
Players /players Player list with dossier slide-out and inline admin actions
Passport /passport Cross-server player profile lookup (stub — pending rewrite)
Users & Roles /users Steam-enriched admin role management
Admin Controls /admin Moderation + Server Config tabs
Audit Log /audit-log Chronological admin action timeline
Settings /settings Server list management and hosting config
Mods /mods Mod registry browser and installation
Console /console Server console/RCON interface

Developer Group (Owner-only)

Page Route Description
Tables /tables SpacetimeDB table browser with live row counts
SQL Console /sql-console Monaco-powered SQL editor with custom dark theme

Design System

The panel uses a warm amber/rust palette defined via CSS custom properties:

Token Value Usage
--hz-bg #0f0d0b Primary background
--hz-accent #d4915c Primary accent (amber)
--hz-bright #ece7de Bright text
--hz-text #c4beb4 Body text
--hz-green #6aab78 Success states
--hz-red #c25a4a Error/danger states
--hz-blue #5a9dc4 Info states

Fonts: - Red Rose — headings and branding - Inter — body text - JetBrains Mono — code and monospace

Animations: 8 keyframe animations for page transitions, staggered card entrances, and scroll reveals via framer-motion.

Architecture

graph TD
    Browser[Browser]

    subgraph React["React 19 App (Vite 6 build)"]
        Auth[AuthProvider → checks JWT session via GET /auth/me]
        Stdb[StdbProvider → WebSocket to SpacetimeDB<br/>read-only subscriptions]
        Pages[Pages — lazy-loaded via React.lazy + code splitting]
        UI[UI Components — 16 shared primitives]
    end

    subgraph Gateway["API Gateway (Hono, port 3081)"]
        Steam[GET /auth/steam → Steam OpenID redirect]
        Callback[GET /auth/callback → verify assertion, issue JWT cookie]
        Me[GET /auth/me → return current session]
        Mutations[POST /api/* → admin mutations<br/>proxied to STDB reducers]
        Hosting[POST /api/hosting/* → BisectHosting lifecycle API]
    end

    subgraph STDB["SpacetimeDB (WebSocket, port 3000)"]
        Subs[Read-only subscriptions — 6 platform tables]
    end

    Browser --> React
    Browser --> Gateway
    Browser --> STDB

Code Splitting

The panel uses React.lazy() for page routes and Vite's manualChunks for vendor libraries:

Chunk Libraries Max Size
react react, react-dom, react-router-dom ~150 KB
stdb @clockworklabs/spacetimedb-sdk ~80 KB
motion framer-motion ~120 KB
monaco @monaco-editor/react, monaco-editor ~400 KB
tanstack @tanstack/react-table, @tanstack/react-virtual ~60 KB

No chunk exceeds 500 KB.