More navigation bugs and fixed broken modal during transition

This commit is contained in:
Carlos-Mesquita
2024-11-26 15:46:20 +00:00
parent 1fc439cb25
commit efb153a33d
5 changed files with 75 additions and 31 deletions

View File

@@ -1,5 +1,5 @@
import { Dialog, Transition } from "@headlessui/react"; import { Dialog, Transition } from "@headlessui/react";
import { Fragment, useEffect, useState } from "react"; import { Fragment, useCallback, useEffect, useState } from "react";
import Button from "./Low/Button"; import Button from "./Low/Button";
interface Props { interface Props {
@@ -11,21 +11,55 @@ interface Props {
export default function QuestionsModal({ isOpen, onClose, type = "module", unanswered = false }: Props) { export default function QuestionsModal({ isOpen, onClose, type = "module", unanswered = false }: Props) {
const [isClosing, setIsClosing] = useState(false); const [isClosing, setIsClosing] = useState(false);
const [mounted, setMounted] = useState(false);
const blockMultipleClicksClose = (x: boolean) => { useEffect(() => {
if (!isClosing) { if (isOpen) {
setIsClosing(true); setMounted(true);
onClose(x);
} }
}, [isOpen]);
setTimeout(() => { useEffect(() => {
if (!isOpen && mounted) {
const timer = setTimeout(() => {
setMounted(false);
setIsClosing(false);
}, 300);
return () => clearTimeout(timer);
}
}, [isOpen, mounted]);
const blockMultipleClicksClose = useCallback((value: boolean) => {
if (isClosing) return;
setIsClosing(true);
onClose(value);
const timer = setTimeout(() => {
setIsClosing(false); setIsClosing(false);
}, 400); }, 300);
}
return () => clearTimeout(timer);
}, [isClosing, onClose]);
if (!mounted && !isOpen) return null;
return ( return (
<Transition show={isOpen} as={Fragment}> <Transition
<Dialog onClose={() => onClose(false)} className="relative z-50"> show={isOpen}
as={Fragment}
beforeEnter={() => setIsClosing(false)}
beforeLeave={() => setIsClosing(true)}
afterLeave={() => {
setIsClosing(false);
setMounted(false);
}}
>
<Dialog
onClose={() => blockMultipleClicksClose(false)}
className="relative z-50"
static
>
<Transition.Child <Transition.Child
as={Fragment} as={Fragment}
enter="ease-out duration-300" enter="ease-out duration-300"
@@ -33,7 +67,8 @@ export default function QuestionsModal({ isOpen, onClose, type = "module", unans
enterTo="opacity-100" enterTo="opacity-100"
leave="ease-in duration-200" leave="ease-in duration-200"
leaveFrom="opacity-100" leaveFrom="opacity-100"
leaveTo="opacity-0"> leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-black/30" /> <div className="fixed inset-0 bg-black/30" />
</Transition.Child> </Transition.Child>
@@ -44,7 +79,8 @@ export default function QuestionsModal({ isOpen, onClose, type = "module", unans
enterTo="opacity-100 scale-100" enterTo="opacity-100 scale-100"
leave="ease-in duration-200" leave="ease-in duration-200"
leaveFrom="opacity-100 scale-100" leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"> leaveTo="opacity-0 scale-95"
>
<div className="fixed inset-0 flex items-center justify-center p-4"> <div className="fixed inset-0 flex items-center justify-center p-4">
<Dialog.Panel className="w-full max-w-2xl h-fit p-8 rounded-xl bg-white flex flex-col gap-4"> <Dialog.Panel className="w-full max-w-2xl h-fit p-8 rounded-xl bg-white flex flex-col gap-4">
{type === "module" && ( {type === "module" && (
@@ -57,10 +93,21 @@ export default function QuestionsModal({ isOpen, onClose, type = "module", unans
Are you sure you want to continue without completing those questions? Are you sure you want to continue without completing those questions?
</span> </span>
<div className="w-full flex justify-between mt-8"> <div className="w-full flex justify-between mt-8">
<Button color="purple" onClick={() => blockMultipleClicksClose(false)} variant="outline" className="max-w-[200px] self-end w-full"> <Button
color="purple"
onClick={() => blockMultipleClicksClose(false)}
variant="outline"
className="max-w-[200px] self-end w-full"
disabled={isClosing}
>
Go Back Go Back
</Button> </Button>
<Button color="purple" onClick={() => blockMultipleClicksClose(true)} className="max-w-[200px] self-end w-full"> <Button
color="purple"
onClick={() => blockMultipleClicksClose(true)}
className="max-w-[200px] self-end w-full"
disabled={isClosing}
>
Continue Continue
</Button> </Button>
</div> </div>

View File

@@ -61,8 +61,8 @@ export default function Finish({ user, practiceScores, scores, modules, informat
const aiUsage = Math.round(ai_usage(solutions) * 100); const aiUsage = Math.round(ai_usage(solutions) * 100);
//const entity = useMemo(() => assignment?.entity || user.entities[0]?.id || "", [assignment?.entity, user.entities]) const entity = useMemo(() => assignment?.entity || user.entities[0]?.id || "", [assignment?.entity, user.entities])
//const { gradingSystem } = useGradingSystem(entity); const { gradingSystem } = useGradingSystem(entity);
const router = useRouter() const router = useRouter()
@@ -104,7 +104,7 @@ export default function Finish({ user, practiceScores, scores, modules, informat
const showLevel = (level: number) => { const showLevel = (level: number) => {
if (selectedModule === "level") { if (selectedModule === "level") {
const label = getGradingLabel(level, []); const label = getGradingLabel(level, gradingSystem?.steps || []);
return ( return (
<div className="flex flex-col items-center justify-center gap-1"> <div className="flex flex-col items-center justify-center gap-1">
<span className="text-xl font-bold">{label}</span> <span className="text-xl font-bold">{label}</span>
@@ -180,7 +180,7 @@ export default function Finish({ user, practiceScores, scores, modules, informat
<BsPen className="h-6 w-6" /> <BsPen className="h-6 w-6" />
<span className="font-semibold">Writing</span> <span className="font-semibold">Writing</span>
</div> </div>
{aiUsage >= 50 && user.type !== "student" && ( {aiUsage >= 50 && selectedModule === "writing" && user.type !== "student" && (
<div <div
className={clsx("flex items-center justify-center border px-3 h-full rounded", { className={clsx("flex items-center justify-center border px-3 h-full rounded", {
"bg-orange-100 border-orange-400 text-orange-700": aiUsage < 80, "bg-orange-100 border-orange-400 text-orange-700": aiUsage < 80,

View File

@@ -65,7 +65,6 @@ const Level: React.FC<ExamProps<LevelExam>> = ({ exam, showSolutions = false, pr
const [showQuestionsModal, setShowQuestionsModal] = useState(false); const [showQuestionsModal, setShowQuestionsModal] = useState(false);
const [continueAnyways, setContinueAnyways] = useState(false); const [continueAnyways, setContinueAnyways] = useState(false);
const [textRender, setTextRender] = useState(false); const [textRender, setTextRender] = useState(false);
const [changedPrompt, setChangedPrompt] = useState(false);
const [questionModalKwargs, setQuestionModalKwargs] = useState<{ const [questionModalKwargs, setQuestionModalKwargs] = useState<{
@@ -98,9 +97,9 @@ const Level: React.FC<ExamProps<LevelExam>> = ({ exam, showSolutions = false, pr
{ {
exam, module: "level", showBlankModal: showQuestionsModal, exam, module: "level", showBlankModal: showQuestionsModal,
setShowBlankModal: setShowQuestionsModal, showSolutions, setShowBlankModal: setShowQuestionsModal, showSolutions,
preview, disableBetweenParts: true, modalKwargs preview, disableBetweenParts: true, modalBetweenParts: true ,modalKwargs
}); }
);
const registerSolution = useCallback((updateSolution: () => UserSolution) => { const registerSolution = useCallback((updateSolution: () => UserSolution) => {
userSolutionRef.current = updateSolution; userSolutionRef.current = updateSolution;
@@ -299,7 +298,6 @@ const Level: React.FC<ExamProps<LevelExam>> = ({ exam, showSolutions = false, pr
currentExercise!.questions[questionIndex + i].prompt = updatedPrompt; currentExercise!.questions[questionIndex + i].prompt = updatedPrompt;
} }
}) })
setChangedPrompt(true);
} }
} }
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -366,14 +364,14 @@ const Level: React.FC<ExamProps<LevelExam>> = ({ exam, showSolutions = false, pr
onNext={() => { setShowPartDivider(false); setIsFirstTimeRender(false); setBgColor("bg-white"); setSeenParts(prev => new Set(prev).add(partIndex)); }} onNext={() => { setShowPartDivider(false); setIsFirstTimeRender(false); setBgColor("bg-white"); setSeenParts(prev => new Set(prev).add(partIndex)); }}
/> : ( /> : (
<> <>
<SectionNavbar {exam.parts.length > 1 && <SectionNavbar
module="level" module="level"
sectionLabel="Part" sectionLabel="Part"
seenParts={seenParts} seenParts={seenParts}
setShowPartDivider={setShowPartDivider} setShowPartDivider={setShowPartDivider}
setSeenParts={setSeenParts} setSeenParts={setSeenParts}
preview={preview} preview={preview}
/> />}
<ModuleTitle <ModuleTitle
examLabel={exam.label} examLabel={exam.label}
partLabel={partLabel()} partLabel={partLabel()}

View File

@@ -75,10 +75,10 @@ const useExamNavigation: UseExamNavigation = ({
// when navbar is used // when navbar is used
useEffect(()=> { useEffect(()=> {
if(startNow && partIndex !== 0) { if(startNow && !showPartDivider && partIndex !== 0) {
setStartNow(false); setStartNow(false);
} }
} , [partIndex, startNow]) } , [partIndex, startNow, showPartDivider])
useEffect(() => { useEffect(() => {
if (!showSolutions && hasDivider(exam, isPartExam ? partIndex : exerciseIndex) && !seenParts.has(partIndex)) { if (!showSolutions && hasDivider(exam, isPartExam ? partIndex : exerciseIndex) && !seenParts.has(partIndex)) {
@@ -161,8 +161,7 @@ const useExamNavigation: UseExamNavigation = ({
return; return;
} }
console.log(modalBetweenParts); if (modalBetweenParts && !seenParts.has(partIndex + 1) && !answeredEveryQuestion(exam as PartExam, userSolutions) && !keepGoing && setShowBlankModal && !showSolutions && !preview) {
if (modalBetweenParts && !answeredEveryQuestion(exam as PartExam, userSolutions) && !keepGoing && setShowBlankModal && !showSolutions && !preview) {
if (modalKwargs) modalKwargs(); if (modalKwargs) modalKwargs();
setShowBlankModal(true); setShowBlankModal(true);
return; return;
@@ -197,7 +196,7 @@ const useExamNavigation: UseExamNavigation = ({
const previousPartExam = () => { const previousPartExam = () => {
if (partIndex === 0 && exerciseIndex === 0 && !startNow) { if (!showPartDivider && partIndex === 0 && exerciseIndex === 0 && questionIndex === 0 && !startNow) {
setStartNow(true); setStartNow(true);
return; return;
} }

View File

@@ -146,7 +146,7 @@ export const rootReducer = (
questionIndex: 0, questionIndex: 0,
exerciseIndex: 0, exerciseIndex: 0,
partIndex: 0, partIndex: 0,
exam: state.exams[moduleIndex + 1], exam: state.exams[moduleIndex],
moduleIndex: moduleIndex moduleIndex: moduleIndex
} }
} else { } else {