Bring player portal in line with Admin + stat-tile My Characters

Implements the "Frontend Theme Redo" design (decision 1a): the logged-in
player portal now uses the same sidebar shell as Admin, and Admin's own
My Characters view gets the same stat-tile treatment.

- PlayerPortalLayout: replace the light 820px top-tab header with the
  Admin sidebar shell (icon nav, sticky content header with page title,
  signed-in footer with sign out). Reuses .admin-grid so the two
  logged-in experiences read as one app.
- Drop the now-redundant inner <h1> from PlayerCharacters/PlayerAccount;
  the title lives in the sticky header.
- CharacterStats: new stat-tile row (Characters / Online now / Linked
  account) that tolerates a restarting shard and hides until an account
  is linked.
- AdminCharacters: render CharacterStats above the roster instead of the
  bare intro paragraph, matching the Player Portal Characters page.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011qPmpmVH1xGCiZoz9m9vW3
This commit is contained in:
2026-07-11 10:58:03 -05:00
parent 6c310629c7
commit bf9edde5b7
5 changed files with 215 additions and 38 deletions

View File

@@ -1,15 +1,16 @@
import CharacterStats from '../../../components/CharacterStats.jsx'
import GameAccounts from '../../../components/GameAccounts.jsx'
import VendorSales from '../../../components/VendorSales.jsx'
import { api } from '../../../api/client.js'
// Staff link their OWN in-game account and view their characters — the same
// shared component players use, pointed at the staff self-service endpoints.
// Sits inside the Admin shell, which supplies the "My Characters" page header;
// stat tiles bring it to parity with the Player Portal's Characters page.
export default function AdminCharacters() {
return (
<section style={{ maxWidth: 760 }}>
<p className="sans" style={{ marginTop: 0, marginBottom: 22, color: 'var(--muted)', fontSize: '0.92rem', lineHeight: 1.6 }}>
Link your own game account to view your characters, stats, skills and vendors.
</p>
<CharacterStats scope={api.admin.shard} />
<GameAccounts scope={api.admin.shard} charTo={(serial) => `/admin/characters/${serial}`} />
<VendorSales fetchSales={api.admin.shard.sales} />
</section>