Server-Tab (DiscordGSM-Stil), Team-Rechte und Bot-Profil-Beschreibung

- Game-Server: eigene Tabelle statt CSV-Setting (automatische Migration), eigener
  Setup-Tab mit Server-Builder (Name, Typ fivem/http, Query-URL, Anzeige-Adresse);
  pro Server ein Live-Embed (gruen/rot, Spieler-Balken, Map, Adresse als Code-Block),
  edit in place; Embed wird beim Server-Loeschen mit entfernt
- Team-System: web_admins mit Bereichs-Scopes (content/community/rollen/bewerbungen/
  server/settings/devlogs); Owner behaelt Brand/System/API-Keys/Team exklusiv;
  32 Routen-Guards auf Scopes umgestellt, sensible PUT-Felder fuer Team gestrippt;
  Team-Tab (Owner) + Tab-Filterung im Frontend, /api/me liefert Scopes
- Bot-Karte: Profil-Beschreibung (Ueber mich) via application.edit
- Fix: settings-Tabelle wird vor der Gameserver-Migration angelegt (frische DBs
  crashten sonst beim Start)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-30 01:23:11 +02:00
co-authored by Claude Fable 5
parent 19ec2802ac
commit 332e89dcbd
6 changed files with 533 additions and 115 deletions
+4 -4
View File
@@ -48,13 +48,13 @@ function Particles() {
export default function App() {
// Login-Status einmal beim Laden holen
const [me, setMe] = useState({ user: null, admin: false, loading: true });
const [me, setMe] = useState({ user: null, admin: false, scopes: [], loading: true });
const [scrolled, setScrolled] = useState(false);
useEffect(() => {
apiGet('/api/me')
.then((data) => setMe({ ...data, loading: false }))
.catch(() => setMe({ user: null, admin: false, loading: false }));
.then((data) => setMe({ scopes: [], ...data, loading: false }))
.catch(() => setMe({ user: null, admin: false, scopes: [], loading: false }));
}, []);
useEffect(() => {
@@ -80,7 +80,7 @@ export default function App() {
<NavLink to="/events">Events</NavLink>
<NavLink to="/changelog">Changelog</NavLink>
{me.admin && <NavLink to="/commits">Commits</NavLink>}
{me.admin && <NavLink to="/settings">Setup</NavLink>}
{(me.admin || me.scopes?.length > 0) && <NavLink to="/settings">Setup</NavLink>}
</nav>
<div className="auth">