From c698351127f940b1043ea3d208a0ff8374a9b6ed Mon Sep 17 00:00:00 2001 From: rgrgogu Date: Thu, 30 Jul 2026 21:29:05 +0800 Subject: [PATCH] added: missing quiz notice per unit inside Course --- src/modules/client/pages/UnitList.jsx | 37 +++++++++++++++++++++------ 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/src/modules/client/pages/UnitList.jsx b/src/modules/client/pages/UnitList.jsx index c887d66..6de4ea1 100644 --- a/src/modules/client/pages/UnitList.jsx +++ b/src/modules/client/pages/UnitList.jsx @@ -336,9 +336,13 @@ const UnitList = () => { const resetCompletion = () => setSelectedCompletion(false); - // ── No-assessment notice — shown once per course visit, informational only ── - // Gated behind the "Course notices" toggle in Account Settings. + // ── Course-readiness notices — shown once per course visit, informational only ── + // Gated behind the "Course notices" toggle in Account Settings. Sequenced so at + // most one is open at a time: missing-quiz notice (unit-level) takes priority, + // then no-assessment (course-level) once that one is dismissed. + const [missingQuizDialogOpen, setMissingQuizDialogOpen] = useState(false); const [noAssessmentDialogOpen, setNoAssessmentDialogOpen] = useState(false); + const missingQuizNoticeShown = useRef(false); const noAssessmentNoticeShown = useRef(false); useEffect(() => { @@ -346,18 +350,27 @@ const UnitList = () => { }, []); // eslint-disable-line react-hooks/exhaustive-deps useEffect(() => { + missingQuizNoticeShown.current = false; noAssessmentNoticeShown.current = false; }, [courseId]); useEffect(() => { - const shouldShow = + const noticesEnabled = course && !courseBlocked && course.duration_seconds && - !course.assessment && !noAssessmentNoticeShown.current && profile && (profile.personal_info?.show_course_notices ?? true); - if (!shouldShow) return; - noAssessmentNoticeShown.current = true; - setNoAssessmentDialogOpen(true); - }, [course, courseBlocked, profile]); + if (!noticesEnabled) return; + + if (!missingQuizNoticeShown.current && (course.units ?? []).some((u) => !u.quiz)) { + missingQuizNoticeShown.current = true; + setMissingQuizDialogOpen(true); + return; // let the assessment notice wait until this one is dismissed + } + if (missingQuizDialogOpen) return; + if (!noAssessmentNoticeShown.current && !course.assessment) { + noAssessmentNoticeShown.current = true; + setNoAssessmentDialogOpen(true); + } + }, [course, courseBlocked, profile, missingQuizDialogOpen]); // ── Session guard — block navigation while a quiz/assessment is in progress ─ const quizActiveRef = useRef(false); // sync check inside handlers @@ -847,6 +860,14 @@ const UnitList = () => { + {/* ── Missing-quiz notice — informational, shown once per course visit ── */} + + {/* ── No-assessment notice — informational, shown once per course visit ── */}