Add persistence layer: TOTP auth, game history, restore
- db/ package: async SQLAlchemy engine + Player/Game/Guess models - api/auth.py: passwordless TOTP login (pyotp), session token via socket auth - api/history.py: record guesses/points, DB-backed standings, restore unfinished games on startup, host-only end_game - api/__init__.py: auth-gated handlers, accounts map, rejoin via account - frontend: Auth (QR + code) and History pages, resume/end-game in lobby/table - docker-compose: real PostgreSQL service wired via DATABASE_URL - tests_history.py for the persistence/auth layer; refresh CLAUDE.md Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useGameStore } from '../store/gameStore';
|
||||
import { emit } from '../lib/socket';
|
||||
import { leaveGame } from '../lib/leaveGame';
|
||||
import { computePlayable } from '../lib/gameRules';
|
||||
import Hand from '../components/Hand';
|
||||
@@ -68,6 +69,11 @@ export default function GameTable() {
|
||||
const activePlayerName = players.find((p) => p.order === active_player)?.name ?? '';
|
||||
|
||||
const handleLeave = () => leaveGame(navigate);
|
||||
const handleEnd = () => {
|
||||
if (window.confirm('Naozaj ukoncit celu hru pre vsetkych?')) {
|
||||
emit.endGame(gameStatus.gid);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="max-w-lg mx-auto p-3 flex flex-col gap-3 pb-6">
|
||||
@@ -77,9 +83,16 @@ export default function GameTable() {
|
||||
<span>Seria {series_number} / Kolo {round_number + 1}</span>
|
||||
<span className="ml-2 text-gray-500">({cards_in_round} kopok)</span>
|
||||
</div>
|
||||
<button onClick={handleLeave} className="text-xs text-gray-500 hover:text-gray-300">
|
||||
Odist
|
||||
</button>
|
||||
<div className="flex gap-3">
|
||||
{myOrder === 0 && (
|
||||
<button onClick={handleEnd} className="text-xs text-red-400 hover:text-red-300">
|
||||
Ukoncit hru
|
||||
</button>
|
||||
)}
|
||||
<button onClick={handleLeave} className="text-xs text-gray-500 hover:text-gray-300">
|
||||
Odist
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Turn indicator */}
|
||||
|
||||
Reference in New Issue
Block a user