UX-Paket: Navbar aufgeräumt, /server-Seite, Lightbox, Skeletons, Audit-Log, Reroll
- Navbar entschlackt: nur noch Devlog · Roadmap · Server · Community · Setup; Galerie/Level/Events/Changelog im Community-Dropdown, Profil/Commits/Logout im Avatar-Menü; Mobile-Burger mit Drawer - Öffentliche /server-Seite: Live-Status-Karten mit Spieler-Balken, Map, Connect-Button und 24h-Spielerzahl-Chart (SVG); Monitor sampelt jede Abfrage in player_history (7 Tage Retention), GET /api/servers liefert nur öffentliche Felder (keine Query-URLs/Hosts) - Lightbox: Galerie- und Devlog-Bilder öffnen im Overlay mit Pfeiltasten, Buttons, Wisch-Gesten und Zähler statt neuem Tab - Skeleton-Loader: schimmernde Platzhalter auf Devlogs, Roadmap, Galerie, Level, Changelog und Server statt "Lade …" - Team-Audit-Log: audit_log-Tabelle (max 500 Einträge), Logging bei Settings/Composer/Vorlagen/Rollen-Menüs/Gameservern/Team/API-Keys/ Branding, GET /api/auditlog (Owner) + Liste im Team-Tab - Giveaway: 🔁 Reroll-Button (Admin-only) + 👥 Teilnehmerliste am Gewinner-Post Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { apiGet, apiDelete } from '../api.js';
|
||||
import { Markdown } from '../markdown.jsx';
|
||||
import Lightbox from '../components/Lightbox.jsx';
|
||||
import { SkeletonCards } from '../components/Skeleton.jsx';
|
||||
|
||||
const dateFmt = new Intl.DateTimeFormat('de-DE', {
|
||||
weekday: 'short', day: '2-digit', month: '2-digit', year: 'numeric',
|
||||
@@ -46,6 +48,7 @@ export default function Devlogs({ me }) {
|
||||
const [error, setError] = useState(false);
|
||||
const [qInput, setQInput] = useState('');
|
||||
const [q, setQ] = useState('');
|
||||
const [lightbox, setLightbox] = useState(null); // { images, start }
|
||||
|
||||
// Sucheingabe entprellen (300 ms), bei neuer Suche zurück auf Seite 1
|
||||
useEffect(() => {
|
||||
@@ -110,7 +113,7 @@ export default function Devlogs({ me }) {
|
||||
</div>
|
||||
|
||||
{error && <p className="notice">Devlogs konnten nicht geladen werden.</p>}
|
||||
{!error && !data && <p className="notice">Lade …</p>}
|
||||
{!error && !data && <SkeletonCards n={3} />}
|
||||
{data?.total === 0 && (
|
||||
<p className="notice">{q ? `Keine Treffer für „${q}".` : 'Noch keine Devlogs archiviert.'}</p>
|
||||
)}
|
||||
@@ -147,8 +150,14 @@ export default function Devlogs({ me }) {
|
||||
</div>
|
||||
{d.images?.length > 0 && (
|
||||
<div className={`card-images n${Math.min(d.images.length, 4)}`}>
|
||||
{d.images.map((src) => (
|
||||
<a key={src} href={src} target="_blank" rel="noreferrer">
|
||||
{d.images.map((src, i) => (
|
||||
<a
|
||||
key={src} href={src}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
setLightbox({ images: d.images, start: i });
|
||||
}}
|
||||
>
|
||||
<img src={src} alt="Devlog-Screenshot" loading="lazy" />
|
||||
</a>
|
||||
))}
|
||||
@@ -166,6 +175,14 @@ export default function Devlogs({ me }) {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{lightbox && (
|
||||
<Lightbox
|
||||
images={lightbox.images}
|
||||
start={lightbox.start}
|
||||
onClose={() => setLightbox(null)}
|
||||
/>
|
||||
)}
|
||||
|
||||
{pages > 1 && (
|
||||
<div className="pager">
|
||||
<button className="btn" disabled={page <= 1} onClick={() => setPage(page - 1)}>
|
||||
|
||||
Reference in New Issue
Block a user