Add user stats feature with API and modal integration

Introduced an endpoint to fetch user stats and integrated it with a new StatsModal component in the frontend. Users can now view game statistics, including played games, wins, losses, and win rates, accessible from the user menu.
This commit is contained in:
2026-02-06 13:14:27 +01:00
parent bfb1df8e59
commit 59e224b4ca
6 changed files with 193 additions and 8 deletions

View File

@@ -20,6 +20,7 @@ import DesignModal from "./components/DesignModal";
import WinnerCard from "./components/WinnerCard";
import WinnerBadge from "./components/WinnerBadge";
import NewGameModal from "./components/NewGameModal";
import StatsModal from "./components/StatsModal";
export default function App() {
useHpGlobalStyles();
@@ -62,6 +63,12 @@ export default function App() {
// New Game Modal
const [newGameOpen, setNewGameOpen] = useState(false);
// ===== Stats Modal =====
const [statsOpen, setStatsOpen] = useState(false);
const [stats, setStats] = useState(null);
const [statsLoading, setStatsLoading] = useState(false);
const [statsError, setStatsError] = useState("");
const load = async () => {
const m = await api("/auth/me");
setMe(m);
@@ -201,6 +208,29 @@ export default function App() {
}
};
// ===== Stats (always fresh on open) =====
const openStatsModal = async () => {
setUserMenuOpen(false);
setStatsOpen(true);
setStatsError("");
setStatsLoading(true);
try {
const s = await api("/auth/me/stats");
setStats(s);
} catch (e) {
setStats(null);
setStatsError("❌ Fehler: " + (e?.message || "unknown"));
} finally {
setStatsLoading(false);
}
};
const closeStatsModal = () => {
setStatsOpen(false);
setStatsError("");
};
// ===== New game flow =====
const createGame = async () => {
const g = await api("/games", {
@@ -366,6 +396,7 @@ export default function App() {
setUserMenuOpen={setUserMenuOpen}
openPwModal={openPwModal}
openDesignModal={openDesignModal}
openStatsModal={openStatsModal}
doLogout={doLogout}
onOpenNewGame={() => setNewGameOpen(true)}
/>
@@ -444,6 +475,15 @@ export default function App() {
closeChipModalToDash={closeChipModalToDash}
chooseChip={chooseChip}
/>
<StatsModal
open={statsOpen}
onClose={closeStatsModal}
me={me}
stats={stats}
loading={statsLoading}
error={statsError}
/>
</div>
);
}