mirror of
https://github.com/mudabbir-ahmad/peworkshop.git
synced 2026-10-07 19:50:20 +00:00
added more clue buttons and positioned them correctly, need to fix elapsed timer on clue page....
This commit is contained in:
1 parent
c325680d90
commit
ddcb6c845f
3 files changed
+114
-5
No files matched your search
@@ -34,13 +34,17 @@ export default function CluePage({ params }) {
|
|||||||
const [clueFound, setClueFound] = useState(false);
|
const [clueFound, setClueFound] = useState(false);
|
||||||
const [allClues, setAllClues] = useState([]);
|
const [allClues, setAllClues] = useState([]);
|
||||||
const [nextClueId, setNextClueId] = useState(null);
|
const [nextClueId, setNextClueId] = useState(null);
|
||||||
|
const [nextClueAvailable, setNextClueAvailable] = useState(false);
|
||||||
const [huntActive, setHuntActive] = useState(true);
|
const [huntActive, setHuntActive] = useState(true);
|
||||||
const [previousHuntState, setPreviousHuntState] = useState(true);
|
const [previousHuntState, setPreviousHuntState] = useState(true);
|
||||||
const [showSuccessNotification, setShowSuccessNotification] = useState(false);
|
const [showSuccessNotification, setShowSuccessNotification] = useState(false);
|
||||||
|
const [showNavErrorNotification, setShowNavErrorNotification] =
|
||||||
|
useState(false);
|
||||||
const [teamData, setTeamData] = useState(null);
|
const [teamData, setTeamData] = useState(null);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { data: session, status } = useSession();
|
const { data: session, status } = useSession();
|
||||||
const notificationTimeoutRef = useRef(null);
|
const notificationTimeoutRef = useRef(null);
|
||||||
|
const navErrorTimeoutRef = useRef(null);
|
||||||
|
|
||||||
// Check if user is admin
|
// Check if user is admin
|
||||||
const isAdmin = session?.user?.role === "admin";
|
const isAdmin = session?.user?.role === "admin";
|
||||||
@@ -78,7 +82,10 @@ export default function CluePage({ params }) {
|
|||||||
// Find next clue for navigation
|
// Find next clue for navigation
|
||||||
const currentIndex = data.findIndex((c) => c.id === parseInt(clueId));
|
const currentIndex = data.findIndex((c) => c.id === parseInt(clueId));
|
||||||
if (currentIndex !== -1 && currentIndex < data.length - 1) {
|
if (currentIndex !== -1 && currentIndex < data.length - 1) {
|
||||||
setNextClueId(data[currentIndex + 1].id);
|
const nextClue = data[currentIndex + 1];
|
||||||
|
setNextClueId(nextClue.id);
|
||||||
|
// Set if the next clue is available (already found or is the next unfound clue)
|
||||||
|
setNextClueAvailable(nextClue.found || nextClue.available);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
@@ -340,19 +347,38 @@ export default function CluePage({ params }) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Clear notification timeout on component unmount
|
// Clear notification timeouts on component unmount
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
if (notificationTimeoutRef.current) {
|
if (notificationTimeoutRef.current) {
|
||||||
clearTimeout(notificationTimeoutRef.current);
|
clearTimeout(notificationTimeoutRef.current);
|
||||||
}
|
}
|
||||||
|
if (navErrorTimeoutRef.current) {
|
||||||
|
clearTimeout(navErrorTimeoutRef.current);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// Navigate to the next clue
|
// Navigate to the next clue
|
||||||
const handleNextClue = () => {
|
const handleNextClue = () => {
|
||||||
if (nextClueId) {
|
if (nextClueId) {
|
||||||
|
// Check if next clue is available before navigating
|
||||||
|
if (nextClueAvailable || isAdmin) {
|
||||||
router.push(`/clue/${nextClueId}`);
|
router.push(`/clue/${nextClueId}`);
|
||||||
|
} else {
|
||||||
|
// Show notification that the next clue is locked
|
||||||
|
setShowNavErrorNotification(true);
|
||||||
|
|
||||||
|
// Clear previous timeout if it exists
|
||||||
|
if (navErrorTimeoutRef.current) {
|
||||||
|
clearTimeout(navErrorTimeoutRef.current);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auto-hide the notification after 3 seconds
|
||||||
|
navErrorTimeoutRef.current = setTimeout(() => {
|
||||||
|
setShowNavErrorNotification(false);
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
router.push("/map");
|
router.push("/map");
|
||||||
}
|
}
|
||||||
@@ -461,7 +487,31 @@ export default function CluePage({ params }) {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{showNavErrorNotification && (
|
||||||
|
<div className="nav-error-notification">
|
||||||
|
<div className="nav-error-notification-content">
|
||||||
|
<div className="nav-error-icon">🔒</div>
|
||||||
|
<div className="nav-error-text">
|
||||||
|
<h3>Clue Locked</h3>
|
||||||
|
<p>
|
||||||
|
You need to find this clue first before moving to the next one.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className="clue-content-wrapper">
|
<div className="clue-content-wrapper">
|
||||||
|
{/* Show a notification when the clue is already found */}
|
||||||
|
{clueFound && (
|
||||||
|
<div className="clue-found-notification">
|
||||||
|
<div className="clue-found-icon">✓</div>
|
||||||
|
<div className="clue-found-text">
|
||||||
|
You've already found this clue!
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Admin tools section - only visible to admins */}
|
{/* Admin tools section - only visible to admins */}
|
||||||
{isAdmin && (
|
{isAdmin && (
|
||||||
<div className="admin-tools">
|
<div className="admin-tools">
|
||||||
@@ -587,6 +637,66 @@ export default function CluePage({ params }) {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.nav-error-notification {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
padding: 20px;
|
||||||
|
background-color: rgba(0, 0, 0, 0.7);
|
||||||
|
z-index: 1000;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
animation: slide-down 0.5s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-error-notification-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background-color: #f44336;
|
||||||
|
color: white;
|
||||||
|
padding: 15px 25px;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
|
||||||
|
max-width: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-error-icon {
|
||||||
|
font-size: 2rem;
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-error-text h3 {
|
||||||
|
margin: 0 0 5px 0;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-error-text p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clue-found-notification {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background-color: #e8f5e9;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 12px 16px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
width: 100%;
|
||||||
|
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.clue-found-icon {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
color: #2e7d32;
|
||||||
|
margin-right: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clue-found-text {
|
||||||
|
color: #2e7d32;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes slide-down {
|
@keyframes slide-down {
|
||||||
0% {
|
0% {
|
||||||
transform: translateY(-100%);
|
transform: translateY(-100%);
|
||||||
|
|||||||
@@ -362,7 +362,6 @@ export default function MapPage() {
|
|||||||
className={styles["map-image"]}
|
className={styles["map-image"]}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Overlay div with the clue button - positioned exactly over the map */}
|
|
||||||
<div id="map-overlay-container" className={styles["map-overlay"]}>
|
<div id="map-overlay-container" className={styles["map-overlay"]}>
|
||||||
{/* Hardcoded Clue 1 button */}
|
{/* Hardcoded Clue 1 button */}
|
||||||
{firstClue && (
|
{firstClue && (
|
||||||
@@ -384,7 +383,6 @@ export default function MapPage() {
|
|||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Add Clue 2 button - positioned 50px more to the right and 30px more down than current position */}
|
|
||||||
{clues.length > 1 && (
|
{clues.length > 1 && (
|
||||||
<button
|
<button
|
||||||
className={getClueButtonClass(clues[1])}
|
className={getClueButtonClass(clues[1])}
|
||||||
@@ -404,7 +402,6 @@ export default function MapPage() {
|
|||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Add Clue 3 button - positioned 50px more to the right and 30px more down than current position */}
|
|
||||||
{clues.length > 1 && (
|
{clues.length > 1 && (
|
||||||
<button
|
<button
|
||||||
className={getClueButtonClass(clues[2])}
|
className={getClueButtonClass(clues[2])}
|
||||||
@@ -423,6 +420,8 @@ export default function MapPage() {
|
|||||||
Clue {clues[2].id}
|
Clue {clues[2].id}
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* clues should go above here */}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Binary file not shown.
Reference in new issue
Block a user