generated from muhtadeetaron/nextjs-template
feat(nav): add flow-guarding for exam result screens
This commit is contained in:
42
hooks/useExamExitGuard.ts
Normal file
42
hooks/useExamExitGuard.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import { useRouter, usePathname } from "next/navigation";
|
||||
import { useEffect } from "react";
|
||||
import { useExamStore } from "@/stores/examStore";
|
||||
import { useTimerStore } from "@/stores/timerStore";
|
||||
|
||||
export function useExamExitGuard(type: string) {
|
||||
const { status, setStatus, cancelExam } = useExamStore();
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
const { stopTimer } = useTimerStore();
|
||||
|
||||
// Guard page render: always redirect if status invalid
|
||||
useEffect(() => {
|
||||
if (status !== "in-progress") {
|
||||
router.replace(`/categories/${type}s`);
|
||||
}
|
||||
}, [status, router, type]);
|
||||
|
||||
// Confirm before leaving page / tab close
|
||||
useEffect(() => {
|
||||
const handleBeforeUnload = (e: BeforeUnloadEvent) => {
|
||||
if (status === "in-progress") {
|
||||
e.preventDefault();
|
||||
e.returnValue = ""; // shows native browser dialog
|
||||
}
|
||||
};
|
||||
window.addEventListener("beforeunload", handleBeforeUnload);
|
||||
return () => window.removeEventListener("beforeunload", handleBeforeUnload);
|
||||
}, [status]);
|
||||
|
||||
// Call this to quit exam manually
|
||||
const showExitDialog = () => {
|
||||
if (window.confirm("Are you sure you want to quit the exam?")) {
|
||||
setStatus("finished");
|
||||
stopTimer();
|
||||
cancelExam();
|
||||
router.replace(`/categories/${type}s`);
|
||||
}
|
||||
};
|
||||
|
||||
return { showExitDialog };
|
||||
}
|
||||
Reference in New Issue
Block a user