@schoolio/player 1.1.0 → 1.2.0
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.d.mts +12 -1
- package/dist/index.d.ts +12 -1
- package/dist/index.js +302 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +302 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -94,9 +94,20 @@ interface QuizPlayerStyles {
|
|
|
94
94
|
buttonClassName?: string;
|
|
95
95
|
progressClassName?: string;
|
|
96
96
|
}
|
|
97
|
+
interface AttemptViewerProps {
|
|
98
|
+
attemptId: string;
|
|
99
|
+
apiBaseUrl: string;
|
|
100
|
+
authToken?: string;
|
|
101
|
+
onError?: (error: Error) => void;
|
|
102
|
+
className?: string;
|
|
103
|
+
showExplanations?: boolean;
|
|
104
|
+
title?: string;
|
|
105
|
+
}
|
|
97
106
|
|
|
98
107
|
declare function QuizPlayer({ quizId, lessonId, assignLessonId, courseId, childId, parentId, apiBaseUrl, authToken, onComplete, onError, onProgress, className, }: QuizPlayerProps): react_jsx_runtime.JSX.Element;
|
|
99
108
|
|
|
109
|
+
declare function AttemptViewer({ attemptId, apiBaseUrl, authToken, onError, className, showExplanations, title, }: AttemptViewerProps): react_jsx_runtime.JSX.Element;
|
|
110
|
+
|
|
100
111
|
interface ApiClientConfig {
|
|
101
112
|
baseUrl: string;
|
|
102
113
|
authToken?: string;
|
|
@@ -143,4 +154,4 @@ declare function calculateScore(answers: QuizAnswerDetail[]): {
|
|
|
143
154
|
};
|
|
144
155
|
declare function formatTime(seconds: number): string;
|
|
145
156
|
|
|
146
|
-
export { type ApiClientConfig, type AttemptStatus, type ExternalQuizAttempt, type QuestionType, type Quiz, type QuizAnswerDetail, QuizApiClient, QuizPlayer, type QuizPlayerProps, type QuizPlayerStyles, type QuizProgress, type QuizQuestion, type QuizResult, calculateScore, checkAnswer, createAnswerDetail, formatTime };
|
|
157
|
+
export { type ApiClientConfig, type AttemptStatus, AttemptViewer, type AttemptViewerProps, type ExternalQuizAttempt, type QuestionType, type Quiz, type QuizAnswerDetail, QuizApiClient, QuizPlayer, type QuizPlayerProps, type QuizPlayerStyles, type QuizProgress, type QuizQuestion, type QuizResult, calculateScore, checkAnswer, createAnswerDetail, formatTime };
|
package/dist/index.d.ts
CHANGED
|
@@ -94,9 +94,20 @@ interface QuizPlayerStyles {
|
|
|
94
94
|
buttonClassName?: string;
|
|
95
95
|
progressClassName?: string;
|
|
96
96
|
}
|
|
97
|
+
interface AttemptViewerProps {
|
|
98
|
+
attemptId: string;
|
|
99
|
+
apiBaseUrl: string;
|
|
100
|
+
authToken?: string;
|
|
101
|
+
onError?: (error: Error) => void;
|
|
102
|
+
className?: string;
|
|
103
|
+
showExplanations?: boolean;
|
|
104
|
+
title?: string;
|
|
105
|
+
}
|
|
97
106
|
|
|
98
107
|
declare function QuizPlayer({ quizId, lessonId, assignLessonId, courseId, childId, parentId, apiBaseUrl, authToken, onComplete, onError, onProgress, className, }: QuizPlayerProps): react_jsx_runtime.JSX.Element;
|
|
99
108
|
|
|
109
|
+
declare function AttemptViewer({ attemptId, apiBaseUrl, authToken, onError, className, showExplanations, title, }: AttemptViewerProps): react_jsx_runtime.JSX.Element;
|
|
110
|
+
|
|
100
111
|
interface ApiClientConfig {
|
|
101
112
|
baseUrl: string;
|
|
102
113
|
authToken?: string;
|
|
@@ -143,4 +154,4 @@ declare function calculateScore(answers: QuizAnswerDetail[]): {
|
|
|
143
154
|
};
|
|
144
155
|
declare function formatTime(seconds: number): string;
|
|
145
156
|
|
|
146
|
-
export { type ApiClientConfig, type AttemptStatus, type ExternalQuizAttempt, type QuestionType, type Quiz, type QuizAnswerDetail, QuizApiClient, QuizPlayer, type QuizPlayerProps, type QuizPlayerStyles, type QuizProgress, type QuizQuestion, type QuizResult, calculateScore, checkAnswer, createAnswerDetail, formatTime };
|
|
157
|
+
export { type ApiClientConfig, type AttemptStatus, AttemptViewer, type AttemptViewerProps, type ExternalQuizAttempt, type QuestionType, type Quiz, type QuizAnswerDetail, QuizApiClient, QuizPlayer, type QuizPlayerProps, type QuizPlayerStyles, type QuizProgress, type QuizQuestion, type QuizResult, calculateScore, checkAnswer, createAnswerDetail, formatTime };
|
package/dist/index.js
CHANGED
|
@@ -614,7 +614,309 @@ function QuizPlayer({
|
|
|
614
614
|
] })
|
|
615
615
|
] });
|
|
616
616
|
}
|
|
617
|
+
var defaultStyles2 = {
|
|
618
|
+
container: {
|
|
619
|
+
fontFamily: "system-ui, -apple-system, sans-serif",
|
|
620
|
+
width: "100%",
|
|
621
|
+
padding: "20px",
|
|
622
|
+
backgroundColor: "#ffffff",
|
|
623
|
+
borderRadius: "12px",
|
|
624
|
+
boxSizing: "border-box"
|
|
625
|
+
},
|
|
626
|
+
header: {
|
|
627
|
+
marginBottom: "24px",
|
|
628
|
+
borderBottom: "1px solid #e5e7eb",
|
|
629
|
+
paddingBottom: "20px"
|
|
630
|
+
},
|
|
631
|
+
summaryGrid: {
|
|
632
|
+
display: "grid",
|
|
633
|
+
gridTemplateColumns: "repeat(auto-fit, minmax(120px, 1fr))",
|
|
634
|
+
gap: "16px"
|
|
635
|
+
},
|
|
636
|
+
summaryCard: {
|
|
637
|
+
padding: "12px",
|
|
638
|
+
backgroundColor: "#f9fafb",
|
|
639
|
+
borderRadius: "8px",
|
|
640
|
+
textAlign: "center"
|
|
641
|
+
},
|
|
642
|
+
summaryValue: {
|
|
643
|
+
fontSize: "20px",
|
|
644
|
+
fontWeight: "600",
|
|
645
|
+
color: "#6721b0",
|
|
646
|
+
marginBottom: "2px"
|
|
647
|
+
},
|
|
648
|
+
summaryLabel: {
|
|
649
|
+
fontSize: "10px",
|
|
650
|
+
color: "#6b7280",
|
|
651
|
+
textTransform: "uppercase",
|
|
652
|
+
letterSpacing: "0.05em"
|
|
653
|
+
},
|
|
654
|
+
questionsList: {
|
|
655
|
+
display: "flex",
|
|
656
|
+
flexDirection: "column",
|
|
657
|
+
gap: "16px"
|
|
658
|
+
},
|
|
659
|
+
questionCard: {
|
|
660
|
+
padding: "16px",
|
|
661
|
+
border: "2px solid #e5e7eb",
|
|
662
|
+
borderRadius: "8px"
|
|
663
|
+
},
|
|
664
|
+
questionCardCorrect: {
|
|
665
|
+
borderColor: "#22c55e",
|
|
666
|
+
backgroundColor: "#f0fdf4"
|
|
667
|
+
},
|
|
668
|
+
questionCardIncorrect: {
|
|
669
|
+
borderColor: "#ef4444",
|
|
670
|
+
backgroundColor: "#fef2f2"
|
|
671
|
+
},
|
|
672
|
+
questionHeader: {
|
|
673
|
+
display: "flex",
|
|
674
|
+
justifyContent: "space-between",
|
|
675
|
+
alignItems: "flex-start",
|
|
676
|
+
marginBottom: "12px"
|
|
677
|
+
},
|
|
678
|
+
questionNumber: {
|
|
679
|
+
fontSize: "12px",
|
|
680
|
+
color: "#6b7280",
|
|
681
|
+
fontWeight: "500"
|
|
682
|
+
},
|
|
683
|
+
questionBadge: {
|
|
684
|
+
padding: "4px 8px",
|
|
685
|
+
borderRadius: "4px",
|
|
686
|
+
fontSize: "12px",
|
|
687
|
+
fontWeight: "600"
|
|
688
|
+
},
|
|
689
|
+
badgeCorrect: {
|
|
690
|
+
backgroundColor: "#dcfce7",
|
|
691
|
+
color: "#166534"
|
|
692
|
+
},
|
|
693
|
+
badgeIncorrect: {
|
|
694
|
+
backgroundColor: "#fee2e2",
|
|
695
|
+
color: "#991b1b"
|
|
696
|
+
},
|
|
697
|
+
questionText: {
|
|
698
|
+
fontSize: "16px",
|
|
699
|
+
fontWeight: "500",
|
|
700
|
+
marginBottom: "12px",
|
|
701
|
+
color: "#111827"
|
|
702
|
+
},
|
|
703
|
+
answerSection: {
|
|
704
|
+
fontSize: "14px",
|
|
705
|
+
marginBottom: "8px"
|
|
706
|
+
},
|
|
707
|
+
answerLabel: {
|
|
708
|
+
fontWeight: "600",
|
|
709
|
+
color: "#6b7280",
|
|
710
|
+
marginRight: "8px"
|
|
711
|
+
},
|
|
712
|
+
studentAnswer: {
|
|
713
|
+
color: "#111827"
|
|
714
|
+
},
|
|
715
|
+
correctAnswer: {
|
|
716
|
+
color: "#166534"
|
|
717
|
+
},
|
|
718
|
+
points: {
|
|
719
|
+
fontSize: "13px",
|
|
720
|
+
color: "#6b7280",
|
|
721
|
+
marginTop: "8px"
|
|
722
|
+
},
|
|
723
|
+
explanation: {
|
|
724
|
+
marginTop: "12px",
|
|
725
|
+
padding: "12px",
|
|
726
|
+
backgroundColor: "#f3e8ff",
|
|
727
|
+
borderRadius: "6px",
|
|
728
|
+
fontSize: "14px",
|
|
729
|
+
color: "#581c87"
|
|
730
|
+
},
|
|
731
|
+
loading: {
|
|
732
|
+
textAlign: "center",
|
|
733
|
+
padding: "40px 20px"
|
|
734
|
+
},
|
|
735
|
+
spinner: {
|
|
736
|
+
display: "inline-block",
|
|
737
|
+
width: "32px",
|
|
738
|
+
height: "32px",
|
|
739
|
+
border: "3px solid #e5e7eb",
|
|
740
|
+
borderTopColor: "#6721b0",
|
|
741
|
+
borderRadius: "50%",
|
|
742
|
+
animation: "spin 1s linear infinite"
|
|
743
|
+
},
|
|
744
|
+
error: {
|
|
745
|
+
textAlign: "center",
|
|
746
|
+
padding: "40px 20px",
|
|
747
|
+
color: "#ef4444"
|
|
748
|
+
},
|
|
749
|
+
retryButton: {
|
|
750
|
+
marginTop: "16px",
|
|
751
|
+
padding: "12px 24px",
|
|
752
|
+
backgroundColor: "#6721b0",
|
|
753
|
+
color: "#ffffff",
|
|
754
|
+
border: "none",
|
|
755
|
+
borderRadius: "8px",
|
|
756
|
+
fontSize: "16px",
|
|
757
|
+
fontWeight: "500",
|
|
758
|
+
cursor: "pointer"
|
|
759
|
+
}
|
|
760
|
+
};
|
|
761
|
+
var spinnerKeyframes = `
|
|
762
|
+
@keyframes spin {
|
|
763
|
+
to { transform: rotate(360deg); }
|
|
764
|
+
}
|
|
765
|
+
`;
|
|
766
|
+
function formatAnswer(answer) {
|
|
767
|
+
if (answer === null || answer === void 0) {
|
|
768
|
+
return "No answer";
|
|
769
|
+
}
|
|
770
|
+
if (typeof answer === "string") {
|
|
771
|
+
return answer;
|
|
772
|
+
}
|
|
773
|
+
if (Array.isArray(answer)) {
|
|
774
|
+
return answer.join(", ");
|
|
775
|
+
}
|
|
776
|
+
if (typeof answer === "object") {
|
|
777
|
+
return Object.entries(answer).map(([k, v]) => `${k} \u2192 ${v}`).join(", ");
|
|
778
|
+
}
|
|
779
|
+
return String(answer);
|
|
780
|
+
}
|
|
781
|
+
function AttemptViewer({
|
|
782
|
+
attemptId,
|
|
783
|
+
apiBaseUrl,
|
|
784
|
+
authToken,
|
|
785
|
+
onError,
|
|
786
|
+
className,
|
|
787
|
+
showExplanations = true,
|
|
788
|
+
title
|
|
789
|
+
}) {
|
|
790
|
+
const [attempt, setAttempt] = react.useState(null);
|
|
791
|
+
const [loading, setLoading] = react.useState(true);
|
|
792
|
+
const [error, setError] = react.useState(null);
|
|
793
|
+
react.useEffect(() => {
|
|
794
|
+
new QuizApiClient({
|
|
795
|
+
baseUrl: apiBaseUrl,
|
|
796
|
+
authToken
|
|
797
|
+
});
|
|
798
|
+
async function fetchAttempt() {
|
|
799
|
+
setLoading(true);
|
|
800
|
+
setError(null);
|
|
801
|
+
try {
|
|
802
|
+
const response = await fetch(`${apiBaseUrl}/api/external/quiz-attempts/${attemptId}`, {
|
|
803
|
+
headers: authToken ? { Authorization: `Bearer ${authToken}` } : {}
|
|
804
|
+
});
|
|
805
|
+
if (!response.ok) {
|
|
806
|
+
throw new Error(`Failed to fetch attempt: ${response.statusText}`);
|
|
807
|
+
}
|
|
808
|
+
const data = await response.json();
|
|
809
|
+
setAttempt(data);
|
|
810
|
+
} catch (err) {
|
|
811
|
+
const errorMessage = err instanceof Error ? err.message : "Failed to load attempt";
|
|
812
|
+
setError(errorMessage);
|
|
813
|
+
onError?.(err instanceof Error ? err : new Error(errorMessage));
|
|
814
|
+
} finally {
|
|
815
|
+
setLoading(false);
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
fetchAttempt();
|
|
819
|
+
}, [attemptId, apiBaseUrl, authToken, onError]);
|
|
820
|
+
const handleRetry = () => {
|
|
821
|
+
setLoading(true);
|
|
822
|
+
setError(null);
|
|
823
|
+
window.location.reload();
|
|
824
|
+
};
|
|
825
|
+
if (loading) {
|
|
826
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: defaultStyles2.container, className, children: [
|
|
827
|
+
/* @__PURE__ */ jsxRuntime.jsx("style", { children: spinnerKeyframes }),
|
|
828
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: defaultStyles2.loading, children: [
|
|
829
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: defaultStyles2.spinner }),
|
|
830
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: { marginTop: "16px", color: "#6b7280" }, children: "Loading attempt..." })
|
|
831
|
+
] })
|
|
832
|
+
] });
|
|
833
|
+
}
|
|
834
|
+
if (error || !attempt) {
|
|
835
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { style: defaultStyles2.container, className, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: defaultStyles2.error, children: [
|
|
836
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "18px", fontWeight: "500" }, children: "Failed to load attempt" }),
|
|
837
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: { marginTop: "8px", color: "#6b7280" }, children: error }),
|
|
838
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { style: defaultStyles2.retryButton, onClick: handleRetry, children: "Try Again" })
|
|
839
|
+
] }) });
|
|
840
|
+
}
|
|
841
|
+
const scorePercentage = attempt.score ?? 0;
|
|
842
|
+
const correctCount = attempt.correctAnswers ?? 0;
|
|
843
|
+
const totalQuestions = attempt.totalQuestions;
|
|
844
|
+
const timeSpent = attempt.timeSpentSeconds ?? 0;
|
|
845
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: defaultStyles2.container, className, children: [
|
|
846
|
+
/* @__PURE__ */ jsxRuntime.jsx("style", { children: spinnerKeyframes }),
|
|
847
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: defaultStyles2.header, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: defaultStyles2.summaryGrid, children: [
|
|
848
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: defaultStyles2.summaryCard, children: [
|
|
849
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: defaultStyles2.summaryValue, children: [
|
|
850
|
+
scorePercentage,
|
|
851
|
+
"%"
|
|
852
|
+
] }),
|
|
853
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: defaultStyles2.summaryLabel, children: "Score" })
|
|
854
|
+
] }),
|
|
855
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: defaultStyles2.summaryCard, children: [
|
|
856
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: defaultStyles2.summaryValue, children: [
|
|
857
|
+
correctCount,
|
|
858
|
+
"/",
|
|
859
|
+
totalQuestions
|
|
860
|
+
] }),
|
|
861
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: defaultStyles2.summaryLabel, children: "Correct" })
|
|
862
|
+
] }),
|
|
863
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: defaultStyles2.summaryCard, children: [
|
|
864
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: defaultStyles2.summaryValue, children: formatTime(timeSpent) }),
|
|
865
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: defaultStyles2.summaryLabel, children: "Time" })
|
|
866
|
+
] })
|
|
867
|
+
] }) }),
|
|
868
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: defaultStyles2.questionsList, children: attempt.answers.map((answer, index) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
869
|
+
"div",
|
|
870
|
+
{
|
|
871
|
+
style: {
|
|
872
|
+
...defaultStyles2.questionCard,
|
|
873
|
+
...answer.isCorrect ? defaultStyles2.questionCardCorrect : defaultStyles2.questionCardIncorrect
|
|
874
|
+
},
|
|
875
|
+
children: [
|
|
876
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: defaultStyles2.questionHeader, children: [
|
|
877
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: defaultStyles2.questionNumber, children: [
|
|
878
|
+
"Question ",
|
|
879
|
+
index + 1
|
|
880
|
+
] }),
|
|
881
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
882
|
+
"span",
|
|
883
|
+
{
|
|
884
|
+
style: {
|
|
885
|
+
...defaultStyles2.questionBadge,
|
|
886
|
+
...answer.isCorrect ? defaultStyles2.badgeCorrect : defaultStyles2.badgeIncorrect
|
|
887
|
+
},
|
|
888
|
+
children: answer.isCorrect ? "Correct" : "Incorrect"
|
|
889
|
+
}
|
|
890
|
+
)
|
|
891
|
+
] }),
|
|
892
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: defaultStyles2.questionText, children: answer.questionText }),
|
|
893
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: defaultStyles2.answerSection, children: [
|
|
894
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: defaultStyles2.answerLabel, children: "Your answer:" }),
|
|
895
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: defaultStyles2.studentAnswer, children: formatAnswer(answer.selectedAnswer) })
|
|
896
|
+
] }),
|
|
897
|
+
!answer.isCorrect && answer.correctAnswer && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: defaultStyles2.answerSection, children: [
|
|
898
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: defaultStyles2.answerLabel, children: "Correct answer:" }),
|
|
899
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: defaultStyles2.correctAnswer, children: formatAnswer(answer.correctAnswer) })
|
|
900
|
+
] }),
|
|
901
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: defaultStyles2.points, children: [
|
|
902
|
+
answer.pointsEarned,
|
|
903
|
+
" / ",
|
|
904
|
+
answer.points,
|
|
905
|
+
" points"
|
|
906
|
+
] }),
|
|
907
|
+
showExplanations && answer.explanation && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: defaultStyles2.explanation, children: [
|
|
908
|
+
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: "Explanation:" }),
|
|
909
|
+
" ",
|
|
910
|
+
answer.explanation
|
|
911
|
+
] })
|
|
912
|
+
]
|
|
913
|
+
},
|
|
914
|
+
answer.questionId
|
|
915
|
+
)) })
|
|
916
|
+
] });
|
|
917
|
+
}
|
|
617
918
|
|
|
919
|
+
exports.AttemptViewer = AttemptViewer;
|
|
618
920
|
exports.QuizApiClient = QuizApiClient;
|
|
619
921
|
exports.QuizPlayer = QuizPlayer;
|
|
620
922
|
exports.calculateScore = calculateScore;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/api.ts","../src/utils.ts","../src/QuizPlayer.tsx"],"names":["jsx","useState","useRef","useEffect","useCallback","selectedAnswer","jsxs"],"mappings":"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","file":"index.js","sourcesContent":["import type { Quiz, ExternalQuizAttempt, QuizAnswerDetail } from './types';\r\n\r\nexport interface ApiClientConfig {\r\n baseUrl: string;\r\n authToken?: string;\r\n}\r\n\r\nexport class QuizApiClient {\r\n private baseUrl: string;\r\n private authToken?: string;\r\n\r\n constructor(config: ApiClientConfig) {\r\n this.baseUrl = config.baseUrl.replace(/\\/$/, ''); // Remove trailing slash\r\n this.authToken = config.authToken;\r\n }\r\n\r\n private async request<T>(\r\n method: string,\r\n endpoint: string,\r\n body?: unknown\r\n ): Promise<T> {\r\n const headers: HeadersInit = {\r\n 'Content-Type': 'application/json',\r\n };\r\n\r\n if (this.authToken) {\r\n headers['Authorization'] = `Bearer ${this.authToken}`;\r\n }\r\n\r\n const response = await fetch(`${this.baseUrl}${endpoint}`, {\r\n method,\r\n headers,\r\n body: body ? JSON.stringify(body) : undefined,\r\n });\r\n\r\n if (!response.ok) {\r\n const error = await response.json().catch(() => ({ error: 'Request failed' }));\r\n throw new Error(error.error || `HTTP ${response.status}`);\r\n }\r\n\r\n return response.json();\r\n }\r\n\r\n async getQuiz(quizId: string): Promise<Quiz> {\r\n return this.request<Quiz>('GET', `/api/external/quizzes/${quizId}`);\r\n }\r\n\r\n async createAttempt(params: {\r\n quizId: string;\r\n lessonId: string;\r\n assignLessonId: string;\r\n courseId: string;\r\n childId: string;\r\n parentId: string;\r\n }): Promise<ExternalQuizAttempt> {\r\n return this.request<ExternalQuizAttempt>('POST', '/api/external/quiz-attempts', params);\r\n }\r\n\r\n async updateAttempt(\r\n attemptId: string,\r\n data: {\r\n answers?: QuizAnswerDetail[];\r\n status?: 'in_progress' | 'completed' | 'abandoned';\r\n score?: number;\r\n correctAnswers?: number;\r\n timeSpentSeconds?: number;\r\n }\r\n ): Promise<ExternalQuizAttempt> {\r\n return this.request<ExternalQuizAttempt>(\r\n 'PATCH',\r\n `/api/external/quiz-attempts/${attemptId}`,\r\n data\r\n );\r\n }\r\n\r\n async getAttempt(attemptId: string): Promise<ExternalQuizAttempt> {\r\n return this.request<ExternalQuizAttempt>('GET', `/api/external/quiz-attempts/${attemptId}`);\r\n }\r\n\r\n async getAttempts(params: {\r\n assignLessonId?: string;\r\n childId?: string;\r\n quizId?: string;\r\n }): Promise<ExternalQuizAttempt[]> {\r\n const queryParams = new URLSearchParams();\r\n if (params.assignLessonId) queryParams.set('assignLessonId', params.assignLessonId);\r\n if (params.childId) queryParams.set('childId', params.childId);\r\n if (params.quizId) queryParams.set('quizId', params.quizId);\r\n\r\n return this.request<ExternalQuizAttempt[]>(\r\n 'GET',\r\n `/api/external/quiz-attempts?${queryParams.toString()}`\r\n );\r\n }\r\n}\r\n","import type { QuizQuestion, QuizAnswerDetail, QuestionType } from './types';\r\n\r\n// Check if an answer is correct based on question type\r\nexport function checkAnswer(\r\n question: QuizQuestion,\r\n selectedAnswer: unknown\r\n): { isCorrect: boolean; pointsEarned: number } {\r\n const { type, correctAnswer, points } = question;\r\n\r\n switch (type) {\r\n case 'single':\r\n case 'true-false': {\r\n const isCorrect = selectedAnswer === correctAnswer;\r\n return { isCorrect, pointsEarned: isCorrect ? points : 0 };\r\n }\r\n\r\n case 'multiple': {\r\n if (!Array.isArray(selectedAnswer) || !Array.isArray(correctAnswer)) {\r\n return { isCorrect: false, pointsEarned: 0 };\r\n }\r\n const sortedSelected = [...selectedAnswer].sort();\r\n const sortedCorrect = [...correctAnswer].sort();\r\n const isCorrect =\r\n sortedSelected.length === sortedCorrect.length &&\r\n sortedSelected.every((val, idx) => val === sortedCorrect[idx]);\r\n return { isCorrect, pointsEarned: isCorrect ? points : 0 };\r\n }\r\n\r\n case 'fill': {\r\n if (!Array.isArray(selectedAnswer) || !question.blanks) {\r\n return { isCorrect: false, pointsEarned: 0 };\r\n }\r\n const isCorrect = question.blanks.every((blank, idx) =>\r\n selectedAnswer[idx]?.toLowerCase().trim() === blank.toLowerCase().trim()\r\n );\r\n return { isCorrect, pointsEarned: isCorrect ? points : 0 };\r\n }\r\n\r\n case 'sorting': {\r\n if (!Array.isArray(selectedAnswer) || !question.correctOrder) {\r\n return { isCorrect: false, pointsEarned: 0 };\r\n }\r\n const isCorrect =\r\n selectedAnswer.length === question.correctOrder.length &&\r\n selectedAnswer.every((val, idx) => val === question.correctOrder![idx]);\r\n return { isCorrect, pointsEarned: isCorrect ? points : 0 };\r\n }\r\n\r\n case 'matrix': {\r\n if (typeof selectedAnswer !== 'object' || !question.correctMatches) {\r\n return { isCorrect: false, pointsEarned: 0 };\r\n }\r\n const selected = selectedAnswer as Record<string, string>;\r\n const correct = question.correctMatches;\r\n const isCorrect = Object.keys(correct).every(\r\n key => selected[key] === correct[key]\r\n );\r\n return { isCorrect, pointsEarned: isCorrect ? points : 0 };\r\n }\r\n\r\n case 'free': {\r\n // For free-form answers, do a simple case-insensitive comparison\r\n if (typeof selectedAnswer !== 'string' || typeof correctAnswer !== 'string') {\r\n return { isCorrect: false, pointsEarned: 0 };\r\n }\r\n const isCorrect = selectedAnswer.toLowerCase().trim() === correctAnswer.toLowerCase().trim();\r\n return { isCorrect, pointsEarned: isCorrect ? points : 0 };\r\n }\r\n\r\n case 'essay':\r\n case 'assessment':\r\n // These require manual grading or are opinion-based\r\n return { isCorrect: false, pointsEarned: 0 };\r\n\r\n default:\r\n return { isCorrect: false, pointsEarned: 0 };\r\n }\r\n}\r\n\r\n// Create an answer detail object\r\nexport function createAnswerDetail(\r\n question: QuizQuestion,\r\n selectedAnswer: unknown\r\n): QuizAnswerDetail {\r\n const { isCorrect, pointsEarned } = checkAnswer(question, selectedAnswer);\r\n\r\n return {\r\n questionId: question.id,\r\n questionText: question.question,\r\n questionType: question.type,\r\n points: question.points,\r\n pointsEarned,\r\n selectedAnswer: selectedAnswer as QuizAnswerDetail['selectedAnswer'],\r\n correctAnswer: question.correctAnswer as QuizAnswerDetail['correctAnswer'],\r\n isCorrect,\r\n explanation: question.explanation,\r\n hint: question.hint,\r\n };\r\n}\r\n\r\n// Calculate total score percentage\r\nexport function calculateScore(answers: QuizAnswerDetail[]): {\r\n score: number;\r\n correctAnswers: number;\r\n totalPoints: number;\r\n earnedPoints: number;\r\n} {\r\n const totalPoints = answers.reduce((sum, a) => sum + a.points, 0);\r\n const earnedPoints = answers.reduce((sum, a) => sum + a.pointsEarned, 0);\r\n const correctAnswers = answers.filter(a => a.isCorrect).length;\r\n const score = totalPoints > 0 ? Math.round((earnedPoints / totalPoints) * 100) : 0;\r\n\r\n return { score, correctAnswers, totalPoints, earnedPoints };\r\n}\r\n\r\n// Format time in seconds to mm:ss\r\nexport function formatTime(seconds: number): string {\r\n const mins = Math.floor(seconds / 60);\r\n const secs = seconds % 60;\r\n return `${mins}:${secs.toString().padStart(2, '0')}`;\r\n}\r\n","import { useState, useEffect, useCallback, useRef } from 'react';\r\nimport type {\r\n QuizPlayerProps,\r\n Quiz,\r\n QuizQuestion,\r\n QuizAnswerDetail,\r\n ExternalQuizAttempt,\r\n QuizResult,\r\n} from './types';\r\nimport { QuizApiClient } from './api';\r\nimport { createAnswerDetail, calculateScore, formatTime } from './utils';\r\n\r\n// Default styles that can be overridden\r\nconst defaultStyles = {\r\n container: {\r\n fontFamily: 'system-ui, -apple-system, sans-serif',\r\n maxWidth: '800px',\r\n margin: '0 auto',\r\n padding: '20px',\r\n backgroundColor: '#ffffff',\r\n borderRadius: '12px',\r\n },\r\n header: {\r\n marginBottom: '20px',\r\n borderBottom: '1px solid #e5e7eb',\r\n paddingBottom: '16px',\r\n },\r\n title: {\r\n fontSize: '24px',\r\n fontWeight: '600',\r\n marginBottom: '8px',\r\n },\r\n progress: {\r\n fontSize: '14px',\r\n color: '#6b7280',\r\n },\r\n progressBar: {\r\n width: '100%',\r\n height: '8px',\r\n backgroundColor: '#e5e7eb',\r\n borderRadius: '4px',\r\n overflow: 'hidden' as const,\r\n marginTop: '8px',\r\n },\r\n progressFill: {\r\n height: '100%',\r\n backgroundColor: '#6721b0',\r\n transition: 'width 0.3s ease',\r\n },\r\n question: {\r\n marginBottom: '24px',\r\n },\r\n questionText: {\r\n fontSize: '18px',\r\n fontWeight: '500',\r\n marginBottom: '16px',\r\n },\r\n options: {\r\n display: 'flex',\r\n flexDirection: 'column' as const,\r\n gap: '8px',\r\n },\r\n option: {\r\n padding: '12px 16px',\r\n border: '2px solid #e5e7eb',\r\n borderRadius: '8px',\r\n cursor: 'pointer',\r\n transition: 'all 0.2s ease',\r\n },\r\n optionSelected: {\r\n borderColor: '#6721b0',\r\n backgroundColor: '#f3e8ff',\r\n },\r\n optionCorrect: {\r\n borderColor: '#22c55e',\r\n backgroundColor: '#f0fdf4',\r\n },\r\n optionIncorrect: {\r\n borderColor: '#ef4444',\r\n backgroundColor: '#fef2f2',\r\n },\r\n input: {\r\n width: '100%',\r\n padding: '12px 16px',\r\n border: '2px solid #e5e7eb',\r\n borderRadius: '8px',\r\n fontSize: '16px',\r\n },\r\n buttons: {\r\n display: 'flex',\r\n justifyContent: 'space-between',\r\n marginTop: '24px',\r\n },\r\n button: {\r\n padding: '12px 24px',\r\n borderRadius: '8px',\r\n fontSize: '16px',\r\n fontWeight: '500',\r\n cursor: 'pointer',\r\n border: 'none',\r\n transition: 'all 0.2s ease',\r\n },\r\n buttonPrimary: {\r\n backgroundColor: '#6721b0',\r\n color: '#ffffff',\r\n },\r\n buttonSecondary: {\r\n backgroundColor: '#f3f4f6',\r\n color: '#374151',\r\n },\r\n buttonDisabled: {\r\n backgroundColor: '#e5e7eb',\r\n color: '#9ca3af',\r\n cursor: 'not-allowed',\r\n },\r\n timer: {\r\n fontSize: '14px',\r\n color: '#6b7280',\r\n marginLeft: '16px',\r\n },\r\n results: {\r\n textAlign: 'center' as const,\r\n padding: '40px 20px',\r\n },\r\n resultScore: {\r\n fontSize: '48px',\r\n fontWeight: '700',\r\n color: '#6721b0',\r\n marginBottom: '8px',\r\n },\r\n resultLabel: {\r\n fontSize: '18px',\r\n color: '#6b7280',\r\n },\r\n loading: {\r\n textAlign: 'center' as const,\r\n padding: '40px',\r\n color: '#6b7280',\r\n },\r\n error: {\r\n textAlign: 'center' as const,\r\n padding: '40px',\r\n color: '#ef4444',\r\n },\r\n};\r\n\r\n// Inline spinner component\r\nfunction Spinner({ size = 16, color = '#ffffff' }: { size?: number; color?: string }) {\r\n return (\r\n <span\r\n style={{\r\n display: 'inline-block',\r\n width: size,\r\n height: size,\r\n border: `2px solid ${color}`,\r\n borderTopColor: 'transparent',\r\n borderRadius: '50%',\r\n animation: 'spin 0.8s linear infinite',\r\n }}\r\n >\r\n <style>\r\n {`@keyframes spin { to { transform: rotate(360deg); } }`}\r\n </style>\r\n </span>\r\n );\r\n}\r\n\r\nexport function QuizPlayer({\r\n quizId,\r\n lessonId,\r\n assignLessonId,\r\n courseId,\r\n childId,\r\n parentId,\r\n apiBaseUrl,\r\n authToken,\r\n onComplete,\r\n onError,\r\n onProgress,\r\n className,\r\n}: QuizPlayerProps) {\r\n const [quiz, setQuiz] = useState<Quiz | null>(null);\r\n const [attempt, setAttempt] = useState<ExternalQuizAttempt | null>(null);\r\n const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0);\r\n const [answers, setAnswers] = useState<Map<string, unknown>>(new Map());\r\n const [answersDetail, setAnswersDetail] = useState<QuizAnswerDetail[]>([]);\r\n const [isSubmitting, setIsSubmitting] = useState(false);\r\n const [isNavigating, setIsNavigating] = useState(false);\r\n const [isCompleted, setIsCompleted] = useState(false);\r\n const [result, setResult] = useState<QuizResult | null>(null);\r\n const [error, setError] = useState<string | null>(null);\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [elapsedSeconds, setElapsedSeconds] = useState(0);\r\n\r\n const apiClient = useRef<QuizApiClient | null>(null);\r\n const timerRef = useRef<ReturnType<typeof setInterval> | null>(null);\r\n const startTimeRef = useRef<number>(Date.now());\r\n\r\n // Initialize API client\r\n useEffect(() => {\r\n apiClient.current = new QuizApiClient({ baseUrl: apiBaseUrl, authToken });\r\n }, [apiBaseUrl, authToken]);\r\n\r\n // Load quiz and create/resume attempt\r\n useEffect(() => {\r\n async function initialize() {\r\n if (!apiClient.current) return;\r\n\r\n try {\r\n setIsLoading(true);\r\n setError(null);\r\n\r\n // Fetch quiz\r\n const quizData = await apiClient.current.getQuiz(quizId);\r\n setQuiz(quizData);\r\n\r\n // Create or resume attempt\r\n const attemptData = await apiClient.current.createAttempt({\r\n quizId,\r\n lessonId,\r\n assignLessonId,\r\n courseId,\r\n childId,\r\n parentId,\r\n });\r\n setAttempt(attemptData);\r\n\r\n // Resume from existing answers if any\r\n if (attemptData.answers && attemptData.answers.length > 0) {\r\n setAnswersDetail(attemptData.answers);\r\n const answersMap = new Map<string, unknown>();\r\n attemptData.answers.forEach(a => {\r\n answersMap.set(a.questionId, a.selectedAnswer);\r\n });\r\n setAnswers(answersMap);\r\n }\r\n\r\n // Check if already completed\r\n if (attemptData.status === 'completed') {\r\n setIsCompleted(true);\r\n const scoreData = calculateScore(attemptData.answers);\r\n setResult({\r\n attemptId: attemptData.id,\r\n score: attemptData.score || scoreData.score,\r\n correctAnswers: attemptData.correctAnswers || scoreData.correctAnswers,\r\n totalQuestions: attemptData.totalQuestions,\r\n answers: attemptData.answers,\r\n timeSpentSeconds: attemptData.timeSpentSeconds || 0,\r\n });\r\n }\r\n\r\n setIsLoading(false);\r\n } catch (err) {\r\n const message = err instanceof Error ? err.message : 'Failed to load quiz';\r\n setError(message);\r\n setIsLoading(false);\r\n onError?.(err instanceof Error ? err : new Error(message));\r\n }\r\n }\r\n\r\n initialize();\r\n }, [quizId, lessonId, assignLessonId, courseId, childId, parentId, onError]);\r\n\r\n // Timer\r\n useEffect(() => {\r\n if (!isLoading && !isCompleted && !error) {\r\n startTimeRef.current = Date.now();\r\n timerRef.current = setInterval(() => {\r\n setElapsedSeconds(Math.floor((Date.now() - startTimeRef.current) / 1000));\r\n }, 1000);\r\n }\r\n\r\n return () => {\r\n if (timerRef.current) {\r\n clearInterval(timerRef.current);\r\n }\r\n };\r\n }, [isLoading, isCompleted, error]);\r\n\r\n // Report progress\r\n useEffect(() => {\r\n if (quiz && onProgress) {\r\n onProgress({\r\n currentQuestion: currentQuestionIndex + 1,\r\n totalQuestions: quiz.questions.length,\r\n answeredQuestions: answers.size,\r\n });\r\n }\r\n }, [currentQuestionIndex, answers.size, quiz, onProgress]);\r\n\r\n const currentQuestion = quiz?.questions[currentQuestionIndex];\r\n\r\n const handleAnswerChange = useCallback((value: unknown) => {\r\n if (!currentQuestion) return;\r\n setAnswers(prev => new Map(prev).set(currentQuestion.id, value));\r\n }, [currentQuestion]);\r\n\r\n const handleNext = useCallback(async () => {\r\n if (!quiz || !attempt || !currentQuestion || !apiClient.current) return;\r\n\r\n const selectedAnswer = answers.get(currentQuestion.id);\r\n if (selectedAnswer === undefined) return;\r\n\r\n setIsNavigating(true);\r\n\r\n // Create answer detail\r\n const answerDetail = createAnswerDetail(currentQuestion, selectedAnswer);\r\n \r\n // Update answers detail state\r\n const newAnswersDetail = [...answersDetail];\r\n const existingIdx = newAnswersDetail.findIndex(a => a.questionId === currentQuestion.id);\r\n if (existingIdx >= 0) {\r\n newAnswersDetail[existingIdx] = answerDetail;\r\n } else {\r\n newAnswersDetail.push(answerDetail);\r\n }\r\n setAnswersDetail(newAnswersDetail);\r\n\r\n // Save progress to server\r\n try {\r\n await apiClient.current.updateAttempt(attempt.id, {\r\n answers: newAnswersDetail,\r\n });\r\n } catch (err) {\r\n console.error('Failed to save progress:', err);\r\n } finally {\r\n setIsNavigating(false);\r\n }\r\n\r\n // Move to next question\r\n if (currentQuestionIndex < quiz.questions.length - 1) {\r\n setCurrentQuestionIndex(prev => prev + 1);\r\n }\r\n }, [quiz, attempt, currentQuestion, answers, answersDetail, currentQuestionIndex]);\r\n\r\n const handlePrevious = useCallback(() => {\r\n if (currentQuestionIndex > 0) {\r\n setCurrentQuestionIndex(prev => prev - 1);\r\n }\r\n }, [currentQuestionIndex]);\r\n\r\n const handleSubmit = useCallback(async () => {\r\n if (!quiz || !attempt || !apiClient.current) return;\r\n\r\n setIsSubmitting(true);\r\n\r\n try {\r\n // Ensure current answer is saved\r\n const currentAnswer = currentQuestion ? answers.get(currentQuestion.id) : undefined;\r\n let finalAnswersDetail = [...answersDetail];\r\n \r\n if (currentQuestion && currentAnswer !== undefined) {\r\n const answerDetail = createAnswerDetail(currentQuestion, currentAnswer);\r\n const existingIdx = finalAnswersDetail.findIndex(a => a.questionId === currentQuestion.id);\r\n if (existingIdx >= 0) {\r\n finalAnswersDetail[existingIdx] = answerDetail;\r\n } else {\r\n finalAnswersDetail.push(answerDetail);\r\n }\r\n }\r\n\r\n // Calculate final score\r\n const scoreData = calculateScore(finalAnswersDetail);\r\n const timeSpent = Math.floor((Date.now() - startTimeRef.current) / 1000);\r\n\r\n // Submit to server\r\n const updatedAttempt = await apiClient.current.updateAttempt(attempt.id, {\r\n answers: finalAnswersDetail,\r\n status: 'completed',\r\n score: scoreData.score,\r\n correctAnswers: scoreData.correctAnswers,\r\n timeSpentSeconds: timeSpent,\r\n });\r\n\r\n // Update state\r\n setIsCompleted(true);\r\n const quizResult: QuizResult = {\r\n attemptId: updatedAttempt.id,\r\n score: scoreData.score,\r\n correctAnswers: scoreData.correctAnswers,\r\n totalQuestions: quiz.questions.length,\r\n answers: finalAnswersDetail,\r\n timeSpentSeconds: timeSpent,\r\n };\r\n setResult(quizResult);\r\n\r\n // Stop timer\r\n if (timerRef.current) {\r\n clearInterval(timerRef.current);\r\n }\r\n\r\n // Callback\r\n onComplete?.(quizResult);\r\n } catch (err) {\r\n const message = err instanceof Error ? err.message : 'Failed to submit quiz';\r\n setError(message);\r\n onError?.(err instanceof Error ? err : new Error(message));\r\n } finally {\r\n setIsSubmitting(false);\r\n }\r\n }, [quiz, attempt, currentQuestion, answers, answersDetail, onComplete, onError]);\r\n\r\n // Render loading state\r\n if (isLoading) {\r\n return (\r\n <div className={className} style={defaultStyles.container}>\r\n <div style={defaultStyles.loading}>Loading quiz...</div>\r\n </div>\r\n );\r\n }\r\n\r\n // Render error state\r\n if (error) {\r\n return (\r\n <div className={className} style={defaultStyles.container}>\r\n <div style={defaultStyles.error}>\r\n <p>Error: {error}</p>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n // Render completed state\r\n if (isCompleted && result) {\r\n return (\r\n <div className={className} style={defaultStyles.container}>\r\n <div style={defaultStyles.results}>\r\n <div style={defaultStyles.resultScore}>{result.score}%</div>\r\n <div style={defaultStyles.resultLabel}>\r\n {result.correctAnswers} of {result.totalQuestions} correct\r\n </div>\r\n <div style={{ ...defaultStyles.resultLabel, marginTop: '8px' }}>\r\n Time: {formatTime(result.timeSpentSeconds)}\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n // Render quiz\r\n if (!quiz || !currentQuestion) {\r\n return (\r\n <div className={className} style={defaultStyles.container}>\r\n <div style={defaultStyles.error}>No quiz data available</div>\r\n </div>\r\n );\r\n }\r\n\r\n const selectedAnswer = answers.get(currentQuestion.id);\r\n const isLastQuestion = currentQuestionIndex === quiz.questions.length - 1;\r\n const progressPercent = ((currentQuestionIndex + 1) / quiz.questions.length) * 100;\r\n\r\n return (\r\n <div className={className} style={defaultStyles.container}>\r\n {/* Header */}\r\n <div style={defaultStyles.header}>\r\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>\r\n <div style={defaultStyles.title}>{quiz.title}</div>\r\n <div style={defaultStyles.timer}>{formatTime(elapsedSeconds)}</div>\r\n </div>\r\n <div style={defaultStyles.progress}>\r\n Question {currentQuestionIndex + 1} of {quiz.questions.length}\r\n </div>\r\n <div style={defaultStyles.progressBar}>\r\n <div style={{ ...defaultStyles.progressFill, width: `${progressPercent}%` }} />\r\n </div>\r\n </div>\r\n\r\n {/* Question */}\r\n <div style={defaultStyles.question}>\r\n <div style={defaultStyles.questionText}>{currentQuestion.question}</div>\r\n\r\n {/* Render options based on question type */}\r\n {(currentQuestion.type === 'single' || currentQuestion.type === 'true-false') && (\r\n <div style={defaultStyles.options}>\r\n {currentQuestion.options?.map((option, idx) => (\r\n <div\r\n key={idx}\r\n style={{\r\n ...defaultStyles.option,\r\n ...(selectedAnswer === option ? defaultStyles.optionSelected : {}),\r\n }}\r\n onClick={() => handleAnswerChange(option)}\r\n >\r\n {option}\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n\r\n {currentQuestion.type === 'multiple' && (\r\n <div style={defaultStyles.options}>\r\n {currentQuestion.options?.map((option, idx) => {\r\n const selected = Array.isArray(selectedAnswer) && selectedAnswer.includes(option);\r\n return (\r\n <div\r\n key={idx}\r\n style={{\r\n ...defaultStyles.option,\r\n ...(selected ? defaultStyles.optionSelected : {}),\r\n }}\r\n onClick={() => {\r\n const current = Array.isArray(selectedAnswer) ? selectedAnswer : [];\r\n if (selected) {\r\n handleAnswerChange(current.filter(o => o !== option));\r\n } else {\r\n handleAnswerChange([...current, option]);\r\n }\r\n }}\r\n >\r\n {option}\r\n </div>\r\n );\r\n })}\r\n </div>\r\n )}\r\n\r\n {(currentQuestion.type === 'free' || currentQuestion.type === 'essay') && (\r\n <textarea\r\n style={{ ...defaultStyles.input, minHeight: currentQuestion.type === 'essay' ? '150px' : '60px' }}\r\n value={(selectedAnswer as string) || ''}\r\n onChange={e => handleAnswerChange(e.target.value)}\r\n placeholder=\"Type your answer here...\"\r\n />\r\n )}\r\n\r\n {currentQuestion.type === 'fill' && (\r\n <div style={defaultStyles.options}>\r\n {currentQuestion.blanks?.map((_, idx) => (\r\n <input\r\n key={idx}\r\n style={defaultStyles.input}\r\n value={(Array.isArray(selectedAnswer) ? selectedAnswer[idx] : '') || ''}\r\n onChange={e => {\r\n const current = Array.isArray(selectedAnswer) ? [...selectedAnswer] : [];\r\n current[idx] = e.target.value;\r\n handleAnswerChange(current);\r\n }}\r\n placeholder={`Blank ${idx + 1}`}\r\n />\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Navigation buttons */}\r\n <div style={defaultStyles.buttons}>\r\n <button\r\n style={{\r\n ...defaultStyles.button,\r\n ...(currentQuestionIndex > 0 ? defaultStyles.buttonSecondary : defaultStyles.buttonDisabled),\r\n }}\r\n onClick={handlePrevious}\r\n disabled={currentQuestionIndex === 0}\r\n >\r\n Previous\r\n </button>\r\n\r\n {isLastQuestion ? (\r\n <button\r\n style={{\r\n ...defaultStyles.button,\r\n ...(isSubmitting ? defaultStyles.buttonDisabled : defaultStyles.buttonPrimary),\r\n }}\r\n onClick={handleSubmit}\r\n disabled={isSubmitting || selectedAnswer === undefined}\r\n >\r\n {isSubmitting ? <Spinner size={16} color=\"#9ca3af\" /> : 'Submit Quiz'}\r\n </button>\r\n ) : (\r\n <button\r\n style={{\r\n ...defaultStyles.button,\r\n ...(isNavigating || selectedAnswer === undefined ? defaultStyles.buttonDisabled : defaultStyles.buttonPrimary),\r\n }}\r\n onClick={handleNext}\r\n disabled={isNavigating || selectedAnswer === undefined}\r\n >\r\n {isNavigating ? <Spinner size={16} color=\"#9ca3af\" /> : 'Next'}\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/api.ts","../src/utils.ts","../src/QuizPlayer.tsx","../src/AttemptViewer.tsx"],"names":["jsx","useState","useRef","useEffect","useCallback","selectedAnswer","jsxs","defaultStyles"],"mappings":"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","file":"index.js","sourcesContent":["import type { Quiz, ExternalQuizAttempt, QuizAnswerDetail } from './types';\r\n\r\nexport interface ApiClientConfig {\r\n baseUrl: string;\r\n authToken?: string;\r\n}\r\n\r\nexport class QuizApiClient {\r\n private baseUrl: string;\r\n private authToken?: string;\r\n\r\n constructor(config: ApiClientConfig) {\r\n this.baseUrl = config.baseUrl.replace(/\\/$/, ''); // Remove trailing slash\r\n this.authToken = config.authToken;\r\n }\r\n\r\n private async request<T>(\r\n method: string,\r\n endpoint: string,\r\n body?: unknown\r\n ): Promise<T> {\r\n const headers: HeadersInit = {\r\n 'Content-Type': 'application/json',\r\n };\r\n\r\n if (this.authToken) {\r\n headers['Authorization'] = `Bearer ${this.authToken}`;\r\n }\r\n\r\n const response = await fetch(`${this.baseUrl}${endpoint}`, {\r\n method,\r\n headers,\r\n body: body ? JSON.stringify(body) : undefined,\r\n });\r\n\r\n if (!response.ok) {\r\n const error = await response.json().catch(() => ({ error: 'Request failed' }));\r\n throw new Error(error.error || `HTTP ${response.status}`);\r\n }\r\n\r\n return response.json();\r\n }\r\n\r\n async getQuiz(quizId: string): Promise<Quiz> {\r\n return this.request<Quiz>('GET', `/api/external/quizzes/${quizId}`);\r\n }\r\n\r\n async createAttempt(params: {\r\n quizId: string;\r\n lessonId: string;\r\n assignLessonId: string;\r\n courseId: string;\r\n childId: string;\r\n parentId: string;\r\n }): Promise<ExternalQuizAttempt> {\r\n return this.request<ExternalQuizAttempt>('POST', '/api/external/quiz-attempts', params);\r\n }\r\n\r\n async updateAttempt(\r\n attemptId: string,\r\n data: {\r\n answers?: QuizAnswerDetail[];\r\n status?: 'in_progress' | 'completed' | 'abandoned';\r\n score?: number;\r\n correctAnswers?: number;\r\n timeSpentSeconds?: number;\r\n }\r\n ): Promise<ExternalQuizAttempt> {\r\n return this.request<ExternalQuizAttempt>(\r\n 'PATCH',\r\n `/api/external/quiz-attempts/${attemptId}`,\r\n data\r\n );\r\n }\r\n\r\n async getAttempt(attemptId: string): Promise<ExternalQuizAttempt> {\r\n return this.request<ExternalQuizAttempt>('GET', `/api/external/quiz-attempts/${attemptId}`);\r\n }\r\n\r\n async getAttempts(params: {\r\n assignLessonId?: string;\r\n childId?: string;\r\n quizId?: string;\r\n }): Promise<ExternalQuizAttempt[]> {\r\n const queryParams = new URLSearchParams();\r\n if (params.assignLessonId) queryParams.set('assignLessonId', params.assignLessonId);\r\n if (params.childId) queryParams.set('childId', params.childId);\r\n if (params.quizId) queryParams.set('quizId', params.quizId);\r\n\r\n return this.request<ExternalQuizAttempt[]>(\r\n 'GET',\r\n `/api/external/quiz-attempts?${queryParams.toString()}`\r\n );\r\n }\r\n}\r\n","import type { QuizQuestion, QuizAnswerDetail, QuestionType } from './types';\r\n\r\n// Check if an answer is correct based on question type\r\nexport function checkAnswer(\r\n question: QuizQuestion,\r\n selectedAnswer: unknown\r\n): { isCorrect: boolean; pointsEarned: number } {\r\n const { type, correctAnswer, points } = question;\r\n\r\n switch (type) {\r\n case 'single':\r\n case 'true-false': {\r\n const isCorrect = selectedAnswer === correctAnswer;\r\n return { isCorrect, pointsEarned: isCorrect ? points : 0 };\r\n }\r\n\r\n case 'multiple': {\r\n if (!Array.isArray(selectedAnswer) || !Array.isArray(correctAnswer)) {\r\n return { isCorrect: false, pointsEarned: 0 };\r\n }\r\n const sortedSelected = [...selectedAnswer].sort();\r\n const sortedCorrect = [...correctAnswer].sort();\r\n const isCorrect =\r\n sortedSelected.length === sortedCorrect.length &&\r\n sortedSelected.every((val, idx) => val === sortedCorrect[idx]);\r\n return { isCorrect, pointsEarned: isCorrect ? points : 0 };\r\n }\r\n\r\n case 'fill': {\r\n if (!Array.isArray(selectedAnswer) || !question.blanks) {\r\n return { isCorrect: false, pointsEarned: 0 };\r\n }\r\n const isCorrect = question.blanks.every((blank, idx) =>\r\n selectedAnswer[idx]?.toLowerCase().trim() === blank.toLowerCase().trim()\r\n );\r\n return { isCorrect, pointsEarned: isCorrect ? points : 0 };\r\n }\r\n\r\n case 'sorting': {\r\n if (!Array.isArray(selectedAnswer) || !question.correctOrder) {\r\n return { isCorrect: false, pointsEarned: 0 };\r\n }\r\n const isCorrect =\r\n selectedAnswer.length === question.correctOrder.length &&\r\n selectedAnswer.every((val, idx) => val === question.correctOrder![idx]);\r\n return { isCorrect, pointsEarned: isCorrect ? points : 0 };\r\n }\r\n\r\n case 'matrix': {\r\n if (typeof selectedAnswer !== 'object' || !question.correctMatches) {\r\n return { isCorrect: false, pointsEarned: 0 };\r\n }\r\n const selected = selectedAnswer as Record<string, string>;\r\n const correct = question.correctMatches;\r\n const isCorrect = Object.keys(correct).every(\r\n key => selected[key] === correct[key]\r\n );\r\n return { isCorrect, pointsEarned: isCorrect ? points : 0 };\r\n }\r\n\r\n case 'free': {\r\n // For free-form answers, do a simple case-insensitive comparison\r\n if (typeof selectedAnswer !== 'string' || typeof correctAnswer !== 'string') {\r\n return { isCorrect: false, pointsEarned: 0 };\r\n }\r\n const isCorrect = selectedAnswer.toLowerCase().trim() === correctAnswer.toLowerCase().trim();\r\n return { isCorrect, pointsEarned: isCorrect ? points : 0 };\r\n }\r\n\r\n case 'essay':\r\n case 'assessment':\r\n // These require manual grading or are opinion-based\r\n return { isCorrect: false, pointsEarned: 0 };\r\n\r\n default:\r\n return { isCorrect: false, pointsEarned: 0 };\r\n }\r\n}\r\n\r\n// Create an answer detail object\r\nexport function createAnswerDetail(\r\n question: QuizQuestion,\r\n selectedAnswer: unknown\r\n): QuizAnswerDetail {\r\n const { isCorrect, pointsEarned } = checkAnswer(question, selectedAnswer);\r\n\r\n return {\r\n questionId: question.id,\r\n questionText: question.question,\r\n questionType: question.type,\r\n points: question.points,\r\n pointsEarned,\r\n selectedAnswer: selectedAnswer as QuizAnswerDetail['selectedAnswer'],\r\n correctAnswer: question.correctAnswer as QuizAnswerDetail['correctAnswer'],\r\n isCorrect,\r\n explanation: question.explanation,\r\n hint: question.hint,\r\n };\r\n}\r\n\r\n// Calculate total score percentage\r\nexport function calculateScore(answers: QuizAnswerDetail[]): {\r\n score: number;\r\n correctAnswers: number;\r\n totalPoints: number;\r\n earnedPoints: number;\r\n} {\r\n const totalPoints = answers.reduce((sum, a) => sum + a.points, 0);\r\n const earnedPoints = answers.reduce((sum, a) => sum + a.pointsEarned, 0);\r\n const correctAnswers = answers.filter(a => a.isCorrect).length;\r\n const score = totalPoints > 0 ? Math.round((earnedPoints / totalPoints) * 100) : 0;\r\n\r\n return { score, correctAnswers, totalPoints, earnedPoints };\r\n}\r\n\r\n// Format time in seconds to mm:ss\r\nexport function formatTime(seconds: number): string {\r\n const mins = Math.floor(seconds / 60);\r\n const secs = seconds % 60;\r\n return `${mins}:${secs.toString().padStart(2, '0')}`;\r\n}\r\n","import { useState, useEffect, useCallback, useRef } from 'react';\r\nimport type {\r\n QuizPlayerProps,\r\n Quiz,\r\n QuizQuestion,\r\n QuizAnswerDetail,\r\n ExternalQuizAttempt,\r\n QuizResult,\r\n} from './types';\r\nimport { QuizApiClient } from './api';\r\nimport { createAnswerDetail, calculateScore, formatTime } from './utils';\r\n\r\n// Default styles that can be overridden\r\nconst defaultStyles = {\r\n container: {\r\n fontFamily: 'system-ui, -apple-system, sans-serif',\r\n maxWidth: '800px',\r\n margin: '0 auto',\r\n padding: '20px',\r\n backgroundColor: '#ffffff',\r\n borderRadius: '12px',\r\n },\r\n header: {\r\n marginBottom: '20px',\r\n borderBottom: '1px solid #e5e7eb',\r\n paddingBottom: '16px',\r\n },\r\n title: {\r\n fontSize: '24px',\r\n fontWeight: '600',\r\n marginBottom: '8px',\r\n },\r\n progress: {\r\n fontSize: '14px',\r\n color: '#6b7280',\r\n },\r\n progressBar: {\r\n width: '100%',\r\n height: '8px',\r\n backgroundColor: '#e5e7eb',\r\n borderRadius: '4px',\r\n overflow: 'hidden' as const,\r\n marginTop: '8px',\r\n },\r\n progressFill: {\r\n height: '100%',\r\n backgroundColor: '#6721b0',\r\n transition: 'width 0.3s ease',\r\n },\r\n question: {\r\n marginBottom: '24px',\r\n },\r\n questionText: {\r\n fontSize: '18px',\r\n fontWeight: '500',\r\n marginBottom: '16px',\r\n },\r\n options: {\r\n display: 'flex',\r\n flexDirection: 'column' as const,\r\n gap: '8px',\r\n },\r\n option: {\r\n padding: '12px 16px',\r\n border: '2px solid #e5e7eb',\r\n borderRadius: '8px',\r\n cursor: 'pointer',\r\n transition: 'all 0.2s ease',\r\n },\r\n optionSelected: {\r\n borderColor: '#6721b0',\r\n backgroundColor: '#f3e8ff',\r\n },\r\n optionCorrect: {\r\n borderColor: '#22c55e',\r\n backgroundColor: '#f0fdf4',\r\n },\r\n optionIncorrect: {\r\n borderColor: '#ef4444',\r\n backgroundColor: '#fef2f2',\r\n },\r\n input: {\r\n width: '100%',\r\n padding: '12px 16px',\r\n border: '2px solid #e5e7eb',\r\n borderRadius: '8px',\r\n fontSize: '16px',\r\n },\r\n buttons: {\r\n display: 'flex',\r\n justifyContent: 'space-between',\r\n marginTop: '24px',\r\n },\r\n button: {\r\n padding: '12px 24px',\r\n borderRadius: '8px',\r\n fontSize: '16px',\r\n fontWeight: '500',\r\n cursor: 'pointer',\r\n border: 'none',\r\n transition: 'all 0.2s ease',\r\n },\r\n buttonPrimary: {\r\n backgroundColor: '#6721b0',\r\n color: '#ffffff',\r\n },\r\n buttonSecondary: {\r\n backgroundColor: '#f3f4f6',\r\n color: '#374151',\r\n },\r\n buttonDisabled: {\r\n backgroundColor: '#e5e7eb',\r\n color: '#9ca3af',\r\n cursor: 'not-allowed',\r\n },\r\n timer: {\r\n fontSize: '14px',\r\n color: '#6b7280',\r\n marginLeft: '16px',\r\n },\r\n results: {\r\n textAlign: 'center' as const,\r\n padding: '40px 20px',\r\n },\r\n resultScore: {\r\n fontSize: '48px',\r\n fontWeight: '700',\r\n color: '#6721b0',\r\n marginBottom: '8px',\r\n },\r\n resultLabel: {\r\n fontSize: '18px',\r\n color: '#6b7280',\r\n },\r\n loading: {\r\n textAlign: 'center' as const,\r\n padding: '40px',\r\n color: '#6b7280',\r\n },\r\n error: {\r\n textAlign: 'center' as const,\r\n padding: '40px',\r\n color: '#ef4444',\r\n },\r\n};\r\n\r\n// Inline spinner component\r\nfunction Spinner({ size = 16, color = '#ffffff' }: { size?: number; color?: string }) {\r\n return (\r\n <span\r\n style={{\r\n display: 'inline-block',\r\n width: size,\r\n height: size,\r\n border: `2px solid ${color}`,\r\n borderTopColor: 'transparent',\r\n borderRadius: '50%',\r\n animation: 'spin 0.8s linear infinite',\r\n }}\r\n >\r\n <style>\r\n {`@keyframes spin { to { transform: rotate(360deg); } }`}\r\n </style>\r\n </span>\r\n );\r\n}\r\n\r\nexport function QuizPlayer({\r\n quizId,\r\n lessonId,\r\n assignLessonId,\r\n courseId,\r\n childId,\r\n parentId,\r\n apiBaseUrl,\r\n authToken,\r\n onComplete,\r\n onError,\r\n onProgress,\r\n className,\r\n}: QuizPlayerProps) {\r\n const [quiz, setQuiz] = useState<Quiz | null>(null);\r\n const [attempt, setAttempt] = useState<ExternalQuizAttempt | null>(null);\r\n const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0);\r\n const [answers, setAnswers] = useState<Map<string, unknown>>(new Map());\r\n const [answersDetail, setAnswersDetail] = useState<QuizAnswerDetail[]>([]);\r\n const [isSubmitting, setIsSubmitting] = useState(false);\r\n const [isNavigating, setIsNavigating] = useState(false);\r\n const [isCompleted, setIsCompleted] = useState(false);\r\n const [result, setResult] = useState<QuizResult | null>(null);\r\n const [error, setError] = useState<string | null>(null);\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [elapsedSeconds, setElapsedSeconds] = useState(0);\r\n\r\n const apiClient = useRef<QuizApiClient | null>(null);\r\n const timerRef = useRef<ReturnType<typeof setInterval> | null>(null);\r\n const startTimeRef = useRef<number>(Date.now());\r\n\r\n // Initialize API client\r\n useEffect(() => {\r\n apiClient.current = new QuizApiClient({ baseUrl: apiBaseUrl, authToken });\r\n }, [apiBaseUrl, authToken]);\r\n\r\n // Load quiz and create/resume attempt\r\n useEffect(() => {\r\n async function initialize() {\r\n if (!apiClient.current) return;\r\n\r\n try {\r\n setIsLoading(true);\r\n setError(null);\r\n\r\n // Fetch quiz\r\n const quizData = await apiClient.current.getQuiz(quizId);\r\n setQuiz(quizData);\r\n\r\n // Create or resume attempt\r\n const attemptData = await apiClient.current.createAttempt({\r\n quizId,\r\n lessonId,\r\n assignLessonId,\r\n courseId,\r\n childId,\r\n parentId,\r\n });\r\n setAttempt(attemptData);\r\n\r\n // Resume from existing answers if any\r\n if (attemptData.answers && attemptData.answers.length > 0) {\r\n setAnswersDetail(attemptData.answers);\r\n const answersMap = new Map<string, unknown>();\r\n attemptData.answers.forEach(a => {\r\n answersMap.set(a.questionId, a.selectedAnswer);\r\n });\r\n setAnswers(answersMap);\r\n }\r\n\r\n // Check if already completed\r\n if (attemptData.status === 'completed') {\r\n setIsCompleted(true);\r\n const scoreData = calculateScore(attemptData.answers);\r\n setResult({\r\n attemptId: attemptData.id,\r\n score: attemptData.score || scoreData.score,\r\n correctAnswers: attemptData.correctAnswers || scoreData.correctAnswers,\r\n totalQuestions: attemptData.totalQuestions,\r\n answers: attemptData.answers,\r\n timeSpentSeconds: attemptData.timeSpentSeconds || 0,\r\n });\r\n }\r\n\r\n setIsLoading(false);\r\n } catch (err) {\r\n const message = err instanceof Error ? err.message : 'Failed to load quiz';\r\n setError(message);\r\n setIsLoading(false);\r\n onError?.(err instanceof Error ? err : new Error(message));\r\n }\r\n }\r\n\r\n initialize();\r\n }, [quizId, lessonId, assignLessonId, courseId, childId, parentId, onError]);\r\n\r\n // Timer\r\n useEffect(() => {\r\n if (!isLoading && !isCompleted && !error) {\r\n startTimeRef.current = Date.now();\r\n timerRef.current = setInterval(() => {\r\n setElapsedSeconds(Math.floor((Date.now() - startTimeRef.current) / 1000));\r\n }, 1000);\r\n }\r\n\r\n return () => {\r\n if (timerRef.current) {\r\n clearInterval(timerRef.current);\r\n }\r\n };\r\n }, [isLoading, isCompleted, error]);\r\n\r\n // Report progress\r\n useEffect(() => {\r\n if (quiz && onProgress) {\r\n onProgress({\r\n currentQuestion: currentQuestionIndex + 1,\r\n totalQuestions: quiz.questions.length,\r\n answeredQuestions: answers.size,\r\n });\r\n }\r\n }, [currentQuestionIndex, answers.size, quiz, onProgress]);\r\n\r\n const currentQuestion = quiz?.questions[currentQuestionIndex];\r\n\r\n const handleAnswerChange = useCallback((value: unknown) => {\r\n if (!currentQuestion) return;\r\n setAnswers(prev => new Map(prev).set(currentQuestion.id, value));\r\n }, [currentQuestion]);\r\n\r\n const handleNext = useCallback(async () => {\r\n if (!quiz || !attempt || !currentQuestion || !apiClient.current) return;\r\n\r\n const selectedAnswer = answers.get(currentQuestion.id);\r\n if (selectedAnswer === undefined) return;\r\n\r\n setIsNavigating(true);\r\n\r\n // Create answer detail\r\n const answerDetail = createAnswerDetail(currentQuestion, selectedAnswer);\r\n \r\n // Update answers detail state\r\n const newAnswersDetail = [...answersDetail];\r\n const existingIdx = newAnswersDetail.findIndex(a => a.questionId === currentQuestion.id);\r\n if (existingIdx >= 0) {\r\n newAnswersDetail[existingIdx] = answerDetail;\r\n } else {\r\n newAnswersDetail.push(answerDetail);\r\n }\r\n setAnswersDetail(newAnswersDetail);\r\n\r\n // Save progress to server\r\n try {\r\n await apiClient.current.updateAttempt(attempt.id, {\r\n answers: newAnswersDetail,\r\n });\r\n } catch (err) {\r\n console.error('Failed to save progress:', err);\r\n } finally {\r\n setIsNavigating(false);\r\n }\r\n\r\n // Move to next question\r\n if (currentQuestionIndex < quiz.questions.length - 1) {\r\n setCurrentQuestionIndex(prev => prev + 1);\r\n }\r\n }, [quiz, attempt, currentQuestion, answers, answersDetail, currentQuestionIndex]);\r\n\r\n const handlePrevious = useCallback(() => {\r\n if (currentQuestionIndex > 0) {\r\n setCurrentQuestionIndex(prev => prev - 1);\r\n }\r\n }, [currentQuestionIndex]);\r\n\r\n const handleSubmit = useCallback(async () => {\r\n if (!quiz || !attempt || !apiClient.current) return;\r\n\r\n setIsSubmitting(true);\r\n\r\n try {\r\n // Ensure current answer is saved\r\n const currentAnswer = currentQuestion ? answers.get(currentQuestion.id) : undefined;\r\n let finalAnswersDetail = [...answersDetail];\r\n \r\n if (currentQuestion && currentAnswer !== undefined) {\r\n const answerDetail = createAnswerDetail(currentQuestion, currentAnswer);\r\n const existingIdx = finalAnswersDetail.findIndex(a => a.questionId === currentQuestion.id);\r\n if (existingIdx >= 0) {\r\n finalAnswersDetail[existingIdx] = answerDetail;\r\n } else {\r\n finalAnswersDetail.push(answerDetail);\r\n }\r\n }\r\n\r\n // Calculate final score\r\n const scoreData = calculateScore(finalAnswersDetail);\r\n const timeSpent = Math.floor((Date.now() - startTimeRef.current) / 1000);\r\n\r\n // Submit to server\r\n const updatedAttempt = await apiClient.current.updateAttempt(attempt.id, {\r\n answers: finalAnswersDetail,\r\n status: 'completed',\r\n score: scoreData.score,\r\n correctAnswers: scoreData.correctAnswers,\r\n timeSpentSeconds: timeSpent,\r\n });\r\n\r\n // Update state\r\n setIsCompleted(true);\r\n const quizResult: QuizResult = {\r\n attemptId: updatedAttempt.id,\r\n score: scoreData.score,\r\n correctAnswers: scoreData.correctAnswers,\r\n totalQuestions: quiz.questions.length,\r\n answers: finalAnswersDetail,\r\n timeSpentSeconds: timeSpent,\r\n };\r\n setResult(quizResult);\r\n\r\n // Stop timer\r\n if (timerRef.current) {\r\n clearInterval(timerRef.current);\r\n }\r\n\r\n // Callback\r\n onComplete?.(quizResult);\r\n } catch (err) {\r\n const message = err instanceof Error ? err.message : 'Failed to submit quiz';\r\n setError(message);\r\n onError?.(err instanceof Error ? err : new Error(message));\r\n } finally {\r\n setIsSubmitting(false);\r\n }\r\n }, [quiz, attempt, currentQuestion, answers, answersDetail, onComplete, onError]);\r\n\r\n // Render loading state\r\n if (isLoading) {\r\n return (\r\n <div className={className} style={defaultStyles.container}>\r\n <div style={defaultStyles.loading}>Loading quiz...</div>\r\n </div>\r\n );\r\n }\r\n\r\n // Render error state\r\n if (error) {\r\n return (\r\n <div className={className} style={defaultStyles.container}>\r\n <div style={defaultStyles.error}>\r\n <p>Error: {error}</p>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n // Render completed state\r\n if (isCompleted && result) {\r\n return (\r\n <div className={className} style={defaultStyles.container}>\r\n <div style={defaultStyles.results}>\r\n <div style={defaultStyles.resultScore}>{result.score}%</div>\r\n <div style={defaultStyles.resultLabel}>\r\n {result.correctAnswers} of {result.totalQuestions} correct\r\n </div>\r\n <div style={{ ...defaultStyles.resultLabel, marginTop: '8px' }}>\r\n Time: {formatTime(result.timeSpentSeconds)}\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n // Render quiz\r\n if (!quiz || !currentQuestion) {\r\n return (\r\n <div className={className} style={defaultStyles.container}>\r\n <div style={defaultStyles.error}>No quiz data available</div>\r\n </div>\r\n );\r\n }\r\n\r\n const selectedAnswer = answers.get(currentQuestion.id);\r\n const isLastQuestion = currentQuestionIndex === quiz.questions.length - 1;\r\n const progressPercent = ((currentQuestionIndex + 1) / quiz.questions.length) * 100;\r\n\r\n return (\r\n <div className={className} style={defaultStyles.container}>\r\n {/* Header */}\r\n <div style={defaultStyles.header}>\r\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>\r\n <div style={defaultStyles.title}>{quiz.title}</div>\r\n <div style={defaultStyles.timer}>{formatTime(elapsedSeconds)}</div>\r\n </div>\r\n <div style={defaultStyles.progress}>\r\n Question {currentQuestionIndex + 1} of {quiz.questions.length}\r\n </div>\r\n <div style={defaultStyles.progressBar}>\r\n <div style={{ ...defaultStyles.progressFill, width: `${progressPercent}%` }} />\r\n </div>\r\n </div>\r\n\r\n {/* Question */}\r\n <div style={defaultStyles.question}>\r\n <div style={defaultStyles.questionText}>{currentQuestion.question}</div>\r\n\r\n {/* Render options based on question type */}\r\n {(currentQuestion.type === 'single' || currentQuestion.type === 'true-false') && (\r\n <div style={defaultStyles.options}>\r\n {currentQuestion.options?.map((option, idx) => (\r\n <div\r\n key={idx}\r\n style={{\r\n ...defaultStyles.option,\r\n ...(selectedAnswer === option ? defaultStyles.optionSelected : {}),\r\n }}\r\n onClick={() => handleAnswerChange(option)}\r\n >\r\n {option}\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n\r\n {currentQuestion.type === 'multiple' && (\r\n <div style={defaultStyles.options}>\r\n {currentQuestion.options?.map((option, idx) => {\r\n const selected = Array.isArray(selectedAnswer) && selectedAnswer.includes(option);\r\n return (\r\n <div\r\n key={idx}\r\n style={{\r\n ...defaultStyles.option,\r\n ...(selected ? defaultStyles.optionSelected : {}),\r\n }}\r\n onClick={() => {\r\n const current = Array.isArray(selectedAnswer) ? selectedAnswer : [];\r\n if (selected) {\r\n handleAnswerChange(current.filter(o => o !== option));\r\n } else {\r\n handleAnswerChange([...current, option]);\r\n }\r\n }}\r\n >\r\n {option}\r\n </div>\r\n );\r\n })}\r\n </div>\r\n )}\r\n\r\n {(currentQuestion.type === 'free' || currentQuestion.type === 'essay') && (\r\n <textarea\r\n style={{ ...defaultStyles.input, minHeight: currentQuestion.type === 'essay' ? '150px' : '60px' }}\r\n value={(selectedAnswer as string) || ''}\r\n onChange={e => handleAnswerChange(e.target.value)}\r\n placeholder=\"Type your answer here...\"\r\n />\r\n )}\r\n\r\n {currentQuestion.type === 'fill' && (\r\n <div style={defaultStyles.options}>\r\n {currentQuestion.blanks?.map((_, idx) => (\r\n <input\r\n key={idx}\r\n style={defaultStyles.input}\r\n value={(Array.isArray(selectedAnswer) ? selectedAnswer[idx] : '') || ''}\r\n onChange={e => {\r\n const current = Array.isArray(selectedAnswer) ? [...selectedAnswer] : [];\r\n current[idx] = e.target.value;\r\n handleAnswerChange(current);\r\n }}\r\n placeholder={`Blank ${idx + 1}`}\r\n />\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Navigation buttons */}\r\n <div style={defaultStyles.buttons}>\r\n <button\r\n style={{\r\n ...defaultStyles.button,\r\n ...(currentQuestionIndex > 0 ? defaultStyles.buttonSecondary : defaultStyles.buttonDisabled),\r\n }}\r\n onClick={handlePrevious}\r\n disabled={currentQuestionIndex === 0}\r\n >\r\n Previous\r\n </button>\r\n\r\n {isLastQuestion ? (\r\n <button\r\n style={{\r\n ...defaultStyles.button,\r\n ...(isSubmitting ? defaultStyles.buttonDisabled : defaultStyles.buttonPrimary),\r\n }}\r\n onClick={handleSubmit}\r\n disabled={isSubmitting || selectedAnswer === undefined}\r\n >\r\n {isSubmitting ? <Spinner size={16} color=\"#9ca3af\" /> : 'Submit Quiz'}\r\n </button>\r\n ) : (\r\n <button\r\n style={{\r\n ...defaultStyles.button,\r\n ...(isNavigating || selectedAnswer === undefined ? defaultStyles.buttonDisabled : defaultStyles.buttonPrimary),\r\n }}\r\n onClick={handleNext}\r\n disabled={isNavigating || selectedAnswer === undefined}\r\n >\r\n {isNavigating ? <Spinner size={16} color=\"#9ca3af\" /> : 'Next'}\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import { useState, useEffect } from 'react';\r\nimport type {\r\n AttemptViewerProps,\r\n ExternalQuizAttempt,\r\n QuizAnswerDetail,\r\n} from './types';\r\nimport { QuizApiClient } from './api';\r\nimport { formatTime } from './utils';\r\n\r\nconst defaultStyles = {\r\n container: {\r\n fontFamily: 'system-ui, -apple-system, sans-serif',\r\n width: '100%',\r\n padding: '20px',\r\n backgroundColor: '#ffffff',\r\n borderRadius: '12px',\r\n boxSizing: 'border-box' as const,\r\n },\r\n header: {\r\n marginBottom: '24px',\r\n borderBottom: '1px solid #e5e7eb',\r\n paddingBottom: '20px',\r\n },\r\n title: {\r\n fontSize: '24px',\r\n fontWeight: '600',\r\n marginBottom: '16px',\r\n color: '#111827',\r\n },\r\n summaryGrid: {\r\n display: 'grid',\r\n gridTemplateColumns: 'repeat(auto-fit, minmax(120px, 1fr))',\r\n gap: '16px',\r\n },\r\n summaryCard: {\r\n padding: '12px',\r\n backgroundColor: '#f9fafb',\r\n borderRadius: '8px',\r\n textAlign: 'center' as const,\r\n },\r\n summaryValue: {\r\n fontSize: '20px',\r\n fontWeight: '600',\r\n color: '#6721b0',\r\n marginBottom: '2px',\r\n },\r\n summaryLabel: {\r\n fontSize: '10px',\r\n color: '#6b7280',\r\n textTransform: 'uppercase' as const,\r\n letterSpacing: '0.05em',\r\n },\r\n questionsList: {\r\n display: 'flex',\r\n flexDirection: 'column' as const,\r\n gap: '16px',\r\n },\r\n questionCard: {\r\n padding: '16px',\r\n border: '2px solid #e5e7eb',\r\n borderRadius: '8px',\r\n },\r\n questionCardCorrect: {\r\n borderColor: '#22c55e',\r\n backgroundColor: '#f0fdf4',\r\n },\r\n questionCardIncorrect: {\r\n borderColor: '#ef4444',\r\n backgroundColor: '#fef2f2',\r\n },\r\n questionHeader: {\r\n display: 'flex',\r\n justifyContent: 'space-between',\r\n alignItems: 'flex-start',\r\n marginBottom: '12px',\r\n },\r\n questionNumber: {\r\n fontSize: '12px',\r\n color: '#6b7280',\r\n fontWeight: '500',\r\n },\r\n questionBadge: {\r\n padding: '4px 8px',\r\n borderRadius: '4px',\r\n fontSize: '12px',\r\n fontWeight: '600',\r\n },\r\n badgeCorrect: {\r\n backgroundColor: '#dcfce7',\r\n color: '#166534',\r\n },\r\n badgeIncorrect: {\r\n backgroundColor: '#fee2e2',\r\n color: '#991b1b',\r\n },\r\n questionText: {\r\n fontSize: '16px',\r\n fontWeight: '500',\r\n marginBottom: '12px',\r\n color: '#111827',\r\n },\r\n answerSection: {\r\n fontSize: '14px',\r\n marginBottom: '8px',\r\n },\r\n answerLabel: {\r\n fontWeight: '600',\r\n color: '#6b7280',\r\n marginRight: '8px',\r\n },\r\n studentAnswer: {\r\n color: '#111827',\r\n },\r\n correctAnswer: {\r\n color: '#166534',\r\n },\r\n points: {\r\n fontSize: '13px',\r\n color: '#6b7280',\r\n marginTop: '8px',\r\n },\r\n explanation: {\r\n marginTop: '12px',\r\n padding: '12px',\r\n backgroundColor: '#f3e8ff',\r\n borderRadius: '6px',\r\n fontSize: '14px',\r\n color: '#581c87',\r\n },\r\n loading: {\r\n textAlign: 'center' as const,\r\n padding: '40px 20px',\r\n },\r\n spinner: {\r\n display: 'inline-block',\r\n width: '32px',\r\n height: '32px',\r\n border: '3px solid #e5e7eb',\r\n borderTopColor: '#6721b0',\r\n borderRadius: '50%',\r\n animation: 'spin 1s linear infinite',\r\n },\r\n error: {\r\n textAlign: 'center' as const,\r\n padding: '40px 20px',\r\n color: '#ef4444',\r\n },\r\n retryButton: {\r\n marginTop: '16px',\r\n padding: '12px 24px',\r\n backgroundColor: '#6721b0',\r\n color: '#ffffff',\r\n border: 'none',\r\n borderRadius: '8px',\r\n fontSize: '16px',\r\n fontWeight: '500',\r\n cursor: 'pointer',\r\n },\r\n};\r\n\r\nconst spinnerKeyframes = `\r\n @keyframes spin {\r\n to { transform: rotate(360deg); }\r\n }\r\n`;\r\n\r\nfunction formatAnswer(answer: unknown): string {\r\n if (answer === null || answer === undefined) {\r\n return 'No answer';\r\n }\r\n if (typeof answer === 'string') {\r\n return answer;\r\n }\r\n if (Array.isArray(answer)) {\r\n return answer.join(', ');\r\n }\r\n if (typeof answer === 'object') {\r\n return Object.entries(answer as Record<string, string>)\r\n .map(([k, v]) => `${k} → ${v}`)\r\n .join(', ');\r\n }\r\n return String(answer);\r\n}\r\n\r\nexport function AttemptViewer({\r\n attemptId,\r\n apiBaseUrl,\r\n authToken,\r\n onError,\r\n className,\r\n showExplanations = true,\r\n title,\r\n}: AttemptViewerProps) {\r\n const [attempt, setAttempt] = useState<ExternalQuizAttempt | null>(null);\r\n const [loading, setLoading] = useState(true);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n useEffect(() => {\r\n const apiClient = new QuizApiClient({\r\n baseUrl: apiBaseUrl,\r\n authToken,\r\n });\r\n\r\n async function fetchAttempt() {\r\n setLoading(true);\r\n setError(null);\r\n try {\r\n const response = await fetch(`${apiBaseUrl}/api/external/quiz-attempts/${attemptId}`, {\r\n headers: authToken ? { Authorization: `Bearer ${authToken}` } : {},\r\n });\r\n if (!response.ok) {\r\n throw new Error(`Failed to fetch attempt: ${response.statusText}`);\r\n }\r\n const data = await response.json();\r\n setAttempt(data);\r\n } catch (err) {\r\n const errorMessage = err instanceof Error ? err.message : 'Failed to load attempt';\r\n setError(errorMessage);\r\n onError?.(err instanceof Error ? err : new Error(errorMessage));\r\n } finally {\r\n setLoading(false);\r\n }\r\n }\r\n\r\n fetchAttempt();\r\n }, [attemptId, apiBaseUrl, authToken, onError]);\r\n\r\n const handleRetry = () => {\r\n setLoading(true);\r\n setError(null);\r\n window.location.reload();\r\n };\r\n\r\n if (loading) {\r\n return (\r\n <div style={defaultStyles.container} className={className}>\r\n <style>{spinnerKeyframes}</style>\r\n <div style={defaultStyles.loading}>\r\n <div style={defaultStyles.spinner} />\r\n <p style={{ marginTop: '16px', color: '#6b7280' }}>Loading attempt...</p>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n if (error || !attempt) {\r\n return (\r\n <div style={defaultStyles.container} className={className}>\r\n <div style={defaultStyles.error}>\r\n <p style={{ fontSize: '18px', fontWeight: '500' }}>Failed to load attempt</p>\r\n <p style={{ marginTop: '8px', color: '#6b7280' }}>{error}</p>\r\n <button style={defaultStyles.retryButton} onClick={handleRetry}>\r\n Try Again\r\n </button>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n const scorePercentage = attempt.score ?? 0;\r\n const correctCount = attempt.correctAnswers ?? 0;\r\n const totalQuestions = attempt.totalQuestions;\r\n const timeSpent = attempt.timeSpentSeconds ?? 0;\r\n\r\n return (\r\n <div style={defaultStyles.container} className={className}>\r\n <style>{spinnerKeyframes}</style>\r\n \r\n <div style={defaultStyles.header}>\r\n <div style={defaultStyles.summaryGrid}>\r\n <div style={defaultStyles.summaryCard}>\r\n <div style={defaultStyles.summaryValue}>{scorePercentage}%</div>\r\n <div style={defaultStyles.summaryLabel}>Score</div>\r\n </div>\r\n <div style={defaultStyles.summaryCard}>\r\n <div style={defaultStyles.summaryValue}>{correctCount}/{totalQuestions}</div>\r\n <div style={defaultStyles.summaryLabel}>Correct</div>\r\n </div>\r\n <div style={defaultStyles.summaryCard}>\r\n <div style={defaultStyles.summaryValue}>{formatTime(timeSpent)}</div>\r\n <div style={defaultStyles.summaryLabel}>Time</div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div style={defaultStyles.questionsList}>\r\n {attempt.answers.map((answer: QuizAnswerDetail, index: number) => (\r\n <div\r\n key={answer.questionId}\r\n style={{\r\n ...defaultStyles.questionCard,\r\n ...(answer.isCorrect ? defaultStyles.questionCardCorrect : defaultStyles.questionCardIncorrect),\r\n }}\r\n >\r\n <div style={defaultStyles.questionHeader}>\r\n <span style={defaultStyles.questionNumber}>Question {index + 1}</span>\r\n <span\r\n style={{\r\n ...defaultStyles.questionBadge,\r\n ...(answer.isCorrect ? defaultStyles.badgeCorrect : defaultStyles.badgeIncorrect),\r\n }}\r\n >\r\n {answer.isCorrect ? 'Correct' : 'Incorrect'}\r\n </span>\r\n </div>\r\n\r\n <div style={defaultStyles.questionText}>{answer.questionText}</div>\r\n\r\n <div style={defaultStyles.answerSection}>\r\n <span style={defaultStyles.answerLabel}>Your answer:</span>\r\n <span style={defaultStyles.studentAnswer}>\r\n {formatAnswer(answer.selectedAnswer)}\r\n </span>\r\n </div>\r\n\r\n {!answer.isCorrect && answer.correctAnswer && (\r\n <div style={defaultStyles.answerSection}>\r\n <span style={defaultStyles.answerLabel}>Correct answer:</span>\r\n <span style={defaultStyles.correctAnswer}>\r\n {formatAnswer(answer.correctAnswer)}\r\n </span>\r\n </div>\r\n )}\r\n\r\n <div style={defaultStyles.points}>\r\n {answer.pointsEarned} / {answer.points} points\r\n </div>\r\n\r\n {showExplanations && answer.explanation && (\r\n <div style={defaultStyles.explanation}>\r\n <strong>Explanation:</strong> {answer.explanation}\r\n </div>\r\n )}\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n );\r\n}\r\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -612,7 +612,308 @@ function QuizPlayer({
|
|
|
612
612
|
] })
|
|
613
613
|
] });
|
|
614
614
|
}
|
|
615
|
+
var defaultStyles2 = {
|
|
616
|
+
container: {
|
|
617
|
+
fontFamily: "system-ui, -apple-system, sans-serif",
|
|
618
|
+
width: "100%",
|
|
619
|
+
padding: "20px",
|
|
620
|
+
backgroundColor: "#ffffff",
|
|
621
|
+
borderRadius: "12px",
|
|
622
|
+
boxSizing: "border-box"
|
|
623
|
+
},
|
|
624
|
+
header: {
|
|
625
|
+
marginBottom: "24px",
|
|
626
|
+
borderBottom: "1px solid #e5e7eb",
|
|
627
|
+
paddingBottom: "20px"
|
|
628
|
+
},
|
|
629
|
+
summaryGrid: {
|
|
630
|
+
display: "grid",
|
|
631
|
+
gridTemplateColumns: "repeat(auto-fit, minmax(120px, 1fr))",
|
|
632
|
+
gap: "16px"
|
|
633
|
+
},
|
|
634
|
+
summaryCard: {
|
|
635
|
+
padding: "12px",
|
|
636
|
+
backgroundColor: "#f9fafb",
|
|
637
|
+
borderRadius: "8px",
|
|
638
|
+
textAlign: "center"
|
|
639
|
+
},
|
|
640
|
+
summaryValue: {
|
|
641
|
+
fontSize: "20px",
|
|
642
|
+
fontWeight: "600",
|
|
643
|
+
color: "#6721b0",
|
|
644
|
+
marginBottom: "2px"
|
|
645
|
+
},
|
|
646
|
+
summaryLabel: {
|
|
647
|
+
fontSize: "10px",
|
|
648
|
+
color: "#6b7280",
|
|
649
|
+
textTransform: "uppercase",
|
|
650
|
+
letterSpacing: "0.05em"
|
|
651
|
+
},
|
|
652
|
+
questionsList: {
|
|
653
|
+
display: "flex",
|
|
654
|
+
flexDirection: "column",
|
|
655
|
+
gap: "16px"
|
|
656
|
+
},
|
|
657
|
+
questionCard: {
|
|
658
|
+
padding: "16px",
|
|
659
|
+
border: "2px solid #e5e7eb",
|
|
660
|
+
borderRadius: "8px"
|
|
661
|
+
},
|
|
662
|
+
questionCardCorrect: {
|
|
663
|
+
borderColor: "#22c55e",
|
|
664
|
+
backgroundColor: "#f0fdf4"
|
|
665
|
+
},
|
|
666
|
+
questionCardIncorrect: {
|
|
667
|
+
borderColor: "#ef4444",
|
|
668
|
+
backgroundColor: "#fef2f2"
|
|
669
|
+
},
|
|
670
|
+
questionHeader: {
|
|
671
|
+
display: "flex",
|
|
672
|
+
justifyContent: "space-between",
|
|
673
|
+
alignItems: "flex-start",
|
|
674
|
+
marginBottom: "12px"
|
|
675
|
+
},
|
|
676
|
+
questionNumber: {
|
|
677
|
+
fontSize: "12px",
|
|
678
|
+
color: "#6b7280",
|
|
679
|
+
fontWeight: "500"
|
|
680
|
+
},
|
|
681
|
+
questionBadge: {
|
|
682
|
+
padding: "4px 8px",
|
|
683
|
+
borderRadius: "4px",
|
|
684
|
+
fontSize: "12px",
|
|
685
|
+
fontWeight: "600"
|
|
686
|
+
},
|
|
687
|
+
badgeCorrect: {
|
|
688
|
+
backgroundColor: "#dcfce7",
|
|
689
|
+
color: "#166534"
|
|
690
|
+
},
|
|
691
|
+
badgeIncorrect: {
|
|
692
|
+
backgroundColor: "#fee2e2",
|
|
693
|
+
color: "#991b1b"
|
|
694
|
+
},
|
|
695
|
+
questionText: {
|
|
696
|
+
fontSize: "16px",
|
|
697
|
+
fontWeight: "500",
|
|
698
|
+
marginBottom: "12px",
|
|
699
|
+
color: "#111827"
|
|
700
|
+
},
|
|
701
|
+
answerSection: {
|
|
702
|
+
fontSize: "14px",
|
|
703
|
+
marginBottom: "8px"
|
|
704
|
+
},
|
|
705
|
+
answerLabel: {
|
|
706
|
+
fontWeight: "600",
|
|
707
|
+
color: "#6b7280",
|
|
708
|
+
marginRight: "8px"
|
|
709
|
+
},
|
|
710
|
+
studentAnswer: {
|
|
711
|
+
color: "#111827"
|
|
712
|
+
},
|
|
713
|
+
correctAnswer: {
|
|
714
|
+
color: "#166534"
|
|
715
|
+
},
|
|
716
|
+
points: {
|
|
717
|
+
fontSize: "13px",
|
|
718
|
+
color: "#6b7280",
|
|
719
|
+
marginTop: "8px"
|
|
720
|
+
},
|
|
721
|
+
explanation: {
|
|
722
|
+
marginTop: "12px",
|
|
723
|
+
padding: "12px",
|
|
724
|
+
backgroundColor: "#f3e8ff",
|
|
725
|
+
borderRadius: "6px",
|
|
726
|
+
fontSize: "14px",
|
|
727
|
+
color: "#581c87"
|
|
728
|
+
},
|
|
729
|
+
loading: {
|
|
730
|
+
textAlign: "center",
|
|
731
|
+
padding: "40px 20px"
|
|
732
|
+
},
|
|
733
|
+
spinner: {
|
|
734
|
+
display: "inline-block",
|
|
735
|
+
width: "32px",
|
|
736
|
+
height: "32px",
|
|
737
|
+
border: "3px solid #e5e7eb",
|
|
738
|
+
borderTopColor: "#6721b0",
|
|
739
|
+
borderRadius: "50%",
|
|
740
|
+
animation: "spin 1s linear infinite"
|
|
741
|
+
},
|
|
742
|
+
error: {
|
|
743
|
+
textAlign: "center",
|
|
744
|
+
padding: "40px 20px",
|
|
745
|
+
color: "#ef4444"
|
|
746
|
+
},
|
|
747
|
+
retryButton: {
|
|
748
|
+
marginTop: "16px",
|
|
749
|
+
padding: "12px 24px",
|
|
750
|
+
backgroundColor: "#6721b0",
|
|
751
|
+
color: "#ffffff",
|
|
752
|
+
border: "none",
|
|
753
|
+
borderRadius: "8px",
|
|
754
|
+
fontSize: "16px",
|
|
755
|
+
fontWeight: "500",
|
|
756
|
+
cursor: "pointer"
|
|
757
|
+
}
|
|
758
|
+
};
|
|
759
|
+
var spinnerKeyframes = `
|
|
760
|
+
@keyframes spin {
|
|
761
|
+
to { transform: rotate(360deg); }
|
|
762
|
+
}
|
|
763
|
+
`;
|
|
764
|
+
function formatAnswer(answer) {
|
|
765
|
+
if (answer === null || answer === void 0) {
|
|
766
|
+
return "No answer";
|
|
767
|
+
}
|
|
768
|
+
if (typeof answer === "string") {
|
|
769
|
+
return answer;
|
|
770
|
+
}
|
|
771
|
+
if (Array.isArray(answer)) {
|
|
772
|
+
return answer.join(", ");
|
|
773
|
+
}
|
|
774
|
+
if (typeof answer === "object") {
|
|
775
|
+
return Object.entries(answer).map(([k, v]) => `${k} \u2192 ${v}`).join(", ");
|
|
776
|
+
}
|
|
777
|
+
return String(answer);
|
|
778
|
+
}
|
|
779
|
+
function AttemptViewer({
|
|
780
|
+
attemptId,
|
|
781
|
+
apiBaseUrl,
|
|
782
|
+
authToken,
|
|
783
|
+
onError,
|
|
784
|
+
className,
|
|
785
|
+
showExplanations = true,
|
|
786
|
+
title
|
|
787
|
+
}) {
|
|
788
|
+
const [attempt, setAttempt] = useState(null);
|
|
789
|
+
const [loading, setLoading] = useState(true);
|
|
790
|
+
const [error, setError] = useState(null);
|
|
791
|
+
useEffect(() => {
|
|
792
|
+
new QuizApiClient({
|
|
793
|
+
baseUrl: apiBaseUrl,
|
|
794
|
+
authToken
|
|
795
|
+
});
|
|
796
|
+
async function fetchAttempt() {
|
|
797
|
+
setLoading(true);
|
|
798
|
+
setError(null);
|
|
799
|
+
try {
|
|
800
|
+
const response = await fetch(`${apiBaseUrl}/api/external/quiz-attempts/${attemptId}`, {
|
|
801
|
+
headers: authToken ? { Authorization: `Bearer ${authToken}` } : {}
|
|
802
|
+
});
|
|
803
|
+
if (!response.ok) {
|
|
804
|
+
throw new Error(`Failed to fetch attempt: ${response.statusText}`);
|
|
805
|
+
}
|
|
806
|
+
const data = await response.json();
|
|
807
|
+
setAttempt(data);
|
|
808
|
+
} catch (err) {
|
|
809
|
+
const errorMessage = err instanceof Error ? err.message : "Failed to load attempt";
|
|
810
|
+
setError(errorMessage);
|
|
811
|
+
onError?.(err instanceof Error ? err : new Error(errorMessage));
|
|
812
|
+
} finally {
|
|
813
|
+
setLoading(false);
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
fetchAttempt();
|
|
817
|
+
}, [attemptId, apiBaseUrl, authToken, onError]);
|
|
818
|
+
const handleRetry = () => {
|
|
819
|
+
setLoading(true);
|
|
820
|
+
setError(null);
|
|
821
|
+
window.location.reload();
|
|
822
|
+
};
|
|
823
|
+
if (loading) {
|
|
824
|
+
return /* @__PURE__ */ jsxs("div", { style: defaultStyles2.container, className, children: [
|
|
825
|
+
/* @__PURE__ */ jsx("style", { children: spinnerKeyframes }),
|
|
826
|
+
/* @__PURE__ */ jsxs("div", { style: defaultStyles2.loading, children: [
|
|
827
|
+
/* @__PURE__ */ jsx("div", { style: defaultStyles2.spinner }),
|
|
828
|
+
/* @__PURE__ */ jsx("p", { style: { marginTop: "16px", color: "#6b7280" }, children: "Loading attempt..." })
|
|
829
|
+
] })
|
|
830
|
+
] });
|
|
831
|
+
}
|
|
832
|
+
if (error || !attempt) {
|
|
833
|
+
return /* @__PURE__ */ jsx("div", { style: defaultStyles2.container, className, children: /* @__PURE__ */ jsxs("div", { style: defaultStyles2.error, children: [
|
|
834
|
+
/* @__PURE__ */ jsx("p", { style: { fontSize: "18px", fontWeight: "500" }, children: "Failed to load attempt" }),
|
|
835
|
+
/* @__PURE__ */ jsx("p", { style: { marginTop: "8px", color: "#6b7280" }, children: error }),
|
|
836
|
+
/* @__PURE__ */ jsx("button", { style: defaultStyles2.retryButton, onClick: handleRetry, children: "Try Again" })
|
|
837
|
+
] }) });
|
|
838
|
+
}
|
|
839
|
+
const scorePercentage = attempt.score ?? 0;
|
|
840
|
+
const correctCount = attempt.correctAnswers ?? 0;
|
|
841
|
+
const totalQuestions = attempt.totalQuestions;
|
|
842
|
+
const timeSpent = attempt.timeSpentSeconds ?? 0;
|
|
843
|
+
return /* @__PURE__ */ jsxs("div", { style: defaultStyles2.container, className, children: [
|
|
844
|
+
/* @__PURE__ */ jsx("style", { children: spinnerKeyframes }),
|
|
845
|
+
/* @__PURE__ */ jsx("div", { style: defaultStyles2.header, children: /* @__PURE__ */ jsxs("div", { style: defaultStyles2.summaryGrid, children: [
|
|
846
|
+
/* @__PURE__ */ jsxs("div", { style: defaultStyles2.summaryCard, children: [
|
|
847
|
+
/* @__PURE__ */ jsxs("div", { style: defaultStyles2.summaryValue, children: [
|
|
848
|
+
scorePercentage,
|
|
849
|
+
"%"
|
|
850
|
+
] }),
|
|
851
|
+
/* @__PURE__ */ jsx("div", { style: defaultStyles2.summaryLabel, children: "Score" })
|
|
852
|
+
] }),
|
|
853
|
+
/* @__PURE__ */ jsxs("div", { style: defaultStyles2.summaryCard, children: [
|
|
854
|
+
/* @__PURE__ */ jsxs("div", { style: defaultStyles2.summaryValue, children: [
|
|
855
|
+
correctCount,
|
|
856
|
+
"/",
|
|
857
|
+
totalQuestions
|
|
858
|
+
] }),
|
|
859
|
+
/* @__PURE__ */ jsx("div", { style: defaultStyles2.summaryLabel, children: "Correct" })
|
|
860
|
+
] }),
|
|
861
|
+
/* @__PURE__ */ jsxs("div", { style: defaultStyles2.summaryCard, children: [
|
|
862
|
+
/* @__PURE__ */ jsx("div", { style: defaultStyles2.summaryValue, children: formatTime(timeSpent) }),
|
|
863
|
+
/* @__PURE__ */ jsx("div", { style: defaultStyles2.summaryLabel, children: "Time" })
|
|
864
|
+
] })
|
|
865
|
+
] }) }),
|
|
866
|
+
/* @__PURE__ */ jsx("div", { style: defaultStyles2.questionsList, children: attempt.answers.map((answer, index) => /* @__PURE__ */ jsxs(
|
|
867
|
+
"div",
|
|
868
|
+
{
|
|
869
|
+
style: {
|
|
870
|
+
...defaultStyles2.questionCard,
|
|
871
|
+
...answer.isCorrect ? defaultStyles2.questionCardCorrect : defaultStyles2.questionCardIncorrect
|
|
872
|
+
},
|
|
873
|
+
children: [
|
|
874
|
+
/* @__PURE__ */ jsxs("div", { style: defaultStyles2.questionHeader, children: [
|
|
875
|
+
/* @__PURE__ */ jsxs("span", { style: defaultStyles2.questionNumber, children: [
|
|
876
|
+
"Question ",
|
|
877
|
+
index + 1
|
|
878
|
+
] }),
|
|
879
|
+
/* @__PURE__ */ jsx(
|
|
880
|
+
"span",
|
|
881
|
+
{
|
|
882
|
+
style: {
|
|
883
|
+
...defaultStyles2.questionBadge,
|
|
884
|
+
...answer.isCorrect ? defaultStyles2.badgeCorrect : defaultStyles2.badgeIncorrect
|
|
885
|
+
},
|
|
886
|
+
children: answer.isCorrect ? "Correct" : "Incorrect"
|
|
887
|
+
}
|
|
888
|
+
)
|
|
889
|
+
] }),
|
|
890
|
+
/* @__PURE__ */ jsx("div", { style: defaultStyles2.questionText, children: answer.questionText }),
|
|
891
|
+
/* @__PURE__ */ jsxs("div", { style: defaultStyles2.answerSection, children: [
|
|
892
|
+
/* @__PURE__ */ jsx("span", { style: defaultStyles2.answerLabel, children: "Your answer:" }),
|
|
893
|
+
/* @__PURE__ */ jsx("span", { style: defaultStyles2.studentAnswer, children: formatAnswer(answer.selectedAnswer) })
|
|
894
|
+
] }),
|
|
895
|
+
!answer.isCorrect && answer.correctAnswer && /* @__PURE__ */ jsxs("div", { style: defaultStyles2.answerSection, children: [
|
|
896
|
+
/* @__PURE__ */ jsx("span", { style: defaultStyles2.answerLabel, children: "Correct answer:" }),
|
|
897
|
+
/* @__PURE__ */ jsx("span", { style: defaultStyles2.correctAnswer, children: formatAnswer(answer.correctAnswer) })
|
|
898
|
+
] }),
|
|
899
|
+
/* @__PURE__ */ jsxs("div", { style: defaultStyles2.points, children: [
|
|
900
|
+
answer.pointsEarned,
|
|
901
|
+
" / ",
|
|
902
|
+
answer.points,
|
|
903
|
+
" points"
|
|
904
|
+
] }),
|
|
905
|
+
showExplanations && answer.explanation && /* @__PURE__ */ jsxs("div", { style: defaultStyles2.explanation, children: [
|
|
906
|
+
/* @__PURE__ */ jsx("strong", { children: "Explanation:" }),
|
|
907
|
+
" ",
|
|
908
|
+
answer.explanation
|
|
909
|
+
] })
|
|
910
|
+
]
|
|
911
|
+
},
|
|
912
|
+
answer.questionId
|
|
913
|
+
)) })
|
|
914
|
+
] });
|
|
915
|
+
}
|
|
615
916
|
|
|
616
|
-
export { QuizApiClient, QuizPlayer, calculateScore, checkAnswer, createAnswerDetail, formatTime };
|
|
917
|
+
export { AttemptViewer, QuizApiClient, QuizPlayer, calculateScore, checkAnswer, createAnswerDetail, formatTime };
|
|
617
918
|
//# sourceMappingURL=index.mjs.map
|
|
618
919
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/api.ts","../src/utils.ts","../src/QuizPlayer.tsx"],"names":["selectedAnswer"],"mappings":"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","file":"index.mjs","sourcesContent":["import type { Quiz, ExternalQuizAttempt, QuizAnswerDetail } from './types';\r\n\r\nexport interface ApiClientConfig {\r\n baseUrl: string;\r\n authToken?: string;\r\n}\r\n\r\nexport class QuizApiClient {\r\n private baseUrl: string;\r\n private authToken?: string;\r\n\r\n constructor(config: ApiClientConfig) {\r\n this.baseUrl = config.baseUrl.replace(/\\/$/, ''); // Remove trailing slash\r\n this.authToken = config.authToken;\r\n }\r\n\r\n private async request<T>(\r\n method: string,\r\n endpoint: string,\r\n body?: unknown\r\n ): Promise<T> {\r\n const headers: HeadersInit = {\r\n 'Content-Type': 'application/json',\r\n };\r\n\r\n if (this.authToken) {\r\n headers['Authorization'] = `Bearer ${this.authToken}`;\r\n }\r\n\r\n const response = await fetch(`${this.baseUrl}${endpoint}`, {\r\n method,\r\n headers,\r\n body: body ? JSON.stringify(body) : undefined,\r\n });\r\n\r\n if (!response.ok) {\r\n const error = await response.json().catch(() => ({ error: 'Request failed' }));\r\n throw new Error(error.error || `HTTP ${response.status}`);\r\n }\r\n\r\n return response.json();\r\n }\r\n\r\n async getQuiz(quizId: string): Promise<Quiz> {\r\n return this.request<Quiz>('GET', `/api/external/quizzes/${quizId}`);\r\n }\r\n\r\n async createAttempt(params: {\r\n quizId: string;\r\n lessonId: string;\r\n assignLessonId: string;\r\n courseId: string;\r\n childId: string;\r\n parentId: string;\r\n }): Promise<ExternalQuizAttempt> {\r\n return this.request<ExternalQuizAttempt>('POST', '/api/external/quiz-attempts', params);\r\n }\r\n\r\n async updateAttempt(\r\n attemptId: string,\r\n data: {\r\n answers?: QuizAnswerDetail[];\r\n status?: 'in_progress' | 'completed' | 'abandoned';\r\n score?: number;\r\n correctAnswers?: number;\r\n timeSpentSeconds?: number;\r\n }\r\n ): Promise<ExternalQuizAttempt> {\r\n return this.request<ExternalQuizAttempt>(\r\n 'PATCH',\r\n `/api/external/quiz-attempts/${attemptId}`,\r\n data\r\n );\r\n }\r\n\r\n async getAttempt(attemptId: string): Promise<ExternalQuizAttempt> {\r\n return this.request<ExternalQuizAttempt>('GET', `/api/external/quiz-attempts/${attemptId}`);\r\n }\r\n\r\n async getAttempts(params: {\r\n assignLessonId?: string;\r\n childId?: string;\r\n quizId?: string;\r\n }): Promise<ExternalQuizAttempt[]> {\r\n const queryParams = new URLSearchParams();\r\n if (params.assignLessonId) queryParams.set('assignLessonId', params.assignLessonId);\r\n if (params.childId) queryParams.set('childId', params.childId);\r\n if (params.quizId) queryParams.set('quizId', params.quizId);\r\n\r\n return this.request<ExternalQuizAttempt[]>(\r\n 'GET',\r\n `/api/external/quiz-attempts?${queryParams.toString()}`\r\n );\r\n }\r\n}\r\n","import type { QuizQuestion, QuizAnswerDetail, QuestionType } from './types';\r\n\r\n// Check if an answer is correct based on question type\r\nexport function checkAnswer(\r\n question: QuizQuestion,\r\n selectedAnswer: unknown\r\n): { isCorrect: boolean; pointsEarned: number } {\r\n const { type, correctAnswer, points } = question;\r\n\r\n switch (type) {\r\n case 'single':\r\n case 'true-false': {\r\n const isCorrect = selectedAnswer === correctAnswer;\r\n return { isCorrect, pointsEarned: isCorrect ? points : 0 };\r\n }\r\n\r\n case 'multiple': {\r\n if (!Array.isArray(selectedAnswer) || !Array.isArray(correctAnswer)) {\r\n return { isCorrect: false, pointsEarned: 0 };\r\n }\r\n const sortedSelected = [...selectedAnswer].sort();\r\n const sortedCorrect = [...correctAnswer].sort();\r\n const isCorrect =\r\n sortedSelected.length === sortedCorrect.length &&\r\n sortedSelected.every((val, idx) => val === sortedCorrect[idx]);\r\n return { isCorrect, pointsEarned: isCorrect ? points : 0 };\r\n }\r\n\r\n case 'fill': {\r\n if (!Array.isArray(selectedAnswer) || !question.blanks) {\r\n return { isCorrect: false, pointsEarned: 0 };\r\n }\r\n const isCorrect = question.blanks.every((blank, idx) =>\r\n selectedAnswer[idx]?.toLowerCase().trim() === blank.toLowerCase().trim()\r\n );\r\n return { isCorrect, pointsEarned: isCorrect ? points : 0 };\r\n }\r\n\r\n case 'sorting': {\r\n if (!Array.isArray(selectedAnswer) || !question.correctOrder) {\r\n return { isCorrect: false, pointsEarned: 0 };\r\n }\r\n const isCorrect =\r\n selectedAnswer.length === question.correctOrder.length &&\r\n selectedAnswer.every((val, idx) => val === question.correctOrder![idx]);\r\n return { isCorrect, pointsEarned: isCorrect ? points : 0 };\r\n }\r\n\r\n case 'matrix': {\r\n if (typeof selectedAnswer !== 'object' || !question.correctMatches) {\r\n return { isCorrect: false, pointsEarned: 0 };\r\n }\r\n const selected = selectedAnswer as Record<string, string>;\r\n const correct = question.correctMatches;\r\n const isCorrect = Object.keys(correct).every(\r\n key => selected[key] === correct[key]\r\n );\r\n return { isCorrect, pointsEarned: isCorrect ? points : 0 };\r\n }\r\n\r\n case 'free': {\r\n // For free-form answers, do a simple case-insensitive comparison\r\n if (typeof selectedAnswer !== 'string' || typeof correctAnswer !== 'string') {\r\n return { isCorrect: false, pointsEarned: 0 };\r\n }\r\n const isCorrect = selectedAnswer.toLowerCase().trim() === correctAnswer.toLowerCase().trim();\r\n return { isCorrect, pointsEarned: isCorrect ? points : 0 };\r\n }\r\n\r\n case 'essay':\r\n case 'assessment':\r\n // These require manual grading or are opinion-based\r\n return { isCorrect: false, pointsEarned: 0 };\r\n\r\n default:\r\n return { isCorrect: false, pointsEarned: 0 };\r\n }\r\n}\r\n\r\n// Create an answer detail object\r\nexport function createAnswerDetail(\r\n question: QuizQuestion,\r\n selectedAnswer: unknown\r\n): QuizAnswerDetail {\r\n const { isCorrect, pointsEarned } = checkAnswer(question, selectedAnswer);\r\n\r\n return {\r\n questionId: question.id,\r\n questionText: question.question,\r\n questionType: question.type,\r\n points: question.points,\r\n pointsEarned,\r\n selectedAnswer: selectedAnswer as QuizAnswerDetail['selectedAnswer'],\r\n correctAnswer: question.correctAnswer as QuizAnswerDetail['correctAnswer'],\r\n isCorrect,\r\n explanation: question.explanation,\r\n hint: question.hint,\r\n };\r\n}\r\n\r\n// Calculate total score percentage\r\nexport function calculateScore(answers: QuizAnswerDetail[]): {\r\n score: number;\r\n correctAnswers: number;\r\n totalPoints: number;\r\n earnedPoints: number;\r\n} {\r\n const totalPoints = answers.reduce((sum, a) => sum + a.points, 0);\r\n const earnedPoints = answers.reduce((sum, a) => sum + a.pointsEarned, 0);\r\n const correctAnswers = answers.filter(a => a.isCorrect).length;\r\n const score = totalPoints > 0 ? Math.round((earnedPoints / totalPoints) * 100) : 0;\r\n\r\n return { score, correctAnswers, totalPoints, earnedPoints };\r\n}\r\n\r\n// Format time in seconds to mm:ss\r\nexport function formatTime(seconds: number): string {\r\n const mins = Math.floor(seconds / 60);\r\n const secs = seconds % 60;\r\n return `${mins}:${secs.toString().padStart(2, '0')}`;\r\n}\r\n","import { useState, useEffect, useCallback, useRef } from 'react';\r\nimport type {\r\n QuizPlayerProps,\r\n Quiz,\r\n QuizQuestion,\r\n QuizAnswerDetail,\r\n ExternalQuizAttempt,\r\n QuizResult,\r\n} from './types';\r\nimport { QuizApiClient } from './api';\r\nimport { createAnswerDetail, calculateScore, formatTime } from './utils';\r\n\r\n// Default styles that can be overridden\r\nconst defaultStyles = {\r\n container: {\r\n fontFamily: 'system-ui, -apple-system, sans-serif',\r\n maxWidth: '800px',\r\n margin: '0 auto',\r\n padding: '20px',\r\n backgroundColor: '#ffffff',\r\n borderRadius: '12px',\r\n },\r\n header: {\r\n marginBottom: '20px',\r\n borderBottom: '1px solid #e5e7eb',\r\n paddingBottom: '16px',\r\n },\r\n title: {\r\n fontSize: '24px',\r\n fontWeight: '600',\r\n marginBottom: '8px',\r\n },\r\n progress: {\r\n fontSize: '14px',\r\n color: '#6b7280',\r\n },\r\n progressBar: {\r\n width: '100%',\r\n height: '8px',\r\n backgroundColor: '#e5e7eb',\r\n borderRadius: '4px',\r\n overflow: 'hidden' as const,\r\n marginTop: '8px',\r\n },\r\n progressFill: {\r\n height: '100%',\r\n backgroundColor: '#6721b0',\r\n transition: 'width 0.3s ease',\r\n },\r\n question: {\r\n marginBottom: '24px',\r\n },\r\n questionText: {\r\n fontSize: '18px',\r\n fontWeight: '500',\r\n marginBottom: '16px',\r\n },\r\n options: {\r\n display: 'flex',\r\n flexDirection: 'column' as const,\r\n gap: '8px',\r\n },\r\n option: {\r\n padding: '12px 16px',\r\n border: '2px solid #e5e7eb',\r\n borderRadius: '8px',\r\n cursor: 'pointer',\r\n transition: 'all 0.2s ease',\r\n },\r\n optionSelected: {\r\n borderColor: '#6721b0',\r\n backgroundColor: '#f3e8ff',\r\n },\r\n optionCorrect: {\r\n borderColor: '#22c55e',\r\n backgroundColor: '#f0fdf4',\r\n },\r\n optionIncorrect: {\r\n borderColor: '#ef4444',\r\n backgroundColor: '#fef2f2',\r\n },\r\n input: {\r\n width: '100%',\r\n padding: '12px 16px',\r\n border: '2px solid #e5e7eb',\r\n borderRadius: '8px',\r\n fontSize: '16px',\r\n },\r\n buttons: {\r\n display: 'flex',\r\n justifyContent: 'space-between',\r\n marginTop: '24px',\r\n },\r\n button: {\r\n padding: '12px 24px',\r\n borderRadius: '8px',\r\n fontSize: '16px',\r\n fontWeight: '500',\r\n cursor: 'pointer',\r\n border: 'none',\r\n transition: 'all 0.2s ease',\r\n },\r\n buttonPrimary: {\r\n backgroundColor: '#6721b0',\r\n color: '#ffffff',\r\n },\r\n buttonSecondary: {\r\n backgroundColor: '#f3f4f6',\r\n color: '#374151',\r\n },\r\n buttonDisabled: {\r\n backgroundColor: '#e5e7eb',\r\n color: '#9ca3af',\r\n cursor: 'not-allowed',\r\n },\r\n timer: {\r\n fontSize: '14px',\r\n color: '#6b7280',\r\n marginLeft: '16px',\r\n },\r\n results: {\r\n textAlign: 'center' as const,\r\n padding: '40px 20px',\r\n },\r\n resultScore: {\r\n fontSize: '48px',\r\n fontWeight: '700',\r\n color: '#6721b0',\r\n marginBottom: '8px',\r\n },\r\n resultLabel: {\r\n fontSize: '18px',\r\n color: '#6b7280',\r\n },\r\n loading: {\r\n textAlign: 'center' as const,\r\n padding: '40px',\r\n color: '#6b7280',\r\n },\r\n error: {\r\n textAlign: 'center' as const,\r\n padding: '40px',\r\n color: '#ef4444',\r\n },\r\n};\r\n\r\n// Inline spinner component\r\nfunction Spinner({ size = 16, color = '#ffffff' }: { size?: number; color?: string }) {\r\n return (\r\n <span\r\n style={{\r\n display: 'inline-block',\r\n width: size,\r\n height: size,\r\n border: `2px solid ${color}`,\r\n borderTopColor: 'transparent',\r\n borderRadius: '50%',\r\n animation: 'spin 0.8s linear infinite',\r\n }}\r\n >\r\n <style>\r\n {`@keyframes spin { to { transform: rotate(360deg); } }`}\r\n </style>\r\n </span>\r\n );\r\n}\r\n\r\nexport function QuizPlayer({\r\n quizId,\r\n lessonId,\r\n assignLessonId,\r\n courseId,\r\n childId,\r\n parentId,\r\n apiBaseUrl,\r\n authToken,\r\n onComplete,\r\n onError,\r\n onProgress,\r\n className,\r\n}: QuizPlayerProps) {\r\n const [quiz, setQuiz] = useState<Quiz | null>(null);\r\n const [attempt, setAttempt] = useState<ExternalQuizAttempt | null>(null);\r\n const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0);\r\n const [answers, setAnswers] = useState<Map<string, unknown>>(new Map());\r\n const [answersDetail, setAnswersDetail] = useState<QuizAnswerDetail[]>([]);\r\n const [isSubmitting, setIsSubmitting] = useState(false);\r\n const [isNavigating, setIsNavigating] = useState(false);\r\n const [isCompleted, setIsCompleted] = useState(false);\r\n const [result, setResult] = useState<QuizResult | null>(null);\r\n const [error, setError] = useState<string | null>(null);\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [elapsedSeconds, setElapsedSeconds] = useState(0);\r\n\r\n const apiClient = useRef<QuizApiClient | null>(null);\r\n const timerRef = useRef<ReturnType<typeof setInterval> | null>(null);\r\n const startTimeRef = useRef<number>(Date.now());\r\n\r\n // Initialize API client\r\n useEffect(() => {\r\n apiClient.current = new QuizApiClient({ baseUrl: apiBaseUrl, authToken });\r\n }, [apiBaseUrl, authToken]);\r\n\r\n // Load quiz and create/resume attempt\r\n useEffect(() => {\r\n async function initialize() {\r\n if (!apiClient.current) return;\r\n\r\n try {\r\n setIsLoading(true);\r\n setError(null);\r\n\r\n // Fetch quiz\r\n const quizData = await apiClient.current.getQuiz(quizId);\r\n setQuiz(quizData);\r\n\r\n // Create or resume attempt\r\n const attemptData = await apiClient.current.createAttempt({\r\n quizId,\r\n lessonId,\r\n assignLessonId,\r\n courseId,\r\n childId,\r\n parentId,\r\n });\r\n setAttempt(attemptData);\r\n\r\n // Resume from existing answers if any\r\n if (attemptData.answers && attemptData.answers.length > 0) {\r\n setAnswersDetail(attemptData.answers);\r\n const answersMap = new Map<string, unknown>();\r\n attemptData.answers.forEach(a => {\r\n answersMap.set(a.questionId, a.selectedAnswer);\r\n });\r\n setAnswers(answersMap);\r\n }\r\n\r\n // Check if already completed\r\n if (attemptData.status === 'completed') {\r\n setIsCompleted(true);\r\n const scoreData = calculateScore(attemptData.answers);\r\n setResult({\r\n attemptId: attemptData.id,\r\n score: attemptData.score || scoreData.score,\r\n correctAnswers: attemptData.correctAnswers || scoreData.correctAnswers,\r\n totalQuestions: attemptData.totalQuestions,\r\n answers: attemptData.answers,\r\n timeSpentSeconds: attemptData.timeSpentSeconds || 0,\r\n });\r\n }\r\n\r\n setIsLoading(false);\r\n } catch (err) {\r\n const message = err instanceof Error ? err.message : 'Failed to load quiz';\r\n setError(message);\r\n setIsLoading(false);\r\n onError?.(err instanceof Error ? err : new Error(message));\r\n }\r\n }\r\n\r\n initialize();\r\n }, [quizId, lessonId, assignLessonId, courseId, childId, parentId, onError]);\r\n\r\n // Timer\r\n useEffect(() => {\r\n if (!isLoading && !isCompleted && !error) {\r\n startTimeRef.current = Date.now();\r\n timerRef.current = setInterval(() => {\r\n setElapsedSeconds(Math.floor((Date.now() - startTimeRef.current) / 1000));\r\n }, 1000);\r\n }\r\n\r\n return () => {\r\n if (timerRef.current) {\r\n clearInterval(timerRef.current);\r\n }\r\n };\r\n }, [isLoading, isCompleted, error]);\r\n\r\n // Report progress\r\n useEffect(() => {\r\n if (quiz && onProgress) {\r\n onProgress({\r\n currentQuestion: currentQuestionIndex + 1,\r\n totalQuestions: quiz.questions.length,\r\n answeredQuestions: answers.size,\r\n });\r\n }\r\n }, [currentQuestionIndex, answers.size, quiz, onProgress]);\r\n\r\n const currentQuestion = quiz?.questions[currentQuestionIndex];\r\n\r\n const handleAnswerChange = useCallback((value: unknown) => {\r\n if (!currentQuestion) return;\r\n setAnswers(prev => new Map(prev).set(currentQuestion.id, value));\r\n }, [currentQuestion]);\r\n\r\n const handleNext = useCallback(async () => {\r\n if (!quiz || !attempt || !currentQuestion || !apiClient.current) return;\r\n\r\n const selectedAnswer = answers.get(currentQuestion.id);\r\n if (selectedAnswer === undefined) return;\r\n\r\n setIsNavigating(true);\r\n\r\n // Create answer detail\r\n const answerDetail = createAnswerDetail(currentQuestion, selectedAnswer);\r\n \r\n // Update answers detail state\r\n const newAnswersDetail = [...answersDetail];\r\n const existingIdx = newAnswersDetail.findIndex(a => a.questionId === currentQuestion.id);\r\n if (existingIdx >= 0) {\r\n newAnswersDetail[existingIdx] = answerDetail;\r\n } else {\r\n newAnswersDetail.push(answerDetail);\r\n }\r\n setAnswersDetail(newAnswersDetail);\r\n\r\n // Save progress to server\r\n try {\r\n await apiClient.current.updateAttempt(attempt.id, {\r\n answers: newAnswersDetail,\r\n });\r\n } catch (err) {\r\n console.error('Failed to save progress:', err);\r\n } finally {\r\n setIsNavigating(false);\r\n }\r\n\r\n // Move to next question\r\n if (currentQuestionIndex < quiz.questions.length - 1) {\r\n setCurrentQuestionIndex(prev => prev + 1);\r\n }\r\n }, [quiz, attempt, currentQuestion, answers, answersDetail, currentQuestionIndex]);\r\n\r\n const handlePrevious = useCallback(() => {\r\n if (currentQuestionIndex > 0) {\r\n setCurrentQuestionIndex(prev => prev - 1);\r\n }\r\n }, [currentQuestionIndex]);\r\n\r\n const handleSubmit = useCallback(async () => {\r\n if (!quiz || !attempt || !apiClient.current) return;\r\n\r\n setIsSubmitting(true);\r\n\r\n try {\r\n // Ensure current answer is saved\r\n const currentAnswer = currentQuestion ? answers.get(currentQuestion.id) : undefined;\r\n let finalAnswersDetail = [...answersDetail];\r\n \r\n if (currentQuestion && currentAnswer !== undefined) {\r\n const answerDetail = createAnswerDetail(currentQuestion, currentAnswer);\r\n const existingIdx = finalAnswersDetail.findIndex(a => a.questionId === currentQuestion.id);\r\n if (existingIdx >= 0) {\r\n finalAnswersDetail[existingIdx] = answerDetail;\r\n } else {\r\n finalAnswersDetail.push(answerDetail);\r\n }\r\n }\r\n\r\n // Calculate final score\r\n const scoreData = calculateScore(finalAnswersDetail);\r\n const timeSpent = Math.floor((Date.now() - startTimeRef.current) / 1000);\r\n\r\n // Submit to server\r\n const updatedAttempt = await apiClient.current.updateAttempt(attempt.id, {\r\n answers: finalAnswersDetail,\r\n status: 'completed',\r\n score: scoreData.score,\r\n correctAnswers: scoreData.correctAnswers,\r\n timeSpentSeconds: timeSpent,\r\n });\r\n\r\n // Update state\r\n setIsCompleted(true);\r\n const quizResult: QuizResult = {\r\n attemptId: updatedAttempt.id,\r\n score: scoreData.score,\r\n correctAnswers: scoreData.correctAnswers,\r\n totalQuestions: quiz.questions.length,\r\n answers: finalAnswersDetail,\r\n timeSpentSeconds: timeSpent,\r\n };\r\n setResult(quizResult);\r\n\r\n // Stop timer\r\n if (timerRef.current) {\r\n clearInterval(timerRef.current);\r\n }\r\n\r\n // Callback\r\n onComplete?.(quizResult);\r\n } catch (err) {\r\n const message = err instanceof Error ? err.message : 'Failed to submit quiz';\r\n setError(message);\r\n onError?.(err instanceof Error ? err : new Error(message));\r\n } finally {\r\n setIsSubmitting(false);\r\n }\r\n }, [quiz, attempt, currentQuestion, answers, answersDetail, onComplete, onError]);\r\n\r\n // Render loading state\r\n if (isLoading) {\r\n return (\r\n <div className={className} style={defaultStyles.container}>\r\n <div style={defaultStyles.loading}>Loading quiz...</div>\r\n </div>\r\n );\r\n }\r\n\r\n // Render error state\r\n if (error) {\r\n return (\r\n <div className={className} style={defaultStyles.container}>\r\n <div style={defaultStyles.error}>\r\n <p>Error: {error}</p>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n // Render completed state\r\n if (isCompleted && result) {\r\n return (\r\n <div className={className} style={defaultStyles.container}>\r\n <div style={defaultStyles.results}>\r\n <div style={defaultStyles.resultScore}>{result.score}%</div>\r\n <div style={defaultStyles.resultLabel}>\r\n {result.correctAnswers} of {result.totalQuestions} correct\r\n </div>\r\n <div style={{ ...defaultStyles.resultLabel, marginTop: '8px' }}>\r\n Time: {formatTime(result.timeSpentSeconds)}\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n // Render quiz\r\n if (!quiz || !currentQuestion) {\r\n return (\r\n <div className={className} style={defaultStyles.container}>\r\n <div style={defaultStyles.error}>No quiz data available</div>\r\n </div>\r\n );\r\n }\r\n\r\n const selectedAnswer = answers.get(currentQuestion.id);\r\n const isLastQuestion = currentQuestionIndex === quiz.questions.length - 1;\r\n const progressPercent = ((currentQuestionIndex + 1) / quiz.questions.length) * 100;\r\n\r\n return (\r\n <div className={className} style={defaultStyles.container}>\r\n {/* Header */}\r\n <div style={defaultStyles.header}>\r\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>\r\n <div style={defaultStyles.title}>{quiz.title}</div>\r\n <div style={defaultStyles.timer}>{formatTime(elapsedSeconds)}</div>\r\n </div>\r\n <div style={defaultStyles.progress}>\r\n Question {currentQuestionIndex + 1} of {quiz.questions.length}\r\n </div>\r\n <div style={defaultStyles.progressBar}>\r\n <div style={{ ...defaultStyles.progressFill, width: `${progressPercent}%` }} />\r\n </div>\r\n </div>\r\n\r\n {/* Question */}\r\n <div style={defaultStyles.question}>\r\n <div style={defaultStyles.questionText}>{currentQuestion.question}</div>\r\n\r\n {/* Render options based on question type */}\r\n {(currentQuestion.type === 'single' || currentQuestion.type === 'true-false') && (\r\n <div style={defaultStyles.options}>\r\n {currentQuestion.options?.map((option, idx) => (\r\n <div\r\n key={idx}\r\n style={{\r\n ...defaultStyles.option,\r\n ...(selectedAnswer === option ? defaultStyles.optionSelected : {}),\r\n }}\r\n onClick={() => handleAnswerChange(option)}\r\n >\r\n {option}\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n\r\n {currentQuestion.type === 'multiple' && (\r\n <div style={defaultStyles.options}>\r\n {currentQuestion.options?.map((option, idx) => {\r\n const selected = Array.isArray(selectedAnswer) && selectedAnswer.includes(option);\r\n return (\r\n <div\r\n key={idx}\r\n style={{\r\n ...defaultStyles.option,\r\n ...(selected ? defaultStyles.optionSelected : {}),\r\n }}\r\n onClick={() => {\r\n const current = Array.isArray(selectedAnswer) ? selectedAnswer : [];\r\n if (selected) {\r\n handleAnswerChange(current.filter(o => o !== option));\r\n } else {\r\n handleAnswerChange([...current, option]);\r\n }\r\n }}\r\n >\r\n {option}\r\n </div>\r\n );\r\n })}\r\n </div>\r\n )}\r\n\r\n {(currentQuestion.type === 'free' || currentQuestion.type === 'essay') && (\r\n <textarea\r\n style={{ ...defaultStyles.input, minHeight: currentQuestion.type === 'essay' ? '150px' : '60px' }}\r\n value={(selectedAnswer as string) || ''}\r\n onChange={e => handleAnswerChange(e.target.value)}\r\n placeholder=\"Type your answer here...\"\r\n />\r\n )}\r\n\r\n {currentQuestion.type === 'fill' && (\r\n <div style={defaultStyles.options}>\r\n {currentQuestion.blanks?.map((_, idx) => (\r\n <input\r\n key={idx}\r\n style={defaultStyles.input}\r\n value={(Array.isArray(selectedAnswer) ? selectedAnswer[idx] : '') || ''}\r\n onChange={e => {\r\n const current = Array.isArray(selectedAnswer) ? [...selectedAnswer] : [];\r\n current[idx] = e.target.value;\r\n handleAnswerChange(current);\r\n }}\r\n placeholder={`Blank ${idx + 1}`}\r\n />\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Navigation buttons */}\r\n <div style={defaultStyles.buttons}>\r\n <button\r\n style={{\r\n ...defaultStyles.button,\r\n ...(currentQuestionIndex > 0 ? defaultStyles.buttonSecondary : defaultStyles.buttonDisabled),\r\n }}\r\n onClick={handlePrevious}\r\n disabled={currentQuestionIndex === 0}\r\n >\r\n Previous\r\n </button>\r\n\r\n {isLastQuestion ? (\r\n <button\r\n style={{\r\n ...defaultStyles.button,\r\n ...(isSubmitting ? defaultStyles.buttonDisabled : defaultStyles.buttonPrimary),\r\n }}\r\n onClick={handleSubmit}\r\n disabled={isSubmitting || selectedAnswer === undefined}\r\n >\r\n {isSubmitting ? <Spinner size={16} color=\"#9ca3af\" /> : 'Submit Quiz'}\r\n </button>\r\n ) : (\r\n <button\r\n style={{\r\n ...defaultStyles.button,\r\n ...(isNavigating || selectedAnswer === undefined ? defaultStyles.buttonDisabled : defaultStyles.buttonPrimary),\r\n }}\r\n onClick={handleNext}\r\n disabled={isNavigating || selectedAnswer === undefined}\r\n >\r\n {isNavigating ? <Spinner size={16} color=\"#9ca3af\" /> : 'Next'}\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/api.ts","../src/utils.ts","../src/QuizPlayer.tsx","../src/AttemptViewer.tsx"],"names":["selectedAnswer","defaultStyles","useState","useEffect","jsxs","jsx"],"mappings":"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","file":"index.mjs","sourcesContent":["import type { Quiz, ExternalQuizAttempt, QuizAnswerDetail } from './types';\r\n\r\nexport interface ApiClientConfig {\r\n baseUrl: string;\r\n authToken?: string;\r\n}\r\n\r\nexport class QuizApiClient {\r\n private baseUrl: string;\r\n private authToken?: string;\r\n\r\n constructor(config: ApiClientConfig) {\r\n this.baseUrl = config.baseUrl.replace(/\\/$/, ''); // Remove trailing slash\r\n this.authToken = config.authToken;\r\n }\r\n\r\n private async request<T>(\r\n method: string,\r\n endpoint: string,\r\n body?: unknown\r\n ): Promise<T> {\r\n const headers: HeadersInit = {\r\n 'Content-Type': 'application/json',\r\n };\r\n\r\n if (this.authToken) {\r\n headers['Authorization'] = `Bearer ${this.authToken}`;\r\n }\r\n\r\n const response = await fetch(`${this.baseUrl}${endpoint}`, {\r\n method,\r\n headers,\r\n body: body ? JSON.stringify(body) : undefined,\r\n });\r\n\r\n if (!response.ok) {\r\n const error = await response.json().catch(() => ({ error: 'Request failed' }));\r\n throw new Error(error.error || `HTTP ${response.status}`);\r\n }\r\n\r\n return response.json();\r\n }\r\n\r\n async getQuiz(quizId: string): Promise<Quiz> {\r\n return this.request<Quiz>('GET', `/api/external/quizzes/${quizId}`);\r\n }\r\n\r\n async createAttempt(params: {\r\n quizId: string;\r\n lessonId: string;\r\n assignLessonId: string;\r\n courseId: string;\r\n childId: string;\r\n parentId: string;\r\n }): Promise<ExternalQuizAttempt> {\r\n return this.request<ExternalQuizAttempt>('POST', '/api/external/quiz-attempts', params);\r\n }\r\n\r\n async updateAttempt(\r\n attemptId: string,\r\n data: {\r\n answers?: QuizAnswerDetail[];\r\n status?: 'in_progress' | 'completed' | 'abandoned';\r\n score?: number;\r\n correctAnswers?: number;\r\n timeSpentSeconds?: number;\r\n }\r\n ): Promise<ExternalQuizAttempt> {\r\n return this.request<ExternalQuizAttempt>(\r\n 'PATCH',\r\n `/api/external/quiz-attempts/${attemptId}`,\r\n data\r\n );\r\n }\r\n\r\n async getAttempt(attemptId: string): Promise<ExternalQuizAttempt> {\r\n return this.request<ExternalQuizAttempt>('GET', `/api/external/quiz-attempts/${attemptId}`);\r\n }\r\n\r\n async getAttempts(params: {\r\n assignLessonId?: string;\r\n childId?: string;\r\n quizId?: string;\r\n }): Promise<ExternalQuizAttempt[]> {\r\n const queryParams = new URLSearchParams();\r\n if (params.assignLessonId) queryParams.set('assignLessonId', params.assignLessonId);\r\n if (params.childId) queryParams.set('childId', params.childId);\r\n if (params.quizId) queryParams.set('quizId', params.quizId);\r\n\r\n return this.request<ExternalQuizAttempt[]>(\r\n 'GET',\r\n `/api/external/quiz-attempts?${queryParams.toString()}`\r\n );\r\n }\r\n}\r\n","import type { QuizQuestion, QuizAnswerDetail, QuestionType } from './types';\r\n\r\n// Check if an answer is correct based on question type\r\nexport function checkAnswer(\r\n question: QuizQuestion,\r\n selectedAnswer: unknown\r\n): { isCorrect: boolean; pointsEarned: number } {\r\n const { type, correctAnswer, points } = question;\r\n\r\n switch (type) {\r\n case 'single':\r\n case 'true-false': {\r\n const isCorrect = selectedAnswer === correctAnswer;\r\n return { isCorrect, pointsEarned: isCorrect ? points : 0 };\r\n }\r\n\r\n case 'multiple': {\r\n if (!Array.isArray(selectedAnswer) || !Array.isArray(correctAnswer)) {\r\n return { isCorrect: false, pointsEarned: 0 };\r\n }\r\n const sortedSelected = [...selectedAnswer].sort();\r\n const sortedCorrect = [...correctAnswer].sort();\r\n const isCorrect =\r\n sortedSelected.length === sortedCorrect.length &&\r\n sortedSelected.every((val, idx) => val === sortedCorrect[idx]);\r\n return { isCorrect, pointsEarned: isCorrect ? points : 0 };\r\n }\r\n\r\n case 'fill': {\r\n if (!Array.isArray(selectedAnswer) || !question.blanks) {\r\n return { isCorrect: false, pointsEarned: 0 };\r\n }\r\n const isCorrect = question.blanks.every((blank, idx) =>\r\n selectedAnswer[idx]?.toLowerCase().trim() === blank.toLowerCase().trim()\r\n );\r\n return { isCorrect, pointsEarned: isCorrect ? points : 0 };\r\n }\r\n\r\n case 'sorting': {\r\n if (!Array.isArray(selectedAnswer) || !question.correctOrder) {\r\n return { isCorrect: false, pointsEarned: 0 };\r\n }\r\n const isCorrect =\r\n selectedAnswer.length === question.correctOrder.length &&\r\n selectedAnswer.every((val, idx) => val === question.correctOrder![idx]);\r\n return { isCorrect, pointsEarned: isCorrect ? points : 0 };\r\n }\r\n\r\n case 'matrix': {\r\n if (typeof selectedAnswer !== 'object' || !question.correctMatches) {\r\n return { isCorrect: false, pointsEarned: 0 };\r\n }\r\n const selected = selectedAnswer as Record<string, string>;\r\n const correct = question.correctMatches;\r\n const isCorrect = Object.keys(correct).every(\r\n key => selected[key] === correct[key]\r\n );\r\n return { isCorrect, pointsEarned: isCorrect ? points : 0 };\r\n }\r\n\r\n case 'free': {\r\n // For free-form answers, do a simple case-insensitive comparison\r\n if (typeof selectedAnswer !== 'string' || typeof correctAnswer !== 'string') {\r\n return { isCorrect: false, pointsEarned: 0 };\r\n }\r\n const isCorrect = selectedAnswer.toLowerCase().trim() === correctAnswer.toLowerCase().trim();\r\n return { isCorrect, pointsEarned: isCorrect ? points : 0 };\r\n }\r\n\r\n case 'essay':\r\n case 'assessment':\r\n // These require manual grading or are opinion-based\r\n return { isCorrect: false, pointsEarned: 0 };\r\n\r\n default:\r\n return { isCorrect: false, pointsEarned: 0 };\r\n }\r\n}\r\n\r\n// Create an answer detail object\r\nexport function createAnswerDetail(\r\n question: QuizQuestion,\r\n selectedAnswer: unknown\r\n): QuizAnswerDetail {\r\n const { isCorrect, pointsEarned } = checkAnswer(question, selectedAnswer);\r\n\r\n return {\r\n questionId: question.id,\r\n questionText: question.question,\r\n questionType: question.type,\r\n points: question.points,\r\n pointsEarned,\r\n selectedAnswer: selectedAnswer as QuizAnswerDetail['selectedAnswer'],\r\n correctAnswer: question.correctAnswer as QuizAnswerDetail['correctAnswer'],\r\n isCorrect,\r\n explanation: question.explanation,\r\n hint: question.hint,\r\n };\r\n}\r\n\r\n// Calculate total score percentage\r\nexport function calculateScore(answers: QuizAnswerDetail[]): {\r\n score: number;\r\n correctAnswers: number;\r\n totalPoints: number;\r\n earnedPoints: number;\r\n} {\r\n const totalPoints = answers.reduce((sum, a) => sum + a.points, 0);\r\n const earnedPoints = answers.reduce((sum, a) => sum + a.pointsEarned, 0);\r\n const correctAnswers = answers.filter(a => a.isCorrect).length;\r\n const score = totalPoints > 0 ? Math.round((earnedPoints / totalPoints) * 100) : 0;\r\n\r\n return { score, correctAnswers, totalPoints, earnedPoints };\r\n}\r\n\r\n// Format time in seconds to mm:ss\r\nexport function formatTime(seconds: number): string {\r\n const mins = Math.floor(seconds / 60);\r\n const secs = seconds % 60;\r\n return `${mins}:${secs.toString().padStart(2, '0')}`;\r\n}\r\n","import { useState, useEffect, useCallback, useRef } from 'react';\r\nimport type {\r\n QuizPlayerProps,\r\n Quiz,\r\n QuizQuestion,\r\n QuizAnswerDetail,\r\n ExternalQuizAttempt,\r\n QuizResult,\r\n} from './types';\r\nimport { QuizApiClient } from './api';\r\nimport { createAnswerDetail, calculateScore, formatTime } from './utils';\r\n\r\n// Default styles that can be overridden\r\nconst defaultStyles = {\r\n container: {\r\n fontFamily: 'system-ui, -apple-system, sans-serif',\r\n maxWidth: '800px',\r\n margin: '0 auto',\r\n padding: '20px',\r\n backgroundColor: '#ffffff',\r\n borderRadius: '12px',\r\n },\r\n header: {\r\n marginBottom: '20px',\r\n borderBottom: '1px solid #e5e7eb',\r\n paddingBottom: '16px',\r\n },\r\n title: {\r\n fontSize: '24px',\r\n fontWeight: '600',\r\n marginBottom: '8px',\r\n },\r\n progress: {\r\n fontSize: '14px',\r\n color: '#6b7280',\r\n },\r\n progressBar: {\r\n width: '100%',\r\n height: '8px',\r\n backgroundColor: '#e5e7eb',\r\n borderRadius: '4px',\r\n overflow: 'hidden' as const,\r\n marginTop: '8px',\r\n },\r\n progressFill: {\r\n height: '100%',\r\n backgroundColor: '#6721b0',\r\n transition: 'width 0.3s ease',\r\n },\r\n question: {\r\n marginBottom: '24px',\r\n },\r\n questionText: {\r\n fontSize: '18px',\r\n fontWeight: '500',\r\n marginBottom: '16px',\r\n },\r\n options: {\r\n display: 'flex',\r\n flexDirection: 'column' as const,\r\n gap: '8px',\r\n },\r\n option: {\r\n padding: '12px 16px',\r\n border: '2px solid #e5e7eb',\r\n borderRadius: '8px',\r\n cursor: 'pointer',\r\n transition: 'all 0.2s ease',\r\n },\r\n optionSelected: {\r\n borderColor: '#6721b0',\r\n backgroundColor: '#f3e8ff',\r\n },\r\n optionCorrect: {\r\n borderColor: '#22c55e',\r\n backgroundColor: '#f0fdf4',\r\n },\r\n optionIncorrect: {\r\n borderColor: '#ef4444',\r\n backgroundColor: '#fef2f2',\r\n },\r\n input: {\r\n width: '100%',\r\n padding: '12px 16px',\r\n border: '2px solid #e5e7eb',\r\n borderRadius: '8px',\r\n fontSize: '16px',\r\n },\r\n buttons: {\r\n display: 'flex',\r\n justifyContent: 'space-between',\r\n marginTop: '24px',\r\n },\r\n button: {\r\n padding: '12px 24px',\r\n borderRadius: '8px',\r\n fontSize: '16px',\r\n fontWeight: '500',\r\n cursor: 'pointer',\r\n border: 'none',\r\n transition: 'all 0.2s ease',\r\n },\r\n buttonPrimary: {\r\n backgroundColor: '#6721b0',\r\n color: '#ffffff',\r\n },\r\n buttonSecondary: {\r\n backgroundColor: '#f3f4f6',\r\n color: '#374151',\r\n },\r\n buttonDisabled: {\r\n backgroundColor: '#e5e7eb',\r\n color: '#9ca3af',\r\n cursor: 'not-allowed',\r\n },\r\n timer: {\r\n fontSize: '14px',\r\n color: '#6b7280',\r\n marginLeft: '16px',\r\n },\r\n results: {\r\n textAlign: 'center' as const,\r\n padding: '40px 20px',\r\n },\r\n resultScore: {\r\n fontSize: '48px',\r\n fontWeight: '700',\r\n color: '#6721b0',\r\n marginBottom: '8px',\r\n },\r\n resultLabel: {\r\n fontSize: '18px',\r\n color: '#6b7280',\r\n },\r\n loading: {\r\n textAlign: 'center' as const,\r\n padding: '40px',\r\n color: '#6b7280',\r\n },\r\n error: {\r\n textAlign: 'center' as const,\r\n padding: '40px',\r\n color: '#ef4444',\r\n },\r\n};\r\n\r\n// Inline spinner component\r\nfunction Spinner({ size = 16, color = '#ffffff' }: { size?: number; color?: string }) {\r\n return (\r\n <span\r\n style={{\r\n display: 'inline-block',\r\n width: size,\r\n height: size,\r\n border: `2px solid ${color}`,\r\n borderTopColor: 'transparent',\r\n borderRadius: '50%',\r\n animation: 'spin 0.8s linear infinite',\r\n }}\r\n >\r\n <style>\r\n {`@keyframes spin { to { transform: rotate(360deg); } }`}\r\n </style>\r\n </span>\r\n );\r\n}\r\n\r\nexport function QuizPlayer({\r\n quizId,\r\n lessonId,\r\n assignLessonId,\r\n courseId,\r\n childId,\r\n parentId,\r\n apiBaseUrl,\r\n authToken,\r\n onComplete,\r\n onError,\r\n onProgress,\r\n className,\r\n}: QuizPlayerProps) {\r\n const [quiz, setQuiz] = useState<Quiz | null>(null);\r\n const [attempt, setAttempt] = useState<ExternalQuizAttempt | null>(null);\r\n const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0);\r\n const [answers, setAnswers] = useState<Map<string, unknown>>(new Map());\r\n const [answersDetail, setAnswersDetail] = useState<QuizAnswerDetail[]>([]);\r\n const [isSubmitting, setIsSubmitting] = useState(false);\r\n const [isNavigating, setIsNavigating] = useState(false);\r\n const [isCompleted, setIsCompleted] = useState(false);\r\n const [result, setResult] = useState<QuizResult | null>(null);\r\n const [error, setError] = useState<string | null>(null);\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [elapsedSeconds, setElapsedSeconds] = useState(0);\r\n\r\n const apiClient = useRef<QuizApiClient | null>(null);\r\n const timerRef = useRef<ReturnType<typeof setInterval> | null>(null);\r\n const startTimeRef = useRef<number>(Date.now());\r\n\r\n // Initialize API client\r\n useEffect(() => {\r\n apiClient.current = new QuizApiClient({ baseUrl: apiBaseUrl, authToken });\r\n }, [apiBaseUrl, authToken]);\r\n\r\n // Load quiz and create/resume attempt\r\n useEffect(() => {\r\n async function initialize() {\r\n if (!apiClient.current) return;\r\n\r\n try {\r\n setIsLoading(true);\r\n setError(null);\r\n\r\n // Fetch quiz\r\n const quizData = await apiClient.current.getQuiz(quizId);\r\n setQuiz(quizData);\r\n\r\n // Create or resume attempt\r\n const attemptData = await apiClient.current.createAttempt({\r\n quizId,\r\n lessonId,\r\n assignLessonId,\r\n courseId,\r\n childId,\r\n parentId,\r\n });\r\n setAttempt(attemptData);\r\n\r\n // Resume from existing answers if any\r\n if (attemptData.answers && attemptData.answers.length > 0) {\r\n setAnswersDetail(attemptData.answers);\r\n const answersMap = new Map<string, unknown>();\r\n attemptData.answers.forEach(a => {\r\n answersMap.set(a.questionId, a.selectedAnswer);\r\n });\r\n setAnswers(answersMap);\r\n }\r\n\r\n // Check if already completed\r\n if (attemptData.status === 'completed') {\r\n setIsCompleted(true);\r\n const scoreData = calculateScore(attemptData.answers);\r\n setResult({\r\n attemptId: attemptData.id,\r\n score: attemptData.score || scoreData.score,\r\n correctAnswers: attemptData.correctAnswers || scoreData.correctAnswers,\r\n totalQuestions: attemptData.totalQuestions,\r\n answers: attemptData.answers,\r\n timeSpentSeconds: attemptData.timeSpentSeconds || 0,\r\n });\r\n }\r\n\r\n setIsLoading(false);\r\n } catch (err) {\r\n const message = err instanceof Error ? err.message : 'Failed to load quiz';\r\n setError(message);\r\n setIsLoading(false);\r\n onError?.(err instanceof Error ? err : new Error(message));\r\n }\r\n }\r\n\r\n initialize();\r\n }, [quizId, lessonId, assignLessonId, courseId, childId, parentId, onError]);\r\n\r\n // Timer\r\n useEffect(() => {\r\n if (!isLoading && !isCompleted && !error) {\r\n startTimeRef.current = Date.now();\r\n timerRef.current = setInterval(() => {\r\n setElapsedSeconds(Math.floor((Date.now() - startTimeRef.current) / 1000));\r\n }, 1000);\r\n }\r\n\r\n return () => {\r\n if (timerRef.current) {\r\n clearInterval(timerRef.current);\r\n }\r\n };\r\n }, [isLoading, isCompleted, error]);\r\n\r\n // Report progress\r\n useEffect(() => {\r\n if (quiz && onProgress) {\r\n onProgress({\r\n currentQuestion: currentQuestionIndex + 1,\r\n totalQuestions: quiz.questions.length,\r\n answeredQuestions: answers.size,\r\n });\r\n }\r\n }, [currentQuestionIndex, answers.size, quiz, onProgress]);\r\n\r\n const currentQuestion = quiz?.questions[currentQuestionIndex];\r\n\r\n const handleAnswerChange = useCallback((value: unknown) => {\r\n if (!currentQuestion) return;\r\n setAnswers(prev => new Map(prev).set(currentQuestion.id, value));\r\n }, [currentQuestion]);\r\n\r\n const handleNext = useCallback(async () => {\r\n if (!quiz || !attempt || !currentQuestion || !apiClient.current) return;\r\n\r\n const selectedAnswer = answers.get(currentQuestion.id);\r\n if (selectedAnswer === undefined) return;\r\n\r\n setIsNavigating(true);\r\n\r\n // Create answer detail\r\n const answerDetail = createAnswerDetail(currentQuestion, selectedAnswer);\r\n \r\n // Update answers detail state\r\n const newAnswersDetail = [...answersDetail];\r\n const existingIdx = newAnswersDetail.findIndex(a => a.questionId === currentQuestion.id);\r\n if (existingIdx >= 0) {\r\n newAnswersDetail[existingIdx] = answerDetail;\r\n } else {\r\n newAnswersDetail.push(answerDetail);\r\n }\r\n setAnswersDetail(newAnswersDetail);\r\n\r\n // Save progress to server\r\n try {\r\n await apiClient.current.updateAttempt(attempt.id, {\r\n answers: newAnswersDetail,\r\n });\r\n } catch (err) {\r\n console.error('Failed to save progress:', err);\r\n } finally {\r\n setIsNavigating(false);\r\n }\r\n\r\n // Move to next question\r\n if (currentQuestionIndex < quiz.questions.length - 1) {\r\n setCurrentQuestionIndex(prev => prev + 1);\r\n }\r\n }, [quiz, attempt, currentQuestion, answers, answersDetail, currentQuestionIndex]);\r\n\r\n const handlePrevious = useCallback(() => {\r\n if (currentQuestionIndex > 0) {\r\n setCurrentQuestionIndex(prev => prev - 1);\r\n }\r\n }, [currentQuestionIndex]);\r\n\r\n const handleSubmit = useCallback(async () => {\r\n if (!quiz || !attempt || !apiClient.current) return;\r\n\r\n setIsSubmitting(true);\r\n\r\n try {\r\n // Ensure current answer is saved\r\n const currentAnswer = currentQuestion ? answers.get(currentQuestion.id) : undefined;\r\n let finalAnswersDetail = [...answersDetail];\r\n \r\n if (currentQuestion && currentAnswer !== undefined) {\r\n const answerDetail = createAnswerDetail(currentQuestion, currentAnswer);\r\n const existingIdx = finalAnswersDetail.findIndex(a => a.questionId === currentQuestion.id);\r\n if (existingIdx >= 0) {\r\n finalAnswersDetail[existingIdx] = answerDetail;\r\n } else {\r\n finalAnswersDetail.push(answerDetail);\r\n }\r\n }\r\n\r\n // Calculate final score\r\n const scoreData = calculateScore(finalAnswersDetail);\r\n const timeSpent = Math.floor((Date.now() - startTimeRef.current) / 1000);\r\n\r\n // Submit to server\r\n const updatedAttempt = await apiClient.current.updateAttempt(attempt.id, {\r\n answers: finalAnswersDetail,\r\n status: 'completed',\r\n score: scoreData.score,\r\n correctAnswers: scoreData.correctAnswers,\r\n timeSpentSeconds: timeSpent,\r\n });\r\n\r\n // Update state\r\n setIsCompleted(true);\r\n const quizResult: QuizResult = {\r\n attemptId: updatedAttempt.id,\r\n score: scoreData.score,\r\n correctAnswers: scoreData.correctAnswers,\r\n totalQuestions: quiz.questions.length,\r\n answers: finalAnswersDetail,\r\n timeSpentSeconds: timeSpent,\r\n };\r\n setResult(quizResult);\r\n\r\n // Stop timer\r\n if (timerRef.current) {\r\n clearInterval(timerRef.current);\r\n }\r\n\r\n // Callback\r\n onComplete?.(quizResult);\r\n } catch (err) {\r\n const message = err instanceof Error ? err.message : 'Failed to submit quiz';\r\n setError(message);\r\n onError?.(err instanceof Error ? err : new Error(message));\r\n } finally {\r\n setIsSubmitting(false);\r\n }\r\n }, [quiz, attempt, currentQuestion, answers, answersDetail, onComplete, onError]);\r\n\r\n // Render loading state\r\n if (isLoading) {\r\n return (\r\n <div className={className} style={defaultStyles.container}>\r\n <div style={defaultStyles.loading}>Loading quiz...</div>\r\n </div>\r\n );\r\n }\r\n\r\n // Render error state\r\n if (error) {\r\n return (\r\n <div className={className} style={defaultStyles.container}>\r\n <div style={defaultStyles.error}>\r\n <p>Error: {error}</p>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n // Render completed state\r\n if (isCompleted && result) {\r\n return (\r\n <div className={className} style={defaultStyles.container}>\r\n <div style={defaultStyles.results}>\r\n <div style={defaultStyles.resultScore}>{result.score}%</div>\r\n <div style={defaultStyles.resultLabel}>\r\n {result.correctAnswers} of {result.totalQuestions} correct\r\n </div>\r\n <div style={{ ...defaultStyles.resultLabel, marginTop: '8px' }}>\r\n Time: {formatTime(result.timeSpentSeconds)}\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n // Render quiz\r\n if (!quiz || !currentQuestion) {\r\n return (\r\n <div className={className} style={defaultStyles.container}>\r\n <div style={defaultStyles.error}>No quiz data available</div>\r\n </div>\r\n );\r\n }\r\n\r\n const selectedAnswer = answers.get(currentQuestion.id);\r\n const isLastQuestion = currentQuestionIndex === quiz.questions.length - 1;\r\n const progressPercent = ((currentQuestionIndex + 1) / quiz.questions.length) * 100;\r\n\r\n return (\r\n <div className={className} style={defaultStyles.container}>\r\n {/* Header */}\r\n <div style={defaultStyles.header}>\r\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>\r\n <div style={defaultStyles.title}>{quiz.title}</div>\r\n <div style={defaultStyles.timer}>{formatTime(elapsedSeconds)}</div>\r\n </div>\r\n <div style={defaultStyles.progress}>\r\n Question {currentQuestionIndex + 1} of {quiz.questions.length}\r\n </div>\r\n <div style={defaultStyles.progressBar}>\r\n <div style={{ ...defaultStyles.progressFill, width: `${progressPercent}%` }} />\r\n </div>\r\n </div>\r\n\r\n {/* Question */}\r\n <div style={defaultStyles.question}>\r\n <div style={defaultStyles.questionText}>{currentQuestion.question}</div>\r\n\r\n {/* Render options based on question type */}\r\n {(currentQuestion.type === 'single' || currentQuestion.type === 'true-false') && (\r\n <div style={defaultStyles.options}>\r\n {currentQuestion.options?.map((option, idx) => (\r\n <div\r\n key={idx}\r\n style={{\r\n ...defaultStyles.option,\r\n ...(selectedAnswer === option ? defaultStyles.optionSelected : {}),\r\n }}\r\n onClick={() => handleAnswerChange(option)}\r\n >\r\n {option}\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n\r\n {currentQuestion.type === 'multiple' && (\r\n <div style={defaultStyles.options}>\r\n {currentQuestion.options?.map((option, idx) => {\r\n const selected = Array.isArray(selectedAnswer) && selectedAnswer.includes(option);\r\n return (\r\n <div\r\n key={idx}\r\n style={{\r\n ...defaultStyles.option,\r\n ...(selected ? defaultStyles.optionSelected : {}),\r\n }}\r\n onClick={() => {\r\n const current = Array.isArray(selectedAnswer) ? selectedAnswer : [];\r\n if (selected) {\r\n handleAnswerChange(current.filter(o => o !== option));\r\n } else {\r\n handleAnswerChange([...current, option]);\r\n }\r\n }}\r\n >\r\n {option}\r\n </div>\r\n );\r\n })}\r\n </div>\r\n )}\r\n\r\n {(currentQuestion.type === 'free' || currentQuestion.type === 'essay') && (\r\n <textarea\r\n style={{ ...defaultStyles.input, minHeight: currentQuestion.type === 'essay' ? '150px' : '60px' }}\r\n value={(selectedAnswer as string) || ''}\r\n onChange={e => handleAnswerChange(e.target.value)}\r\n placeholder=\"Type your answer here...\"\r\n />\r\n )}\r\n\r\n {currentQuestion.type === 'fill' && (\r\n <div style={defaultStyles.options}>\r\n {currentQuestion.blanks?.map((_, idx) => (\r\n <input\r\n key={idx}\r\n style={defaultStyles.input}\r\n value={(Array.isArray(selectedAnswer) ? selectedAnswer[idx] : '') || ''}\r\n onChange={e => {\r\n const current = Array.isArray(selectedAnswer) ? [...selectedAnswer] : [];\r\n current[idx] = e.target.value;\r\n handleAnswerChange(current);\r\n }}\r\n placeholder={`Blank ${idx + 1}`}\r\n />\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Navigation buttons */}\r\n <div style={defaultStyles.buttons}>\r\n <button\r\n style={{\r\n ...defaultStyles.button,\r\n ...(currentQuestionIndex > 0 ? defaultStyles.buttonSecondary : defaultStyles.buttonDisabled),\r\n }}\r\n onClick={handlePrevious}\r\n disabled={currentQuestionIndex === 0}\r\n >\r\n Previous\r\n </button>\r\n\r\n {isLastQuestion ? (\r\n <button\r\n style={{\r\n ...defaultStyles.button,\r\n ...(isSubmitting ? defaultStyles.buttonDisabled : defaultStyles.buttonPrimary),\r\n }}\r\n onClick={handleSubmit}\r\n disabled={isSubmitting || selectedAnswer === undefined}\r\n >\r\n {isSubmitting ? <Spinner size={16} color=\"#9ca3af\" /> : 'Submit Quiz'}\r\n </button>\r\n ) : (\r\n <button\r\n style={{\r\n ...defaultStyles.button,\r\n ...(isNavigating || selectedAnswer === undefined ? defaultStyles.buttonDisabled : defaultStyles.buttonPrimary),\r\n }}\r\n onClick={handleNext}\r\n disabled={isNavigating || selectedAnswer === undefined}\r\n >\r\n {isNavigating ? <Spinner size={16} color=\"#9ca3af\" /> : 'Next'}\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import { useState, useEffect } from 'react';\r\nimport type {\r\n AttemptViewerProps,\r\n ExternalQuizAttempt,\r\n QuizAnswerDetail,\r\n} from './types';\r\nimport { QuizApiClient } from './api';\r\nimport { formatTime } from './utils';\r\n\r\nconst defaultStyles = {\r\n container: {\r\n fontFamily: 'system-ui, -apple-system, sans-serif',\r\n width: '100%',\r\n padding: '20px',\r\n backgroundColor: '#ffffff',\r\n borderRadius: '12px',\r\n boxSizing: 'border-box' as const,\r\n },\r\n header: {\r\n marginBottom: '24px',\r\n borderBottom: '1px solid #e5e7eb',\r\n paddingBottom: '20px',\r\n },\r\n title: {\r\n fontSize: '24px',\r\n fontWeight: '600',\r\n marginBottom: '16px',\r\n color: '#111827',\r\n },\r\n summaryGrid: {\r\n display: 'grid',\r\n gridTemplateColumns: 'repeat(auto-fit, minmax(120px, 1fr))',\r\n gap: '16px',\r\n },\r\n summaryCard: {\r\n padding: '12px',\r\n backgroundColor: '#f9fafb',\r\n borderRadius: '8px',\r\n textAlign: 'center' as const,\r\n },\r\n summaryValue: {\r\n fontSize: '20px',\r\n fontWeight: '600',\r\n color: '#6721b0',\r\n marginBottom: '2px',\r\n },\r\n summaryLabel: {\r\n fontSize: '10px',\r\n color: '#6b7280',\r\n textTransform: 'uppercase' as const,\r\n letterSpacing: '0.05em',\r\n },\r\n questionsList: {\r\n display: 'flex',\r\n flexDirection: 'column' as const,\r\n gap: '16px',\r\n },\r\n questionCard: {\r\n padding: '16px',\r\n border: '2px solid #e5e7eb',\r\n borderRadius: '8px',\r\n },\r\n questionCardCorrect: {\r\n borderColor: '#22c55e',\r\n backgroundColor: '#f0fdf4',\r\n },\r\n questionCardIncorrect: {\r\n borderColor: '#ef4444',\r\n backgroundColor: '#fef2f2',\r\n },\r\n questionHeader: {\r\n display: 'flex',\r\n justifyContent: 'space-between',\r\n alignItems: 'flex-start',\r\n marginBottom: '12px',\r\n },\r\n questionNumber: {\r\n fontSize: '12px',\r\n color: '#6b7280',\r\n fontWeight: '500',\r\n },\r\n questionBadge: {\r\n padding: '4px 8px',\r\n borderRadius: '4px',\r\n fontSize: '12px',\r\n fontWeight: '600',\r\n },\r\n badgeCorrect: {\r\n backgroundColor: '#dcfce7',\r\n color: '#166534',\r\n },\r\n badgeIncorrect: {\r\n backgroundColor: '#fee2e2',\r\n color: '#991b1b',\r\n },\r\n questionText: {\r\n fontSize: '16px',\r\n fontWeight: '500',\r\n marginBottom: '12px',\r\n color: '#111827',\r\n },\r\n answerSection: {\r\n fontSize: '14px',\r\n marginBottom: '8px',\r\n },\r\n answerLabel: {\r\n fontWeight: '600',\r\n color: '#6b7280',\r\n marginRight: '8px',\r\n },\r\n studentAnswer: {\r\n color: '#111827',\r\n },\r\n correctAnswer: {\r\n color: '#166534',\r\n },\r\n points: {\r\n fontSize: '13px',\r\n color: '#6b7280',\r\n marginTop: '8px',\r\n },\r\n explanation: {\r\n marginTop: '12px',\r\n padding: '12px',\r\n backgroundColor: '#f3e8ff',\r\n borderRadius: '6px',\r\n fontSize: '14px',\r\n color: '#581c87',\r\n },\r\n loading: {\r\n textAlign: 'center' as const,\r\n padding: '40px 20px',\r\n },\r\n spinner: {\r\n display: 'inline-block',\r\n width: '32px',\r\n height: '32px',\r\n border: '3px solid #e5e7eb',\r\n borderTopColor: '#6721b0',\r\n borderRadius: '50%',\r\n animation: 'spin 1s linear infinite',\r\n },\r\n error: {\r\n textAlign: 'center' as const,\r\n padding: '40px 20px',\r\n color: '#ef4444',\r\n },\r\n retryButton: {\r\n marginTop: '16px',\r\n padding: '12px 24px',\r\n backgroundColor: '#6721b0',\r\n color: '#ffffff',\r\n border: 'none',\r\n borderRadius: '8px',\r\n fontSize: '16px',\r\n fontWeight: '500',\r\n cursor: 'pointer',\r\n },\r\n};\r\n\r\nconst spinnerKeyframes = `\r\n @keyframes spin {\r\n to { transform: rotate(360deg); }\r\n }\r\n`;\r\n\r\nfunction formatAnswer(answer: unknown): string {\r\n if (answer === null || answer === undefined) {\r\n return 'No answer';\r\n }\r\n if (typeof answer === 'string') {\r\n return answer;\r\n }\r\n if (Array.isArray(answer)) {\r\n return answer.join(', ');\r\n }\r\n if (typeof answer === 'object') {\r\n return Object.entries(answer as Record<string, string>)\r\n .map(([k, v]) => `${k} → ${v}`)\r\n .join(', ');\r\n }\r\n return String(answer);\r\n}\r\n\r\nexport function AttemptViewer({\r\n attemptId,\r\n apiBaseUrl,\r\n authToken,\r\n onError,\r\n className,\r\n showExplanations = true,\r\n title,\r\n}: AttemptViewerProps) {\r\n const [attempt, setAttempt] = useState<ExternalQuizAttempt | null>(null);\r\n const [loading, setLoading] = useState(true);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n useEffect(() => {\r\n const apiClient = new QuizApiClient({\r\n baseUrl: apiBaseUrl,\r\n authToken,\r\n });\r\n\r\n async function fetchAttempt() {\r\n setLoading(true);\r\n setError(null);\r\n try {\r\n const response = await fetch(`${apiBaseUrl}/api/external/quiz-attempts/${attemptId}`, {\r\n headers: authToken ? { Authorization: `Bearer ${authToken}` } : {},\r\n });\r\n if (!response.ok) {\r\n throw new Error(`Failed to fetch attempt: ${response.statusText}`);\r\n }\r\n const data = await response.json();\r\n setAttempt(data);\r\n } catch (err) {\r\n const errorMessage = err instanceof Error ? err.message : 'Failed to load attempt';\r\n setError(errorMessage);\r\n onError?.(err instanceof Error ? err : new Error(errorMessage));\r\n } finally {\r\n setLoading(false);\r\n }\r\n }\r\n\r\n fetchAttempt();\r\n }, [attemptId, apiBaseUrl, authToken, onError]);\r\n\r\n const handleRetry = () => {\r\n setLoading(true);\r\n setError(null);\r\n window.location.reload();\r\n };\r\n\r\n if (loading) {\r\n return (\r\n <div style={defaultStyles.container} className={className}>\r\n <style>{spinnerKeyframes}</style>\r\n <div style={defaultStyles.loading}>\r\n <div style={defaultStyles.spinner} />\r\n <p style={{ marginTop: '16px', color: '#6b7280' }}>Loading attempt...</p>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n if (error || !attempt) {\r\n return (\r\n <div style={defaultStyles.container} className={className}>\r\n <div style={defaultStyles.error}>\r\n <p style={{ fontSize: '18px', fontWeight: '500' }}>Failed to load attempt</p>\r\n <p style={{ marginTop: '8px', color: '#6b7280' }}>{error}</p>\r\n <button style={defaultStyles.retryButton} onClick={handleRetry}>\r\n Try Again\r\n </button>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n const scorePercentage = attempt.score ?? 0;\r\n const correctCount = attempt.correctAnswers ?? 0;\r\n const totalQuestions = attempt.totalQuestions;\r\n const timeSpent = attempt.timeSpentSeconds ?? 0;\r\n\r\n return (\r\n <div style={defaultStyles.container} className={className}>\r\n <style>{spinnerKeyframes}</style>\r\n \r\n <div style={defaultStyles.header}>\r\n <div style={defaultStyles.summaryGrid}>\r\n <div style={defaultStyles.summaryCard}>\r\n <div style={defaultStyles.summaryValue}>{scorePercentage}%</div>\r\n <div style={defaultStyles.summaryLabel}>Score</div>\r\n </div>\r\n <div style={defaultStyles.summaryCard}>\r\n <div style={defaultStyles.summaryValue}>{correctCount}/{totalQuestions}</div>\r\n <div style={defaultStyles.summaryLabel}>Correct</div>\r\n </div>\r\n <div style={defaultStyles.summaryCard}>\r\n <div style={defaultStyles.summaryValue}>{formatTime(timeSpent)}</div>\r\n <div style={defaultStyles.summaryLabel}>Time</div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div style={defaultStyles.questionsList}>\r\n {attempt.answers.map((answer: QuizAnswerDetail, index: number) => (\r\n <div\r\n key={answer.questionId}\r\n style={{\r\n ...defaultStyles.questionCard,\r\n ...(answer.isCorrect ? defaultStyles.questionCardCorrect : defaultStyles.questionCardIncorrect),\r\n }}\r\n >\r\n <div style={defaultStyles.questionHeader}>\r\n <span style={defaultStyles.questionNumber}>Question {index + 1}</span>\r\n <span\r\n style={{\r\n ...defaultStyles.questionBadge,\r\n ...(answer.isCorrect ? defaultStyles.badgeCorrect : defaultStyles.badgeIncorrect),\r\n }}\r\n >\r\n {answer.isCorrect ? 'Correct' : 'Incorrect'}\r\n </span>\r\n </div>\r\n\r\n <div style={defaultStyles.questionText}>{answer.questionText}</div>\r\n\r\n <div style={defaultStyles.answerSection}>\r\n <span style={defaultStyles.answerLabel}>Your answer:</span>\r\n <span style={defaultStyles.studentAnswer}>\r\n {formatAnswer(answer.selectedAnswer)}\r\n </span>\r\n </div>\r\n\r\n {!answer.isCorrect && answer.correctAnswer && (\r\n <div style={defaultStyles.answerSection}>\r\n <span style={defaultStyles.answerLabel}>Correct answer:</span>\r\n <span style={defaultStyles.correctAnswer}>\r\n {formatAnswer(answer.correctAnswer)}\r\n </span>\r\n </div>\r\n )}\r\n\r\n <div style={defaultStyles.points}>\r\n {answer.pointsEarned} / {answer.points} points\r\n </div>\r\n\r\n {showExplanations && answer.explanation && (\r\n <div style={defaultStyles.explanation}>\r\n <strong>Explanation:</strong> {answer.explanation}\r\n </div>\r\n )}\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n );\r\n}\r\n"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@schoolio/player",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Quiz Player component for loading and playing quizzes from Quiz Engine",
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "Quiz Player component for loading and playing quizzes, and attempts from Quiz Engine",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
7
7
|
"types": "./dist/index.d.ts",
|