Add right/wrong marking with steal mechanism and question stats
Adds Correct/Wrong buttons to admin panel that track question answer stats across games and implement a steal system where the next team gets one chance to answer if the first team is wrong. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -23,6 +23,7 @@ export default function GameAdminView() {
|
||||
const [newTeamName, setNewTeamName] = useState("");
|
||||
const [currentTurnTeamId, setCurrentTurnTeamId] = useState(null);
|
||||
const [currentTurnTeamName, setCurrentTurnTeamName] = useState(null);
|
||||
const [stealActive, setStealActive] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
loadGameState();
|
||||
@@ -41,6 +42,7 @@ export default function GameAdminView() {
|
||||
setTotalQuestions(response.data.total_questions);
|
||||
setCurrentTurnTeamId(response.data.current_turn_team_id);
|
||||
setCurrentTurnTeamName(response.data.current_turn_team_name);
|
||||
setStealActive(response.data.steal_active || false);
|
||||
} catch (error) {
|
||||
console.error("Error loading game state:", error);
|
||||
}
|
||||
@@ -87,6 +89,13 @@ export default function GameAdminView() {
|
||||
setCurrentTurnTeamName(data.current_turn_team_name);
|
||||
});
|
||||
|
||||
socket.on("steal_state_changed", (data) => {
|
||||
console.log("Steal state changed:", data);
|
||||
setStealActive(data.steal_active);
|
||||
setCurrentTurnTeamId(data.current_turn_team_id);
|
||||
setCurrentTurnTeamName(data.current_turn_team_name);
|
||||
});
|
||||
|
||||
return () => {
|
||||
socket.off("question_with_answer");
|
||||
socket.off("score_updated");
|
||||
@@ -94,6 +103,7 @@ export default function GameAdminView() {
|
||||
socket.off("lifeline_updated");
|
||||
socket.off("timer_reset");
|
||||
socket.off("turn_changed");
|
||||
socket.off("steal_state_changed");
|
||||
};
|
||||
}, [socket]);
|
||||
|
||||
@@ -220,6 +230,24 @@ export default function GameAdminView() {
|
||||
}
|
||||
};
|
||||
|
||||
const handleMarkCorrect = async () => {
|
||||
try {
|
||||
await adminAPI.markCorrect(gameId);
|
||||
} catch (error) {
|
||||
console.error("Error marking correct:", error);
|
||||
alert("Error marking correct");
|
||||
}
|
||||
};
|
||||
|
||||
const handleMarkWrong = async () => {
|
||||
try {
|
||||
await adminAPI.markWrong(gameId);
|
||||
} catch (error) {
|
||||
console.error("Error marking wrong:", error);
|
||||
alert("Error marking wrong");
|
||||
}
|
||||
};
|
||||
|
||||
const handleAdvanceTurn = async () => {
|
||||
try {
|
||||
await adminAPI.advanceTurn(gameId);
|
||||
@@ -399,6 +427,20 @@ export default function GameAdminView() {
|
||||
<div className="answer-box">
|
||||
<strong>Answer:</strong> {currentQuestion.answer}
|
||||
</div>
|
||||
{stealActive && (
|
||||
<div style={{
|
||||
marginTop: "0.75rem",
|
||||
padding: "0.5rem 1rem",
|
||||
background: "#FFF3E0",
|
||||
border: "2px solid #FF9800",
|
||||
borderRadius: "8px",
|
||||
color: "#E65100",
|
||||
fontWeight: "bold",
|
||||
textAlign: "center",
|
||||
}}>
|
||||
STEAL OPPORTUNITY — {currentTurnTeamName}'s turn to steal
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<p>No question selected. Click "Start Game" to begin.</p>
|
||||
@@ -559,21 +601,57 @@ export default function GameAdminView() {
|
||||
{/* Button grid - 2 columns on desktop, 1 on mobile */}
|
||||
<div className="controls-button-grid">
|
||||
{gameState?.is_active && teams.length > 0 && (
|
||||
<button
|
||||
onClick={handleAdvanceTurn}
|
||||
className="btn-next-turn"
|
||||
style={{
|
||||
padding: "0.75rem 1.5rem",
|
||||
background: "#673AB7",
|
||||
color: "white",
|
||||
border: "none",
|
||||
borderRadius: "4px",
|
||||
cursor: "pointer",
|
||||
fontSize: "1rem",
|
||||
}}
|
||||
>
|
||||
Next Turn {currentTurnTeamName ? `(${currentTurnTeamName})` : ""}
|
||||
</button>
|
||||
<>
|
||||
<button
|
||||
onClick={handleAdvanceTurn}
|
||||
className="btn-next-turn"
|
||||
style={{
|
||||
padding: "0.75rem 1.5rem",
|
||||
background: "#673AB7",
|
||||
color: "white",
|
||||
border: "none",
|
||||
borderRadius: "4px",
|
||||
cursor: "pointer",
|
||||
fontSize: "1rem",
|
||||
}}
|
||||
>
|
||||
Next Turn {currentTurnTeamName ? `(${currentTurnTeamName})` : ""}
|
||||
</button>
|
||||
{currentQuestion && (
|
||||
<>
|
||||
<button
|
||||
onClick={handleMarkCorrect}
|
||||
style={{
|
||||
padding: "0.75rem 1.5rem",
|
||||
background: "#4CAF50",
|
||||
color: "white",
|
||||
border: stealActive ? "3px solid #FF9800" : "none",
|
||||
borderRadius: "4px",
|
||||
cursor: "pointer",
|
||||
fontSize: "1rem",
|
||||
fontWeight: "bold",
|
||||
}}
|
||||
>
|
||||
{stealActive ? "Steal Correct (+1)" : "Correct (+1)"}
|
||||
</button>
|
||||
<button
|
||||
onClick={handleMarkWrong}
|
||||
style={{
|
||||
padding: "0.75rem 1.5rem",
|
||||
background: stealActive ? "#b71c1c" : "#f44336",
|
||||
color: "white",
|
||||
border: stealActive ? "3px solid #FF9800" : "none",
|
||||
borderRadius: "4px",
|
||||
cursor: "pointer",
|
||||
fontSize: "1rem",
|
||||
fontWeight: "bold",
|
||||
}}
|
||||
>
|
||||
{stealActive ? "Steal Wrong" : "Wrong"}
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{currentQuestion && (
|
||||
<button
|
||||
|
||||
@@ -120,6 +120,8 @@ export const adminAPI = {
|
||||
addLifeline: (gameId: number, teamId: number) =>
|
||||
api.post(`/admin/game/${gameId}/team/${teamId}/add-lifeline`),
|
||||
advanceTurn: (id: number) => api.post(`/admin/game/${id}/advance-turn`),
|
||||
markCorrect: (id: number) => api.post(`/admin/game/${id}/mark-correct`),
|
||||
markWrong: (id: number) => api.post(`/admin/game/${id}/mark-wrong`),
|
||||
};
|
||||
|
||||
// Categories API
|
||||
|
||||
Reference in New Issue
Block a user