mirror of
https://github.com/mudabbir-ahmad/peworkshop.git
synced 2026-10-07 19:50:20 +00:00
map WIP
This commit is contained in:
1 parent
d675b228c6
commit
c5f2c0a98a
4 files changed
+189
-230
No files matched your search
+9
-51
@@ -10,7 +10,11 @@ import {
|
||||
clearHuntTimer,
|
||||
formatElapsedTime,
|
||||
} from "@/utils/timerService";
|
||||
import { populateMap, updateCluePointStatus } from "@/utils/map-populate";
|
||||
import {
|
||||
populateMap,
|
||||
updateCluePointStatus,
|
||||
attachClueClickHandlers,
|
||||
} from "@/utils/map-populate";
|
||||
|
||||
export default function MapPage() {
|
||||
const { data: session, status } = useSession();
|
||||
@@ -188,59 +192,13 @@ export default function MapPage() {
|
||||
.then((success) => {
|
||||
if (success) {
|
||||
console.log("Map populated successfully");
|
||||
|
||||
// After populating the map, update the status of each clue point
|
||||
updateCluePointStatus(svgElement, clues);
|
||||
|
||||
// Add click handlers to each clue point
|
||||
const cluePoints = svgElement.querySelectorAll(".clue-point");
|
||||
cluePoints.forEach((circle, index) => {
|
||||
if (index < clues.length) {
|
||||
const clue = clues[index];
|
||||
const isAvailable = clue.available;
|
||||
|
||||
// Make circle interactive
|
||||
circle.style.cursor = isAvailable ? "pointer" : "not-allowed";
|
||||
|
||||
// Add click handler
|
||||
circle.onclick = (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
if (isAvailable) {
|
||||
console.log(`Navigating to clue ${clue.id}`);
|
||||
router.push(`/clue/${clue.id}`);
|
||||
} else {
|
||||
alert("Complete previous clues first to unlock this one!");
|
||||
}
|
||||
};
|
||||
|
||||
// Add hover effects
|
||||
circle.onmouseenter = () => {
|
||||
if (isAvailable) {
|
||||
circle.style.fill = "#ffb74d"; // Lighter orange for hover
|
||||
}
|
||||
};
|
||||
|
||||
circle.onmouseleave = () => {
|
||||
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
|
||||
} else {
|
||||
circle.style.fill = "#9e9e9e"; // Back to grey for unavailable clues
|
||||
}
|
||||
};
|
||||
|
||||
// Add tooltip with clue information
|
||||
const label = document.createElementNS(
|
||||
"http://www.w3.org/2000/svg",
|
||||
"title"
|
||||
);
|
||||
label.textContent = `Clue #${index + 1}: ${
|
||||
clue.title || "Mystery clue"
|
||||
}${!isAvailable ? " (Locked)" : ""}`;
|
||||
circle.appendChild(label);
|
||||
}
|
||||
// Attach click handlers for navigation
|
||||
attachClueClickHandlers(svgElement, clues, (clueId) => {
|
||||
router.push(`/clue/${clueId}`);
|
||||
});
|
||||
} else {
|
||||
console.error("Failed to populate map");
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import { queryOne } from "@/lib/db";
|
||||
import { getToken } from "next-auth/jwt";
|
||||
|
||||
export const dynamic = "force-dynamic"; // No caching
|
||||
|
||||
export async function GET(request) {
|
||||
try {
|
||||
// Verify token
|
||||
const token = await getToken({
|
||||
req: request,
|
||||
secret:
|
||||
process.env.NEXTAUTH_SECRET ||
|
||||
"your-fallback-secret-should-be-at-least-32-chars",
|
||||
});
|
||||
|
||||
if (!token) {
|
||||
return Response.json({ error: "Unauthorized access" }, { status: 401 });
|
||||
}
|
||||
|
||||
// Get the total count of clues
|
||||
const result = await queryOne("SELECT COUNT(*) as count FROM clues");
|
||||
|
||||
if (!result) {
|
||||
return Response.json({ error: "Failed to count clues" }, { status: 500 });
|
||||
}
|
||||
|
||||
return Response.json(
|
||||
{ count: result.count },
|
||||
{
|
||||
headers: {
|
||||
"Cache-Control": "no-store, no-cache, must-revalidate",
|
||||
Pragma: "no-cache",
|
||||
},
|
||||
}
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("Error counting clues:", error);
|
||||
return Response.json({ error: "Server error" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user