Show loading spinner while awaiting backend score

This commit is contained in:
2026-03-10 21:25:55 -07:00
parent 9c8a0c53a8
commit 451bfaf44e
+19 -15
View File
@@ -8,13 +8,13 @@ import {
} from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { useGameStore } from '@/stores/game-store';
import { useAuthStore } from '@/stores/auth-store';
import { submitScore } from '@/api/leaderboards';
import ScoreDisplay from './ScoreDisplay';
import ShareableResult from './ShareableResult';
import type { GameMode } from './ShareableResult';
import CelebrationOverlay from './CelebrationOverlay';
import { playSound } from '@/lib/sounds';
import { useNavigate } from 'react-router';
import { Loader2 } from 'lucide-react';
function formatElapsed(seconds: number): string {
const m = Math.floor(seconds / 60);
@@ -31,11 +31,15 @@ export default function GameCompletionModal() {
const hintsUsed = useGameStore((s) => s.hintsUsed);
const isDailyChallenge = useGameStore((s) => s.isDailyChallenge);
const dailyChallengeDate = useGameStore((s) => s.dailyChallengeDate);
const validationError = useGameStore((s) => s.validationError);
const resetGame = useGameStore((s) => s.resetGame);
const user = useAuthStore((s) => s.user);
const navigate = useNavigate();
const [showModal, setShowModal] = useState(false);
const gameMode: GameMode = isDailyChallenge && dailyChallengeDate
? { type: 'daily', date: dailyChallengeDate }
: { type: 'freeplay' };
useEffect(() => {
if (status === 'completed') {
setShowModal(true);
@@ -45,18 +49,6 @@ export default function GameCompletionModal() {
if (isDailyChallenge && dailyChallengeDate) {
localStorage.setItem('daily-completed-' + dailyChallengeDate, 'true');
}
// Auto-submit score if logged in
if (user && score) {
submitScore(
score.totalScore,
score.linkCount,
score.elapsedSeconds,
hintsUsed,
).catch(() => {
// Silent fail — score is still shown locally
});
}
} else {
setShowModal(false);
}
@@ -88,6 +80,17 @@ export default function GameCompletionModal() {
</DialogDescription>
</DialogHeader>
<div className="py-4">
{!score && !validationError && (
<div className="flex flex-col items-center gap-2 py-4">
<Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
<span className="text-sm text-muted-foreground">Calculating score...</span>
</div>
)}
{validationError && (
<div className="text-center text-sm text-destructive py-4">
{validationError}
</div>
)}
{score && (
<>
<ScoreDisplay score={score} />
@@ -107,6 +110,7 @@ export default function GameCompletionModal() {
chain={chain}
movieATitle={movieA.title}
movieBTitle={movieB.title}
mode={gameMode}
/>
)}
<div className="flex gap-3">