oops
This commit is contained in:
@@ -111,6 +111,17 @@
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 8px;
|
||||
background: white;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.team-card-active-turn {
|
||||
border: 3px solid #673AB7;
|
||||
background: #EDE7F6;
|
||||
box-shadow: 0 0 10px rgba(103, 58, 183, 0.3);
|
||||
}
|
||||
|
||||
.team-card-active-turn .team-name {
|
||||
color: #673AB7;
|
||||
}
|
||||
|
||||
.team-card-header {
|
||||
|
||||
@@ -21,6 +21,8 @@ export default function GameAdminView() {
|
||||
const [timerExpired, setTimerExpired] = useState(false);
|
||||
const [timerPaused, setTimerPaused] = useState(false);
|
||||
const [newTeamName, setNewTeamName] = useState("");
|
||||
const [currentTurnTeamId, setCurrentTurnTeamId] = useState(null);
|
||||
const [currentTurnTeamName, setCurrentTurnTeamName] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
loadGameState();
|
||||
@@ -37,6 +39,8 @@ export default function GameAdminView() {
|
||||
setCurrentQuestion(response.data.current_question);
|
||||
setQuestionIndex(response.data.current_question_index);
|
||||
setTotalQuestions(response.data.total_questions);
|
||||
setCurrentTurnTeamId(response.data.current_turn_team_id);
|
||||
setCurrentTurnTeamName(response.data.current_turn_team_name);
|
||||
} catch (error) {
|
||||
console.error("Error loading game state:", error);
|
||||
}
|
||||
@@ -77,12 +81,19 @@ export default function GameAdminView() {
|
||||
setTimerPaused(false);
|
||||
});
|
||||
|
||||
socket.on("turn_changed", (data) => {
|
||||
console.log("Turn changed:", data);
|
||||
setCurrentTurnTeamId(data.current_turn_team_id);
|
||||
setCurrentTurnTeamName(data.current_turn_team_name);
|
||||
});
|
||||
|
||||
return () => {
|
||||
socket.off("question_with_answer");
|
||||
socket.off("score_updated");
|
||||
socket.off("timer_paused");
|
||||
socket.off("lifeline_updated");
|
||||
socket.off("timer_reset");
|
||||
socket.off("turn_changed");
|
||||
};
|
||||
}, [socket]);
|
||||
|
||||
@@ -209,6 +220,15 @@ export default function GameAdminView() {
|
||||
}
|
||||
};
|
||||
|
||||
const handleAdvanceTurn = async () => {
|
||||
try {
|
||||
await adminAPI.advanceTurn(gameId);
|
||||
} catch (error) {
|
||||
console.error("Error advancing turn:", error);
|
||||
alert("Error advancing turn");
|
||||
}
|
||||
};
|
||||
|
||||
const handleToggleAnswer = async () => {
|
||||
const newShowAnswer = !showAnswer;
|
||||
try {
|
||||
@@ -417,7 +437,7 @@ export default function GameAdminView() {
|
||||
) : (
|
||||
<div className="teams-list">
|
||||
{teams.map((team) => (
|
||||
<div key={team.id} className="team-card">
|
||||
<div key={team.id} className={`team-card ${team.id === currentTurnTeamId ? 'team-card-active-turn' : ''}`}>
|
||||
<div className="team-card-header">
|
||||
<div className="team-name-section">
|
||||
<strong className="team-name">{team.name}</strong>
|
||||
@@ -538,6 +558,23 @@ 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>
|
||||
)}
|
||||
{currentQuestion && (
|
||||
<button
|
||||
onClick={handleToggleAnswer}
|
||||
|
||||
@@ -18,6 +18,8 @@ export default function ContestantView() {
|
||||
const [timerActive, setTimerActive] = useState(false);
|
||||
const [timerPaused, setTimerPaused] = useState(false);
|
||||
const [categories, setCategories] = useState([]);
|
||||
const [currentTurnTeamId, setCurrentTurnTeamId] = useState(null);
|
||||
const [currentTurnTeamName, setCurrentTurnTeamName] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
// Load initial game state
|
||||
@@ -140,6 +142,8 @@ export default function ContestantView() {
|
||||
setTimerSeconds(30);
|
||||
setTimerActive(false);
|
||||
setTimerPaused(false);
|
||||
setCurrentTurnTeamId(null);
|
||||
setCurrentTurnTeamName(null);
|
||||
});
|
||||
|
||||
socket.on("lifeline_updated", (data) => {
|
||||
@@ -154,6 +158,12 @@ export default function ContestantView() {
|
||||
setTimerPaused(false);
|
||||
});
|
||||
|
||||
socket.on("turn_changed", (data) => {
|
||||
console.log("Turn changed:", data);
|
||||
setCurrentTurnTeamId(data.current_turn_team_id);
|
||||
setCurrentTurnTeamName(data.current_turn_team_name);
|
||||
});
|
||||
|
||||
return () => {
|
||||
socket.off("game_started");
|
||||
socket.off("question_changed");
|
||||
@@ -163,6 +173,7 @@ export default function ContestantView() {
|
||||
socket.off("game_ended");
|
||||
socket.off("lifeline_updated");
|
||||
socket.off("timer_reset");
|
||||
socket.off("turn_changed");
|
||||
};
|
||||
}, [socket]);
|
||||
|
||||
@@ -283,6 +294,25 @@ export default function ContestantView() {
|
||||
>
|
||||
{currentQuestion ? (
|
||||
<div style={{ width: "100%", textAlign: "center" }}>
|
||||
{/* Turn indicator */}
|
||||
{currentTurnTeamName && (
|
||||
<div
|
||||
className="turn-indicator"
|
||||
style={{
|
||||
fontSize: "2rem",
|
||||
fontWeight: "bold",
|
||||
marginBottom: "1.5rem",
|
||||
padding: "1rem 2rem",
|
||||
background: "#673AB7",
|
||||
color: "white",
|
||||
borderRadius: "8px",
|
||||
display: "inline-block",
|
||||
animation: "pulse 2s infinite",
|
||||
}}
|
||||
>
|
||||
{currentTurnTeamName}'s Turn
|
||||
</div>
|
||||
)}
|
||||
{/* Timer progress bar */}
|
||||
<div
|
||||
style={{
|
||||
@@ -476,6 +506,11 @@ export default function ContestantView() {
|
||||
justifyContent: "space-between",
|
||||
alignItems: "baseline",
|
||||
fontSize: "1.8rem",
|
||||
padding: "0.5rem 1rem",
|
||||
borderRadius: "8px",
|
||||
background: (team.team_id || team.id) === currentTurnTeamId ? "#673AB7" : "transparent",
|
||||
color: (team.team_id || team.id) === currentTurnTeamId ? "white" : "inherit",
|
||||
transition: "all 0.3s ease",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
|
||||
@@ -54,3 +54,20 @@ button:focus,
|
||||
button:focus-visible {
|
||||
outline: 4px auto -webkit-focus-ring-color;
|
||||
}
|
||||
|
||||
/* Turn indicator pulse animation */
|
||||
@keyframes pulse {
|
||||
0% {
|
||||
box-shadow: 0 0 0 0 rgba(103, 58, 183, 0.4);
|
||||
}
|
||||
70% {
|
||||
box-shadow: 0 0 0 15px rgba(103, 58, 183, 0);
|
||||
}
|
||||
100% {
|
||||
box-shadow: 0 0 0 0 rgba(103, 58, 183, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.turn-indicator {
|
||||
animation: pulse 2s infinite;
|
||||
}
|
||||
|
||||
@@ -106,6 +106,7 @@ export const adminAPI = {
|
||||
api.post(`/admin/game/${gameId}/team/${teamId}/use-lifeline`),
|
||||
addLifeline: (gameId, teamId) =>
|
||||
api.post(`/admin/game/${gameId}/team/${teamId}/add-lifeline`),
|
||||
advanceTurn: (id) => api.post(`/admin/game/${id}/advance-turn`),
|
||||
};
|
||||
|
||||
// Categories API
|
||||
|
||||
Reference in New Issue
Block a user