"use client"; import { useState, useEffect, useRef } from "react"; import { useSession } from "next-auth/react"; import { useRouter } from "next/navigation"; import { setHuntTimer, clearHuntTimer, formatElapsedTime, } from "@/utils/timerService"; export default function AdminDashboard() { const { data: session, status } = useSession(); const [timerActive, setTimerActive] = useState(false); const [loading, setLoading] = useState(true); const [error, setError] = useState(""); const [elapsedTime, setElapsedTime] = useState(0); // in seconds const [timerDisplay, setTimerDisplay] = useState("--:--:--"); const [presetHours, setPresetHours] = useState(""); const [presetMinutes, setPresetMinutes] = useState(""); const [presetSeconds, setPresetSeconds] = useState(""); const [timerEndTime, setTimerEndTime] = useState(null); const timerRef = useRef(null); const router = useRouter(); // Load timer status on page load useEffect(() => { async function loadTimerStatus() { try { const response = await fetch("/api/hunt/timer", { credentials: "include", headers: { "Cache-Control": "no-cache", }, }); const data = await response.json(); if (data.active) { setTimerActive(true); // Calculate elapsed time if (data.startTime) { const startTime = new Date(data.startTime).getTime(); const currentTime = Date.now(); const elapsed = Math.floor((currentTime - startTime) / 1000); setElapsedTime(elapsed); // Update global timer data for all clients setHuntTimer(data.startTime, data.endTime); } // If there's an end time, set it if (data.endTime) { setTimerEndTime(new Date(data.endTime).getTime()); } } setLoading(false); } catch (err) { console.error("Failed to load timer status:", err); setError("Failed to load timer status"); setLoading(false); } } if (status === "authenticated") { loadTimerStatus(); } }, [status]); // Check if user is admin useEffect(() => { if (status === "authenticated") { if (session?.user?.role !== "admin") { router.push("/team-selection"); } } else if (status === "unauthenticated") { router.push("/login"); } }, [session, status, router]); // Timer update effect useEffect(() => { if (timerActive) { timerRef.current = setInterval(() => { setElapsedTime((prev) => { const newElapsed = prev + 1; // If we have an end time and we've reached it, stop the timer if (timerEndTime && Date.now() >= timerEndTime) { stopTimer(); return prev; } // Update the display formatTimeDisplay(newElapsed); return newElapsed; }); }, 1000); } else { if (timerRef.current) { clearInterval(timerRef.current); } } return () => { if (timerRef.current) { clearInterval(timerRef.current); } }; }, [timerActive, timerEndTime]); // Format time for display whenever elapsed time changes useEffect(() => { formatTimeDisplay(elapsedTime); }, [elapsedTime]); // Format seconds into HH:MM:SS const formatTimeDisplay = (totalSeconds) => { if (!timerActive) { setTimerDisplay("--:--:--"); return; } const hours = Math.floor(totalSeconds / 3600); const minutes = Math.floor((totalSeconds % 3600) / 60); const seconds = totalSeconds % 60; const display = [ hours.toString().padStart(2, "0"), minutes.toString().padStart(2, "0"), seconds.toString().padStart(2, "0"), ].join(":"); setTimerDisplay(display); }; const startTimer = async (preset = false) => { setLoading(true); try { let endTime = null; // If using preset, calculate the end time if (preset) { const hours = parseInt(presetHours || "0"); const minutes = parseInt(presetMinutes || "0"); const seconds = parseInt(presetSeconds || "0"); // Validate input if (isNaN(hours) || isNaN(minutes) || isNaN(seconds)) { setError( "Please enter valid numbers for hours, minutes, and seconds" ); setLoading(false); return; } // Calculate total duration in milliseconds const durationMs = (hours * 3600 + minutes * 60 + seconds) * 1000; if (durationMs <= 0) { setError("Please enter a duration greater than zero"); setLoading(false); return; } // Set end time endTime = new Date(Date.now() + durationMs).toISOString(); } // API call to start timer const response = await fetch("/api/hunt/timer", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ action: "start", endTime: endTime, }), }); const data = await response.json(); if (data.success) { setTimerActive(true); setElapsedTime(0); if (endTime) { setTimerEndTime(new Date(endTime).getTime()); } else { setTimerEndTime(null); } // Update global timer data for all clients setHuntTimer(data.startTime, data.endTime); setError(""); } else { setError(data.error || "Failed to start timer"); } } catch (err) { console.error("Failed to start timer:", err); setError("Failed to start timer"); } finally { setLoading(false); } }; const stopTimer = async () => { setLoading(true); try { const response = await fetch("/api/hunt/timer", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ action: "stop" }), }); const data = await response.json(); if (data.success) { setTimerActive(false); setTimerEndTime(null); setElapsedTime(0); formatTimeDisplay(0); // Clear timer data for all clients clearHuntTimer(); } else { setError(data.error || "Failed to stop timer"); } } catch (err) { console.error("Failed to stop timer:", err); setError("Failed to stop timer"); } finally { setLoading(false); } }; const startPresetTimer = () => { startTimer(true); }; // Handle access denied and loading states if (status === "loading" || loading) { return
{error}
}