"use client"; import { useState, useEffect } from "react"; import { useRouter } from "next/navigation"; import Link from "next/link"; export default function MapPage() { const [clues, setClues] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [huntActive, setHuntActive] = useState(false); const router = useRouter(); useEffect(() => { async function checkHuntStatus() { try { const response = await fetch("/api/hunt-status", { credentials: "include", }); if (response.ok) { const data = await response.json(); setHuntActive(data.active || false); // If hunt is not active, redirect to the home page if (!data.active) { router.push("/"); return false; } return true; } else { console.error("Failed to check hunt status"); return false; } } catch (err) { console.error("Error checking hunt status:", err); return false; } } async function fetchClues() { try { // First verify the hunt is active const huntIsActive = await checkHuntStatus(); if (!huntIsActive) return; // Fetch the clues from the API with proper error handling const response = await fetch("/api/clues", { credentials: "include", }); // Handle non-OK responses without throwing if (!response.ok) { const contentType = response.headers.get("content-type"); if (contentType && contentType.includes("application/json")) { // If it's JSON, parse it for the error message const errorData = await response.json(); throw new Error(errorData.error || "Failed to fetch clues"); } else { // If it's not JSON, use the status text throw new Error( `Failed to fetch clues: ${response.status} ${response.statusText}` ); } } // Parse the JSON response const data = await response.json(); // If we got back an error field, show it as an error if (data.error) { throw new Error(data.error); } setClues(data.clues || []); } catch (err) { console.error("Error fetching clues:", err); setError(err.message); } finally { setLoading(false); } } fetchClues(); }, [router]); // Generate random x positions and sort by descending y positions const generatePositions = (clues) => { const positions = []; const maxWidth = 800; const maxHeight = 500; const padding = 50; for (let i = 0; i < clues.length; i++) { positions.push({ id: clues[i].id, title: clues[i].title || `Clue ${i + 1}`, x: Math.random() * (maxWidth - 2 * padding) + padding, y: (i + 1) * (maxHeight / (clues.length + 1)), }); } return positions; }; const cluePositions = clues.length > 0 ? generatePositions(clues) : []; if (loading) { return (