From 3787696aa8ac19ae9c77b1496af69d281b2f2fd5 Mon Sep 17 00:00:00 2001 From: Stefan Date: Wed, 3 Dec 2025 10:09:08 +0100 Subject: [PATCH] Replace system confirm dialog with styled resign confirmation modal - Replace window.confirm() with a custom styled modal dialog - Match existing modal styling (header, content, footer pattern) - Add Flag icon and AlertTriangle warning icon - Use localized Cancel button text from common translations - Improved UX with X close button and proper button styling --- src/components/ChessGame.tsx | 75 ++++++++++++++++++++++++++++++++---- 1 file changed, 67 insertions(+), 8 deletions(-) diff --git a/src/components/ChessGame.tsx b/src/components/ChessGame.tsx index 80c7b60..5eee632 100644 --- a/src/components/ChessGame.tsx +++ b/src/components/ChessGame.tsx @@ -13,7 +13,7 @@ import { SupportedLanguage } from "@/lib/i18n/translations"; import { lookupOpening, lookupPossibleOpenings, extractMoveSequenceFromPGN, OpeningMetadata } from "@/lib/openings"; import { GameAnalysisModal } from "./GameAnalysisModal"; import { GameOverModal, MoveHistoryItem } from "./GameOverModal"; -import { Brain, ArrowLeft, Download, Flag } from "lucide-react"; +import { Brain, ArrowLeft, Download, Flag, AlertTriangle, X } from "lucide-react"; import { CapturedPieces } from "./CapturedPieces"; import { detectMissedTactics, uciToSan, DetectedTactic } from "@/lib/tacticDetection"; import { upsertSavedGame } from "@/lib/savedGames"; @@ -65,6 +65,7 @@ export default function ChessGame({ gameId, initialFen, initialPgn, initialPerso const [playerColor, setPlayerColor] = useState<'white' | 'black'>(initialColor); const [showAnalysisModal, setShowAnalysisModal] = useState(false); const [showDownloadModal, setShowDownloadModal] = useState(false); + const [showResignConfirm, setShowResignConfirm] = useState(false); const [gameOverState, setGameOverState] = useState<{ result: string, winner: "White" | "Black" | "Draw" } | null>(null); const [moveHistory, setMoveHistory] = useState([]); const [selectedPersonality, setSelectedPersonality] = useState(initialPersonality); @@ -599,13 +600,13 @@ export default function ChessGame({ gameId, initialFen, initialPgn, initialPerso updateCapturedPieces(); }; - const handleResign = useCallback(async () => { + const handleResignClick = useCallback(() => { if (gameOverState) return; + setShowResignConfirm(true); + }, [gameOverState]); - // Show confirmation dialog - const confirmed = window.confirm(t.game.resignConfirm); - if (!confirmed) return; - + const handleResignConfirm = useCallback(async () => { + setShowResignConfirm(false); setIsAnalyzing(false); const currentFen = gameRef.current.fen(); @@ -635,7 +636,11 @@ export default function ChessGame({ gameId, initialFen, initialPgn, initialPerso result, winner, }); - }, [gameOverState, moveHistory, playerColor, stockfish, stockfishDepth, t.game.resignConfirm, t.game.resignation]); + }, [moveHistory, playerColor, stockfish, stockfishDepth, t.game.resignation]); + + const handleResignCancel = useCallback(() => { + setShowResignConfirm(false); + }, []); const handleDownloadPGN = () => { const pgn = gameRef.current.pgn(); @@ -784,7 +789,7 @@ export default function ChessGame({ gameId, initialFen, initialPgn, initialPerso + + + + {/* Content */} +
+
+ +

+ {t.game.resignConfirm} +

+
+
+ + {/* Footer */} +
+ + +
+ + + )} ); }