mirror of
https://github.com/mudabbir-ahmad/peworkshop.git
synced 2026-10-07 19:50:20 +00:00
163 lines
4.2 KiB
JavaScript
163 lines
4.2 KiB
JavaScript
"use client";
|
|
import { useState, useEffect, useRef } from "react";
|
|
import { useSession } from "next-auth/react";
|
|
import { useRouter } from "next/navigation";
|
|
import Link from "next/link";
|
|
import Image from "next/image";
|
|
import styles from "./map.module.css";
|
|
import NavBar from "@/components/NavBar";
|
|
|
|
export default function MapPage() {
|
|
const { data: session, status } = useSession();
|
|
const [teamData, setTeamData] = useState(null);
|
|
const [loading, setLoading] = useState(true);
|
|
const [error, setError] = useState(null);
|
|
const [mapLoaded, setMapLoaded] = useState(false);
|
|
const [huntActive, setHuntActive] = useState(null);
|
|
const router = useRouter();
|
|
const mapRef = useRef(null);
|
|
|
|
useEffect(() => {
|
|
// Redirect to login if not authenticated
|
|
if (status === "unauthenticated") {
|
|
router.push("/login");
|
|
return;
|
|
}
|
|
|
|
if (status === "authenticated") {
|
|
checkHuntStatus();
|
|
fetchTeamData();
|
|
}
|
|
}, [status, router]);
|
|
|
|
const checkHuntStatus = async () => {
|
|
try {
|
|
const timestamp = Date.now();
|
|
const response = await fetch(`/api/hunt-status?t=${timestamp}`, {
|
|
method: "GET",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
"Cache-Control": "no-store, no-cache, must-revalidate",
|
|
Pragma: "no-cache",
|
|
},
|
|
credentials: "include",
|
|
});
|
|
|
|
if (response.ok) {
|
|
const data = await response.json();
|
|
setHuntActive(data.active);
|
|
|
|
// Redirect to waiting page if hunt is not active
|
|
if (!data.active) {
|
|
router.push("/waiting");
|
|
return;
|
|
}
|
|
} else {
|
|
throw new Error("Failed to check hunt status");
|
|
}
|
|
} catch (err) {
|
|
console.error("Failed to check hunt status:", err);
|
|
setError("Failed to check if hunt is active. Please try again.");
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
const fetchTeamData = async () => {
|
|
try {
|
|
const response = await fetch("/api/user/team", {
|
|
method: "GET",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
"Cache-Control": "no-cache, no-store, must-revalidate",
|
|
Pragma: "no-cache",
|
|
},
|
|
credentials: "include",
|
|
});
|
|
|
|
if (response.status === 401) {
|
|
router.push("/login");
|
|
return null;
|
|
}
|
|
|
|
if (response.status === 404) {
|
|
router.push("/team-selection");
|
|
return null;
|
|
}
|
|
|
|
if (!response.ok) {
|
|
throw new Error("Failed to fetch team data");
|
|
}
|
|
|
|
const data = await response.json();
|
|
console.log("Team data loaded:", data);
|
|
setTeamData(data);
|
|
return data;
|
|
} catch (err) {
|
|
console.error("Failed to fetch team data:", err);
|
|
setError(err.message);
|
|
return null;
|
|
}
|
|
};
|
|
|
|
const handleMapLoad = () => {
|
|
setMapLoaded(true);
|
|
};
|
|
|
|
const handleMapError = () => {
|
|
setError("Failed to load the map. Please try again.");
|
|
};
|
|
|
|
if (loading) {
|
|
return (
|
|
<div className={styles["loading-container"]}>
|
|
<div className={styles["loading-spinner"]}></div>
|
|
<div>Loading map...</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (error) {
|
|
return (
|
|
<div className={styles["map-error"]}>
|
|
<h2>Error</h2>
|
|
<p>{error}</p>
|
|
<button onClick={fetchTeamData}>Retry</button>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className={styles.mapPage}>
|
|
<div className={styles.mapHeader}>
|
|
<div className={styles.teamInfo}>
|
|
<h1 className={styles.teamName}>
|
|
{teamData?.team ? teamData.team.name : "Loading..."}
|
|
</h1>
|
|
<div className={styles.teamProgress}>
|
|
{teamData?.progress !== undefined
|
|
? `${teamData.progress}% Complete`
|
|
: "..."}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className={styles.mapContainer}>
|
|
<div className={styles.treasureMap}>
|
|
<Image
|
|
src="/images/map.svg"
|
|
alt="Treasure Map"
|
|
layout="fill"
|
|
objectFit="contain"
|
|
onLoad={handleMapLoad}
|
|
onError={handleMapError}
|
|
ref={mapRef}
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Replace hardcoded navbar with NavBar component */}
|
|
<NavBar activeLink="map" teamData={teamData?.team} />
|
|
</div>
|
|
);
|
|
}
|