mirror of
https://github.com/mudabbir-ahmad/peworkshop.git
synced 2026-10-07 19:50:20 +00:00
Grey = cant click Red = current Green = complete blue = skipped? Need to add Clue page Need to fix Leaderboard.
193 lines
6.3 KiB
JavaScript
193 lines
6.3 KiB
JavaScript
"use client";
|
|
import { useEffect, useState } from "react";
|
|
import { useRouter } from "next/navigation";
|
|
import { useSession } from "next-auth/react";
|
|
import styles from "./waiting.module.css";
|
|
import { setHuntTimer, clearHuntTimer } from "@/utils/timerService";
|
|
|
|
export default function WaitingPage() {
|
|
const router = useRouter();
|
|
const { status } = useSession();
|
|
const [huntActive, setHuntActive] = useState(false);
|
|
const [huntEnded, setHuntEnded] = useState(false);
|
|
const [loading, setLoading] = useState(true);
|
|
const [lastHuntData, setLastHuntData] = useState(null);
|
|
|
|
// Check hunt status VERY aggressively
|
|
useEffect(() => {
|
|
let redirectAttempted = false;
|
|
let lastKnownHuntStatus = false;
|
|
|
|
async function checkHuntStatus() {
|
|
if (redirectAttempted) return;
|
|
|
|
try {
|
|
// First check if we have a team ID from the session
|
|
const userResponse = await fetch("/api/user", {
|
|
method: "GET",
|
|
headers: {
|
|
"Cache-Control": "no-store, no-cache, must-revalidate",
|
|
Pragma: "no-cache",
|
|
},
|
|
credentials: "include",
|
|
});
|
|
|
|
if (userResponse.ok) {
|
|
const userData = await userResponse.json();
|
|
|
|
// If user has a team, check if that team has an active hunt session
|
|
if (userData.teamId) {
|
|
const teamHuntResponse = await fetch(
|
|
`/api/teams/${userData.teamId}/hunt-session`,
|
|
{
|
|
method: "GET",
|
|
headers: {
|
|
"Cache-Control": "no-store, no-cache, must-revalidate",
|
|
Pragma: "no-cache",
|
|
},
|
|
credentials: "include",
|
|
}
|
|
);
|
|
|
|
// If team has an active hunt session, redirect to map
|
|
if (teamHuntResponse.ok) {
|
|
const teamHuntData = await teamHuntResponse.json();
|
|
if (teamHuntData.startTime) {
|
|
// Store the start time in the centralized timer service
|
|
setHuntTimer(teamHuntData.startTime);
|
|
|
|
console.log("Team hunt is active! Redirecting to map...");
|
|
redirectAttempted = true;
|
|
lastKnownHuntStatus = true;
|
|
|
|
// Show loading screen and redirect
|
|
document.body.innerHTML =
|
|
'<div style="display:flex;justify-content:center;align-items:center;height:100vh;font-family:sans-serif;"><div style="text-align:center"><div style="font-size:24px">Loading Map...</div><div style="margin-top:20px">Please wait...</div></div></div>';
|
|
window.location.href = "/map";
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Fall back to checking the global hunt status
|
|
const timestamp = Date.now();
|
|
const globalResponse = await fetch(`/api/hunt-status?_t=${timestamp}`, {
|
|
method: "GET",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
"Cache-Control": "no-store, no-cache, must-revalidate",
|
|
Pragma: "no-cache",
|
|
},
|
|
});
|
|
|
|
if (globalResponse.ok) {
|
|
const data = await globalResponse.json();
|
|
console.log("Hunt status check result:", data);
|
|
|
|
// Store the most recent hunt data to determine if hunt ended
|
|
if (lastHuntData && lastHuntData.active && !data.active) {
|
|
// Hunt was active before but now it's not - it has ended
|
|
console.log("Hunt has ended! Showing leaderboard...");
|
|
setHuntEnded(true);
|
|
|
|
// Clear any timer data
|
|
clearHuntTimer();
|
|
|
|
// Redirect to leaderboard after a brief delay
|
|
setTimeout(() => {
|
|
window.location.href = "/leaderboard?huntEnded=true";
|
|
}, 2000);
|
|
|
|
return;
|
|
}
|
|
|
|
// Save the current hunt data for next comparison
|
|
setLastHuntData(data);
|
|
|
|
if (data.active) {
|
|
// Store the global start time in the centralized timer service
|
|
if (data.startTime) {
|
|
setHuntTimer(data.startTime, data.endTime);
|
|
}
|
|
|
|
console.log("Hunt is active! Redirecting immediately...");
|
|
redirectAttempted = true;
|
|
lastKnownHuntStatus = true;
|
|
|
|
// Show loading screen during redirect
|
|
document.body.innerHTML =
|
|
'<div style="display:flex;justify-content:center;align-items:center;height:100vh;font-family:sans-serif;"><div style="text-align:center"><div style="font-size:24px">Loading Map...</div><div style="margin-top:20px">Please wait...</div></div></div>';
|
|
window.location.href = "/map";
|
|
return;
|
|
}
|
|
|
|
setHuntActive(data.active);
|
|
}
|
|
|
|
setLoading(false);
|
|
} catch (err) {
|
|
console.error("Error checking hunt status:", err);
|
|
setLoading(false);
|
|
}
|
|
}
|
|
|
|
// Check immediately and very frequently
|
|
checkHuntStatus();
|
|
const intervalId = setInterval(checkHuntStatus, 500); // Check every 500ms
|
|
|
|
return () => clearInterval(intervalId);
|
|
}, []);
|
|
|
|
// Redirect to login if not authenticated
|
|
useEffect(() => {
|
|
if (status === "unauthenticated") {
|
|
router.push("/login");
|
|
}
|
|
}, [status, router]);
|
|
|
|
if (loading) {
|
|
return (
|
|
<div className={styles.container}>
|
|
<div className={styles.spinner}></div>
|
|
<h2>Loading...</h2>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className={styles.container}>
|
|
{huntEnded ? (
|
|
<>
|
|
<h1>Hunt Has Ended</h1>
|
|
<p>
|
|
The treasure hunt has ended. You can view the results on the
|
|
leaderboard.
|
|
</p>
|
|
<div className={styles.endedMessage}>
|
|
<p>Hunt Complete!</p>
|
|
<button onClick={() => router.push("/leaderboard?huntEnded=true")}>
|
|
View Results
|
|
</button>
|
|
</div>
|
|
</>
|
|
) : (
|
|
<>
|
|
<h1>Waiting for Hunt to Start</h1>
|
|
<p>
|
|
The treasure hunt has not started yet. Please wait for the
|
|
administrator to start the hunt.
|
|
</p>
|
|
<div className={styles.waitingAnimation}>⏳</div>
|
|
{huntActive && (
|
|
<div className={styles.startedMessage}>
|
|
<p>The hunt has started!</p>
|
|
<button onClick={() => router.push("/map")}>Go to Map</button>
|
|
</div>
|
|
)}
|
|
</>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|