mirror of
https://github.com/mudabbir-ahmad/peworkshop.git
synced 2026-10-08 03:50:21 +00:00
fixing map timing errors and still trying to make leaderboard and clues pages.
Added two menus to the admin dashboard with a navbar at the bottom: Added navbar button for timer. Added navbar button to edit clues centrally. Added navbar button to view Admin version of leaderboard. To add: - the admin version of the leaderboard. has the same sort of initial view as the normal leaderboard however clicking on a team will create a drop down with their team stats. Grey = cant click Red = current Green = complete blue = skipped? Need to add Clue page Need to fix Leaderboard.
This commit is contained in:
1 parent
30d88407a0
commit
c098ad40bf
9 files changed
+1217
-29
No files matched your search
+28
-25
@@ -200,17 +200,20 @@ export default function MapPage() {
|
||||
|
||||
// Convert NodeList to Array for easier manipulation
|
||||
Array.from(circleSvgElements).forEach((circle, index) => {
|
||||
// Only process if we have a clue for this index
|
||||
if (clues[index]) {
|
||||
// Only process if we have a clue for this index and it's within bounds
|
||||
if (index < clues.length) {
|
||||
// Map SVG circle at position index to the clue at index
|
||||
// This uses sequential order rather than coordinates
|
||||
const clue = clues[index];
|
||||
|
||||
// Check if this clue is available (either found or next in sequence)
|
||||
const isAvailable =
|
||||
clues[index].found || index <= nextAvailableClueIndex;
|
||||
const isAvailable = clue.found || index <= nextAvailableClueIndex;
|
||||
|
||||
// Make circle interactive
|
||||
circle.style.cursor = isAvailable ? "pointer" : "not-allowed";
|
||||
|
||||
// Set appropriate colors
|
||||
if (clues[index].found) {
|
||||
if (clue.found) {
|
||||
// Found clues are green
|
||||
circle.style.fill = "#4caf50";
|
||||
circle.style.stroke = "#2e7d32";
|
||||
@@ -232,8 +235,8 @@ export default function MapPage() {
|
||||
e.stopPropagation();
|
||||
|
||||
if (isAvailable) {
|
||||
console.log(`Navigating to clue ${clues[index].id}`);
|
||||
router.push(`/clue/${clues[index].id}`);
|
||||
console.log(`Navigating to clue ${clue.id}`);
|
||||
router.push(`/clue/${clue.id}`);
|
||||
} else {
|
||||
alert("Complete previous clues first to unlock this one!");
|
||||
}
|
||||
@@ -247,7 +250,7 @@ export default function MapPage() {
|
||||
};
|
||||
|
||||
circle.onmouseleave = () => {
|
||||
if (clues[index].found) {
|
||||
if (clue.found) {
|
||||
circle.style.fill = "#4caf50"; // Back to green for found clues
|
||||
} else if (isAvailable) {
|
||||
circle.style.fill = "#ff9800"; // Back to orange for available clues
|
||||
@@ -256,13 +259,13 @@ export default function MapPage() {
|
||||
}
|
||||
};
|
||||
|
||||
// Add tooltip/title
|
||||
// Add tooltip/title with actual clue ID and position information
|
||||
const label = document.createElementNS(
|
||||
"http://www.w3.org/2000/svg",
|
||||
"title"
|
||||
);
|
||||
label.textContent = `Clue #${index + 1}: ${
|
||||
clues[index].title || "Mystery clue"
|
||||
clue.title || "Mystery clue"
|
||||
}${!isAvailable ? " (Locked)" : ""}`;
|
||||
circle.appendChild(label);
|
||||
}
|
||||
@@ -409,26 +412,26 @@ export default function MapPage() {
|
||||
try {
|
||||
// First try to get timer data from the centralized service
|
||||
let timerData = getHuntTimer();
|
||||
|
||||
|
||||
// If no timer data yet, fetch it from API
|
||||
if (!timerData || !timerData.startTime) {
|
||||
console.log("No timer data found, fetching from API...");
|
||||
const startTimeStr = await fetchTeamHuntStartTime();
|
||||
console.log("Got start time:", startTimeStr);
|
||||
|
||||
|
||||
if (startTimeStr) {
|
||||
setHuntTimer(startTimeStr);
|
||||
timerData = getHuntTimer();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Set up interval for timer updates
|
||||
const timerInterval = setInterval(() => {
|
||||
if (!isMounted.current) {
|
||||
clearInterval(timerInterval);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const currentTimerData = getHuntTimer();
|
||||
if (currentTimerData && currentTimerData.startTime) {
|
||||
const formattedTime = formatElapsedTime(currentTimerData.startTime);
|
||||
@@ -438,12 +441,12 @@ export default function MapPage() {
|
||||
setElapsedTime("00:00:00");
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
|
||||
// Initial timer update
|
||||
if (timerData && timerData.startTime) {
|
||||
setElapsedTime(formatElapsedTime(timerData.startTime));
|
||||
}
|
||||
|
||||
|
||||
return () => {
|
||||
clearInterval(timerInterval);
|
||||
};
|
||||
@@ -451,7 +454,7 @@ export default function MapPage() {
|
||||
console.error("Error initializing timer:", error);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
initializeTimer();
|
||||
}, []); // Empty dependency array since fetchTeamHuntStartTime is defined inside the component
|
||||
|
||||
@@ -459,7 +462,7 @@ export default function MapPage() {
|
||||
useEffect(() => {
|
||||
const checkHuntStatus = async () => {
|
||||
if (!isMounted.current) return;
|
||||
|
||||
|
||||
try {
|
||||
const timestamp = Date.now(); // Add cache-busting timestamp
|
||||
const response = await fetch(`/api/hunt-status?t=${timestamp}`, {
|
||||
@@ -471,15 +474,15 @@ export default function MapPage() {
|
||||
},
|
||||
credentials: "include",
|
||||
});
|
||||
|
||||
|
||||
if (!response.ok) {
|
||||
console.error("Failed to fetch hunt status:", response.statusText);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const data = await response.json();
|
||||
console.log("Map page hunt status check:", data);
|
||||
|
||||
|
||||
// If hunt is not active, force redirect to waiting page
|
||||
if (!data.active) {
|
||||
console.log("Hunt not active, redirecting to waiting page");
|
||||
@@ -488,7 +491,7 @@ export default function MapPage() {
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// If timer endTime exists and has passed, redirect to leaderboard
|
||||
if (data.endTime && new Date(data.endTime) <= new Date()) {
|
||||
console.log("Timer expired, redirecting to leaderboard");
|
||||
@@ -497,7 +500,7 @@ export default function MapPage() {
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Otherwise, hunt is active and timer is running
|
||||
if (isMounted.current) {
|
||||
setHuntActive(true);
|
||||
@@ -506,11 +509,11 @@ export default function MapPage() {
|
||||
console.error("Failed to check hunt status:", err);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Check immediately and every second
|
||||
checkHuntStatus();
|
||||
const intervalId = setInterval(checkHuntStatus, 1000);
|
||||
|
||||
|
||||
return () => clearInterval(intervalId);
|
||||
}, [softRedirect]);
|
||||
|
||||
|
||||
Reference in new issue
Block a user