@schoolio/player 1.4.5 → 1.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1283,7 +1283,9 @@ var defaultStyles = {
1283
1283
  option: {
1284
1284
  width: "100%",
1285
1285
  padding: "12px 16px",
1286
- border: "2px solid #e5e7eb",
1286
+ borderWidth: "2px",
1287
+ borderStyle: "solid",
1288
+ borderColor: "#e5e7eb",
1287
1289
  borderRadius: "8px",
1288
1290
  cursor: "pointer",
1289
1291
  transition: "all 0.2s ease",
@@ -1706,7 +1708,9 @@ function MatchingDragDrop({ leftItems, rightItems, currentMatches, correctMatche
1706
1708
  alignItems: "center",
1707
1709
  gap: "12px",
1708
1710
  padding: "12px 16px",
1709
- border: "2px dashed #e5e7eb",
1711
+ borderWidth: "2px",
1712
+ borderStyle: "dashed",
1713
+ borderColor: "#e5e7eb",
1710
1714
  borderRadius: "8px",
1711
1715
  backgroundColor: "#ffffff",
1712
1716
  minHeight: "56px",
@@ -1789,7 +1793,9 @@ function MatchingDragDrop({ leftItems, rightItems, currentMatches, correctMatche
1789
1793
  {
1790
1794
  style: {
1791
1795
  padding: "12px 16px",
1792
- border: "2px solid #e5e7eb",
1796
+ borderWidth: "2px",
1797
+ borderStyle: "solid",
1798
+ borderColor: "#e5e7eb",
1793
1799
  borderRadius: "8px",
1794
1800
  backgroundColor: "#ffffff",
1795
1801
  cursor: showFeedback ? "default" : "grab",
@@ -1890,6 +1896,7 @@ function QuizPlayer({
1890
1896
  const [showReportModal, setShowReportModal] = useState3(false);
1891
1897
  const [isReporting, setIsReporting] = useState3(false);
1892
1898
  const [reportComment, setReportComment] = useState3("");
1899
+ const [retryKey, setRetryKey] = useState3(0);
1893
1900
  const apiClient = useRef3(null);
1894
1901
  const timerRef = useRef3(null);
1895
1902
  const startTimeRef = useRef3(0);
@@ -1964,7 +1971,7 @@ function QuizPlayer({
1964
1971
  }
1965
1972
  }
1966
1973
  initialize();
1967
- }, [quizId, lessonId, assignLessonId, courseId, childId, parentId, forceNewAttempt]);
1974
+ }, [quizId, lessonId, assignLessonId, courseId, childId, parentId, forceNewAttempt, retryKey]);
1968
1975
  useEffect3(() => {
1969
1976
  if (timerStarted && !isCompleted && !errorCode) {
1970
1977
  startTimeRef.current = Date.now();
@@ -2238,6 +2245,38 @@ function QuizPlayer({
2238
2245
  setIsReporting(false);
2239
2246
  }
2240
2247
  }, [currentQuestion, apiClient, attempt, quiz, childId, parentId, lessonId, courseId, assignLessonId]);
2248
+ const handleRetryQuiz = useCallback2(() => {
2249
+ setCurrentQuestionIndex(0);
2250
+ setAnswers(/* @__PURE__ */ new Map());
2251
+ setAnswersDetail([]);
2252
+ setIsCompleted(false);
2253
+ setResult(null);
2254
+ setErrorCode(null);
2255
+ setShowIntro(true);
2256
+ setShowFeedback(false);
2257
+ setCurrentAnswerDetail(null);
2258
+ setTimerStarted(false);
2259
+ setElapsedSeconds(0);
2260
+ startTimeRef.current = 0;
2261
+ setExtraQuestions([]);
2262
+ setSkippedQuestionIds(/* @__PURE__ */ new Set());
2263
+ setAttempt(null);
2264
+ setShowResumeChoice(false);
2265
+ setHasExistingProgress(false);
2266
+ setExistingProgressCount(0);
2267
+ setIsSubmitting(false);
2268
+ setIsNavigating(false);
2269
+ setIsGeneratingExtra(false);
2270
+ setIsStartingFresh(false);
2271
+ setShowSkipModal(false);
2272
+ setIsSkipping(false);
2273
+ setSkipComment("");
2274
+ setSelectedSkipReason(null);
2275
+ setShowReportModal(false);
2276
+ setIsReporting(false);
2277
+ setReportComment("");
2278
+ setRetryKey((prev) => prev + 1);
2279
+ }, []);
2241
2280
  if (isLoading) {
2242
2281
  return /* @__PURE__ */ jsx4("div", { className, style: defaultStyles.container, children: /* @__PURE__ */ jsx4("div", { style: defaultStyles.loading, children: "Loading quiz..." }) });
2243
2282
  }
@@ -2401,6 +2440,16 @@ function QuizPlayer({
2401
2440
  opacity: 1;
2402
2441
  }
2403
2442
  }
2443
+ @keyframes buttonFadeIn {
2444
+ 0% {
2445
+ opacity: 0;
2446
+ transform: translateY(10px);
2447
+ }
2448
+ 100% {
2449
+ opacity: 1;
2450
+ transform: translateY(0);
2451
+ }
2452
+ }
2404
2453
  ` }),
2405
2454
  /* @__PURE__ */ jsxs4("div", { style: defaultStyles.results, children: [
2406
2455
  percentage >= 60 && /* @__PURE__ */ jsx4("div", { style: defaultStyles.confettiContainer, children: confettiPieces.map((piece) => /* @__PURE__ */ jsx4(
@@ -2553,7 +2602,39 @@ function QuizPlayer({
2553
2602
  /* @__PURE__ */ jsxs4("div", { style: { ...defaultStyles.resultDetails, marginTop: "8px" }, children: [
2554
2603
  "Time: ",
2555
2604
  formatTime(result.timeSpentSeconds)
2556
- ] })
2605
+ ] }),
2606
+ /* @__PURE__ */ jsx4(
2607
+ "button",
2608
+ {
2609
+ style: {
2610
+ marginTop: "24px",
2611
+ padding: "14px 32px",
2612
+ fontSize: "16px",
2613
+ fontWeight: "600",
2614
+ color: "#7c3aed",
2615
+ background: "white",
2616
+ border: "2px solid #7c3aed",
2617
+ borderRadius: "12px",
2618
+ cursor: "pointer",
2619
+ transition: "all 0.2s ease",
2620
+ animation: "buttonFadeIn 0.5s ease-out 0.8s forwards",
2621
+ opacity: 0
2622
+ },
2623
+ onClick: handleRetryQuiz,
2624
+ onMouseOver: (e) => {
2625
+ e.currentTarget.style.background = "#7c3aed";
2626
+ e.currentTarget.style.color = "white";
2627
+ e.currentTarget.style.transform = "translateY(-2px)";
2628
+ },
2629
+ onMouseOut: (e) => {
2630
+ e.currentTarget.style.background = "white";
2631
+ e.currentTarget.style.color = "#7c3aed";
2632
+ e.currentTarget.style.transform = "translateY(0)";
2633
+ },
2634
+ "data-testid": "button-retry-quiz",
2635
+ children: "Try Again"
2636
+ }
2637
+ )
2557
2638
  ] }) })
2558
2639
  ] })
2559
2640
  ] });
@@ -2655,294 +2736,132 @@ function QuizPlayer({
2655
2736
  const remainingSlots = maxQuestions - totalQuestions;
2656
2737
  const questionsToAdd = Math.min(5, remainingSlots);
2657
2738
  const canAddMore = onGenerateMoreQuestions && remainingSlots > 0;
2658
- return /* @__PURE__ */ jsx4("div", { className, style: defaultStyles.container, children: /* @__PURE__ */ jsxs4("div", { style: defaultStyles.mainLayout, children: [
2659
- /* @__PURE__ */ jsxs4("div", { style: defaultStyles.quizContent, children: [
2660
- /* @__PURE__ */ jsxs4("div", { style: defaultStyles.header, children: [
2661
- /* @__PURE__ */ jsx4("div", { style: defaultStyles.title, children: quiz.title }),
2662
- /* @__PURE__ */ jsxs4("div", { style: defaultStyles.progress, children: [
2663
- "Question ",
2664
- currentQuestionIndex + 1,
2665
- " of ",
2666
- totalQuestions
2667
- ] }),
2668
- /* @__PURE__ */ jsx4("div", { style: defaultStyles.progressBar, children: /* @__PURE__ */ jsx4("div", { style: { ...defaultStyles.progressFill, width: `${progressPercent}%` } }) })
2669
- ] }),
2670
- /* @__PURE__ */ jsxs4("div", { style: { ...defaultStyles.question, position: "relative", paddingBottom: "40px" }, children: [
2671
- /* @__PURE__ */ jsx4("div", { style: defaultStyles.questionText, children: /* @__PURE__ */ jsx4(TextToSpeech, { text: currentQuestion.question, inline: true, size: "md" }) }),
2672
- isExtraQuestion && /* @__PURE__ */ jsxs4(
2673
- "button",
2674
- {
2675
- onClick: () => setShowSkipModal(true),
2676
- title: "Skip question",
2677
- style: {
2678
- position: "absolute",
2679
- bottom: "8px",
2680
- left: "0",
2681
- background: "transparent",
2682
- border: "none",
2683
- cursor: "pointer",
2684
- padding: "6px 10px",
2685
- borderRadius: "6px",
2686
- color: "#9ca3af",
2687
- display: "flex",
2688
- alignItems: "center",
2689
- justifyContent: "center",
2690
- gap: "4px",
2691
- fontSize: "12px",
2692
- opacity: 0.6,
2693
- transition: "opacity 0.2s, color 0.2s"
2694
- },
2695
- onMouseEnter: (e) => {
2696
- e.currentTarget.style.opacity = "1";
2697
- e.currentTarget.style.color = "#6b7280";
2698
- },
2699
- onMouseLeave: (e) => {
2700
- e.currentTarget.style.opacity = "0.6";
2701
- e.currentTarget.style.color = "#9ca3af";
2702
- },
2703
- "data-testid": "button-skip-question",
2704
- children: [
2705
- /* @__PURE__ */ jsxs4("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2706
- /* @__PURE__ */ jsx4("polygon", { points: "5 4 15 12 5 20 5 4" }),
2707
- /* @__PURE__ */ jsx4("line", { x1: "19", y1: "5", x2: "19", y2: "19" })
2708
- ] }),
2709
- /* @__PURE__ */ jsx4("span", { children: "Skip" })
2710
- ]
2739
+ return /* @__PURE__ */ jsxs4("div", { className, style: defaultStyles.container, children: [
2740
+ /* @__PURE__ */ jsx4("style", { children: `
2741
+ .quiz-option:focus,
2742
+ .quiz-option:active,
2743
+ .quiz-option:focus-visible,
2744
+ .quiz-option:focus-within {
2745
+ outline: none !important;
2746
+ box-shadow: none !important;
2711
2747
  }
2712
- ),
2713
- !isExtraQuestion && /* @__PURE__ */ jsxs4(
2714
- "button",
2715
- {
2716
- onClick: () => setShowReportModal(true),
2717
- title: "Report an issue with this question",
2718
- style: {
2719
- position: "absolute",
2720
- bottom: "8px",
2721
- left: "0",
2722
- background: "transparent",
2723
- border: "none",
2724
- cursor: "pointer",
2725
- padding: "6px 10px",
2726
- borderRadius: "6px",
2727
- color: "#9ca3af",
2728
- display: "flex",
2729
- alignItems: "center",
2730
- justifyContent: "center",
2731
- gap: "4px",
2732
- fontSize: "12px",
2733
- opacity: 0.6,
2734
- transition: "opacity 0.2s, color 0.2s"
2735
- },
2736
- onMouseEnter: (e) => {
2737
- e.currentTarget.style.opacity = "1";
2738
- e.currentTarget.style.color = "#ef4444";
2739
- },
2740
- onMouseLeave: (e) => {
2741
- e.currentTarget.style.opacity = "0.6";
2742
- e.currentTarget.style.color = "#9ca3af";
2743
- },
2744
- "data-testid": "button-report-question",
2745
- children: [
2746
- /* @__PURE__ */ jsxs4("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2747
- /* @__PURE__ */ jsx4("path", { d: "M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z" }),
2748
- /* @__PURE__ */ jsx4("line", { x1: "4", y1: "22", x2: "4", y2: "15" })
2749
- ] }),
2750
- /* @__PURE__ */ jsx4("span", { children: "Report" })
2751
- ]
2752
- }
2753
- ),
2754
- (currentQuestion.type === "single" || currentQuestion.type === "true-false") && /* @__PURE__ */ jsx4("div", { style: defaultStyles.options, children: currentQuestion.options?.map((option, idx) => {
2755
- const isSelected = selectedAnswer === option;
2756
- const isCorrectOption = currentQuestion.correctAnswer === option;
2757
- let optionStyle = { ...defaultStyles.option };
2758
- if (showFeedback) {
2759
- if (isCorrectOption) {
2760
- optionStyle = { ...optionStyle, ...defaultStyles.optionCorrect };
2761
- } else if (isSelected && !isCorrectOption) {
2762
- optionStyle = { ...optionStyle, ...defaultStyles.optionIncorrect };
2763
- }
2764
- } else if (isSelected) {
2765
- optionStyle = { ...optionStyle, ...defaultStyles.optionSelected };
2748
+ .quiz-option {
2749
+ -webkit-tap-highlight-color: transparent;
2766
2750
  }
2767
- return /* @__PURE__ */ jsxs4(
2768
- "div",
2751
+ ` }),
2752
+ /* @__PURE__ */ jsxs4("div", { style: defaultStyles.mainLayout, children: [
2753
+ /* @__PURE__ */ jsxs4("div", { style: defaultStyles.quizContent, children: [
2754
+ /* @__PURE__ */ jsxs4("div", { style: defaultStyles.header, children: [
2755
+ /* @__PURE__ */ jsx4("div", { style: defaultStyles.title, children: quiz.title }),
2756
+ /* @__PURE__ */ jsxs4("div", { style: defaultStyles.progress, children: [
2757
+ "Question ",
2758
+ currentQuestionIndex + 1,
2759
+ " of ",
2760
+ totalQuestions
2761
+ ] }),
2762
+ /* @__PURE__ */ jsx4("div", { style: defaultStyles.progressBar, children: /* @__PURE__ */ jsx4("div", { style: { ...defaultStyles.progressFill, width: `${progressPercent}%` } }) })
2763
+ ] }),
2764
+ /* @__PURE__ */ jsxs4("div", { style: { ...defaultStyles.question, position: "relative", paddingBottom: "40px" }, children: [
2765
+ /* @__PURE__ */ jsx4("div", { style: defaultStyles.questionText, children: /* @__PURE__ */ jsx4(TextToSpeech, { text: currentQuestion.question, inline: true, size: "md" }) }),
2766
+ isExtraQuestion && /* @__PURE__ */ jsxs4(
2767
+ "button",
2769
2768
  {
2769
+ onClick: () => setShowSkipModal(true),
2770
+ title: "Skip question",
2770
2771
  style: {
2771
- ...optionStyle,
2772
- cursor: showFeedback ? "default" : "pointer",
2772
+ position: "absolute",
2773
+ bottom: "8px",
2774
+ left: "0",
2775
+ background: "transparent",
2776
+ border: "none",
2777
+ cursor: "pointer",
2778
+ padding: "6px 10px",
2779
+ borderRadius: "6px",
2780
+ color: "#9ca3af",
2773
2781
  display: "flex",
2774
2782
  alignItems: "center",
2775
- gap: "8px"
2783
+ justifyContent: "center",
2784
+ gap: "4px",
2785
+ fontSize: "12px",
2786
+ opacity: 0.6,
2787
+ transition: "opacity 0.2s, color 0.2s"
2788
+ },
2789
+ onMouseEnter: (e) => {
2790
+ e.currentTarget.style.opacity = "1";
2791
+ e.currentTarget.style.color = "#6b7280";
2776
2792
  },
2777
- onClick: () => !showFeedback && handleAnswerChange(option),
2793
+ onMouseLeave: (e) => {
2794
+ e.currentTarget.style.opacity = "0.6";
2795
+ e.currentTarget.style.color = "#9ca3af";
2796
+ },
2797
+ "data-testid": "button-skip-question",
2778
2798
  children: [
2779
- /* @__PURE__ */ jsx4("span", { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsx4(TextToSpeech, { text: option, size: "sm" }) }),
2780
- /* @__PURE__ */ jsx4("span", { style: { flex: 1 }, children: option })
2799
+ /* @__PURE__ */ jsxs4("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2800
+ /* @__PURE__ */ jsx4("polygon", { points: "5 4 15 12 5 20 5 4" }),
2801
+ /* @__PURE__ */ jsx4("line", { x1: "19", y1: "5", x2: "19", y2: "19" })
2802
+ ] }),
2803
+ /* @__PURE__ */ jsx4("span", { children: "Skip" })
2781
2804
  ]
2782
- },
2783
- idx
2784
- );
2785
- }) }),
2786
- currentQuestion.type === "multiple" && /* @__PURE__ */ jsx4("div", { style: defaultStyles.options, children: currentQuestion.options?.map((option, idx) => {
2787
- const selected = Array.isArray(selectedAnswer) && selectedAnswer.includes(option);
2788
- const correctAnswers = Array.isArray(currentQuestion.correctAnswer) ? currentQuestion.correctAnswer : currentQuestion.correctAnswer ? [currentQuestion.correctAnswer] : [];
2789
- const isCorrectOption = correctAnswers.includes(option);
2790
- let optionStyle = { ...defaultStyles.option };
2791
- if (showFeedback) {
2792
- if (isCorrectOption) {
2793
- optionStyle = { ...optionStyle, ...defaultStyles.optionCorrect };
2794
- } else if (selected && !isCorrectOption) {
2795
- optionStyle = { ...optionStyle, ...defaultStyles.optionIncorrect };
2796
2805
  }
2797
- } else if (selected) {
2798
- optionStyle = { ...optionStyle, ...defaultStyles.optionSelected };
2799
- }
2800
- return /* @__PURE__ */ jsxs4(
2801
- "div",
2806
+ ),
2807
+ !isExtraQuestion && /* @__PURE__ */ jsxs4(
2808
+ "button",
2802
2809
  {
2810
+ onClick: () => setShowReportModal(true),
2811
+ title: "Report an issue with this question",
2803
2812
  style: {
2804
- ...optionStyle,
2805
- cursor: showFeedback ? "default" : "pointer",
2813
+ position: "absolute",
2814
+ bottom: "8px",
2815
+ left: "0",
2816
+ background: "transparent",
2817
+ border: "none",
2818
+ cursor: "pointer",
2819
+ padding: "6px 10px",
2820
+ borderRadius: "6px",
2821
+ color: "#9ca3af",
2806
2822
  display: "flex",
2807
2823
  alignItems: "center",
2808
- gap: "8px"
2824
+ justifyContent: "center",
2825
+ gap: "4px",
2826
+ fontSize: "12px",
2827
+ opacity: 0.6,
2828
+ transition: "opacity 0.2s, color 0.2s"
2809
2829
  },
2810
- onClick: () => {
2811
- if (showFeedback) return;
2812
- const current = Array.isArray(selectedAnswer) ? selectedAnswer : [];
2813
- if (selected) {
2814
- handleAnswerChange(current.filter((o) => o !== option));
2815
- } else {
2816
- handleAnswerChange([...current, option]);
2817
- }
2830
+ onMouseEnter: (e) => {
2831
+ e.currentTarget.style.opacity = "1";
2832
+ e.currentTarget.style.color = "#ef4444";
2818
2833
  },
2834
+ onMouseLeave: (e) => {
2835
+ e.currentTarget.style.opacity = "0.6";
2836
+ e.currentTarget.style.color = "#9ca3af";
2837
+ },
2838
+ "data-testid": "button-report-question",
2819
2839
  children: [
2820
- /* @__PURE__ */ jsx4("span", { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsx4(TextToSpeech, { text: option, size: "sm" }) }),
2821
- /* @__PURE__ */ jsx4("span", { style: { flex: 1 }, children: option })
2840
+ /* @__PURE__ */ jsxs4("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2841
+ /* @__PURE__ */ jsx4("path", { d: "M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z" }),
2842
+ /* @__PURE__ */ jsx4("line", { x1: "4", y1: "22", x2: "4", y2: "15" })
2843
+ ] }),
2844
+ /* @__PURE__ */ jsx4("span", { children: "Report" })
2822
2845
  ]
2823
- },
2824
- idx
2825
- );
2826
- }) }),
2827
- (currentQuestion.type === "free" || currentQuestion.type === "essay") && /* @__PURE__ */ jsx4(
2828
- "textarea",
2829
- {
2830
- style: { ...defaultStyles.input, minHeight: currentQuestion.type === "essay" ? "150px" : "60px" },
2831
- value: selectedAnswer || "",
2832
- onChange: (e) => handleAnswerChange(e.target.value),
2833
- placeholder: "Type your answer here...",
2834
- disabled: showFeedback
2835
- }
2836
- ),
2837
- currentQuestion.type === "fill" && /* @__PURE__ */ jsx4("div", { style: defaultStyles.options, children: currentQuestion.blanks?.map((_, idx) => /* @__PURE__ */ jsx4(
2838
- "input",
2839
- {
2840
- style: defaultStyles.input,
2841
- value: (Array.isArray(selectedAnswer) ? selectedAnswer[idx] : "") || "",
2842
- onChange: (e) => {
2843
- const current = Array.isArray(selectedAnswer) ? [...selectedAnswer] : [];
2844
- current[idx] = e.target.value;
2845
- handleAnswerChange(current);
2846
- },
2847
- placeholder: `Blank ${idx + 1}`,
2848
- disabled: showFeedback
2849
- },
2850
- idx
2851
- )) }),
2852
- currentQuestion.type === "sorting" && currentQuestion.items && /* @__PURE__ */ jsx4(
2853
- SortingDragDrop,
2854
- {
2855
- items: currentQuestion.items,
2856
- currentOrder: Array.isArray(selectedAnswer) ? selectedAnswer : currentQuestion.items.map((_, i) => i),
2857
- correctOrder: currentQuestion.correctOrder,
2858
- showFeedback,
2859
- onOrderChange: handleAnswerChange
2860
- }
2861
- ),
2862
- currentQuestion.type === "matrix" && currentQuestion.leftItems && currentQuestion.rightItems && /* @__PURE__ */ jsx4(
2863
- MatchingDragDrop,
2864
- {
2865
- leftItems: currentQuestion.leftItems,
2866
- rightItems: currentQuestion.rightItems,
2867
- currentMatches: typeof selectedAnswer === "object" && selectedAnswer !== null && !Array.isArray(selectedAnswer) ? selectedAnswer : {},
2868
- correctMatches: currentQuestion.correctMatches,
2869
- showFeedback,
2870
- onMatchChange: handleAnswerChange
2871
- }
2872
- ),
2873
- currentQuestion.type === "assessment" && /* @__PURE__ */ jsx4("div", { style: defaultStyles.options, children: (() => {
2874
- const scaleType = currentQuestion.scaleType || "likert";
2875
- if (scaleType === "yes-no") {
2876
- const options = ["Yes", "No"];
2877
- return options.map((option, idx) => {
2878
- const isSelected = selectedAnswer === option;
2879
- let optionStyle = { ...defaultStyles.option };
2880
- if (isSelected) {
2881
- optionStyle = { ...optionStyle, ...defaultStyles.optionSelected };
2882
- }
2883
- return /* @__PURE__ */ jsx4(
2884
- "div",
2885
- {
2886
- style: {
2887
- ...optionStyle,
2888
- cursor: showFeedback ? "default" : "pointer",
2889
- display: "flex",
2890
- alignItems: "center",
2891
- gap: "8px"
2892
- },
2893
- onClick: () => !showFeedback && handleAnswerChange(option),
2894
- "data-testid": `assessment-option-${option.toLowerCase()}`,
2895
- children: /* @__PURE__ */ jsx4("span", { style: { flex: 1 }, children: option })
2896
- },
2897
- idx
2898
- );
2899
- });
2900
- }
2901
- if (scaleType === "rating") {
2902
- const min = currentQuestion.scaleMin || 1;
2903
- const max = currentQuestion.scaleMax || 5;
2904
- const ratings = Array.from({ length: max - min + 1 }, (_, i) => min + i);
2905
- return /* @__PURE__ */ jsx4("div", { style: { display: "flex", gap: "8px", flexWrap: "wrap", justifyContent: "center" }, children: ratings.map((rating) => {
2906
- const isSelected = selectedAnswer === rating;
2907
- return /* @__PURE__ */ jsx4(
2908
- "button",
2909
- {
2910
- onClick: () => !showFeedback && handleAnswerChange(rating),
2911
- disabled: showFeedback,
2912
- style: {
2913
- width: "48px",
2914
- height: "48px",
2915
- borderRadius: "50%",
2916
- border: isSelected ? "2px solid #6721b0" : "2px solid #e5e7eb",
2917
- backgroundColor: isSelected ? "#f3e8ff" : "#ffffff",
2918
- cursor: showFeedback ? "not-allowed" : "pointer",
2919
- fontSize: "18px",
2920
- fontWeight: "600",
2921
- color: isSelected ? "#6721b0" : "#374151"
2922
- },
2923
- "data-testid": `assessment-rating-${rating}`,
2924
- children: rating
2925
- },
2926
- rating
2927
- );
2928
- }) });
2929
- }
2930
- const likertOptions = [
2931
- "Strongly Disagree",
2932
- "Disagree",
2933
- "Neutral",
2934
- "Agree",
2935
- "Strongly Agree"
2936
- ];
2937
- return likertOptions.map((option, idx) => {
2846
+ }
2847
+ ),
2848
+ (currentQuestion.type === "single" || currentQuestion.type === "true-false") && /* @__PURE__ */ jsx4("div", { style: defaultStyles.options, children: currentQuestion.options?.map((option, idx) => {
2938
2849
  const isSelected = selectedAnswer === option;
2850
+ const isCorrectOption = currentQuestion.correctAnswer === option;
2939
2851
  let optionStyle = { ...defaultStyles.option };
2940
- if (isSelected) {
2852
+ if (showFeedback) {
2853
+ if (isCorrectOption) {
2854
+ optionStyle = { ...optionStyle, ...defaultStyles.optionCorrect };
2855
+ } else if (isSelected && !isCorrectOption) {
2856
+ optionStyle = { ...optionStyle, ...defaultStyles.optionIncorrect };
2857
+ }
2858
+ } else if (isSelected) {
2941
2859
  optionStyle = { ...optionStyle, ...defaultStyles.optionSelected };
2942
2860
  }
2943
- return /* @__PURE__ */ jsx4(
2861
+ return /* @__PURE__ */ jsxs4(
2944
2862
  "div",
2945
2863
  {
2864
+ className: "quiz-option",
2946
2865
  style: {
2947
2866
  ...optionStyle,
2948
2867
  cursor: showFeedback ? "default" : "pointer",
@@ -2951,350 +2870,532 @@ function QuizPlayer({
2951
2870
  gap: "8px"
2952
2871
  },
2953
2872
  onClick: () => !showFeedback && handleAnswerChange(option),
2954
- "data-testid": `assessment-likert-${idx}`,
2955
- children: /* @__PURE__ */ jsx4("span", { style: { flex: 1 }, children: option })
2873
+ children: [
2874
+ /* @__PURE__ */ jsx4("span", { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsx4(TextToSpeech, { text: option, size: "sm" }) }),
2875
+ /* @__PURE__ */ jsx4("span", { style: { flex: 1 }, children: option })
2876
+ ]
2956
2877
  },
2957
2878
  idx
2958
2879
  );
2959
- });
2960
- })() }),
2961
- showFeedback && currentAnswerDetail && /* @__PURE__ */ jsxs4("div", { style: {
2962
- ...defaultStyles.feedback,
2963
- ...currentQuestion.type === "assessment" ? defaultStyles.feedbackNeutral : currentAnswerDetail.isCorrect ? defaultStyles.feedbackCorrect : defaultStyles.feedbackIncorrect
2964
- }, children: [
2965
- /* @__PURE__ */ jsx4("div", { style: {
2966
- ...defaultStyles.feedbackTitle,
2967
- ...currentQuestion.type === "assessment" ? defaultStyles.feedbackTitleNeutral : currentAnswerDetail.isCorrect ? defaultStyles.feedbackTitleCorrect : defaultStyles.feedbackTitleIncorrect
2968
- }, children: currentQuestion.type === "assessment" ? "\u2713 Response recorded" : currentAnswerDetail.isCorrect ? "\u2713 Correct!" : "\u2717 Incorrect" }),
2969
- currentQuestion.explanation && /* @__PURE__ */ jsx4("div", { style: defaultStyles.feedbackExplanation, children: currentQuestion.explanation })
2970
- ] })
2971
- ] }),
2972
- showSkipModal && /* @__PURE__ */ jsx4("div", { style: {
2973
- position: "fixed",
2974
- top: 0,
2975
- left: 0,
2976
- right: 0,
2977
- bottom: 0,
2978
- backgroundColor: "rgba(0, 0, 0, 0.5)",
2979
- display: "flex",
2980
- alignItems: "center",
2981
- justifyContent: "center",
2982
- zIndex: 1e3
2983
- }, children: /* @__PURE__ */ jsxs4("div", { style: {
2984
- backgroundColor: "#ffffff",
2985
- borderRadius: "12px",
2986
- padding: "24px",
2987
- maxWidth: "400px",
2988
- width: "90%",
2989
- boxShadow: "0 20px 40px rgba(0, 0, 0, 0.2)"
2990
- }, children: [
2991
- /* @__PURE__ */ jsx4("h3", { style: { margin: "0 0 8px 0", fontSize: "18px", fontWeight: "600", color: "#1f2937" }, children: "Skip Question" }),
2992
- /* @__PURE__ */ jsx4("p", { style: { margin: "0 0 16px 0", fontSize: "14px", color: "#6b7280" }, children: "Help us improve by telling us why you're skipping this question." }),
2993
- /* @__PURE__ */ jsxs4("div", { style: { display: "flex", flexDirection: "column", gap: "8px", marginBottom: "16px" }, children: [
2994
- /* @__PURE__ */ jsx4(
2995
- "button",
2996
- {
2997
- onClick: () => setSelectedSkipReason("question_issue"),
2998
- disabled: isSkipping,
2999
- style: {
3000
- padding: "12px 16px",
3001
- borderRadius: "8px",
3002
- border: selectedSkipReason === "question_issue" ? "2px solid #8b5cf6" : "1px solid #e5e7eb",
3003
- backgroundColor: selectedSkipReason === "question_issue" ? "#f5f3ff" : "#f9fafb",
3004
- cursor: isSkipping ? "not-allowed" : "pointer",
3005
- fontSize: "14px",
3006
- fontWeight: "500",
3007
- color: "#374151",
3008
- textAlign: "left",
3009
- opacity: isSkipping ? 0.6 : 1
3010
- },
3011
- "data-testid": "button-skip-reason-issue",
3012
- children: "Question has an issue"
2880
+ }) }),
2881
+ currentQuestion.type === "multiple" && /* @__PURE__ */ jsx4("div", { style: defaultStyles.options, children: currentQuestion.options?.map((option, idx) => {
2882
+ const selected = Array.isArray(selectedAnswer) && selectedAnswer.includes(option);
2883
+ const correctAnswers = Array.isArray(currentQuestion.correctAnswer) ? currentQuestion.correctAnswer : currentQuestion.correctAnswer ? [currentQuestion.correctAnswer] : [];
2884
+ const isCorrectOption = correctAnswers.includes(option);
2885
+ let optionStyle = { ...defaultStyles.option };
2886
+ if (showFeedback) {
2887
+ if (isCorrectOption) {
2888
+ optionStyle = { ...optionStyle, ...defaultStyles.optionCorrect };
2889
+ } else if (selected && !isCorrectOption) {
2890
+ optionStyle = { ...optionStyle, ...defaultStyles.optionIncorrect };
2891
+ }
2892
+ } else if (selected) {
2893
+ optionStyle = { ...optionStyle, ...defaultStyles.optionSelected };
3013
2894
  }
3014
- ),
3015
- /* @__PURE__ */ jsx4(
3016
- "button",
3017
- {
3018
- onClick: () => setSelectedSkipReason("dont_know"),
3019
- disabled: isSkipping,
3020
- style: {
3021
- padding: "12px 16px",
3022
- borderRadius: "8px",
3023
- border: selectedSkipReason === "dont_know" ? "2px solid #8b5cf6" : "1px solid #e5e7eb",
3024
- backgroundColor: selectedSkipReason === "dont_know" ? "#f5f3ff" : "#f9fafb",
3025
- cursor: isSkipping ? "not-allowed" : "pointer",
3026
- fontSize: "14px",
3027
- fontWeight: "500",
3028
- color: "#374151",
3029
- textAlign: "left",
3030
- opacity: isSkipping ? 0.6 : 1
2895
+ return /* @__PURE__ */ jsxs4(
2896
+ "div",
2897
+ {
2898
+ className: "quiz-option",
2899
+ style: {
2900
+ ...optionStyle,
2901
+ cursor: showFeedback ? "default" : "pointer",
2902
+ display: "flex",
2903
+ alignItems: "center",
2904
+ gap: "8px"
2905
+ },
2906
+ onClick: () => {
2907
+ if (showFeedback) return;
2908
+ const current = Array.isArray(selectedAnswer) ? selectedAnswer : [];
2909
+ if (selected) {
2910
+ handleAnswerChange(current.filter((o) => o !== option));
2911
+ } else {
2912
+ handleAnswerChange([...current, option]);
2913
+ }
2914
+ },
2915
+ children: [
2916
+ /* @__PURE__ */ jsx4("span", { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsx4(TextToSpeech, { text: option, size: "sm" }) }),
2917
+ /* @__PURE__ */ jsx4("span", { style: { flex: 1 }, children: option })
2918
+ ]
3031
2919
  },
3032
- "data-testid": "button-skip-reason-dont-know",
3033
- children: "I don't know the answer"
3034
- }
3035
- )
3036
- ] }),
3037
- /* @__PURE__ */ jsxs4("div", { style: { marginBottom: "16px" }, children: [
3038
- /* @__PURE__ */ jsx4("label", { style: { display: "block", fontSize: "13px", fontWeight: "500", color: "#374151", marginBottom: "6px" }, children: "Additional details (optional)" }),
3039
- /* @__PURE__ */ jsx4(
2920
+ idx
2921
+ );
2922
+ }) }),
2923
+ (currentQuestion.type === "free" || currentQuestion.type === "essay") && /* @__PURE__ */ jsx4(
3040
2924
  "textarea",
3041
2925
  {
3042
- value: skipComment,
3043
- onChange: (e) => setSkipComment(e.target.value.slice(0, 200)),
3044
- placeholder: "Tell us more about the issue...",
3045
- disabled: isSkipping,
3046
- style: {
3047
- width: "100%",
3048
- minHeight: "80px",
3049
- padding: "10px 12px",
3050
- borderRadius: "8px",
3051
- border: "1px solid #e5e7eb",
3052
- fontSize: "14px",
3053
- resize: "vertical",
3054
- fontFamily: "inherit",
3055
- boxSizing: "border-box"
3056
- },
3057
- "data-testid": "input-skip-comment"
2926
+ style: { ...defaultStyles.input, minHeight: currentQuestion.type === "essay" ? "150px" : "60px" },
2927
+ value: selectedAnswer || "",
2928
+ onChange: (e) => handleAnswerChange(e.target.value),
2929
+ placeholder: "Type your answer here...",
2930
+ disabled: showFeedback
3058
2931
  }
3059
2932
  ),
3060
- /* @__PURE__ */ jsxs4("div", { style: { fontSize: "12px", color: "#9ca3af", marginTop: "4px", textAlign: "right" }, children: [
3061
- skipComment.length,
3062
- "/200"
3063
- ] })
3064
- ] }),
3065
- /* @__PURE__ */ jsxs4("div", { style: { display: "flex", gap: "10px" }, children: [
3066
- /* @__PURE__ */ jsx4(
3067
- "button",
2933
+ currentQuestion.type === "fill" && /* @__PURE__ */ jsx4("div", { style: defaultStyles.options, children: currentQuestion.blanks?.map((_, idx) => /* @__PURE__ */ jsx4(
2934
+ "input",
3068
2935
  {
3069
- onClick: () => {
3070
- setShowSkipModal(false);
3071
- setSkipComment("");
3072
- setSelectedSkipReason(null);
2936
+ style: defaultStyles.input,
2937
+ value: (Array.isArray(selectedAnswer) ? selectedAnswer[idx] : "") || "",
2938
+ onChange: (e) => {
2939
+ const current = Array.isArray(selectedAnswer) ? [...selectedAnswer] : [];
2940
+ current[idx] = e.target.value;
2941
+ handleAnswerChange(current);
3073
2942
  },
3074
- style: {
3075
- flex: 1,
3076
- padding: "10px 16px",
3077
- borderRadius: "8px",
3078
- border: "1px solid #e5e7eb",
3079
- backgroundColor: "#ffffff",
3080
- cursor: "pointer",
3081
- fontSize: "14px",
3082
- fontWeight: "500",
3083
- color: "#6b7280"
3084
- },
3085
- "data-testid": "button-skip-cancel",
3086
- children: "Cancel"
3087
- }
3088
- ),
3089
- /* @__PURE__ */ jsx4(
3090
- "button",
2943
+ placeholder: `Blank ${idx + 1}`,
2944
+ disabled: showFeedback
2945
+ },
2946
+ idx
2947
+ )) }),
2948
+ currentQuestion.type === "sorting" && currentQuestion.items && /* @__PURE__ */ jsx4(
2949
+ SortingDragDrop,
3091
2950
  {
3092
- onClick: () => selectedSkipReason && handleSkipQuestion(selectedSkipReason, skipComment),
3093
- disabled: isSkipping || !selectedSkipReason,
3094
- style: {
3095
- flex: 1,
3096
- padding: "10px 16px",
3097
- borderRadius: "8px",
3098
- border: "none",
3099
- backgroundColor: selectedSkipReason ? "#8b5cf6" : "#d1d5db",
3100
- cursor: isSkipping || !selectedSkipReason ? "not-allowed" : "pointer",
3101
- fontSize: "14px",
3102
- fontWeight: "500",
3103
- color: "#ffffff",
3104
- opacity: isSkipping ? 0.6 : 1
3105
- },
3106
- "data-testid": "button-skip-submit",
3107
- children: isSkipping ? "Skipping..." : "Skip Question"
2951
+ items: currentQuestion.items,
2952
+ currentOrder: Array.isArray(selectedAnswer) ? selectedAnswer : currentQuestion.items.map((_, i) => i),
2953
+ correctOrder: currentQuestion.correctOrder,
2954
+ showFeedback,
2955
+ onOrderChange: handleAnswerChange
3108
2956
  }
3109
- )
3110
- ] })
3111
- ] }) }),
3112
- showReportModal && /* @__PURE__ */ jsx4("div", { style: {
3113
- position: "fixed",
3114
- top: 0,
3115
- left: 0,
3116
- right: 0,
3117
- bottom: 0,
3118
- backgroundColor: "rgba(0, 0, 0, 0.5)",
3119
- display: "flex",
3120
- alignItems: "center",
3121
- justifyContent: "center",
3122
- zIndex: 1e3
3123
- }, children: /* @__PURE__ */ jsxs4("div", { style: {
3124
- backgroundColor: "#ffffff",
3125
- borderRadius: "12px",
3126
- padding: "24px",
3127
- maxWidth: "400px",
3128
- width: "90%",
3129
- boxShadow: "0 20px 40px rgba(0, 0, 0, 0.2)"
3130
- }, children: [
3131
- /* @__PURE__ */ jsx4("h3", { style: { margin: "0 0 8px 0", fontSize: "18px", fontWeight: "600", color: "#1f2937" }, children: "Report Question" }),
3132
- /* @__PURE__ */ jsx4("p", { style: { margin: "0 0 16px 0", fontSize: "14px", color: "#6b7280" }, children: "What's wrong with this question?" }),
3133
- /* @__PURE__ */ jsxs4("div", { style: { marginBottom: "16px" }, children: [
3134
- /* @__PURE__ */ jsx4(
3135
- "textarea",
2957
+ ),
2958
+ currentQuestion.type === "matrix" && currentQuestion.leftItems && currentQuestion.rightItems && /* @__PURE__ */ jsx4(
2959
+ MatchingDragDrop,
3136
2960
  {
3137
- value: reportComment,
3138
- onChange: (e) => setReportComment(e.target.value.slice(0, 300)),
3139
- placeholder: "Describe the issue with this question...",
3140
- disabled: isReporting,
3141
- style: {
3142
- width: "100%",
3143
- minHeight: "120px",
3144
- padding: "10px 12px",
3145
- borderRadius: "8px",
3146
- border: "1px solid #e5e7eb",
3147
- fontSize: "14px",
3148
- resize: "vertical",
3149
- fontFamily: "inherit",
3150
- boxSizing: "border-box"
3151
- },
3152
- "data-testid": "input-report-comment"
2961
+ leftItems: currentQuestion.leftItems,
2962
+ rightItems: currentQuestion.rightItems,
2963
+ currentMatches: typeof selectedAnswer === "object" && selectedAnswer !== null && !Array.isArray(selectedAnswer) ? selectedAnswer : {},
2964
+ correctMatches: currentQuestion.correctMatches,
2965
+ showFeedback,
2966
+ onMatchChange: handleAnswerChange
3153
2967
  }
3154
2968
  ),
3155
- /* @__PURE__ */ jsxs4("div", { style: { fontSize: "12px", color: "#9ca3af", marginTop: "4px", textAlign: "right" }, children: [
3156
- reportComment.length,
3157
- "/300"
2969
+ currentQuestion.type === "assessment" && /* @__PURE__ */ jsx4("div", { style: defaultStyles.options, children: (() => {
2970
+ const scaleType = currentQuestion.scaleType || "likert";
2971
+ if (scaleType === "yes-no") {
2972
+ const options = ["Yes", "No"];
2973
+ return options.map((option, idx) => {
2974
+ const isSelected = selectedAnswer === option;
2975
+ let optionStyle = { ...defaultStyles.option };
2976
+ if (isSelected) {
2977
+ optionStyle = { ...optionStyle, ...defaultStyles.optionSelected };
2978
+ }
2979
+ return /* @__PURE__ */ jsx4(
2980
+ "div",
2981
+ {
2982
+ className: "quiz-option",
2983
+ style: {
2984
+ ...optionStyle,
2985
+ cursor: showFeedback ? "default" : "pointer",
2986
+ display: "flex",
2987
+ alignItems: "center",
2988
+ gap: "8px"
2989
+ },
2990
+ onClick: () => !showFeedback && handleAnswerChange(option),
2991
+ "data-testid": `assessment-option-${option.toLowerCase()}`,
2992
+ children: /* @__PURE__ */ jsx4("span", { style: { flex: 1 }, children: option })
2993
+ },
2994
+ idx
2995
+ );
2996
+ });
2997
+ }
2998
+ if (scaleType === "rating") {
2999
+ const min = currentQuestion.scaleMin || 1;
3000
+ const max = currentQuestion.scaleMax || 5;
3001
+ const ratings = Array.from({ length: max - min + 1 }, (_, i) => min + i);
3002
+ return /* @__PURE__ */ jsx4("div", { style: { display: "flex", gap: "8px", flexWrap: "wrap", justifyContent: "center" }, children: ratings.map((rating) => {
3003
+ const isSelected = selectedAnswer === rating;
3004
+ return /* @__PURE__ */ jsx4(
3005
+ "button",
3006
+ {
3007
+ className: "quiz-option",
3008
+ onClick: () => !showFeedback && handleAnswerChange(rating),
3009
+ disabled: showFeedback,
3010
+ style: {
3011
+ width: "48px",
3012
+ height: "48px",
3013
+ borderRadius: "50%",
3014
+ border: isSelected ? "2px solid #6721b0" : "2px solid #e5e7eb",
3015
+ backgroundColor: isSelected ? "#f3e8ff" : "#ffffff",
3016
+ cursor: showFeedback ? "not-allowed" : "pointer",
3017
+ fontSize: "18px",
3018
+ fontWeight: "600",
3019
+ color: isSelected ? "#6721b0" : "#374151",
3020
+ outline: "none"
3021
+ },
3022
+ "data-testid": `assessment-rating-${rating}`,
3023
+ children: rating
3024
+ },
3025
+ rating
3026
+ );
3027
+ }) });
3028
+ }
3029
+ const likertOptions = [
3030
+ "Strongly Disagree",
3031
+ "Disagree",
3032
+ "Neutral",
3033
+ "Agree",
3034
+ "Strongly Agree"
3035
+ ];
3036
+ return likertOptions.map((option, idx) => {
3037
+ const isSelected = selectedAnswer === option;
3038
+ let optionStyle = { ...defaultStyles.option };
3039
+ if (isSelected) {
3040
+ optionStyle = { ...optionStyle, ...defaultStyles.optionSelected };
3041
+ }
3042
+ return /* @__PURE__ */ jsx4(
3043
+ "div",
3044
+ {
3045
+ className: "quiz-option",
3046
+ style: {
3047
+ ...optionStyle,
3048
+ cursor: showFeedback ? "default" : "pointer",
3049
+ display: "flex",
3050
+ alignItems: "center",
3051
+ gap: "8px"
3052
+ },
3053
+ onClick: () => !showFeedback && handleAnswerChange(option),
3054
+ "data-testid": `assessment-likert-${idx}`,
3055
+ children: /* @__PURE__ */ jsx4("span", { style: { flex: 1 }, children: option })
3056
+ },
3057
+ idx
3058
+ );
3059
+ });
3060
+ })() }),
3061
+ showFeedback && currentAnswerDetail && /* @__PURE__ */ jsxs4("div", { style: {
3062
+ ...defaultStyles.feedback,
3063
+ ...currentQuestion.type === "assessment" ? defaultStyles.feedbackNeutral : currentAnswerDetail.isCorrect ? defaultStyles.feedbackCorrect : defaultStyles.feedbackIncorrect
3064
+ }, children: [
3065
+ /* @__PURE__ */ jsx4("div", { style: {
3066
+ ...defaultStyles.feedbackTitle,
3067
+ ...currentQuestion.type === "assessment" ? defaultStyles.feedbackTitleNeutral : currentAnswerDetail.isCorrect ? defaultStyles.feedbackTitleCorrect : defaultStyles.feedbackTitleIncorrect
3068
+ }, children: currentQuestion.type === "assessment" ? "\u2713 Response recorded" : currentAnswerDetail.isCorrect ? "\u2713 Correct!" : "\u2717 Incorrect" }),
3069
+ currentQuestion.explanation && /* @__PURE__ */ jsx4("div", { style: defaultStyles.feedbackExplanation, children: currentQuestion.explanation })
3158
3070
  ] })
3159
3071
  ] }),
3160
- /* @__PURE__ */ jsxs4("div", { style: { display: "flex", gap: "10px" }, children: [
3161
- /* @__PURE__ */ jsx4(
3072
+ showSkipModal && /* @__PURE__ */ jsx4("div", { style: {
3073
+ position: "fixed",
3074
+ top: 0,
3075
+ left: 0,
3076
+ right: 0,
3077
+ bottom: 0,
3078
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
3079
+ display: "flex",
3080
+ alignItems: "center",
3081
+ justifyContent: "center",
3082
+ zIndex: 1e3
3083
+ }, children: /* @__PURE__ */ jsxs4("div", { style: {
3084
+ backgroundColor: "#ffffff",
3085
+ borderRadius: "12px",
3086
+ padding: "24px",
3087
+ maxWidth: "400px",
3088
+ width: "90%",
3089
+ boxShadow: "0 20px 40px rgba(0, 0, 0, 0.2)"
3090
+ }, children: [
3091
+ /* @__PURE__ */ jsx4("h3", { style: { margin: "0 0 8px 0", fontSize: "18px", fontWeight: "600", color: "#1f2937" }, children: "Skip Question" }),
3092
+ /* @__PURE__ */ jsx4("p", { style: { margin: "0 0 16px 0", fontSize: "14px", color: "#6b7280" }, children: "Help us improve by telling us why you're skipping this question." }),
3093
+ /* @__PURE__ */ jsxs4("div", { style: { display: "flex", flexDirection: "column", gap: "8px", marginBottom: "16px" }, children: [
3094
+ /* @__PURE__ */ jsx4(
3095
+ "button",
3096
+ {
3097
+ onClick: () => setSelectedSkipReason("question_issue"),
3098
+ disabled: isSkipping,
3099
+ style: {
3100
+ padding: "12px 16px",
3101
+ borderRadius: "8px",
3102
+ border: selectedSkipReason === "question_issue" ? "2px solid #8b5cf6" : "1px solid #e5e7eb",
3103
+ backgroundColor: selectedSkipReason === "question_issue" ? "#f5f3ff" : "#f9fafb",
3104
+ cursor: isSkipping ? "not-allowed" : "pointer",
3105
+ fontSize: "14px",
3106
+ fontWeight: "500",
3107
+ color: "#374151",
3108
+ textAlign: "left",
3109
+ opacity: isSkipping ? 0.6 : 1
3110
+ },
3111
+ "data-testid": "button-skip-reason-issue",
3112
+ children: "Question has an issue"
3113
+ }
3114
+ ),
3115
+ /* @__PURE__ */ jsx4(
3116
+ "button",
3117
+ {
3118
+ onClick: () => setSelectedSkipReason("dont_know"),
3119
+ disabled: isSkipping,
3120
+ style: {
3121
+ padding: "12px 16px",
3122
+ borderRadius: "8px",
3123
+ border: selectedSkipReason === "dont_know" ? "2px solid #8b5cf6" : "1px solid #e5e7eb",
3124
+ backgroundColor: selectedSkipReason === "dont_know" ? "#f5f3ff" : "#f9fafb",
3125
+ cursor: isSkipping ? "not-allowed" : "pointer",
3126
+ fontSize: "14px",
3127
+ fontWeight: "500",
3128
+ color: "#374151",
3129
+ textAlign: "left",
3130
+ opacity: isSkipping ? 0.6 : 1
3131
+ },
3132
+ "data-testid": "button-skip-reason-dont-know",
3133
+ children: "I don't know the answer"
3134
+ }
3135
+ )
3136
+ ] }),
3137
+ /* @__PURE__ */ jsxs4("div", { style: { marginBottom: "16px" }, children: [
3138
+ /* @__PURE__ */ jsx4("label", { style: { display: "block", fontSize: "13px", fontWeight: "500", color: "#374151", marginBottom: "6px" }, children: "Additional details (optional)" }),
3139
+ /* @__PURE__ */ jsx4(
3140
+ "textarea",
3141
+ {
3142
+ value: skipComment,
3143
+ onChange: (e) => setSkipComment(e.target.value.slice(0, 200)),
3144
+ placeholder: "Tell us more about the issue...",
3145
+ disabled: isSkipping,
3146
+ style: {
3147
+ width: "100%",
3148
+ minHeight: "80px",
3149
+ padding: "10px 12px",
3150
+ borderRadius: "8px",
3151
+ border: "1px solid #e5e7eb",
3152
+ fontSize: "14px",
3153
+ resize: "vertical",
3154
+ fontFamily: "inherit",
3155
+ boxSizing: "border-box"
3156
+ },
3157
+ "data-testid": "input-skip-comment"
3158
+ }
3159
+ ),
3160
+ /* @__PURE__ */ jsxs4("div", { style: { fontSize: "12px", color: "#9ca3af", marginTop: "4px", textAlign: "right" }, children: [
3161
+ skipComment.length,
3162
+ "/200"
3163
+ ] })
3164
+ ] }),
3165
+ /* @__PURE__ */ jsxs4("div", { style: { display: "flex", gap: "10px" }, children: [
3166
+ /* @__PURE__ */ jsx4(
3167
+ "button",
3168
+ {
3169
+ onClick: () => {
3170
+ setShowSkipModal(false);
3171
+ setSkipComment("");
3172
+ setSelectedSkipReason(null);
3173
+ },
3174
+ style: {
3175
+ flex: 1,
3176
+ padding: "10px 16px",
3177
+ borderRadius: "8px",
3178
+ border: "1px solid #e5e7eb",
3179
+ backgroundColor: "#ffffff",
3180
+ cursor: "pointer",
3181
+ fontSize: "14px",
3182
+ fontWeight: "500",
3183
+ color: "#6b7280"
3184
+ },
3185
+ "data-testid": "button-skip-cancel",
3186
+ children: "Cancel"
3187
+ }
3188
+ ),
3189
+ /* @__PURE__ */ jsx4(
3190
+ "button",
3191
+ {
3192
+ onClick: () => selectedSkipReason && handleSkipQuestion(selectedSkipReason, skipComment),
3193
+ disabled: isSkipping || !selectedSkipReason,
3194
+ style: {
3195
+ flex: 1,
3196
+ padding: "10px 16px",
3197
+ borderRadius: "8px",
3198
+ border: "none",
3199
+ backgroundColor: selectedSkipReason ? "#8b5cf6" : "#d1d5db",
3200
+ cursor: isSkipping || !selectedSkipReason ? "not-allowed" : "pointer",
3201
+ fontSize: "14px",
3202
+ fontWeight: "500",
3203
+ color: "#ffffff",
3204
+ opacity: isSkipping ? 0.6 : 1
3205
+ },
3206
+ "data-testid": "button-skip-submit",
3207
+ children: isSkipping ? "Skipping..." : "Skip Question"
3208
+ }
3209
+ )
3210
+ ] })
3211
+ ] }) }),
3212
+ showReportModal && /* @__PURE__ */ jsx4("div", { style: {
3213
+ position: "fixed",
3214
+ top: 0,
3215
+ left: 0,
3216
+ right: 0,
3217
+ bottom: 0,
3218
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
3219
+ display: "flex",
3220
+ alignItems: "center",
3221
+ justifyContent: "center",
3222
+ zIndex: 1e3
3223
+ }, children: /* @__PURE__ */ jsxs4("div", { style: {
3224
+ backgroundColor: "#ffffff",
3225
+ borderRadius: "12px",
3226
+ padding: "24px",
3227
+ maxWidth: "400px",
3228
+ width: "90%",
3229
+ boxShadow: "0 20px 40px rgba(0, 0, 0, 0.2)"
3230
+ }, children: [
3231
+ /* @__PURE__ */ jsx4("h3", { style: { margin: "0 0 8px 0", fontSize: "18px", fontWeight: "600", color: "#1f2937" }, children: "Report Question" }),
3232
+ /* @__PURE__ */ jsx4("p", { style: { margin: "0 0 16px 0", fontSize: "14px", color: "#6b7280" }, children: "What's wrong with this question?" }),
3233
+ /* @__PURE__ */ jsxs4("div", { style: { marginBottom: "16px" }, children: [
3234
+ /* @__PURE__ */ jsx4(
3235
+ "textarea",
3236
+ {
3237
+ value: reportComment,
3238
+ onChange: (e) => setReportComment(e.target.value.slice(0, 300)),
3239
+ placeholder: "Describe the issue with this question...",
3240
+ disabled: isReporting,
3241
+ style: {
3242
+ width: "100%",
3243
+ minHeight: "120px",
3244
+ padding: "10px 12px",
3245
+ borderRadius: "8px",
3246
+ border: "1px solid #e5e7eb",
3247
+ fontSize: "14px",
3248
+ resize: "vertical",
3249
+ fontFamily: "inherit",
3250
+ boxSizing: "border-box"
3251
+ },
3252
+ "data-testid": "input-report-comment"
3253
+ }
3254
+ ),
3255
+ /* @__PURE__ */ jsxs4("div", { style: { fontSize: "12px", color: "#9ca3af", marginTop: "4px", textAlign: "right" }, children: [
3256
+ reportComment.length,
3257
+ "/300"
3258
+ ] })
3259
+ ] }),
3260
+ /* @__PURE__ */ jsxs4("div", { style: { display: "flex", gap: "10px" }, children: [
3261
+ /* @__PURE__ */ jsx4(
3262
+ "button",
3263
+ {
3264
+ onClick: () => {
3265
+ setShowReportModal(false);
3266
+ setReportComment("");
3267
+ },
3268
+ style: {
3269
+ flex: 1,
3270
+ padding: "10px 16px",
3271
+ borderRadius: "8px",
3272
+ border: "1px solid #e5e7eb",
3273
+ backgroundColor: "#ffffff",
3274
+ cursor: "pointer",
3275
+ fontSize: "14px",
3276
+ fontWeight: "500",
3277
+ color: "#6b7280"
3278
+ },
3279
+ "data-testid": "button-report-cancel",
3280
+ children: "Cancel"
3281
+ }
3282
+ ),
3283
+ /* @__PURE__ */ jsx4(
3284
+ "button",
3285
+ {
3286
+ onClick: () => handleReportQuestion(reportComment),
3287
+ disabled: isReporting || !reportComment.trim(),
3288
+ style: {
3289
+ flex: 1,
3290
+ padding: "10px 16px",
3291
+ borderRadius: "8px",
3292
+ border: "none",
3293
+ backgroundColor: reportComment.trim() ? "#ef4444" : "#d1d5db",
3294
+ cursor: isReporting || !reportComment.trim() ? "not-allowed" : "pointer",
3295
+ fontSize: "14px",
3296
+ fontWeight: "500",
3297
+ color: "#ffffff",
3298
+ opacity: isReporting ? 0.6 : 1
3299
+ },
3300
+ "data-testid": "button-report-submit",
3301
+ children: isReporting ? "Reporting..." : "Report"
3302
+ }
3303
+ )
3304
+ ] })
3305
+ ] }) }),
3306
+ /* @__PURE__ */ jsxs4("div", { style: defaultStyles.buttonsColumn, children: [
3307
+ showFeedback && isLastQuestion && canAddMore && /* @__PURE__ */ jsx4(
3162
3308
  "button",
3163
3309
  {
3164
- onClick: () => {
3165
- setShowReportModal(false);
3166
- setReportComment("");
3167
- },
3168
3310
  style: {
3169
- flex: 1,
3170
- padding: "10px 16px",
3171
- borderRadius: "8px",
3172
- border: "1px solid #e5e7eb",
3173
- backgroundColor: "#ffffff",
3174
- cursor: "pointer",
3175
- fontSize: "14px",
3176
- fontWeight: "500",
3177
- color: "#6b7280"
3311
+ ...defaultStyles.buttonAddMore,
3312
+ ...isGeneratingExtra ? defaultStyles.buttonAddMoreDisabled : {}
3178
3313
  },
3179
- "data-testid": "button-report-cancel",
3180
- children: "Cancel"
3314
+ onClick: handleAddMoreQuestions,
3315
+ disabled: isGeneratingExtra,
3316
+ "data-testid": "button-add-more-questions",
3317
+ children: isGeneratingExtra ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
3318
+ /* @__PURE__ */ jsx4(Spinner, { size: 16, color: "#9ca3af" }),
3319
+ "Generating Questions..."
3320
+ ] }) : /* @__PURE__ */ jsxs4(Fragment2, { children: [
3321
+ "+ Add ",
3322
+ questionsToAdd,
3323
+ " More Question",
3324
+ questionsToAdd !== 1 ? "s" : ""
3325
+ ] })
3181
3326
  }
3182
3327
  ),
3183
- /* @__PURE__ */ jsx4(
3184
- "button",
3185
- {
3186
- onClick: () => handleReportQuestion(reportComment),
3187
- disabled: isReporting || !reportComment.trim(),
3188
- style: {
3189
- flex: 1,
3190
- padding: "10px 16px",
3191
- borderRadius: "8px",
3192
- border: "none",
3193
- backgroundColor: reportComment.trim() ? "#ef4444" : "#d1d5db",
3194
- cursor: isReporting || !reportComment.trim() ? "not-allowed" : "pointer",
3195
- fontSize: "14px",
3196
- fontWeight: "500",
3197
- color: "#ffffff",
3198
- opacity: isReporting ? 0.6 : 1
3199
- },
3200
- "data-testid": "button-report-submit",
3201
- children: isReporting ? "Reporting..." : "Report"
3202
- }
3203
- )
3328
+ /* @__PURE__ */ jsx4("div", { style: { ...defaultStyles.buttons, justifyContent: "flex-end" }, children: showFeedback ? (
3329
+ // After viewing feedback
3330
+ isLastQuestion ? /* @__PURE__ */ jsx4(
3331
+ "button",
3332
+ {
3333
+ style: {
3334
+ ...defaultStyles.button,
3335
+ ...isSubmitting || isGeneratingExtra ? defaultStyles.buttonDisabled : defaultStyles.buttonPrimary
3336
+ },
3337
+ onClick: handleSubmit,
3338
+ disabled: isSubmitting || isGeneratingExtra,
3339
+ "data-testid": "button-submit-quiz",
3340
+ children: isSubmitting ? /* @__PURE__ */ jsx4(Spinner, { size: 16, color: "#9ca3af" }) : "Submit Quiz"
3341
+ }
3342
+ ) : /* @__PURE__ */ jsx4(
3343
+ "button",
3344
+ {
3345
+ style: {
3346
+ ...defaultStyles.button,
3347
+ ...defaultStyles.buttonPrimary
3348
+ },
3349
+ onClick: handleContinue,
3350
+ "data-testid": "button-continue",
3351
+ children: "Continue"
3352
+ }
3353
+ )
3354
+ ) : (
3355
+ // Before checking answer
3356
+ /* @__PURE__ */ jsx4(
3357
+ "button",
3358
+ {
3359
+ style: {
3360
+ ...defaultStyles.button,
3361
+ ...isNavigating || selectedAnswer === void 0 ? defaultStyles.buttonDisabled : defaultStyles.buttonPrimary
3362
+ },
3363
+ onClick: handleCheckAnswer,
3364
+ disabled: isNavigating || selectedAnswer === void 0,
3365
+ "data-testid": "button-check-answer",
3366
+ children: isNavigating ? /* @__PURE__ */ jsx4(Spinner, { size: 16, color: "#9ca3af" }) : "Check Answer"
3367
+ }
3368
+ )
3369
+ ) })
3204
3370
  ] })
3205
- ] }) }),
3206
- /* @__PURE__ */ jsxs4("div", { style: defaultStyles.buttonsColumn, children: [
3207
- showFeedback && isLastQuestion && canAddMore && /* @__PURE__ */ jsx4(
3208
- "button",
3209
- {
3210
- style: {
3211
- ...defaultStyles.buttonAddMore,
3212
- ...isGeneratingExtra ? defaultStyles.buttonAddMoreDisabled : {}
3213
- },
3214
- onClick: handleAddMoreQuestions,
3215
- disabled: isGeneratingExtra,
3216
- "data-testid": "button-add-more-questions",
3217
- children: isGeneratingExtra ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
3218
- /* @__PURE__ */ jsx4(Spinner, { size: 16, color: "#9ca3af" }),
3219
- "Generating Questions..."
3220
- ] }) : /* @__PURE__ */ jsxs4(Fragment2, { children: [
3221
- "+ Add ",
3222
- questionsToAdd,
3223
- " More Question",
3224
- questionsToAdd !== 1 ? "s" : ""
3225
- ] })
3226
- }
3227
- ),
3228
- /* @__PURE__ */ jsx4("div", { style: { ...defaultStyles.buttons, justifyContent: "flex-end" }, children: showFeedback ? (
3229
- // After viewing feedback
3230
- isLastQuestion ? /* @__PURE__ */ jsx4(
3231
- "button",
3232
- {
3233
- style: {
3234
- ...defaultStyles.button,
3235
- ...isSubmitting || isGeneratingExtra ? defaultStyles.buttonDisabled : defaultStyles.buttonPrimary
3236
- },
3237
- onClick: handleSubmit,
3238
- disabled: isSubmitting || isGeneratingExtra,
3239
- "data-testid": "button-submit-quiz",
3240
- children: isSubmitting ? /* @__PURE__ */ jsx4(Spinner, { size: 16, color: "#9ca3af" }) : "Submit Quiz"
3241
- }
3242
- ) : /* @__PURE__ */ jsx4(
3243
- "button",
3244
- {
3245
- style: {
3246
- ...defaultStyles.button,
3247
- ...defaultStyles.buttonPrimary
3248
- },
3249
- onClick: handleContinue,
3250
- "data-testid": "button-continue",
3251
- children: "Continue"
3252
- }
3253
- )
3254
- ) : (
3255
- // Before checking answer
3256
- /* @__PURE__ */ jsx4(
3257
- "button",
3258
- {
3259
- style: {
3260
- ...defaultStyles.button,
3261
- ...isNavigating || selectedAnswer === void 0 ? defaultStyles.buttonDisabled : defaultStyles.buttonPrimary
3262
- },
3263
- onClick: handleCheckAnswer,
3264
- disabled: isNavigating || selectedAnswer === void 0,
3265
- "data-testid": "button-check-answer",
3266
- children: isNavigating ? /* @__PURE__ */ jsx4(Spinner, { size: 16, color: "#9ca3af" }) : "Check Answer"
3267
- }
3268
- )
3269
- ) })
3270
- ] })
3271
- ] }),
3272
- /* @__PURE__ */ jsx4("div", { style: defaultStyles.chatPanel, children: apiClient.current && /* @__PURE__ */ jsx4(
3273
- QuestionChatPanel,
3274
- {
3275
- apiClient: apiClient.current,
3276
- question: {
3277
- id: currentQuestion.id,
3278
- question: currentQuestion.question,
3279
- type: currentQuestion.type,
3280
- options: currentQuestion.options,
3281
- correctAnswer: currentQuestion.correctAnswer,
3282
- explanation: currentQuestion.explanation
3283
- },
3284
- quizId: quiz.id,
3285
- childId,
3286
- parentId,
3287
- lessonId,
3288
- courseId,
3289
- answerResult: showFeedback && currentAnswerDetail ? {
3290
- wasIncorrect: currentQuestion.type !== "assessment" && !currentAnswerDetail.isCorrect,
3291
- selectedAnswer: typeof selectedAnswer === "string" ? selectedAnswer : Array.isArray(selectedAnswer) ? selectedAnswer.join(", ") : void 0,
3292
- correctAnswer: typeof currentQuestion.correctAnswer === "string" ? currentQuestion.correctAnswer : Array.isArray(currentQuestion.correctAnswer) ? currentQuestion.correctAnswer.join(", ") : void 0,
3293
- explanation: currentQuestion.explanation
3294
- } : void 0
3295
- }
3296
- ) })
3297
- ] }) });
3371
+ ] }),
3372
+ /* @__PURE__ */ jsx4("div", { style: defaultStyles.chatPanel, children: apiClient.current && /* @__PURE__ */ jsx4(
3373
+ QuestionChatPanel,
3374
+ {
3375
+ apiClient: apiClient.current,
3376
+ question: {
3377
+ id: currentQuestion.id,
3378
+ question: currentQuestion.question,
3379
+ type: currentQuestion.type,
3380
+ options: currentQuestion.options,
3381
+ correctAnswer: currentQuestion.correctAnswer,
3382
+ explanation: currentQuestion.explanation
3383
+ },
3384
+ quizId: quiz.id,
3385
+ childId,
3386
+ parentId,
3387
+ lessonId,
3388
+ courseId,
3389
+ answerResult: showFeedback && currentAnswerDetail ? {
3390
+ wasIncorrect: currentQuestion.type !== "assessment" && !currentAnswerDetail.isCorrect,
3391
+ selectedAnswer: typeof selectedAnswer === "string" ? selectedAnswer : Array.isArray(selectedAnswer) ? selectedAnswer.join(", ") : void 0,
3392
+ correctAnswer: typeof currentQuestion.correctAnswer === "string" ? currentQuestion.correctAnswer : Array.isArray(currentQuestion.correctAnswer) ? currentQuestion.correctAnswer.join(", ") : void 0,
3393
+ explanation: currentQuestion.explanation
3394
+ } : void 0
3395
+ }
3396
+ ) })
3397
+ ] })
3398
+ ] });
3298
3399
  }
3299
3400
 
3300
3401
  // src/AttemptViewer.tsx
@@ -3442,7 +3543,12 @@ var defaultStyles2 = {
3442
3543
  marginTop: "12px",
3443
3544
  display: "flex",
3444
3545
  flexDirection: "column",
3445
- gap: "8px"
3546
+ gap: "8px",
3547
+ backgroundColor: "#ffffff",
3548
+ padding: "16px",
3549
+ borderRadius: "8px",
3550
+ border: "1px solid #e5e7eb",
3551
+ boxShadow: "0 1px 3px rgba(0, 0, 0, 0.05)"
3446
3552
  },
3447
3553
  chatMessage: {
3448
3554
  padding: "8px 12px",