"use client"; import { useState, useEffect } from "react"; import { useRouter } from "next/navigation"; import { useSession } from "next-auth/react"; import { formatElapsedTime, getHuntTimer } from "@/utils/timerService"; import Link from "next/link"; import dynamic from "next/dynamic"; // Dynamically import QR scanner component with no SSR to avoid hydration issues const QRScanner = dynamic(() => import("@/components/QRScanner"), { ssr: false, }); export default function CluePage({ params }) { const [clue, setClue] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [foundNow, setFoundNow] = useState(false); const [elapsedTime, setElapsedTime] = useState("00:00:00"); const [showScanner, setShowScanner] = useState(false); const [scanResult, setScanResult] = useState(null); const [scanMessage, setScanMessage] = useState(null); const router = useRouter(); const { status } = useSession(); const { clueId } = params; useEffect(() => { if (status === "unauthenticated") { router.push("/login"); return; } if (status === "loading") { return; } // Fetch clue data async function fetchClue() { try { setLoading(true); const response = await fetch(`/api/clues/${clueId}`, { method: "GET", headers: { "Content-Type": "application/json", "Cache-Control": "no-cache, no-store, must-revalidate", }, credentials: "include", }); if (!response.ok) { if (response.status === 404) { throw new Error("Clue not found"); } else { const data = await response.json(); throw new Error(data.error || "Failed to fetch clue"); } } const data = await response.json(); setClue(data); setFoundNow(data.foundNow); setLoading(false); } catch (err) { console.error("Error fetching clue:", err); setError(err.message); setLoading(false); } } fetchClue(); }, [clueId, router, status]); // Update timer display useEffect(() => { // Set up timer display updates const timerData = getHuntTimer(); if (!timerData || !timerData.isActive) { return; } const timer = setInterval(() => { setElapsedTime(formatElapsedTime(timerData.startTime)); }, 1000); // Initial set setElapsedTime(formatElapsedTime(timerData.startTime)); return () => clearInterval(timer); }, []); // Handle QR scan result const handleScan = (data) => { setScanResult(data); setScanMessage(`QR Code scanned: ${data}`); // Here you would typically verify the QR code matches expected value // and then mark the clue as found via API // For now, just simulate successful scan and move to the next clue try { const scannedClueId = parseInt(data); if (scannedClueId === parseInt(clueId)) { // Correct QR code scanned, mark as found and move to next clue markClueAsFound(clueId); } else { setScanMessage( "Incorrect QR code. Please scan the correct code for this clue." ); } } catch (err) { setScanMessage("Invalid QR code format. Please try again."); } }; // Function to mark clue as found and navigate to the next clue const markClueAsFound = async (currentClueId) => { try { // Mark the clue as found via API const response = await fetch("/api/mark-clue", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ clueId: currentClueId }), }); if (response.ok) { // Success message setScanMessage("Clue verified! Moving to the next clue..."); // Fetch all clues to find the next available one const allCluesResponse = await fetch("/api/clues"); const allClues = await allCluesResponse.json(); // Find the current clue index const currentIndex = allClues.findIndex( (c) => c.id === parseInt(currentClueId) ); if (currentIndex !== -1 && currentIndex < allClues.length - 1) { // Navigate to the next clue after a brief delay setTimeout(() => { router.push(`/clue/${allClues[currentIndex + 1].id}`); }, 1500); } else { // This was the last clue setTimeout(() => { router.push("/map"); }, 1500); } } else { setScanMessage("Error verifying clue. Please try again."); } } catch (err) { console.error("Error marking clue as found:", err); setScanMessage("Error verifying clue. Please try again."); } }; // Function to handle skip button const handleSkip = async () => { // Fetch all clues to find the next one try { const response = await fetch("/api/clues"); const allClues = await response.json(); // Find the current clue index const currentIndex = allClues.findIndex((c) => c.id === parseInt(clueId)); if (currentIndex !== -1 && currentIndex < allClues.length - 1) { // Navigate to the next clue router.push(`/clue/${allClues[currentIndex + 1].id}`); } else { // This was the last clue router.push("/map"); } } catch (err) { console.error("Error skipping to next clue:", err); setError("Failed to skip to next clue"); } }; if (loading) { return (

Loading clue...

); } if (error) { return (
Error: {error}
); } if (!clue) { return (
Clue not found
); } return (
{elapsedTime}
{/* QR Scanner Section */}

Scan QR Code

{scanMessage &&
{scanMessage}
}
{/* Clue Information Section */}
{foundNow && (
πŸŽ‰
New Clue Discovered!
)}

{clue.title}

Description

{clue.description}

{clue.location && (

Location Hint

{clue.location}

)}
{/* Action Buttons */}
{/* Bottom Navigation */}
πŸ—ΊοΈ
Map
πŸ“Š
Stats
πŸ‘₯
Team
🏠
Home
); }