@schoolio/player 1.4.3 → 1.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -103,6 +103,13 @@ var QuizApiClient = class {
103
103
  }
104
104
  return response.blob();
105
105
  }
106
+ async logError(params) {
107
+ try {
108
+ await this.request("POST", "/api/external/log-error", params);
109
+ } catch (e) {
110
+ console.warn("[QuizEngine] Failed to log error:", e);
111
+ }
112
+ }
106
113
  };
107
114
 
108
115
  // src/utils.ts
@@ -158,15 +165,16 @@ function checkAnswer(question, selectedAnswer) {
158
165
  return { isCorrect, pointsEarned: isCorrect ? points : 0 };
159
166
  }
160
167
  case "essay":
161
- case "assessment":
162
168
  return { isCorrect: false, pointsEarned: 0 };
169
+ case "assessment":
170
+ return { isCorrect: true, pointsEarned: points };
163
171
  default:
164
172
  return { isCorrect: false, pointsEarned: 0 };
165
173
  }
166
174
  }
167
175
  function createAnswerDetail(question, selectedAnswer) {
168
176
  const { isCorrect, pointsEarned } = checkAnswer(question, selectedAnswer);
169
- return {
177
+ const detail = {
170
178
  questionId: question.id,
171
179
  questionText: question.question,
172
180
  questionType: question.type,
@@ -178,6 +186,14 @@ function createAnswerDetail(question, selectedAnswer) {
178
186
  explanation: question.explanation,
179
187
  hint: question.hint
180
188
  };
189
+ if (question.type === "sorting") {
190
+ detail.items = question.items;
191
+ detail.correctOrder = question.correctOrder;
192
+ } else if (question.type === "matrix") {
193
+ detail.leftItems = question.leftItems;
194
+ detail.rightItems = question.rightItems;
195
+ }
196
+ return detail;
181
197
  }
182
198
  function calculateScore(answers) {
183
199
  const totalPoints = answers.reduce((sum, a) => sum + a.points, 0);
@@ -1014,8 +1030,191 @@ function QuestionChatPanel({
1014
1030
  ] });
1015
1031
  }
1016
1032
 
1033
+ // src/errors.ts
1034
+ var ERROR_DEFINITIONS = {
1035
+ QUIZ_NOT_FOUND: {
1036
+ code: "QUIZ_NOT_FOUND",
1037
+ userMessage: "We couldn't find this quiz",
1038
+ subMessage: "The quiz may have been removed or the link is incorrect.",
1039
+ cause: "The quiz ID does not exist in the database, or the quiz has been deleted.",
1040
+ isBlocking: true
1041
+ },
1042
+ ATTEMPT_NOT_FOUND: {
1043
+ code: "ATTEMPT_NOT_FOUND",
1044
+ userMessage: "We couldn't find this quiz attempt",
1045
+ subMessage: "The attempt may have expired or the link is incorrect.",
1046
+ cause: "The attempt ID does not exist, or the attempt has been deleted/archived.",
1047
+ isBlocking: true
1048
+ },
1049
+ QUIZ_EXPIRED: {
1050
+ code: "QUIZ_EXPIRED",
1051
+ userMessage: "This quiz has expired",
1052
+ subMessage: "The deadline for this quiz has passed.",
1053
+ cause: "The quiz end date/time has passed and submissions are no longer accepted.",
1054
+ isBlocking: true
1055
+ },
1056
+ QUIZ_NOT_STARTED: {
1057
+ code: "QUIZ_NOT_STARTED",
1058
+ userMessage: "This quiz is not available yet",
1059
+ subMessage: "Please check back when the quiz opens.",
1060
+ cause: "The quiz start date/time has not yet been reached.",
1061
+ isBlocking: true
1062
+ },
1063
+ NETWORK_ERROR: {
1064
+ code: "NETWORK_ERROR",
1065
+ userMessage: "Connection problem",
1066
+ subMessage: "Please check your internet connection and try again.",
1067
+ cause: "Unable to reach the server due to network connectivity issues.",
1068
+ isBlocking: true
1069
+ },
1070
+ SERVER_ERROR: {
1071
+ code: "SERVER_ERROR",
1072
+ userMessage: "Something went wrong on our end",
1073
+ subMessage: "Our team has been notified. Please try again later.",
1074
+ cause: "The server encountered an internal error (HTTP 500+).",
1075
+ isBlocking: true
1076
+ },
1077
+ UNAUTHORIZED: {
1078
+ code: "UNAUTHORIZED",
1079
+ userMessage: "Please sign in to continue",
1080
+ subMessage: "You need to be logged in to access this quiz.",
1081
+ cause: "The user is not authenticated (HTTP 401).",
1082
+ isBlocking: true
1083
+ },
1084
+ FORBIDDEN: {
1085
+ code: "FORBIDDEN",
1086
+ userMessage: "You don't have access to this quiz",
1087
+ subMessage: "Contact your instructor if you believe this is a mistake.",
1088
+ cause: "The user does not have permission to access this resource (HTTP 403).",
1089
+ isBlocking: true
1090
+ },
1091
+ TTS_FAILED: {
1092
+ code: "TTS_FAILED",
1093
+ userMessage: "Text-to-speech unavailable",
1094
+ subMessage: "Audio features are temporarily unavailable.",
1095
+ cause: "The text-to-speech service failed or is unreachable.",
1096
+ isBlocking: false
1097
+ },
1098
+ CHAT_FAILED: {
1099
+ code: "CHAT_FAILED",
1100
+ userMessage: "Chat assistance unavailable",
1101
+ subMessage: "The AI helper is temporarily unavailable.",
1102
+ cause: "The chat/AI service failed to initialize or respond.",
1103
+ isBlocking: false
1104
+ },
1105
+ SUBMISSION_FAILED: {
1106
+ code: "SUBMISSION_FAILED",
1107
+ userMessage: "Failed to submit your answer",
1108
+ subMessage: "Please try again. Your progress has been saved.",
1109
+ cause: "The answer submission request failed due to network or server issues.",
1110
+ isBlocking: false
1111
+ },
1112
+ UNKNOWN_ERROR: {
1113
+ code: "UNKNOWN_ERROR",
1114
+ userMessage: "Something unexpected happened",
1115
+ subMessage: "Please try refreshing the page.",
1116
+ cause: "An unclassified error occurred.",
1117
+ isBlocking: true
1118
+ }
1119
+ };
1120
+ function getErrorFromHttpStatus(status, context) {
1121
+ switch (status) {
1122
+ case 401:
1123
+ return "UNAUTHORIZED";
1124
+ case 403:
1125
+ return "FORBIDDEN";
1126
+ case 404:
1127
+ return context === "attempt" ? "ATTEMPT_NOT_FOUND" : "QUIZ_NOT_FOUND";
1128
+ case 410:
1129
+ return "QUIZ_EXPIRED";
1130
+ case 500:
1131
+ case 502:
1132
+ case 503:
1133
+ case 504:
1134
+ return "SERVER_ERROR";
1135
+ default:
1136
+ if (status >= 400 && status < 500) {
1137
+ return context === "attempt" ? "ATTEMPT_NOT_FOUND" : "QUIZ_NOT_FOUND";
1138
+ }
1139
+ return "UNKNOWN_ERROR";
1140
+ }
1141
+ }
1142
+ function getErrorFromMessage(message, context) {
1143
+ const lowerMessage = message.toLowerCase();
1144
+ if (lowerMessage.includes("network") || lowerMessage.includes("fetch") || lowerMessage.includes("connection")) {
1145
+ return "NETWORK_ERROR";
1146
+ }
1147
+ if (lowerMessage.includes("not found") || lowerMessage.includes("404")) {
1148
+ return context === "attempt" ? "ATTEMPT_NOT_FOUND" : "QUIZ_NOT_FOUND";
1149
+ }
1150
+ if (lowerMessage.includes("unauthorized") || lowerMessage.includes("401")) {
1151
+ return "UNAUTHORIZED";
1152
+ }
1153
+ if (lowerMessage.includes("forbidden") || lowerMessage.includes("403")) {
1154
+ return "FORBIDDEN";
1155
+ }
1156
+ if (lowerMessage.includes("expired")) {
1157
+ return "QUIZ_EXPIRED";
1158
+ }
1159
+ if (lowerMessage.includes("tts") || lowerMessage.includes("speech")) {
1160
+ return "TTS_FAILED";
1161
+ }
1162
+ if (lowerMessage.includes("chat")) {
1163
+ return "CHAT_FAILED";
1164
+ }
1165
+ return "UNKNOWN_ERROR";
1166
+ }
1167
+
1168
+ // src/MaintenanceScreen.tsx
1169
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
1170
+ function MaintenanceScreen({ errorCode }) {
1171
+ const errorDef = errorCode ? ERROR_DEFINITIONS[errorCode] : null;
1172
+ const message = errorDef?.userMessage || "Your quiz is on its way...";
1173
+ const subMessage = errorDef?.subMessage || "Please check back soon!";
1174
+ const containerStyle = {
1175
+ display: "flex",
1176
+ flexDirection: "column",
1177
+ alignItems: "center",
1178
+ justifyContent: "center",
1179
+ minHeight: "300px",
1180
+ padding: "40px",
1181
+ background: "linear-gradient(135deg, #f8f7ff 0%, #e8e4f8 50%, #f0ebff 100%)",
1182
+ borderRadius: "16px"
1183
+ };
1184
+ const iconStyle = {
1185
+ fontSize: "48px",
1186
+ marginBottom: "24px",
1187
+ color: "#8b5cf6"
1188
+ };
1189
+ const messageStyle = {
1190
+ fontSize: "20px",
1191
+ fontWeight: "600",
1192
+ color: "#4c1d95",
1193
+ textAlign: "center",
1194
+ marginBottom: "12px"
1195
+ };
1196
+ const submessageStyle = {
1197
+ fontSize: "14px",
1198
+ color: "#7c3aed",
1199
+ textAlign: "center",
1200
+ opacity: 0.8
1201
+ };
1202
+ return /* @__PURE__ */ jsxs3("div", { style: containerStyle, "data-testid": "maintenance-screen", "data-error-code": errorCode || "none", children: [
1203
+ /* @__PURE__ */ jsx3("div", { style: iconStyle, children: /* @__PURE__ */ jsxs3("svg", { width: "64", height: "64", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1204
+ /* @__PURE__ */ jsx3("circle", { cx: "12", cy: "12", r: "10" }),
1205
+ /* @__PURE__ */ jsx3("path", { d: "M12 8v4" }),
1206
+ /* @__PURE__ */ jsx3("path", { d: "M12 16h.01" })
1207
+ ] }) }),
1208
+ /* @__PURE__ */ jsx3("div", { style: messageStyle, "data-testid": "text-error-message", children: message }),
1209
+ /* @__PURE__ */ jsx3("div", { style: submessageStyle, "data-testid": "text-error-submessage", children: subMessage })
1210
+ ] });
1211
+ }
1212
+
1213
+ // src/assets/astronautData.ts
1214
+ var astronautImage = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAB4AAAAQ4CAMAAADfDTFxAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAwBQTFRFYGBgsVEZcHBwq6urhYSEkZGRiomJuJsBMxoHJCAhUFBQQEBAXZu4ATtbnp6ev7+/dDURJnqMdnR1enl5ABoqAm2rVSYMamhpLCkqKCUlz8/PMS0uWksA39/fbmxtAViJEBAQAAAAzunzMDAwPDo6qKioj46OgICAoqKiOC8AOTU2oKCgaq3LNDExibbNQD4+mpqaV1RVRUJCZmRlpqampKSkSEVGlpaWUE5OTElKnJycIm5+mJiYXlxdf35+lJSUXFlaU1FSZGFiWFZWAV+UBGaebtLoWlhZqMjWTMjiS0hJc3FyAUlyidvtbGpraGZmb25ujYyMYF5ed3Z2F0lUFw4CAVB+////AUJnLCgpecXVKXyqfHp75eXlT0xN1dXVNzQ1hai8ksXZPzw9qNLlTn6UsOfywMDAICAgASxFwNzsEz1GgH5/R0RFJ1ZwOjc4JiIjNjM0KicoRmt4tra2HhscMi8vXVtbACU5CwsLLisreJ+xKUhWBHS0gYCBOzg5fnx9YmBghIOD/NQBITlHgH9/PMPgWVdYJyQlMCwtESYyIx8gTUtLgoGBPV5qSUdH8m4jg4KCVVNTAA8XfHt7DwcCAAcLAHW4FRQV7+/vr6+vBAwOOLfSDzE4LZKoHmJwRkNEQj9APjs8CyUqCBgcMZ62i4qLj4+P42chfXx8aWdoDw4OUk9QZWNjNavExVkcAGahGlViKYaal0UWjo2NbWtsiYiI1GAfh4aH7McBfmoBl5eXlZWVk5KSn5+fdHNzpaWlnZ2dfn19cW9viD4UkI+Qjo2OeHd33boBnoUBATNQzawBjncBbl0AnuHw7/b63+/3EBcbFH256urqEkpq+vr6mZmZElJ1GhgYU1xeo6OjGG6fm5ubEh4jRVdejIuM9fX1lpWWnp2elJOTICcrnJuboaGhornEE3WtQU5Wv9HaJzg8h5icQZSmz9jeeo+XY2xucHd7EjtTkJ2iBwYGfYqNGV+HMTtAQoWr8/v9v8bIw8vNIi0yZHyHFygs////mvWEFwAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAMcVSURBVHja7L3viyRnuf9f9CRCuhgLtAeTlj5TRcdTwSUkRo+bBDXG2SDoMIkubI/g8Sz4wBow5AdnzczAJsfAYGRXgo7MTPWjGA5pNAr7QEXQVNSQE9hnIsoiHvacj99z/oJ9dJ747brv+v2ju7q7qqa79/V6oMlmd3709vSrr+u+rvet/B0AAABqR+EhAAAAQMAAAAAIGAAAABAwAAAAAgYAAAAEDAAAgIABAAAAAQMAACBgAAAAQMAAAAAIGAAAAAEDAAAAAgaA6dE0zTkQKOqQhvzn4a92eGwAEDAAlE1bOzhQVd0YSVdVDhxMDICAAaCMktc5UC1jItTmQR8NAyBgAJjWvQOla0yLrjawMAACBoDJsPsNNb/CFTTNIfIfcytkqzlo82ACIGAAKFb5NjIKX0tVzIGmdXo5aFrf9XFGKdwcUAkDIGAAGE3HaaYKXsXU2r3CaI6ZKomtRp+HFgABA0CefQeJ0lc1+xOoN6bh5Pmxrjg2jzAAAgaAMfa1lMGU7g2wNTPekm46PMwACBgAIthON3Zs63R6JaGZsY+saDzYAAgYACR9JRqnYbZ75WL3lUiEh3XATBYAAgaAv9sHVrRJ3OlVQrsR/SyMZAEgYIDbHE2J2tfuVUjUwdYBE1kACBjg9sUJh6S6g06vcrSwF60rdKIBEDDAbYntWKEN272aiDi/yUAWAAIGuP30exAUo12nVyedRvCZVRQMgIABblf91lf8RsrgLgoGQMAAtyGBfnXT7p0KWhMFAyBggNuM4OzXck5Jv6ITHcxfNxnHAkDAAMuPFuq3d7qEClZYSgJAwADLTUedF/3GFKwf8FcDgIABlhf7YJ70G1OwxVEwAAIGWFb61imPXmUqWOUoGAABAywzgekac6RfMRHtLSXpA/6S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";
1215
+
1017
1216
  // src/QuizPlayer.tsx
1018
- import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
1217
+ import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1019
1218
  var defaultStyles = {
1020
1219
  container: {
1021
1220
  fontFamily: "system-ui, -apple-system, sans-serif",
@@ -1316,6 +1515,13 @@ var defaultStyles = {
1316
1515
  backgroundColor: "#fef2f2",
1317
1516
  borderColor: "#ef4444"
1318
1517
  },
1518
+ feedbackNeutral: {
1519
+ backgroundColor: "#f0f9ff",
1520
+ borderColor: "#0ea5e9"
1521
+ },
1522
+ feedbackTitleNeutral: {
1523
+ color: "#0369a1"
1524
+ },
1319
1525
  feedbackTitle: {
1320
1526
  fontSize: "16px",
1321
1527
  fontWeight: "600",
@@ -1336,8 +1542,292 @@ var defaultStyles = {
1336
1542
  lineHeight: "1.5"
1337
1543
  }
1338
1544
  };
1545
+ function SortingDragDrop({ items, currentOrder, correctOrder, showFeedback, onOrderChange }) {
1546
+ const [draggedIndex, setDraggedIndex] = useState3(null);
1547
+ const [dragOverIndex, setDragOverIndex] = useState3(null);
1548
+ const handleDragStart = (e, position) => {
1549
+ if (showFeedback) return;
1550
+ setDraggedIndex(position);
1551
+ e.dataTransfer.effectAllowed = "move";
1552
+ e.dataTransfer.setData("text/plain", position.toString());
1553
+ };
1554
+ const handleDragOver = (e, position) => {
1555
+ e.preventDefault();
1556
+ if (showFeedback) return;
1557
+ e.dataTransfer.dropEffect = "move";
1558
+ setDragOverIndex(position);
1559
+ };
1560
+ const handleDragLeave = () => {
1561
+ setDragOverIndex(null);
1562
+ };
1563
+ const handleDrop = (e, toPosition) => {
1564
+ e.preventDefault();
1565
+ if (showFeedback) return;
1566
+ const fromPosition = parseInt(e.dataTransfer.getData("text/plain"), 10);
1567
+ if (fromPosition !== toPosition) {
1568
+ const newOrder = [...currentOrder];
1569
+ const [movedItem] = newOrder.splice(fromPosition, 1);
1570
+ newOrder.splice(toPosition, 0, movedItem);
1571
+ onOrderChange(newOrder);
1572
+ }
1573
+ setDraggedIndex(null);
1574
+ setDragOverIndex(null);
1575
+ };
1576
+ const handleDragEnd = () => {
1577
+ setDraggedIndex(null);
1578
+ setDragOverIndex(null);
1579
+ };
1580
+ return /* @__PURE__ */ jsx4("div", { style: defaultStyles.options, children: currentOrder.map((itemIndex, position) => {
1581
+ const isCorrectPosition = correctOrder?.[position] === itemIndex;
1582
+ const isDragging = draggedIndex === position;
1583
+ const isDragOver = dragOverIndex === position;
1584
+ let itemStyle = {
1585
+ ...defaultStyles.option,
1586
+ display: "flex",
1587
+ alignItems: "center",
1588
+ gap: "12px",
1589
+ cursor: showFeedback ? "default" : "grab",
1590
+ opacity: isDragging ? 0.5 : 1,
1591
+ transition: "all 0.2s ease",
1592
+ transform: isDragOver && !showFeedback ? "scale(1.02)" : "scale(1)"
1593
+ };
1594
+ if (showFeedback) {
1595
+ if (isCorrectPosition) {
1596
+ itemStyle = { ...itemStyle, ...defaultStyles.optionCorrect };
1597
+ } else {
1598
+ itemStyle = { ...itemStyle, ...defaultStyles.optionIncorrect };
1599
+ }
1600
+ } else if (isDragOver) {
1601
+ itemStyle = { ...itemStyle, borderColor: "#6366f1", backgroundColor: "#eef2ff" };
1602
+ }
1603
+ return /* @__PURE__ */ jsxs4(
1604
+ "div",
1605
+ {
1606
+ style: itemStyle,
1607
+ "data-testid": `sorting-item-${position}`,
1608
+ draggable: !showFeedback,
1609
+ onDragStart: (e) => handleDragStart(e, position),
1610
+ onDragOver: (e) => handleDragOver(e, position),
1611
+ onDragLeave: handleDragLeave,
1612
+ onDrop: (e) => handleDrop(e, position),
1613
+ onDragEnd: handleDragEnd,
1614
+ children: [
1615
+ !showFeedback && /* @__PURE__ */ jsx4("div", { style: {
1616
+ cursor: "grab",
1617
+ padding: "4px",
1618
+ display: "flex",
1619
+ alignItems: "center",
1620
+ color: "#9ca3af"
1621
+ }, children: /* @__PURE__ */ jsxs4("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1622
+ /* @__PURE__ */ jsx4("circle", { cx: "9", cy: "5", r: "1" }),
1623
+ /* @__PURE__ */ jsx4("circle", { cx: "9", cy: "12", r: "1" }),
1624
+ /* @__PURE__ */ jsx4("circle", { cx: "9", cy: "19", r: "1" }),
1625
+ /* @__PURE__ */ jsx4("circle", { cx: "15", cy: "5", r: "1" }),
1626
+ /* @__PURE__ */ jsx4("circle", { cx: "15", cy: "12", r: "1" }),
1627
+ /* @__PURE__ */ jsx4("circle", { cx: "15", cy: "19", r: "1" })
1628
+ ] }) }),
1629
+ showFeedback && /* @__PURE__ */ jsx4("div", { style: {
1630
+ display: "flex",
1631
+ alignItems: "center",
1632
+ color: isCorrectPosition ? "#22c55e" : "#ef4444"
1633
+ }, children: isCorrectPosition ? /* @__PURE__ */ jsxs4("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1634
+ /* @__PURE__ */ jsx4("path", { d: "M22 11.08V12a10 10 0 1 1-5.93-9.14" }),
1635
+ /* @__PURE__ */ jsx4("polyline", { points: "22 4 12 14.01 9 11.01" })
1636
+ ] }) : /* @__PURE__ */ jsxs4("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1637
+ /* @__PURE__ */ jsx4("circle", { cx: "12", cy: "12", r: "10" }),
1638
+ /* @__PURE__ */ jsx4("line", { x1: "15", y1: "9", x2: "9", y2: "15" }),
1639
+ /* @__PURE__ */ jsx4("line", { x1: "9", y1: "9", x2: "15", y2: "15" })
1640
+ ] }) }),
1641
+ /* @__PURE__ */ jsx4("span", { style: { flex: 1 }, children: items[itemIndex] }),
1642
+ /* @__PURE__ */ jsx4("span", { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsx4(TextToSpeech, { text: items[itemIndex], size: "sm" }) })
1643
+ ]
1644
+ },
1645
+ itemIndex
1646
+ );
1647
+ }) });
1648
+ }
1649
+ function MatchingDragDrop({ leftItems, rightItems, currentMatches, correctMatches, showFeedback, onMatchChange }) {
1650
+ const [draggedItem, setDraggedItem] = useState3(null);
1651
+ const [dragOverLeft, setDragOverLeft] = useState3(null);
1652
+ const matchedRightItems = Object.values(currentMatches);
1653
+ const unmatchedRightItems = rightItems.filter((item) => !matchedRightItems.includes(item));
1654
+ const handleDragStart = (e, rightItem) => {
1655
+ if (showFeedback) return;
1656
+ setDraggedItem(rightItem);
1657
+ e.dataTransfer.effectAllowed = "move";
1658
+ e.dataTransfer.setData("text/plain", rightItem);
1659
+ };
1660
+ const handleDragOver = (e, leftItem) => {
1661
+ e.preventDefault();
1662
+ if (showFeedback) return;
1663
+ e.dataTransfer.dropEffect = "move";
1664
+ setDragOverLeft(leftItem);
1665
+ };
1666
+ const handleDragLeave = () => {
1667
+ setDragOverLeft(null);
1668
+ };
1669
+ const handleDrop = (e, leftItem) => {
1670
+ e.preventDefault();
1671
+ if (showFeedback) return;
1672
+ const rightItem = e.dataTransfer.getData("text/plain");
1673
+ if (rightItem) {
1674
+ const newMatches = { ...currentMatches };
1675
+ Object.keys(newMatches).forEach((key) => {
1676
+ if (newMatches[key] === rightItem) {
1677
+ delete newMatches[key];
1678
+ }
1679
+ });
1680
+ newMatches[leftItem] = rightItem;
1681
+ onMatchChange(newMatches);
1682
+ }
1683
+ setDraggedItem(null);
1684
+ setDragOverLeft(null);
1685
+ };
1686
+ const handleDragEnd = () => {
1687
+ setDraggedItem(null);
1688
+ setDragOverLeft(null);
1689
+ };
1690
+ const handleClearMatch = (leftItem) => {
1691
+ if (showFeedback) return;
1692
+ const newMatches = { ...currentMatches };
1693
+ delete newMatches[leftItem];
1694
+ onMatchChange(newMatches);
1695
+ };
1696
+ return /* @__PURE__ */ jsxs4("div", { style: { display: "flex", gap: "24px", flexWrap: "wrap" }, children: [
1697
+ /* @__PURE__ */ jsxs4("div", { style: { flex: 1, minWidth: "200px", display: "flex", flexDirection: "column", gap: "8px" }, children: [
1698
+ /* @__PURE__ */ jsx4("div", { style: { fontSize: "14px", fontWeight: "600", color: "#6b7280", marginBottom: "4px" }, children: "Match these items:" }),
1699
+ leftItems.map((leftItem, idx) => {
1700
+ const matchedRight = currentMatches[leftItem];
1701
+ const correctMatch = correctMatches?.[leftItem];
1702
+ const isCorrect = matchedRight === correctMatch;
1703
+ const isDragOver = dragOverLeft === leftItem;
1704
+ let rowStyle = {
1705
+ display: "flex",
1706
+ alignItems: "center",
1707
+ gap: "12px",
1708
+ padding: "12px 16px",
1709
+ border: "2px dashed #e5e7eb",
1710
+ borderRadius: "8px",
1711
+ backgroundColor: "#ffffff",
1712
+ minHeight: "56px",
1713
+ transition: "all 0.2s ease"
1714
+ };
1715
+ if (showFeedback) {
1716
+ rowStyle.borderStyle = "solid";
1717
+ if (isCorrect) {
1718
+ rowStyle = { ...rowStyle, borderColor: "#22c55e", backgroundColor: "#f0fdf4" };
1719
+ } else {
1720
+ rowStyle = { ...rowStyle, borderColor: "#ef4444", backgroundColor: "#fef2f2" };
1721
+ }
1722
+ } else if (isDragOver) {
1723
+ rowStyle = { ...rowStyle, borderColor: "#6366f1", backgroundColor: "#eef2ff", borderStyle: "solid" };
1724
+ } else if (matchedRight) {
1725
+ rowStyle = { ...rowStyle, borderStyle: "solid", borderColor: "#22c55e" };
1726
+ }
1727
+ return /* @__PURE__ */ jsxs4(
1728
+ "div",
1729
+ {
1730
+ style: rowStyle,
1731
+ "data-testid": `matrix-row-${idx}`,
1732
+ onDragOver: (e) => handleDragOver(e, leftItem),
1733
+ onDragLeave: handleDragLeave,
1734
+ onDrop: (e) => handleDrop(e, leftItem),
1735
+ children: [
1736
+ /* @__PURE__ */ jsx4("span", { style: { flex: 1, fontWeight: "500" }, children: leftItem }),
1737
+ /* @__PURE__ */ jsx4("span", { style: { color: "#6b7280" }, children: "\u2192" }),
1738
+ matchedRight ? /* @__PURE__ */ jsxs4("div", { style: {
1739
+ display: "flex",
1740
+ alignItems: "center",
1741
+ gap: "8px",
1742
+ padding: "6px 12px",
1743
+ backgroundColor: showFeedback ? isCorrect ? "#dcfce7" : "#fee2e2" : "#e0e7ff",
1744
+ borderRadius: "6px",
1745
+ fontSize: "14px"
1746
+ }, children: [
1747
+ /* @__PURE__ */ jsx4("span", { children: matchedRight }),
1748
+ !showFeedback && /* @__PURE__ */ jsx4(
1749
+ "button",
1750
+ {
1751
+ onClick: () => handleClearMatch(leftItem),
1752
+ style: {
1753
+ background: "none",
1754
+ border: "none",
1755
+ cursor: "pointer",
1756
+ padding: "2px",
1757
+ display: "flex",
1758
+ color: "#6b7280"
1759
+ },
1760
+ "aria-label": "Remove match",
1761
+ children: /* @__PURE__ */ jsxs4("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1762
+ /* @__PURE__ */ jsx4("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1763
+ /* @__PURE__ */ jsx4("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1764
+ ] })
1765
+ }
1766
+ ),
1767
+ showFeedback && (isCorrect ? /* @__PURE__ */ jsx4("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "#22c55e", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx4("polyline", { points: "20 6 9 17 4 12" }) }) : /* @__PURE__ */ jsxs4("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "#ef4444", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1768
+ /* @__PURE__ */ jsx4("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1769
+ /* @__PURE__ */ jsx4("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1770
+ ] }))
1771
+ ] }) : /* @__PURE__ */ jsx4("span", { style: { color: "#9ca3af", fontSize: "14px", fontStyle: "italic" }, children: "Drop here" }),
1772
+ showFeedback && !isCorrect && correctMatch && /* @__PURE__ */ jsxs4("span", { style: { color: "#166534", fontSize: "13px", marginLeft: "8px" }, children: [
1773
+ "(Correct: ",
1774
+ correctMatch,
1775
+ ")"
1776
+ ] })
1777
+ ]
1778
+ },
1779
+ idx
1780
+ );
1781
+ })
1782
+ ] }),
1783
+ /* @__PURE__ */ jsxs4("div", { style: { flex: 1, minWidth: "200px", display: "flex", flexDirection: "column", gap: "8px" }, children: [
1784
+ /* @__PURE__ */ jsx4("div", { style: { fontSize: "14px", fontWeight: "600", color: "#6b7280", marginBottom: "4px" }, children: "Drag to match:" }),
1785
+ unmatchedRightItems.length > 0 ? unmatchedRightItems.map((rightItem, idx) => {
1786
+ const isDragging = draggedItem === rightItem;
1787
+ return /* @__PURE__ */ jsxs4(
1788
+ "div",
1789
+ {
1790
+ style: {
1791
+ padding: "12px 16px",
1792
+ border: "2px solid #e5e7eb",
1793
+ borderRadius: "8px",
1794
+ backgroundColor: "#ffffff",
1795
+ cursor: showFeedback ? "default" : "grab",
1796
+ opacity: isDragging ? 0.5 : 1,
1797
+ display: "flex",
1798
+ alignItems: "center",
1799
+ gap: "8px",
1800
+ transition: "all 0.2s ease"
1801
+ },
1802
+ draggable: !showFeedback,
1803
+ onDragStart: (e) => handleDragStart(e, rightItem),
1804
+ onDragEnd: handleDragEnd,
1805
+ "data-testid": `draggable-right-${idx}`,
1806
+ children: [
1807
+ !showFeedback && /* @__PURE__ */ jsx4("div", { style: { color: "#9ca3af", display: "flex" }, children: /* @__PURE__ */ jsxs4("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1808
+ /* @__PURE__ */ jsx4("circle", { cx: "9", cy: "5", r: "1" }),
1809
+ /* @__PURE__ */ jsx4("circle", { cx: "9", cy: "12", r: "1" }),
1810
+ /* @__PURE__ */ jsx4("circle", { cx: "9", cy: "19", r: "1" }),
1811
+ /* @__PURE__ */ jsx4("circle", { cx: "15", cy: "5", r: "1" }),
1812
+ /* @__PURE__ */ jsx4("circle", { cx: "15", cy: "12", r: "1" }),
1813
+ /* @__PURE__ */ jsx4("circle", { cx: "15", cy: "19", r: "1" })
1814
+ ] }) }),
1815
+ /* @__PURE__ */ jsx4("span", { style: { flex: 1 }, children: rightItem })
1816
+ ]
1817
+ },
1818
+ idx
1819
+ );
1820
+ }) : /* @__PURE__ */ jsx4("div", { style: {
1821
+ padding: "16px",
1822
+ textAlign: "center",
1823
+ color: "#22c55e",
1824
+ fontSize: "14px"
1825
+ }, children: "All items matched!" })
1826
+ ] })
1827
+ ] });
1828
+ }
1339
1829
  function Spinner({ size = 16, color = "#ffffff" }) {
1340
- return /* @__PURE__ */ jsx3(
1830
+ return /* @__PURE__ */ jsx4(
1341
1831
  "span",
1342
1832
  {
1343
1833
  style: {
@@ -1349,7 +1839,7 @@ function Spinner({ size = 16, color = "#ffffff" }) {
1349
1839
  borderRadius: "50%",
1350
1840
  animation: "spin 0.8s linear infinite"
1351
1841
  },
1352
- children: /* @__PURE__ */ jsx3("style", { children: `@keyframes spin { to { transform: rotate(360deg); } }` })
1842
+ children: /* @__PURE__ */ jsx4("style", { children: `@keyframes spin { to { transform: rotate(360deg); } }` })
1353
1843
  }
1354
1844
  );
1355
1845
  }
@@ -1367,7 +1857,8 @@ function QuizPlayer({
1367
1857
  onProgress,
1368
1858
  onGenerateMoreQuestions,
1369
1859
  className,
1370
- forceNewAttempt = true
1860
+ forceNewAttempt = true,
1861
+ hideScore = false
1371
1862
  }) {
1372
1863
  const [quiz, setQuiz] = useState3(null);
1373
1864
  const [attempt, setAttempt] = useState3(null);
@@ -1378,10 +1869,14 @@ function QuizPlayer({
1378
1869
  const [isNavigating, setIsNavigating] = useState3(false);
1379
1870
  const [isCompleted, setIsCompleted] = useState3(false);
1380
1871
  const [result, setResult] = useState3(null);
1381
- const [error, setError] = useState3(null);
1872
+ const [errorCode, setErrorCode] = useState3(null);
1382
1873
  const [isLoading, setIsLoading] = useState3(true);
1383
1874
  const [elapsedSeconds, setElapsedSeconds] = useState3(0);
1384
1875
  const [showIntro, setShowIntro] = useState3(true);
1876
+ const [showResumeChoice, setShowResumeChoice] = useState3(false);
1877
+ const [hasExistingProgress, setHasExistingProgress] = useState3(false);
1878
+ const [existingProgressCount, setExistingProgressCount] = useState3(0);
1879
+ const [isStartingFresh, setIsStartingFresh] = useState3(false);
1385
1880
  const [timerStarted, setTimerStarted] = useState3(false);
1386
1881
  const [showFeedback, setShowFeedback] = useState3(false);
1387
1882
  const [currentAnswerDetail, setCurrentAnswerDetail] = useState3(null);
@@ -1416,7 +1911,7 @@ function QuizPlayer({
1416
1911
  if (!apiClient.current) return;
1417
1912
  try {
1418
1913
  setIsLoading(true);
1419
- setError(null);
1914
+ setErrorCode(null);
1420
1915
  const quizData = await apiClient.current.getQuiz(quizId);
1421
1916
  setQuiz(quizData);
1422
1917
  const attemptData = await apiClient.current.createAttempt({
@@ -1429,7 +1924,10 @@ function QuizPlayer({
1429
1924
  forceNew: forceNewAttempt
1430
1925
  });
1431
1926
  setAttempt(attemptData);
1432
- if (!forceNewAttempt && attemptData.answers && attemptData.answers.length > 0) {
1927
+ if (!forceNewAttempt && attemptData.answers && attemptData.answers.length > 0 && attemptData.status === "in_progress") {
1928
+ setHasExistingProgress(true);
1929
+ setExistingProgressCount(attemptData.answers.length);
1930
+ setShowResumeChoice(true);
1433
1931
  setAnswersDetail(attemptData.answers);
1434
1932
  const answersMap = /* @__PURE__ */ new Map();
1435
1933
  attemptData.answers.forEach((a) => {
@@ -1452,7 +1950,15 @@ function QuizPlayer({
1452
1950
  setIsLoading(false);
1453
1951
  } catch (err) {
1454
1952
  const message = err instanceof Error ? err.message : "Failed to load quiz";
1455
- setError(message);
1953
+ const code = getErrorFromMessage(message, "quiz");
1954
+ setErrorCode(code);
1955
+ apiClient.current?.logError({
1956
+ errorCode: code,
1957
+ context: "quiz",
1958
+ resourceId: quizId,
1959
+ component: "QuizPlayer",
1960
+ message
1961
+ });
1456
1962
  setIsLoading(false);
1457
1963
  onErrorRef.current?.(err instanceof Error ? err : new Error(message));
1458
1964
  }
@@ -1460,7 +1966,7 @@ function QuizPlayer({
1460
1966
  initialize();
1461
1967
  }, [quizId, lessonId, assignLessonId, courseId, childId, parentId, forceNewAttempt]);
1462
1968
  useEffect3(() => {
1463
- if (timerStarted && !isCompleted && !error) {
1969
+ if (timerStarted && !isCompleted && !errorCode) {
1464
1970
  startTimeRef.current = Date.now();
1465
1971
  timerRef.current = setInterval(() => {
1466
1972
  setElapsedSeconds(Math.floor((Date.now() - startTimeRef.current) / 1e3));
@@ -1471,11 +1977,62 @@ function QuizPlayer({
1471
1977
  clearInterval(timerRef.current);
1472
1978
  }
1473
1979
  };
1474
- }, [timerStarted, isCompleted, error]);
1980
+ }, [timerStarted, isCompleted, errorCode]);
1475
1981
  const handleStart = useCallback2(() => {
1476
1982
  setShowIntro(false);
1983
+ setShowResumeChoice(false);
1477
1984
  setTimerStarted(true);
1478
1985
  }, []);
1986
+ const handleResumePrevious = useCallback2(() => {
1987
+ if (quiz && answers.size > 0) {
1988
+ const answeredIds = new Set(answers.keys());
1989
+ const allQs = [...quiz.questions, ...extraQuestions].filter((q) => !skippedQuestionIds.has(q.id));
1990
+ let resumeIndex = 0;
1991
+ for (let i = 0; i < allQs.length; i++) {
1992
+ if (!answeredIds.has(allQs[i].id)) {
1993
+ resumeIndex = i;
1994
+ break;
1995
+ }
1996
+ resumeIndex = allQs.length - 1;
1997
+ }
1998
+ setCurrentQuestionIndex(resumeIndex);
1999
+ }
2000
+ setShowIntro(false);
2001
+ setShowResumeChoice(false);
2002
+ setTimerStarted(true);
2003
+ }, [quiz, answers, extraQuestions, skippedQuestionIds]);
2004
+ const handleStartFresh = useCallback2(async () => {
2005
+ if (!apiClient.current || !attempt) return;
2006
+ setIsStartingFresh(true);
2007
+ try {
2008
+ await apiClient.current.updateAttempt(attempt.id, {
2009
+ status: "abandoned"
2010
+ });
2011
+ const newAttemptData = await apiClient.current.createAttempt({
2012
+ quizId,
2013
+ lessonId,
2014
+ assignLessonId,
2015
+ courseId,
2016
+ childId,
2017
+ parentId,
2018
+ forceNew: true
2019
+ });
2020
+ setAttempt(newAttemptData);
2021
+ setAnswers(/* @__PURE__ */ new Map());
2022
+ setAnswersDetail([]);
2023
+ setCurrentQuestionIndex(0);
2024
+ setHasExistingProgress(false);
2025
+ setExistingProgressCount(0);
2026
+ setShowResumeChoice(false);
2027
+ setShowIntro(false);
2028
+ setTimerStarted(true);
2029
+ } catch (err) {
2030
+ const message = err instanceof Error ? err.message : "Failed to start fresh";
2031
+ onErrorRef.current?.(new Error(message));
2032
+ } finally {
2033
+ setIsStartingFresh(false);
2034
+ }
2035
+ }, [attempt, quizId, lessonId, assignLessonId, courseId, childId, parentId]);
1479
2036
  useEffect3(() => {
1480
2037
  setShowFeedback(false);
1481
2038
  setCurrentAnswerDetail(null);
@@ -1595,7 +2152,15 @@ function QuizPlayer({
1595
2152
  onCompleteRef.current?.(quizResult);
1596
2153
  } catch (err) {
1597
2154
  const message = err instanceof Error ? err.message : "Failed to submit quiz";
1598
- setError(message);
2155
+ const code = getErrorFromMessage(message, "quiz");
2156
+ setErrorCode(code);
2157
+ apiClient.current?.logError({
2158
+ errorCode: code,
2159
+ context: "quiz",
2160
+ resourceId: quizId,
2161
+ component: "QuizPlayer",
2162
+ message
2163
+ });
1599
2164
  onErrorRef.current?.(err instanceof Error ? err : new Error(message));
1600
2165
  } finally {
1601
2166
  setIsSubmitting(false);
@@ -1674,13 +2239,10 @@ function QuizPlayer({
1674
2239
  }
1675
2240
  }, [currentQuestion, apiClient, attempt, quiz, childId, parentId, lessonId, courseId, assignLessonId]);
1676
2241
  if (isLoading) {
1677
- return /* @__PURE__ */ jsx3("div", { className, style: defaultStyles.container, children: /* @__PURE__ */ jsx3("div", { style: defaultStyles.loading, children: "Loading quiz..." }) });
2242
+ return /* @__PURE__ */ jsx4("div", { className, style: defaultStyles.container, children: /* @__PURE__ */ jsx4("div", { style: defaultStyles.loading, children: "Loading quiz..." }) });
1678
2243
  }
1679
- if (error) {
1680
- return /* @__PURE__ */ jsx3("div", { className, style: defaultStyles.container, children: /* @__PURE__ */ jsx3("div", { style: defaultStyles.error, children: /* @__PURE__ */ jsxs3("p", { children: [
1681
- "Error: ",
1682
- error
1683
- ] }) }) });
2244
+ if (errorCode) {
2245
+ return /* @__PURE__ */ jsx4("div", { className, style: defaultStyles.container, children: /* @__PURE__ */ jsx4(MaintenanceScreen, { errorCode }) });
1684
2246
  }
1685
2247
  if (isCompleted && result) {
1686
2248
  const percentage = result.totalQuestions > 0 ? Math.round(result.correctAnswers / result.totalQuestions * 100) : 0;
@@ -1738,7 +2300,7 @@ function QuizPlayer({
1738
2300
  rotation: Math.random() * 360,
1739
2301
  size: 6 + Math.random() * 8
1740
2302
  }));
1741
- const StarIcon = ({ filled, delay }) => /* @__PURE__ */ jsx3(
2303
+ const StarIcon = ({ filled, delay }) => /* @__PURE__ */ jsx4(
1742
2304
  "svg",
1743
2305
  {
1744
2306
  width: "36",
@@ -1749,7 +2311,7 @@ function QuizPlayer({
1749
2311
  animationDelay: `${delay}s`,
1750
2312
  opacity: 0
1751
2313
  },
1752
- children: /* @__PURE__ */ jsx3(
2314
+ children: /* @__PURE__ */ jsx4(
1753
2315
  "path",
1754
2316
  {
1755
2317
  d: "M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z",
@@ -1760,62 +2322,23 @@ function QuizPlayer({
1760
2322
  )
1761
2323
  }
1762
2324
  );
1763
- const MascotOwl = ({ mood }) => {
1764
- const getEyeExpression = () => {
1765
- switch (mood) {
1766
- case "celebrating":
1767
- return { leftEye: ">", rightEye: "<", pupilY: 42 };
1768
- // Squinting happy
1769
- case "happy":
1770
- return { leftEye: null, rightEye: null, pupilY: 42 };
1771
- // Normal happy
1772
- case "encouraging":
1773
- return { leftEye: null, rightEye: null, pupilY: 44 };
1774
- // Looking down warmly
1775
- default:
1776
- return { leftEye: null, rightEye: null, pupilY: 42 };
1777
- }
1778
- };
1779
- const eyeExpr = getEyeExpression();
1780
- return /* @__PURE__ */ jsxs3(
1781
- "svg",
2325
+ const Mascot = ({ mood }) => {
2326
+ return /* @__PURE__ */ jsx4(
2327
+ "img",
1782
2328
  {
1783
- width: "120",
1784
- height: "120",
1785
- viewBox: "0 0 100 100",
2329
+ src: astronautImage,
2330
+ alt: "Astronaut mascot",
2331
+ width: "180",
2332
+ height: "180",
1786
2333
  style: {
1787
- animation: mood === "celebrating" ? "bounce 0.6s ease-in-out infinite" : "gentleBob 2s ease-in-out infinite"
1788
- },
1789
- children: [
1790
- /* @__PURE__ */ jsx3("ellipse", { cx: "50", cy: "60", rx: "35", ry: "30", fill: "#8b5cf6" }),
1791
- /* @__PURE__ */ jsx3("ellipse", { cx: "50", cy: "65", rx: "25", ry: "20", fill: "#c4b5fd" }),
1792
- /* @__PURE__ */ jsx3("circle", { cx: "50", cy: "35", r: "28", fill: "#a78bfa" }),
1793
- /* @__PURE__ */ jsx3("polygon", { points: "28,15 35,30 22,28", fill: "#7c3aed" }),
1794
- /* @__PURE__ */ jsx3("polygon", { points: "72,15 65,30 78,28", fill: "#7c3aed" }),
1795
- /* @__PURE__ */ jsx3("ellipse", { cx: "38", cy: "38", rx: "10", ry: "12", fill: "white" }),
1796
- /* @__PURE__ */ jsx3("ellipse", { cx: "62", cy: "38", rx: "10", ry: "12", fill: "white" }),
1797
- eyeExpr.leftEye ? /* @__PURE__ */ jsx3("text", { x: "38", y: "44", textAnchor: "middle", fontSize: "16", fill: "#1f2937", children: eyeExpr.leftEye }) : /* @__PURE__ */ jsx3("circle", { cx: "38", cy: eyeExpr.pupilY, r: "5", fill: "#1f2937" }),
1798
- eyeExpr.rightEye ? /* @__PURE__ */ jsx3("text", { x: "62", y: "44", textAnchor: "middle", fontSize: "16", fill: "#1f2937", children: eyeExpr.rightEye }) : /* @__PURE__ */ jsx3("circle", { cx: "62", cy: eyeExpr.pupilY, r: "5", fill: "#1f2937" }),
1799
- /* @__PURE__ */ jsx3("polygon", { points: "50,45 45,52 55,52", fill: "#fbbf24" }),
1800
- (mood === "celebrating" || mood === "happy") && /* @__PURE__ */ jsxs3(Fragment2, { children: [
1801
- /* @__PURE__ */ jsx3("ellipse", { cx: "28", cy: "45", rx: "5", ry: "3", fill: "#fda4af", opacity: "0.6" }),
1802
- /* @__PURE__ */ jsx3("ellipse", { cx: "72", cy: "45", rx: "5", ry: "3", fill: "#fda4af", opacity: "0.6" })
1803
- ] }),
1804
- mood === "celebrating" ? /* @__PURE__ */ jsxs3(Fragment2, { children: [
1805
- /* @__PURE__ */ jsx3("ellipse", { cx: "18", cy: "55", rx: "8", ry: "15", fill: "#7c3aed", transform: "rotate(-30 18 55)" }),
1806
- /* @__PURE__ */ jsx3("ellipse", { cx: "82", cy: "55", rx: "8", ry: "15", fill: "#7c3aed", transform: "rotate(30 82 55)" })
1807
- ] }) : /* @__PURE__ */ jsxs3(Fragment2, { children: [
1808
- /* @__PURE__ */ jsx3("ellipse", { cx: "20", cy: "60", rx: "8", ry: "15", fill: "#7c3aed" }),
1809
- /* @__PURE__ */ jsx3("ellipse", { cx: "80", cy: "60", rx: "8", ry: "15", fill: "#7c3aed" })
1810
- ] }),
1811
- /* @__PURE__ */ jsx3("ellipse", { cx: "40", cy: "88", rx: "8", ry: "4", fill: "#fbbf24" }),
1812
- /* @__PURE__ */ jsx3("ellipse", { cx: "60", cy: "88", rx: "8", ry: "4", fill: "#fbbf24" })
1813
- ]
2334
+ animation: mood === "celebrating" ? "bounce 0.6s ease-in-out infinite" : "gentleBob 2s ease-in-out infinite",
2335
+ objectFit: "contain"
2336
+ }
1814
2337
  }
1815
2338
  );
1816
2339
  };
1817
- return /* @__PURE__ */ jsxs3("div", { className, style: defaultStyles.container, children: [
1818
- /* @__PURE__ */ jsx3("style", { children: `
2340
+ return /* @__PURE__ */ jsxs4("div", { className, style: defaultStyles.container, children: [
2341
+ /* @__PURE__ */ jsx4("style", { children: `
1819
2342
  @keyframes confettiFall {
1820
2343
  0% {
1821
2344
  transform: translateY(-10px) rotate(0deg);
@@ -1879,8 +2402,8 @@ function QuizPlayer({
1879
2402
  }
1880
2403
  }
1881
2404
  ` }),
1882
- /* @__PURE__ */ jsxs3("div", { style: defaultStyles.results, children: [
1883
- percentage >= 60 && /* @__PURE__ */ jsx3("div", { style: defaultStyles.confettiContainer, children: confettiPieces.map((piece) => /* @__PURE__ */ jsx3(
2405
+ /* @__PURE__ */ jsxs4("div", { style: defaultStyles.results, children: [
2406
+ percentage >= 60 && /* @__PURE__ */ jsx4("div", { style: defaultStyles.confettiContainer, children: confettiPieces.map((piece) => /* @__PURE__ */ jsx4(
1884
2407
  "div",
1885
2408
  {
1886
2409
  style: {
@@ -1897,15 +2420,70 @@ function QuizPlayer({
1897
2420
  },
1898
2421
  piece.id
1899
2422
  )) }),
1900
- /* @__PURE__ */ jsx3("div", { style: { ...defaultStyles.resultsBackground, background: theme.bgGradient } }),
1901
- /* @__PURE__ */ jsxs3("div", { style: defaultStyles.resultsContent, children: [
1902
- /* @__PURE__ */ jsxs3("div", { style: defaultStyles.resultStars, children: [
1903
- /* @__PURE__ */ jsx3(StarIcon, { filled: theme.stars >= 1, delay: 0.3 }),
1904
- /* @__PURE__ */ jsx3(StarIcon, { filled: theme.stars >= 2, delay: 0.5 }),
1905
- /* @__PURE__ */ jsx3(StarIcon, { filled: theme.stars >= 3, delay: 0.7 })
2423
+ /* @__PURE__ */ jsx4("div", { style: { ...defaultStyles.resultsBackground, background: theme.bgGradient } }),
2424
+ /* @__PURE__ */ jsx4("div", { style: defaultStyles.resultsContent, children: hideScore ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
2425
+ /* @__PURE__ */ jsx4("div", { style: { marginBottom: "24px" }, children: /* @__PURE__ */ jsx4(Mascot, { mood: "happy" }) }),
2426
+ /* @__PURE__ */ jsx4(
2427
+ "div",
2428
+ {
2429
+ style: {
2430
+ background: "linear-gradient(135deg, #dcfce7 0%, #bbf7d0 100%)",
2431
+ padding: "12px 28px",
2432
+ borderRadius: "50px",
2433
+ boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
2434
+ marginBottom: "20px",
2435
+ animation: "badgePop 0.6s ease-out 0.2s forwards",
2436
+ opacity: 0,
2437
+ border: "3px solid #22c55e"
2438
+ },
2439
+ children: /* @__PURE__ */ jsx4(
2440
+ "span",
2441
+ {
2442
+ style: {
2443
+ fontSize: "22px",
2444
+ fontWeight: "700",
2445
+ color: "#1f2937",
2446
+ textShadow: "0 1px 2px rgba(255,255,255,0.5)"
2447
+ },
2448
+ children: "All Done!"
2449
+ }
2450
+ )
2451
+ }
2452
+ ),
2453
+ /* @__PURE__ */ jsx4(
2454
+ "div",
2455
+ {
2456
+ style: {
2457
+ animation: "scoreSlideIn 0.5s ease-out 0.4s forwards",
2458
+ opacity: 0
2459
+ },
2460
+ children: /* @__PURE__ */ jsx4(
2461
+ "div",
2462
+ {
2463
+ style: {
2464
+ fontSize: "24px",
2465
+ fontWeight: "600",
2466
+ color: "#22c55e",
2467
+ lineHeight: "1.4",
2468
+ marginBottom: "12px"
2469
+ },
2470
+ children: "The quiz was submitted successfully!"
2471
+ }
2472
+ )
2473
+ }
2474
+ ),
2475
+ /* @__PURE__ */ jsxs4("div", { style: { ...defaultStyles.resultDetails, marginTop: "8px" }, children: [
2476
+ "Time: ",
2477
+ formatTime(result.timeSpentSeconds)
2478
+ ] })
2479
+ ] }) : /* @__PURE__ */ jsxs4(Fragment2, { children: [
2480
+ /* @__PURE__ */ jsxs4("div", { style: defaultStyles.resultStars, children: [
2481
+ /* @__PURE__ */ jsx4(StarIcon, { filled: theme.stars >= 1, delay: 0.3 }),
2482
+ /* @__PURE__ */ jsx4(StarIcon, { filled: theme.stars >= 2, delay: 0.5 }),
2483
+ /* @__PURE__ */ jsx4(StarIcon, { filled: theme.stars >= 3, delay: 0.7 })
1906
2484
  ] }),
1907
- /* @__PURE__ */ jsx3("div", { style: { marginBottom: "16px" }, children: /* @__PURE__ */ jsx3(MascotOwl, { mood: theme.mascotMood }) }),
1908
- /* @__PURE__ */ jsx3(
2485
+ /* @__PURE__ */ jsx4("div", { style: { marginBottom: "16px" }, children: /* @__PURE__ */ jsx4(Mascot, { mood: theme.mascotMood }) }),
2486
+ /* @__PURE__ */ jsx4(
1909
2487
  "div",
1910
2488
  {
1911
2489
  style: {
@@ -1918,7 +2496,7 @@ function QuizPlayer({
1918
2496
  opacity: 0,
1919
2497
  border: `3px solid ${theme.badgeColor}`
1920
2498
  },
1921
- children: /* @__PURE__ */ jsx3(
2499
+ children: /* @__PURE__ */ jsx4(
1922
2500
  "span",
1923
2501
  {
1924
2502
  style: {
@@ -1932,7 +2510,7 @@ function QuizPlayer({
1932
2510
  )
1933
2511
  }
1934
2512
  ),
1935
- /* @__PURE__ */ jsxs3(
2513
+ /* @__PURE__ */ jsxs4(
1936
2514
  "div",
1937
2515
  {
1938
2516
  style: {
@@ -1940,7 +2518,7 @@ function QuizPlayer({
1940
2518
  opacity: 0
1941
2519
  },
1942
2520
  children: [
1943
- /* @__PURE__ */ jsxs3(
2521
+ /* @__PURE__ */ jsxs4(
1944
2522
  "div",
1945
2523
  {
1946
2524
  style: {
@@ -1957,7 +2535,7 @@ function QuizPlayer({
1957
2535
  ]
1958
2536
  }
1959
2537
  ),
1960
- /* @__PURE__ */ jsx3(
2538
+ /* @__PURE__ */ jsx4(
1961
2539
  "div",
1962
2540
  {
1963
2541
  style: {
@@ -1972,25 +2550,84 @@ function QuizPlayer({
1972
2550
  ]
1973
2551
  }
1974
2552
  ),
1975
- /* @__PURE__ */ jsxs3("div", { style: { ...defaultStyles.resultDetails, marginTop: "8px" }, children: [
2553
+ /* @__PURE__ */ jsxs4("div", { style: { ...defaultStyles.resultDetails, marginTop: "8px" }, children: [
1976
2554
  "Time: ",
1977
2555
  formatTime(result.timeSpentSeconds)
1978
2556
  ] })
1979
- ] })
2557
+ ] }) })
1980
2558
  ] })
1981
2559
  ] });
1982
2560
  }
2561
+ if (quiz && showIntro && showResumeChoice && hasExistingProgress) {
2562
+ return /* @__PURE__ */ jsx4("div", { className, style: defaultStyles.container, children: /* @__PURE__ */ jsxs4("div", { style: defaultStyles.intro, children: [
2563
+ /* @__PURE__ */ jsx4("div", { style: defaultStyles.introTitle, children: "Welcome Back!" }),
2564
+ /* @__PURE__ */ jsx4("div", { style: defaultStyles.introSubtitle, children: "You have an unfinished quiz. Would you like to continue or start over?" }),
2565
+ /* @__PURE__ */ jsxs4("div", { style: defaultStyles.introQuestionCount, children: [
2566
+ existingProgressCount,
2567
+ " of ",
2568
+ quiz.questions.length,
2569
+ " question",
2570
+ quiz.questions.length !== 1 ? "s" : "",
2571
+ " answered"
2572
+ ] }),
2573
+ /* @__PURE__ */ jsxs4("div", { style: { display: "flex", flexDirection: "column", gap: "12px", marginTop: "8px" }, children: [
2574
+ /* @__PURE__ */ jsx4(
2575
+ "button",
2576
+ {
2577
+ style: defaultStyles.startButton,
2578
+ onClick: handleResumePrevious,
2579
+ onMouseOver: (e) => {
2580
+ e.currentTarget.style.transform = "translateY(-2px)";
2581
+ e.currentTarget.style.boxShadow = "0 6px 20px rgba(124, 58, 237, 0.5)";
2582
+ },
2583
+ onMouseOut: (e) => {
2584
+ e.currentTarget.style.transform = "translateY(0)";
2585
+ e.currentTarget.style.boxShadow = "0 4px 14px rgba(124, 58, 237, 0.4)";
2586
+ },
2587
+ "data-testid": "button-continue-quiz",
2588
+ children: "Continue Where I Left Off"
2589
+ }
2590
+ ),
2591
+ /* @__PURE__ */ jsx4(
2592
+ "button",
2593
+ {
2594
+ style: {
2595
+ ...defaultStyles.startButton,
2596
+ background: "transparent",
2597
+ color: "#7c3aed",
2598
+ border: "2px solid #7c3aed",
2599
+ boxShadow: "none"
2600
+ },
2601
+ onClick: handleStartFresh,
2602
+ disabled: isStartingFresh,
2603
+ onMouseOver: (e) => {
2604
+ if (!isStartingFresh) {
2605
+ e.currentTarget.style.transform = "translateY(-2px)";
2606
+ e.currentTarget.style.background = "rgba(124, 58, 237, 0.1)";
2607
+ }
2608
+ },
2609
+ onMouseOut: (e) => {
2610
+ e.currentTarget.style.transform = "translateY(0)";
2611
+ e.currentTarget.style.background = "transparent";
2612
+ },
2613
+ "data-testid": "button-start-fresh",
2614
+ children: isStartingFresh ? "Starting..." : "Start Fresh"
2615
+ }
2616
+ )
2617
+ ] })
2618
+ ] }) });
2619
+ }
1983
2620
  if (quiz && showIntro) {
1984
- return /* @__PURE__ */ jsx3("div", { className, style: defaultStyles.container, children: /* @__PURE__ */ jsxs3("div", { style: defaultStyles.intro, children: [
1985
- /* @__PURE__ */ jsx3("div", { style: defaultStyles.introTitle, children: quiz.title }),
1986
- /* @__PURE__ */ jsx3("div", { style: defaultStyles.introSubtitle, children: "Ready to test your knowledge?" }),
1987
- /* @__PURE__ */ jsxs3("div", { style: defaultStyles.introQuestionCount, children: [
2621
+ return /* @__PURE__ */ jsx4("div", { className, style: defaultStyles.container, children: /* @__PURE__ */ jsxs4("div", { style: defaultStyles.intro, children: [
2622
+ /* @__PURE__ */ jsx4("div", { style: defaultStyles.introTitle, children: quiz.title }),
2623
+ /* @__PURE__ */ jsx4("div", { style: defaultStyles.introSubtitle, children: "Ready to test your knowledge?" }),
2624
+ /* @__PURE__ */ jsxs4("div", { style: defaultStyles.introQuestionCount, children: [
1988
2625
  quiz.questions.length,
1989
2626
  " question",
1990
2627
  quiz.questions.length !== 1 ? "s" : "",
1991
2628
  " to answer"
1992
2629
  ] }),
1993
- /* @__PURE__ */ jsx3(
2630
+ /* @__PURE__ */ jsx4(
1994
2631
  "button",
1995
2632
  {
1996
2633
  style: defaultStyles.startButton,
@@ -2010,7 +2647,7 @@ function QuizPlayer({
2010
2647
  ] }) });
2011
2648
  }
2012
2649
  if (!quiz || !currentQuestion) {
2013
- return /* @__PURE__ */ jsx3("div", { className, style: defaultStyles.container, children: /* @__PURE__ */ jsx3("div", { style: defaultStyles.error, children: "No quiz data available" }) });
2650
+ return /* @__PURE__ */ jsx4("div", { className, style: defaultStyles.container, children: /* @__PURE__ */ jsx4("div", { style: defaultStyles.error, children: "No quiz data available" }) });
2014
2651
  }
2015
2652
  const selectedAnswer = answers.get(currentQuestion.id);
2016
2653
  const isLastQuestion = currentQuestionIndex === totalQuestions - 1;
@@ -2018,21 +2655,21 @@ function QuizPlayer({
2018
2655
  const remainingSlots = maxQuestions - totalQuestions;
2019
2656
  const questionsToAdd = Math.min(5, remainingSlots);
2020
2657
  const canAddMore = onGenerateMoreQuestions && remainingSlots > 0;
2021
- return /* @__PURE__ */ jsx3("div", { className, style: defaultStyles.container, children: /* @__PURE__ */ jsxs3("div", { style: defaultStyles.mainLayout, children: [
2022
- /* @__PURE__ */ jsxs3("div", { style: defaultStyles.quizContent, children: [
2023
- /* @__PURE__ */ jsxs3("div", { style: defaultStyles.header, children: [
2024
- /* @__PURE__ */ jsx3("div", { style: defaultStyles.title, children: quiz.title }),
2025
- /* @__PURE__ */ jsxs3("div", { style: defaultStyles.progress, children: [
2658
+ return /* @__PURE__ */ jsx4("div", { className, style: defaultStyles.container, children: /* @__PURE__ */ jsxs4("div", { style: defaultStyles.mainLayout, children: [
2659
+ /* @__PURE__ */ jsxs4("div", { style: defaultStyles.quizContent, children: [
2660
+ /* @__PURE__ */ jsxs4("div", { style: defaultStyles.header, children: [
2661
+ /* @__PURE__ */ jsx4("div", { style: defaultStyles.title, children: quiz.title }),
2662
+ /* @__PURE__ */ jsxs4("div", { style: defaultStyles.progress, children: [
2026
2663
  "Question ",
2027
2664
  currentQuestionIndex + 1,
2028
2665
  " of ",
2029
2666
  totalQuestions
2030
2667
  ] }),
2031
- /* @__PURE__ */ jsx3("div", { style: defaultStyles.progressBar, children: /* @__PURE__ */ jsx3("div", { style: { ...defaultStyles.progressFill, width: `${progressPercent}%` } }) })
2668
+ /* @__PURE__ */ jsx4("div", { style: defaultStyles.progressBar, children: /* @__PURE__ */ jsx4("div", { style: { ...defaultStyles.progressFill, width: `${progressPercent}%` } }) })
2032
2669
  ] }),
2033
- /* @__PURE__ */ jsxs3("div", { style: { ...defaultStyles.question, position: "relative", paddingBottom: "40px" }, children: [
2034
- /* @__PURE__ */ jsx3("div", { style: defaultStyles.questionText, children: /* @__PURE__ */ jsx3(TextToSpeech, { text: currentQuestion.question, inline: true, size: "md" }) }),
2035
- isExtraQuestion && /* @__PURE__ */ jsxs3(
2670
+ /* @__PURE__ */ jsxs4("div", { style: { ...defaultStyles.question, position: "relative", paddingBottom: "40px" }, children: [
2671
+ /* @__PURE__ */ jsx4("div", { style: defaultStyles.questionText, children: /* @__PURE__ */ jsx4(TextToSpeech, { text: currentQuestion.question, inline: true, size: "md" }) }),
2672
+ isExtraQuestion && /* @__PURE__ */ jsxs4(
2036
2673
  "button",
2037
2674
  {
2038
2675
  onClick: () => setShowSkipModal(true),
@@ -2065,15 +2702,15 @@ function QuizPlayer({
2065
2702
  },
2066
2703
  "data-testid": "button-skip-question",
2067
2704
  children: [
2068
- /* @__PURE__ */ jsxs3("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2069
- /* @__PURE__ */ jsx3("polygon", { points: "5 4 15 12 5 20 5 4" }),
2070
- /* @__PURE__ */ jsx3("line", { x1: "19", y1: "5", x2: "19", y2: "19" })
2705
+ /* @__PURE__ */ jsxs4("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2706
+ /* @__PURE__ */ jsx4("polygon", { points: "5 4 15 12 5 20 5 4" }),
2707
+ /* @__PURE__ */ jsx4("line", { x1: "19", y1: "5", x2: "19", y2: "19" })
2071
2708
  ] }),
2072
- /* @__PURE__ */ jsx3("span", { children: "Skip" })
2709
+ /* @__PURE__ */ jsx4("span", { children: "Skip" })
2073
2710
  ]
2074
2711
  }
2075
2712
  ),
2076
- !isExtraQuestion && /* @__PURE__ */ jsxs3(
2713
+ !isExtraQuestion && /* @__PURE__ */ jsxs4(
2077
2714
  "button",
2078
2715
  {
2079
2716
  onClick: () => setShowReportModal(true),
@@ -2106,15 +2743,15 @@ function QuizPlayer({
2106
2743
  },
2107
2744
  "data-testid": "button-report-question",
2108
2745
  children: [
2109
- /* @__PURE__ */ jsxs3("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2110
- /* @__PURE__ */ jsx3("path", { d: "M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z" }),
2111
- /* @__PURE__ */ jsx3("line", { x1: "4", y1: "22", x2: "4", y2: "15" })
2746
+ /* @__PURE__ */ jsxs4("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2747
+ /* @__PURE__ */ jsx4("path", { d: "M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z" }),
2748
+ /* @__PURE__ */ jsx4("line", { x1: "4", y1: "22", x2: "4", y2: "15" })
2112
2749
  ] }),
2113
- /* @__PURE__ */ jsx3("span", { children: "Report" })
2750
+ /* @__PURE__ */ jsx4("span", { children: "Report" })
2114
2751
  ]
2115
2752
  }
2116
2753
  ),
2117
- (currentQuestion.type === "single" || currentQuestion.type === "true-false") && /* @__PURE__ */ jsx3("div", { style: defaultStyles.options, children: currentQuestion.options?.map((option, idx) => {
2754
+ (currentQuestion.type === "single" || currentQuestion.type === "true-false") && /* @__PURE__ */ jsx4("div", { style: defaultStyles.options, children: currentQuestion.options?.map((option, idx) => {
2118
2755
  const isSelected = selectedAnswer === option;
2119
2756
  const isCorrectOption = currentQuestion.correctAnswer === option;
2120
2757
  let optionStyle = { ...defaultStyles.option };
@@ -2127,7 +2764,7 @@ function QuizPlayer({
2127
2764
  } else if (isSelected) {
2128
2765
  optionStyle = { ...optionStyle, ...defaultStyles.optionSelected };
2129
2766
  }
2130
- return /* @__PURE__ */ jsxs3(
2767
+ return /* @__PURE__ */ jsxs4(
2131
2768
  "div",
2132
2769
  {
2133
2770
  style: {
@@ -2139,14 +2776,14 @@ function QuizPlayer({
2139
2776
  },
2140
2777
  onClick: () => !showFeedback && handleAnswerChange(option),
2141
2778
  children: [
2142
- /* @__PURE__ */ jsx3("span", { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsx3(TextToSpeech, { text: option, size: "sm" }) }),
2143
- /* @__PURE__ */ jsx3("span", { style: { flex: 1 }, children: option })
2779
+ /* @__PURE__ */ jsx4("span", { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsx4(TextToSpeech, { text: option, size: "sm" }) }),
2780
+ /* @__PURE__ */ jsx4("span", { style: { flex: 1 }, children: option })
2144
2781
  ]
2145
2782
  },
2146
2783
  idx
2147
2784
  );
2148
2785
  }) }),
2149
- currentQuestion.type === "multiple" && /* @__PURE__ */ jsx3("div", { style: defaultStyles.options, children: currentQuestion.options?.map((option, idx) => {
2786
+ currentQuestion.type === "multiple" && /* @__PURE__ */ jsx4("div", { style: defaultStyles.options, children: currentQuestion.options?.map((option, idx) => {
2150
2787
  const selected = Array.isArray(selectedAnswer) && selectedAnswer.includes(option);
2151
2788
  const correctAnswers = Array.isArray(currentQuestion.correctAnswer) ? currentQuestion.correctAnswer : currentQuestion.correctAnswer ? [currentQuestion.correctAnswer] : [];
2152
2789
  const isCorrectOption = correctAnswers.includes(option);
@@ -2160,7 +2797,7 @@ function QuizPlayer({
2160
2797
  } else if (selected) {
2161
2798
  optionStyle = { ...optionStyle, ...defaultStyles.optionSelected };
2162
2799
  }
2163
- return /* @__PURE__ */ jsxs3(
2800
+ return /* @__PURE__ */ jsxs4(
2164
2801
  "div",
2165
2802
  {
2166
2803
  style: {
@@ -2180,14 +2817,14 @@ function QuizPlayer({
2180
2817
  }
2181
2818
  },
2182
2819
  children: [
2183
- /* @__PURE__ */ jsx3("span", { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsx3(TextToSpeech, { text: option, size: "sm" }) }),
2184
- /* @__PURE__ */ jsx3("span", { style: { flex: 1 }, children: option })
2820
+ /* @__PURE__ */ jsx4("span", { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsx4(TextToSpeech, { text: option, size: "sm" }) }),
2821
+ /* @__PURE__ */ jsx4("span", { style: { flex: 1 }, children: option })
2185
2822
  ]
2186
2823
  },
2187
2824
  idx
2188
2825
  );
2189
2826
  }) }),
2190
- (currentQuestion.type === "free" || currentQuestion.type === "essay") && /* @__PURE__ */ jsx3(
2827
+ (currentQuestion.type === "free" || currentQuestion.type === "essay") && /* @__PURE__ */ jsx4(
2191
2828
  "textarea",
2192
2829
  {
2193
2830
  style: { ...defaultStyles.input, minHeight: currentQuestion.type === "essay" ? "150px" : "60px" },
@@ -2197,7 +2834,7 @@ function QuizPlayer({
2197
2834
  disabled: showFeedback
2198
2835
  }
2199
2836
  ),
2200
- currentQuestion.type === "fill" && /* @__PURE__ */ jsx3("div", { style: defaultStyles.options, children: currentQuestion.blanks?.map((_, idx) => /* @__PURE__ */ jsx3(
2837
+ currentQuestion.type === "fill" && /* @__PURE__ */ jsx4("div", { style: defaultStyles.options, children: currentQuestion.blanks?.map((_, idx) => /* @__PURE__ */ jsx4(
2201
2838
  "input",
2202
2839
  {
2203
2840
  style: defaultStyles.input,
@@ -2212,18 +2849,127 @@ function QuizPlayer({
2212
2849
  },
2213
2850
  idx
2214
2851
  )) }),
2215
- showFeedback && currentAnswerDetail && /* @__PURE__ */ jsxs3("div", { style: {
2852
+ currentQuestion.type === "sorting" && currentQuestion.items && /* @__PURE__ */ jsx4(
2853
+ SortingDragDrop,
2854
+ {
2855
+ items: currentQuestion.items,
2856
+ currentOrder: Array.isArray(selectedAnswer) ? selectedAnswer : currentQuestion.items.map((_, i) => i),
2857
+ correctOrder: currentQuestion.correctOrder,
2858
+ showFeedback,
2859
+ onOrderChange: handleAnswerChange
2860
+ }
2861
+ ),
2862
+ currentQuestion.type === "matrix" && currentQuestion.leftItems && currentQuestion.rightItems && /* @__PURE__ */ jsx4(
2863
+ MatchingDragDrop,
2864
+ {
2865
+ leftItems: currentQuestion.leftItems,
2866
+ rightItems: currentQuestion.rightItems,
2867
+ currentMatches: typeof selectedAnswer === "object" && selectedAnswer !== null && !Array.isArray(selectedAnswer) ? selectedAnswer : {},
2868
+ correctMatches: currentQuestion.correctMatches,
2869
+ showFeedback,
2870
+ onMatchChange: handleAnswerChange
2871
+ }
2872
+ ),
2873
+ currentQuestion.type === "assessment" && /* @__PURE__ */ jsx4("div", { style: defaultStyles.options, children: (() => {
2874
+ const scaleType = currentQuestion.scaleType || "likert";
2875
+ if (scaleType === "yes-no") {
2876
+ const options = ["Yes", "No"];
2877
+ return options.map((option, idx) => {
2878
+ const isSelected = selectedAnswer === option;
2879
+ let optionStyle = { ...defaultStyles.option };
2880
+ if (isSelected) {
2881
+ optionStyle = { ...optionStyle, ...defaultStyles.optionSelected };
2882
+ }
2883
+ return /* @__PURE__ */ jsx4(
2884
+ "div",
2885
+ {
2886
+ style: {
2887
+ ...optionStyle,
2888
+ cursor: showFeedback ? "default" : "pointer",
2889
+ display: "flex",
2890
+ alignItems: "center",
2891
+ gap: "8px"
2892
+ },
2893
+ onClick: () => !showFeedback && handleAnswerChange(option),
2894
+ "data-testid": `assessment-option-${option.toLowerCase()}`,
2895
+ children: /* @__PURE__ */ jsx4("span", { style: { flex: 1 }, children: option })
2896
+ },
2897
+ idx
2898
+ );
2899
+ });
2900
+ }
2901
+ if (scaleType === "rating") {
2902
+ const min = currentQuestion.scaleMin || 1;
2903
+ const max = currentQuestion.scaleMax || 5;
2904
+ const ratings = Array.from({ length: max - min + 1 }, (_, i) => min + i);
2905
+ return /* @__PURE__ */ jsx4("div", { style: { display: "flex", gap: "8px", flexWrap: "wrap", justifyContent: "center" }, children: ratings.map((rating) => {
2906
+ const isSelected = selectedAnswer === rating;
2907
+ return /* @__PURE__ */ jsx4(
2908
+ "button",
2909
+ {
2910
+ onClick: () => !showFeedback && handleAnswerChange(rating),
2911
+ disabled: showFeedback,
2912
+ style: {
2913
+ width: "48px",
2914
+ height: "48px",
2915
+ borderRadius: "50%",
2916
+ border: isSelected ? "2px solid #6721b0" : "2px solid #e5e7eb",
2917
+ backgroundColor: isSelected ? "#f3e8ff" : "#ffffff",
2918
+ cursor: showFeedback ? "not-allowed" : "pointer",
2919
+ fontSize: "18px",
2920
+ fontWeight: "600",
2921
+ color: isSelected ? "#6721b0" : "#374151"
2922
+ },
2923
+ "data-testid": `assessment-rating-${rating}`,
2924
+ children: rating
2925
+ },
2926
+ rating
2927
+ );
2928
+ }) });
2929
+ }
2930
+ const likertOptions = [
2931
+ "Strongly Disagree",
2932
+ "Disagree",
2933
+ "Neutral",
2934
+ "Agree",
2935
+ "Strongly Agree"
2936
+ ];
2937
+ return likertOptions.map((option, idx) => {
2938
+ const isSelected = selectedAnswer === option;
2939
+ let optionStyle = { ...defaultStyles.option };
2940
+ if (isSelected) {
2941
+ optionStyle = { ...optionStyle, ...defaultStyles.optionSelected };
2942
+ }
2943
+ return /* @__PURE__ */ jsx4(
2944
+ "div",
2945
+ {
2946
+ style: {
2947
+ ...optionStyle,
2948
+ cursor: showFeedback ? "default" : "pointer",
2949
+ display: "flex",
2950
+ alignItems: "center",
2951
+ gap: "8px"
2952
+ },
2953
+ onClick: () => !showFeedback && handleAnswerChange(option),
2954
+ "data-testid": `assessment-likert-${idx}`,
2955
+ children: /* @__PURE__ */ jsx4("span", { style: { flex: 1 }, children: option })
2956
+ },
2957
+ idx
2958
+ );
2959
+ });
2960
+ })() }),
2961
+ showFeedback && currentAnswerDetail && /* @__PURE__ */ jsxs4("div", { style: {
2216
2962
  ...defaultStyles.feedback,
2217
- ...currentAnswerDetail.isCorrect ? defaultStyles.feedbackCorrect : defaultStyles.feedbackIncorrect
2963
+ ...currentQuestion.type === "assessment" ? defaultStyles.feedbackNeutral : currentAnswerDetail.isCorrect ? defaultStyles.feedbackCorrect : defaultStyles.feedbackIncorrect
2218
2964
  }, children: [
2219
- /* @__PURE__ */ jsx3("div", { style: {
2965
+ /* @__PURE__ */ jsx4("div", { style: {
2220
2966
  ...defaultStyles.feedbackTitle,
2221
- ...currentAnswerDetail.isCorrect ? defaultStyles.feedbackTitleCorrect : defaultStyles.feedbackTitleIncorrect
2222
- }, children: currentAnswerDetail.isCorrect ? "\u2713 Correct!" : "\u2717 Incorrect" }),
2223
- currentQuestion.explanation && /* @__PURE__ */ jsx3("div", { style: defaultStyles.feedbackExplanation, children: currentQuestion.explanation })
2967
+ ...currentQuestion.type === "assessment" ? defaultStyles.feedbackTitleNeutral : currentAnswerDetail.isCorrect ? defaultStyles.feedbackTitleCorrect : defaultStyles.feedbackTitleIncorrect
2968
+ }, children: currentQuestion.type === "assessment" ? "\u2713 Response recorded" : currentAnswerDetail.isCorrect ? "\u2713 Correct!" : "\u2717 Incorrect" }),
2969
+ currentQuestion.explanation && /* @__PURE__ */ jsx4("div", { style: defaultStyles.feedbackExplanation, children: currentQuestion.explanation })
2224
2970
  ] })
2225
2971
  ] }),
2226
- showSkipModal && /* @__PURE__ */ jsx3("div", { style: {
2972
+ showSkipModal && /* @__PURE__ */ jsx4("div", { style: {
2227
2973
  position: "fixed",
2228
2974
  top: 0,
2229
2975
  left: 0,
@@ -2234,7 +2980,7 @@ function QuizPlayer({
2234
2980
  alignItems: "center",
2235
2981
  justifyContent: "center",
2236
2982
  zIndex: 1e3
2237
- }, children: /* @__PURE__ */ jsxs3("div", { style: {
2983
+ }, children: /* @__PURE__ */ jsxs4("div", { style: {
2238
2984
  backgroundColor: "#ffffff",
2239
2985
  borderRadius: "12px",
2240
2986
  padding: "24px",
@@ -2242,10 +2988,10 @@ function QuizPlayer({
2242
2988
  width: "90%",
2243
2989
  boxShadow: "0 20px 40px rgba(0, 0, 0, 0.2)"
2244
2990
  }, children: [
2245
- /* @__PURE__ */ jsx3("h3", { style: { margin: "0 0 8px 0", fontSize: "18px", fontWeight: "600", color: "#1f2937" }, children: "Skip Question" }),
2246
- /* @__PURE__ */ jsx3("p", { style: { margin: "0 0 16px 0", fontSize: "14px", color: "#6b7280" }, children: "Help us improve by telling us why you're skipping this question." }),
2247
- /* @__PURE__ */ jsxs3("div", { style: { display: "flex", flexDirection: "column", gap: "8px", marginBottom: "16px" }, children: [
2248
- /* @__PURE__ */ jsx3(
2991
+ /* @__PURE__ */ jsx4("h3", { style: { margin: "0 0 8px 0", fontSize: "18px", fontWeight: "600", color: "#1f2937" }, children: "Skip Question" }),
2992
+ /* @__PURE__ */ jsx4("p", { style: { margin: "0 0 16px 0", fontSize: "14px", color: "#6b7280" }, children: "Help us improve by telling us why you're skipping this question." }),
2993
+ /* @__PURE__ */ jsxs4("div", { style: { display: "flex", flexDirection: "column", gap: "8px", marginBottom: "16px" }, children: [
2994
+ /* @__PURE__ */ jsx4(
2249
2995
  "button",
2250
2996
  {
2251
2997
  onClick: () => setSelectedSkipReason("question_issue"),
@@ -2266,7 +3012,7 @@ function QuizPlayer({
2266
3012
  children: "Question has an issue"
2267
3013
  }
2268
3014
  ),
2269
- /* @__PURE__ */ jsx3(
3015
+ /* @__PURE__ */ jsx4(
2270
3016
  "button",
2271
3017
  {
2272
3018
  onClick: () => setSelectedSkipReason("dont_know"),
@@ -2288,9 +3034,9 @@ function QuizPlayer({
2288
3034
  }
2289
3035
  )
2290
3036
  ] }),
2291
- /* @__PURE__ */ jsxs3("div", { style: { marginBottom: "16px" }, children: [
2292
- /* @__PURE__ */ jsx3("label", { style: { display: "block", fontSize: "13px", fontWeight: "500", color: "#374151", marginBottom: "6px" }, children: "Additional details (optional)" }),
2293
- /* @__PURE__ */ jsx3(
3037
+ /* @__PURE__ */ jsxs4("div", { style: { marginBottom: "16px" }, children: [
3038
+ /* @__PURE__ */ jsx4("label", { style: { display: "block", fontSize: "13px", fontWeight: "500", color: "#374151", marginBottom: "6px" }, children: "Additional details (optional)" }),
3039
+ /* @__PURE__ */ jsx4(
2294
3040
  "textarea",
2295
3041
  {
2296
3042
  value: skipComment,
@@ -2311,13 +3057,13 @@ function QuizPlayer({
2311
3057
  "data-testid": "input-skip-comment"
2312
3058
  }
2313
3059
  ),
2314
- /* @__PURE__ */ jsxs3("div", { style: { fontSize: "12px", color: "#9ca3af", marginTop: "4px", textAlign: "right" }, children: [
3060
+ /* @__PURE__ */ jsxs4("div", { style: { fontSize: "12px", color: "#9ca3af", marginTop: "4px", textAlign: "right" }, children: [
2315
3061
  skipComment.length,
2316
3062
  "/200"
2317
3063
  ] })
2318
3064
  ] }),
2319
- /* @__PURE__ */ jsxs3("div", { style: { display: "flex", gap: "10px" }, children: [
2320
- /* @__PURE__ */ jsx3(
3065
+ /* @__PURE__ */ jsxs4("div", { style: { display: "flex", gap: "10px" }, children: [
3066
+ /* @__PURE__ */ jsx4(
2321
3067
  "button",
2322
3068
  {
2323
3069
  onClick: () => {
@@ -2340,7 +3086,7 @@ function QuizPlayer({
2340
3086
  children: "Cancel"
2341
3087
  }
2342
3088
  ),
2343
- /* @__PURE__ */ jsx3(
3089
+ /* @__PURE__ */ jsx4(
2344
3090
  "button",
2345
3091
  {
2346
3092
  onClick: () => selectedSkipReason && handleSkipQuestion(selectedSkipReason, skipComment),
@@ -2363,7 +3109,7 @@ function QuizPlayer({
2363
3109
  )
2364
3110
  ] })
2365
3111
  ] }) }),
2366
- showReportModal && /* @__PURE__ */ jsx3("div", { style: {
3112
+ showReportModal && /* @__PURE__ */ jsx4("div", { style: {
2367
3113
  position: "fixed",
2368
3114
  top: 0,
2369
3115
  left: 0,
@@ -2374,7 +3120,7 @@ function QuizPlayer({
2374
3120
  alignItems: "center",
2375
3121
  justifyContent: "center",
2376
3122
  zIndex: 1e3
2377
- }, children: /* @__PURE__ */ jsxs3("div", { style: {
3123
+ }, children: /* @__PURE__ */ jsxs4("div", { style: {
2378
3124
  backgroundColor: "#ffffff",
2379
3125
  borderRadius: "12px",
2380
3126
  padding: "24px",
@@ -2382,10 +3128,10 @@ function QuizPlayer({
2382
3128
  width: "90%",
2383
3129
  boxShadow: "0 20px 40px rgba(0, 0, 0, 0.2)"
2384
3130
  }, children: [
2385
- /* @__PURE__ */ jsx3("h3", { style: { margin: "0 0 8px 0", fontSize: "18px", fontWeight: "600", color: "#1f2937" }, children: "Report Question" }),
2386
- /* @__PURE__ */ jsx3("p", { style: { margin: "0 0 16px 0", fontSize: "14px", color: "#6b7280" }, children: "What's wrong with this question?" }),
2387
- /* @__PURE__ */ jsxs3("div", { style: { marginBottom: "16px" }, children: [
2388
- /* @__PURE__ */ jsx3(
3131
+ /* @__PURE__ */ jsx4("h3", { style: { margin: "0 0 8px 0", fontSize: "18px", fontWeight: "600", color: "#1f2937" }, children: "Report Question" }),
3132
+ /* @__PURE__ */ jsx4("p", { style: { margin: "0 0 16px 0", fontSize: "14px", color: "#6b7280" }, children: "What's wrong with this question?" }),
3133
+ /* @__PURE__ */ jsxs4("div", { style: { marginBottom: "16px" }, children: [
3134
+ /* @__PURE__ */ jsx4(
2389
3135
  "textarea",
2390
3136
  {
2391
3137
  value: reportComment,
@@ -2406,13 +3152,13 @@ function QuizPlayer({
2406
3152
  "data-testid": "input-report-comment"
2407
3153
  }
2408
3154
  ),
2409
- /* @__PURE__ */ jsxs3("div", { style: { fontSize: "12px", color: "#9ca3af", marginTop: "4px", textAlign: "right" }, children: [
3155
+ /* @__PURE__ */ jsxs4("div", { style: { fontSize: "12px", color: "#9ca3af", marginTop: "4px", textAlign: "right" }, children: [
2410
3156
  reportComment.length,
2411
3157
  "/300"
2412
3158
  ] })
2413
3159
  ] }),
2414
- /* @__PURE__ */ jsxs3("div", { style: { display: "flex", gap: "10px" }, children: [
2415
- /* @__PURE__ */ jsx3(
3160
+ /* @__PURE__ */ jsxs4("div", { style: { display: "flex", gap: "10px" }, children: [
3161
+ /* @__PURE__ */ jsx4(
2416
3162
  "button",
2417
3163
  {
2418
3164
  onClick: () => {
@@ -2434,7 +3180,7 @@ function QuizPlayer({
2434
3180
  children: "Cancel"
2435
3181
  }
2436
3182
  ),
2437
- /* @__PURE__ */ jsx3(
3183
+ /* @__PURE__ */ jsx4(
2438
3184
  "button",
2439
3185
  {
2440
3186
  onClick: () => handleReportQuestion(reportComment),
@@ -2457,8 +3203,8 @@ function QuizPlayer({
2457
3203
  )
2458
3204
  ] })
2459
3205
  ] }) }),
2460
- /* @__PURE__ */ jsxs3("div", { style: defaultStyles.buttonsColumn, children: [
2461
- showFeedback && isLastQuestion && canAddMore && /* @__PURE__ */ jsx3(
3206
+ /* @__PURE__ */ jsxs4("div", { style: defaultStyles.buttonsColumn, children: [
3207
+ showFeedback && isLastQuestion && canAddMore && /* @__PURE__ */ jsx4(
2462
3208
  "button",
2463
3209
  {
2464
3210
  style: {
@@ -2468,10 +3214,10 @@ function QuizPlayer({
2468
3214
  onClick: handleAddMoreQuestions,
2469
3215
  disabled: isGeneratingExtra,
2470
3216
  "data-testid": "button-add-more-questions",
2471
- children: isGeneratingExtra ? /* @__PURE__ */ jsxs3(Fragment2, { children: [
2472
- /* @__PURE__ */ jsx3(Spinner, { size: 16, color: "#9ca3af" }),
3217
+ children: isGeneratingExtra ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
3218
+ /* @__PURE__ */ jsx4(Spinner, { size: 16, color: "#9ca3af" }),
2473
3219
  "Generating Questions..."
2474
- ] }) : /* @__PURE__ */ jsxs3(Fragment2, { children: [
3220
+ ] }) : /* @__PURE__ */ jsxs4(Fragment2, { children: [
2475
3221
  "+ Add ",
2476
3222
  questionsToAdd,
2477
3223
  " More Question",
@@ -2479,9 +3225,9 @@ function QuizPlayer({
2479
3225
  ] })
2480
3226
  }
2481
3227
  ),
2482
- /* @__PURE__ */ jsx3("div", { style: { ...defaultStyles.buttons, justifyContent: "flex-end" }, children: showFeedback ? (
3228
+ /* @__PURE__ */ jsx4("div", { style: { ...defaultStyles.buttons, justifyContent: "flex-end" }, children: showFeedback ? (
2483
3229
  // After viewing feedback
2484
- isLastQuestion ? /* @__PURE__ */ jsx3(
3230
+ isLastQuestion ? /* @__PURE__ */ jsx4(
2485
3231
  "button",
2486
3232
  {
2487
3233
  style: {
@@ -2491,9 +3237,9 @@ function QuizPlayer({
2491
3237
  onClick: handleSubmit,
2492
3238
  disabled: isSubmitting || isGeneratingExtra,
2493
3239
  "data-testid": "button-submit-quiz",
2494
- children: isSubmitting ? /* @__PURE__ */ jsx3(Spinner, { size: 16, color: "#9ca3af" }) : "Submit Quiz"
3240
+ children: isSubmitting ? /* @__PURE__ */ jsx4(Spinner, { size: 16, color: "#9ca3af" }) : "Submit Quiz"
2495
3241
  }
2496
- ) : /* @__PURE__ */ jsx3(
3242
+ ) : /* @__PURE__ */ jsx4(
2497
3243
  "button",
2498
3244
  {
2499
3245
  style: {
@@ -2507,7 +3253,7 @@ function QuizPlayer({
2507
3253
  )
2508
3254
  ) : (
2509
3255
  // Before checking answer
2510
- /* @__PURE__ */ jsx3(
3256
+ /* @__PURE__ */ jsx4(
2511
3257
  "button",
2512
3258
  {
2513
3259
  style: {
@@ -2517,13 +3263,13 @@ function QuizPlayer({
2517
3263
  onClick: handleCheckAnswer,
2518
3264
  disabled: isNavigating || selectedAnswer === void 0,
2519
3265
  "data-testid": "button-check-answer",
2520
- children: isNavigating ? /* @__PURE__ */ jsx3(Spinner, { size: 16, color: "#9ca3af" }) : "Check Answer"
3266
+ children: isNavigating ? /* @__PURE__ */ jsx4(Spinner, { size: 16, color: "#9ca3af" }) : "Check Answer"
2521
3267
  }
2522
3268
  )
2523
3269
  ) })
2524
3270
  ] })
2525
3271
  ] }),
2526
- /* @__PURE__ */ jsx3("div", { style: defaultStyles.chatPanel, children: apiClient.current && /* @__PURE__ */ jsx3(
3272
+ /* @__PURE__ */ jsx4("div", { style: defaultStyles.chatPanel, children: apiClient.current && /* @__PURE__ */ jsx4(
2527
3273
  QuestionChatPanel,
2528
3274
  {
2529
3275
  apiClient: apiClient.current,
@@ -2541,7 +3287,7 @@ function QuizPlayer({
2541
3287
  lessonId,
2542
3288
  courseId,
2543
3289
  answerResult: showFeedback && currentAnswerDetail ? {
2544
- wasIncorrect: !currentAnswerDetail.isCorrect,
3290
+ wasIncorrect: currentQuestion.type !== "assessment" && !currentAnswerDetail.isCorrect,
2545
3291
  selectedAnswer: typeof selectedAnswer === "string" ? selectedAnswer : Array.isArray(selectedAnswer) ? selectedAnswer.join(", ") : void 0,
2546
3292
  correctAnswer: typeof currentQuestion.correctAnswer === "string" ? currentQuestion.correctAnswer : Array.isArray(currentQuestion.correctAnswer) ? currentQuestion.correctAnswer.join(", ") : void 0,
2547
3293
  explanation: currentQuestion.explanation
@@ -2552,8 +3298,8 @@ function QuizPlayer({
2552
3298
  }
2553
3299
 
2554
3300
  // src/AttemptViewer.tsx
2555
- import { useState as useState4, useEffect as useEffect4 } from "react";
2556
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
3301
+ import { useState as useState4, useEffect as useEffect4, useRef as useRef4 } from "react";
3302
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
2557
3303
  var defaultStyles2 = {
2558
3304
  container: {
2559
3305
  fontFamily: "system-ui, -apple-system, sans-serif",
@@ -2749,10 +3495,31 @@ var spinnerKeyframes = `
2749
3495
  to { transform: rotate(360deg); }
2750
3496
  }
2751
3497
  `;
2752
- function formatAnswer(answer) {
3498
+ function formatAnswer(answer, questionType, items, leftItems) {
2753
3499
  if (answer === null || answer === void 0) {
2754
3500
  return "No answer";
2755
3501
  }
3502
+ if (questionType === "sorting" && Array.isArray(answer)) {
3503
+ const indices = answer;
3504
+ if (items && items.length > 0) {
3505
+ return indices.map((idx, pos) => `${pos + 1}. ${items[idx] ?? `Item ${idx + 1}`}`).join(", ");
3506
+ }
3507
+ return indices.map((idx, pos) => `Position ${pos + 1}: Item ${idx + 1}`).join(", ");
3508
+ }
3509
+ if (questionType === "matrix" && typeof answer === "object" && !Array.isArray(answer)) {
3510
+ const matches = answer;
3511
+ if (leftItems && leftItems.length > 0) {
3512
+ return leftItems.map((left) => {
3513
+ const right = matches[left];
3514
+ return `${left} \u2192 ${right || "No answer"}`;
3515
+ }).join(", ");
3516
+ }
3517
+ const entries = Object.entries(matches);
3518
+ if (entries.length === 0) {
3519
+ return "No answer";
3520
+ }
3521
+ return entries.map(([left, right]) => `${left} \u2192 ${right || "No answer"}`).join(", ");
3522
+ }
2756
3523
  if (typeof answer === "string") {
2757
3524
  return answer;
2758
3525
  }
@@ -2764,6 +3531,15 @@ function formatAnswer(answer) {
2764
3531
  }
2765
3532
  return String(answer);
2766
3533
  }
3534
+ function formatCorrectSortingAnswer(items, correctOrder) {
3535
+ return correctOrder.map((idx, pos) => `${pos + 1}. ${items[idx] ?? `Item ${idx + 1}`}`).join(", ");
3536
+ }
3537
+ function formatCorrectMatrixAnswer(correctMatches, leftItems) {
3538
+ if (leftItems && leftItems.length > 0) {
3539
+ return leftItems.map((left) => `${left} \u2192 ${correctMatches[left] || "N/A"}`).join(", ");
3540
+ }
3541
+ return Object.entries(correctMatches).map(([left, right]) => `${left} \u2192 ${right}`).join(", ");
3542
+ }
2767
3543
  function AttemptViewer({
2768
3544
  attemptId,
2769
3545
  apiBaseUrl,
@@ -2776,23 +3552,39 @@ function AttemptViewer({
2776
3552
  }) {
2777
3553
  const [attempt, setAttempt] = useState4(null);
2778
3554
  const [loading, setLoading] = useState4(true);
2779
- const [error, setError] = useState4(null);
3555
+ const [errorCode, setErrorCode] = useState4(null);
2780
3556
  const [chatHistories, setChatHistories] = useState4({});
2781
3557
  const [expandedChats, setExpandedChats] = useState4(/* @__PURE__ */ new Set());
3558
+ const [fetchedAttemptId, setFetchedAttemptId] = useState4(null);
3559
+ const onErrorRef = useRef4(onError);
3560
+ onErrorRef.current = onError;
2782
3561
  useEffect4(() => {
3562
+ if (fetchedAttemptId === attemptId) return;
2783
3563
  const apiClient = new QuizApiClient({
2784
3564
  baseUrl: apiBaseUrl,
2785
3565
  authToken
2786
3566
  });
2787
3567
  async function fetchAttempt() {
2788
3568
  setLoading(true);
2789
- setError(null);
3569
+ setErrorCode(null);
2790
3570
  try {
2791
3571
  const response = await fetch(`${apiBaseUrl}/api/external/quiz-attempts/${attemptId}`, {
2792
3572
  headers: authToken ? { Authorization: `Bearer ${authToken}` } : {}
2793
3573
  });
2794
3574
  if (!response.ok) {
2795
- throw new Error(`Failed to fetch attempt: ${response.statusText}`);
3575
+ const code = getErrorFromHttpStatus(response.status, "attempt");
3576
+ setErrorCode(code);
3577
+ apiClient.logError({
3578
+ errorCode: code,
3579
+ context: "attempt",
3580
+ resourceId: attemptId,
3581
+ component: "AttemptViewer",
3582
+ message: `HTTP ${response.status}: ${response.statusText}`
3583
+ });
3584
+ onErrorRef.current?.(new Error(`Failed to fetch attempt: ${response.statusText}`));
3585
+ setLoading(false);
3586
+ setFetchedAttemptId(attemptId);
3587
+ return;
2796
3588
  }
2797
3589
  const data = await response.json();
2798
3590
  setAttempt(data);
@@ -2806,14 +3598,23 @@ function AttemptViewer({
2806
3598
  }
2807
3599
  } catch (err) {
2808
3600
  const errorMessage = err instanceof Error ? err.message : "Failed to load attempt";
2809
- setError(errorMessage);
2810
- onError?.(err instanceof Error ? err : new Error(errorMessage));
3601
+ const code = getErrorFromMessage(errorMessage, "attempt");
3602
+ setErrorCode(code);
3603
+ apiClient.logError({
3604
+ errorCode: code,
3605
+ context: "attempt",
3606
+ resourceId: attemptId,
3607
+ component: "AttemptViewer",
3608
+ message: errorMessage
3609
+ });
3610
+ onErrorRef.current?.(err instanceof Error ? err : new Error(errorMessage));
2811
3611
  } finally {
2812
3612
  setLoading(false);
3613
+ setFetchedAttemptId(attemptId);
2813
3614
  }
2814
3615
  }
2815
3616
  fetchAttempt();
2816
- }, [attemptId, apiBaseUrl, authToken, onError, showConversation]);
3617
+ }, [attemptId, apiBaseUrl, authToken, showConversation, fetchedAttemptId]);
2817
3618
  const toggleChatExpanded = (questionId) => {
2818
3619
  setExpandedChats((prev) => {
2819
3620
  const newSet = new Set(prev);
@@ -2827,53 +3628,49 @@ function AttemptViewer({
2827
3628
  };
2828
3629
  const handleRetry = () => {
2829
3630
  setLoading(true);
2830
- setError(null);
3631
+ setErrorCode(null);
2831
3632
  window.location.reload();
2832
3633
  };
2833
3634
  if (loading) {
2834
- return /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.container, className, children: [
2835
- /* @__PURE__ */ jsx4("style", { children: spinnerKeyframes }),
2836
- /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.loading, children: [
2837
- /* @__PURE__ */ jsx4("div", { style: defaultStyles2.spinner }),
2838
- /* @__PURE__ */ jsx4("p", { style: { marginTop: "16px", color: "#6b7280" }, children: "Loading attempt..." })
3635
+ return /* @__PURE__ */ jsxs5("div", { style: defaultStyles2.container, className, children: [
3636
+ /* @__PURE__ */ jsx5("style", { children: spinnerKeyframes }),
3637
+ /* @__PURE__ */ jsxs5("div", { style: defaultStyles2.loading, children: [
3638
+ /* @__PURE__ */ jsx5("div", { style: defaultStyles2.spinner }),
3639
+ /* @__PURE__ */ jsx5("p", { style: { marginTop: "16px", color: "#6b7280" }, children: "Loading attempt..." })
2839
3640
  ] })
2840
3641
  ] });
2841
3642
  }
2842
- if (error || !attempt) {
2843
- return /* @__PURE__ */ jsx4("div", { style: defaultStyles2.container, className, children: /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.error, children: [
2844
- /* @__PURE__ */ jsx4("p", { style: { fontSize: "18px", fontWeight: "500" }, children: "Failed to load attempt" }),
2845
- /* @__PURE__ */ jsx4("p", { style: { marginTop: "8px", color: "#6b7280" }, children: error }),
2846
- /* @__PURE__ */ jsx4("button", { style: defaultStyles2.retryButton, onClick: handleRetry, children: "Try Again" })
2847
- ] }) });
3643
+ if (errorCode || !attempt) {
3644
+ return /* @__PURE__ */ jsx5("div", { style: defaultStyles2.container, className, children: /* @__PURE__ */ jsx5(MaintenanceScreen, { errorCode: errorCode || "ATTEMPT_NOT_FOUND" }) });
2848
3645
  }
2849
3646
  const scorePercentage = attempt.score ?? 0;
2850
3647
  const correctCount = attempt.correctAnswers ?? 0;
2851
3648
  const totalQuestions = attempt.totalQuestions;
2852
3649
  const timeSpent = attempt.timeSpentSeconds ?? 0;
2853
- return /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.container, className, children: [
2854
- /* @__PURE__ */ jsx4("style", { children: spinnerKeyframes }),
2855
- /* @__PURE__ */ jsx4("div", { style: defaultStyles2.header, children: /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.summaryGrid, children: [
2856
- /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.summaryCard, children: [
2857
- /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.summaryValue, children: [
3650
+ return /* @__PURE__ */ jsxs5("div", { style: defaultStyles2.container, className, children: [
3651
+ /* @__PURE__ */ jsx5("style", { children: spinnerKeyframes }),
3652
+ /* @__PURE__ */ jsx5("div", { style: defaultStyles2.header, children: /* @__PURE__ */ jsxs5("div", { style: defaultStyles2.summaryGrid, children: [
3653
+ /* @__PURE__ */ jsxs5("div", { style: defaultStyles2.summaryCard, children: [
3654
+ /* @__PURE__ */ jsxs5("div", { style: defaultStyles2.summaryValue, children: [
2858
3655
  scorePercentage,
2859
3656
  "%"
2860
3657
  ] }),
2861
- /* @__PURE__ */ jsx4("div", { style: defaultStyles2.summaryLabel, children: "Score" })
3658
+ /* @__PURE__ */ jsx5("div", { style: defaultStyles2.summaryLabel, children: "Score" })
2862
3659
  ] }),
2863
- /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.summaryCard, children: [
2864
- /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.summaryValue, children: [
3660
+ /* @__PURE__ */ jsxs5("div", { style: defaultStyles2.summaryCard, children: [
3661
+ /* @__PURE__ */ jsxs5("div", { style: defaultStyles2.summaryValue, children: [
2865
3662
  correctCount,
2866
3663
  "/",
2867
3664
  totalQuestions
2868
3665
  ] }),
2869
- /* @__PURE__ */ jsx4("div", { style: defaultStyles2.summaryLabel, children: "Correct" })
3666
+ /* @__PURE__ */ jsx5("div", { style: defaultStyles2.summaryLabel, children: "Correct" })
2870
3667
  ] }),
2871
- /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.summaryCard, children: [
2872
- /* @__PURE__ */ jsx4("div", { style: defaultStyles2.summaryValue, children: formatTime(timeSpent) }),
2873
- /* @__PURE__ */ jsx4("div", { style: defaultStyles2.summaryLabel, children: "Time" })
3668
+ /* @__PURE__ */ jsxs5("div", { style: defaultStyles2.summaryCard, children: [
3669
+ /* @__PURE__ */ jsx5("div", { style: defaultStyles2.summaryValue, children: formatTime(timeSpent) }),
3670
+ /* @__PURE__ */ jsx5("div", { style: defaultStyles2.summaryLabel, children: "Time" })
2874
3671
  ] })
2875
3672
  ] }) }),
2876
- /* @__PURE__ */ jsx4("div", { style: defaultStyles2.questionsList, children: attempt.answers.map((answer, index) => /* @__PURE__ */ jsxs4(
3673
+ /* @__PURE__ */ jsx5("div", { style: defaultStyles2.questionsList, children: attempt.answers.map((answer, index) => /* @__PURE__ */ jsxs5(
2877
3674
  "div",
2878
3675
  {
2879
3676
  style: {
@@ -2881,12 +3678,12 @@ function AttemptViewer({
2881
3678
  ...answer.isCorrect ? defaultStyles2.questionCardCorrect : defaultStyles2.questionCardIncorrect
2882
3679
  },
2883
3680
  children: [
2884
- /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.questionHeader, children: [
2885
- /* @__PURE__ */ jsxs4("span", { style: defaultStyles2.questionNumber, children: [
3681
+ /* @__PURE__ */ jsxs5("div", { style: defaultStyles2.questionHeader, children: [
3682
+ /* @__PURE__ */ jsxs5("span", { style: defaultStyles2.questionNumber, children: [
2886
3683
  "Question ",
2887
3684
  index + 1
2888
3685
  ] }),
2889
- /* @__PURE__ */ jsx4(
3686
+ /* @__PURE__ */ jsx5(
2890
3687
  "span",
2891
3688
  {
2892
3689
  style: {
@@ -2897,35 +3694,35 @@ function AttemptViewer({
2897
3694
  }
2898
3695
  )
2899
3696
  ] }),
2900
- /* @__PURE__ */ jsx4("div", { style: defaultStyles2.questionText, children: answer.questionText }),
2901
- /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.answerSection, children: [
2902
- /* @__PURE__ */ jsx4("span", { style: defaultStyles2.answerLabel, children: "Your answer:" }),
2903
- /* @__PURE__ */ jsx4("span", { style: defaultStyles2.studentAnswer, children: formatAnswer(answer.selectedAnswer) })
3697
+ /* @__PURE__ */ jsx5("div", { style: defaultStyles2.questionText, children: answer.questionText }),
3698
+ /* @__PURE__ */ jsxs5("div", { style: defaultStyles2.answerSection, children: [
3699
+ /* @__PURE__ */ jsx5("span", { style: defaultStyles2.answerLabel, children: "Your answer:" }),
3700
+ /* @__PURE__ */ jsx5("span", { style: defaultStyles2.studentAnswer, children: formatAnswer(answer.selectedAnswer, answer.questionType, answer.items, answer.leftItems) })
2904
3701
  ] }),
2905
- !answer.isCorrect && answer.correctAnswer && /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.answerSection, children: [
2906
- /* @__PURE__ */ jsx4("span", { style: defaultStyles2.answerLabel, children: "Correct answer:" }),
2907
- /* @__PURE__ */ jsx4("span", { style: defaultStyles2.correctAnswer, children: formatAnswer(answer.correctAnswer) })
3702
+ !answer.isCorrect && answer.correctAnswer && /* @__PURE__ */ jsxs5("div", { style: defaultStyles2.answerSection, children: [
3703
+ /* @__PURE__ */ jsx5("span", { style: defaultStyles2.answerLabel, children: "Correct answer:" }),
3704
+ /* @__PURE__ */ jsx5("span", { style: defaultStyles2.correctAnswer, children: answer.questionType === "sorting" && answer.items && answer.correctOrder ? formatCorrectSortingAnswer(answer.items, answer.correctOrder) : answer.questionType === "matrix" && answer.correctAnswer && typeof answer.correctAnswer === "object" && !Array.isArray(answer.correctAnswer) ? formatCorrectMatrixAnswer(answer.correctAnswer, answer.leftItems) : formatAnswer(answer.correctAnswer, answer.questionType, answer.items, answer.leftItems) })
2908
3705
  ] }),
2909
- /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.points, children: [
3706
+ /* @__PURE__ */ jsxs5("div", { style: defaultStyles2.points, children: [
2910
3707
  answer.pointsEarned,
2911
3708
  " / ",
2912
3709
  answer.points,
2913
3710
  " points"
2914
3711
  ] }),
2915
- showExplanations && answer.explanation && /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.explanation, children: [
2916
- /* @__PURE__ */ jsx4("strong", { children: "Explanation:" }),
3712
+ showExplanations && answer.explanation && /* @__PURE__ */ jsxs5("div", { style: defaultStyles2.explanation, children: [
3713
+ /* @__PURE__ */ jsx5("strong", { children: "Explanation:" }),
2917
3714
  " ",
2918
3715
  answer.explanation
2919
3716
  ] }),
2920
- showConversation && chatHistories[answer.questionId] && chatHistories[answer.questionId].messages.length > 0 && /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.chatHistorySection, children: [
2921
- /* @__PURE__ */ jsxs4(
3717
+ showConversation && chatHistories[answer.questionId] && chatHistories[answer.questionId].messages.length > 0 && /* @__PURE__ */ jsxs5("div", { style: defaultStyles2.chatHistorySection, children: [
3718
+ /* @__PURE__ */ jsxs5(
2922
3719
  "button",
2923
3720
  {
2924
3721
  style: defaultStyles2.chatToggleButton,
2925
3722
  onClick: () => toggleChatExpanded(answer.questionId),
2926
3723
  "data-testid": `button-toggle-chat-${answer.questionId}`,
2927
3724
  children: [
2928
- /* @__PURE__ */ jsx4("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx4("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" }) }),
3725
+ /* @__PURE__ */ jsx5("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx5("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" }) }),
2929
3726
  expandedChats.has(answer.questionId) ? "Hide" : "View",
2930
3727
  " Chat History (",
2931
3728
  chatHistories[answer.questionId].messages.length,
@@ -2933,7 +3730,7 @@ function AttemptViewer({
2933
3730
  ]
2934
3731
  }
2935
3732
  ),
2936
- expandedChats.has(answer.questionId) && /* @__PURE__ */ jsx4("div", { style: defaultStyles2.chatMessages, children: chatHistories[answer.questionId].messages.map((msg, msgIndex) => /* @__PURE__ */ jsx4(
3733
+ expandedChats.has(answer.questionId) && /* @__PURE__ */ jsx5("div", { style: defaultStyles2.chatMessages, children: chatHistories[answer.questionId].messages.map((msg, msgIndex) => /* @__PURE__ */ jsx5(
2937
3734
  "div",
2938
3735
  {
2939
3736
  style: {
@@ -2951,14 +3748,620 @@ function AttemptViewer({
2951
3748
  )) })
2952
3749
  ] });
2953
3750
  }
3751
+
3752
+ // src/ErrorTypesPanel.tsx
3753
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
3754
+ var panelStyles2 = {
3755
+ container: {
3756
+ fontFamily: "system-ui, -apple-system, sans-serif",
3757
+ padding: "24px",
3758
+ backgroundColor: "#ffffff",
3759
+ borderRadius: "12px",
3760
+ maxWidth: "800px"
3761
+ },
3762
+ header: {
3763
+ marginBottom: "24px"
3764
+ },
3765
+ title: {
3766
+ fontSize: "20px",
3767
+ fontWeight: "600",
3768
+ color: "#111827",
3769
+ marginBottom: "8px"
3770
+ },
3771
+ subtitle: {
3772
+ fontSize: "14px",
3773
+ color: "#6b7280"
3774
+ },
3775
+ section: {
3776
+ marginBottom: "24px"
3777
+ },
3778
+ sectionTitle: {
3779
+ fontSize: "14px",
3780
+ fontWeight: "600",
3781
+ color: "#374151",
3782
+ marginBottom: "12px",
3783
+ textTransform: "uppercase",
3784
+ letterSpacing: "0.05em"
3785
+ },
3786
+ errorList: {
3787
+ display: "flex",
3788
+ flexDirection: "column",
3789
+ gap: "12px"
3790
+ },
3791
+ errorCard: {
3792
+ padding: "16px",
3793
+ backgroundColor: "#f9fafb",
3794
+ borderRadius: "8px",
3795
+ border: "1px solid #e5e7eb"
3796
+ },
3797
+ errorCardBlocking: {
3798
+ borderLeft: "4px solid #ef4444"
3799
+ },
3800
+ errorCardNonBlocking: {
3801
+ borderLeft: "4px solid #f59e0b"
3802
+ },
3803
+ errorHeader: {
3804
+ display: "flex",
3805
+ justifyContent: "space-between",
3806
+ alignItems: "flex-start",
3807
+ marginBottom: "8px"
3808
+ },
3809
+ errorCode: {
3810
+ fontSize: "13px",
3811
+ fontWeight: "600",
3812
+ color: "#1f2937",
3813
+ fontFamily: "monospace",
3814
+ backgroundColor: "#e5e7eb",
3815
+ padding: "2px 8px",
3816
+ borderRadius: "4px"
3817
+ },
3818
+ errorBadge: {
3819
+ fontSize: "11px",
3820
+ fontWeight: "500",
3821
+ padding: "2px 8px",
3822
+ borderRadius: "12px"
3823
+ },
3824
+ blockingBadge: {
3825
+ backgroundColor: "#fee2e2",
3826
+ color: "#dc2626"
3827
+ },
3828
+ nonBlockingBadge: {
3829
+ backgroundColor: "#fef3c7",
3830
+ color: "#d97706"
3831
+ },
3832
+ userMessage: {
3833
+ fontSize: "15px",
3834
+ fontWeight: "500",
3835
+ color: "#111827",
3836
+ marginBottom: "4px"
3837
+ },
3838
+ subMessage: {
3839
+ fontSize: "13px",
3840
+ color: "#6b7280",
3841
+ marginBottom: "8px"
3842
+ },
3843
+ causeLabel: {
3844
+ fontSize: "11px",
3845
+ fontWeight: "600",
3846
+ color: "#9ca3af",
3847
+ textTransform: "uppercase",
3848
+ marginBottom: "4px"
3849
+ },
3850
+ causeText: {
3851
+ fontSize: "13px",
3852
+ color: "#4b5563",
3853
+ fontStyle: "italic"
3854
+ }
3855
+ };
3856
+ function ErrorTypesPanel({ className }) {
3857
+ const blockingErrors = Object.values(ERROR_DEFINITIONS).filter((e) => e.isBlocking);
3858
+ const nonBlockingErrors = Object.values(ERROR_DEFINITIONS).filter((e) => !e.isBlocking);
3859
+ const renderErrorCard = (error) => /* @__PURE__ */ jsxs6(
3860
+ "div",
3861
+ {
3862
+ style: {
3863
+ ...panelStyles2.errorCard,
3864
+ ...error.isBlocking ? panelStyles2.errorCardBlocking : panelStyles2.errorCardNonBlocking
3865
+ },
3866
+ "data-testid": `error-card-${error.code}`,
3867
+ children: [
3868
+ /* @__PURE__ */ jsxs6("div", { style: panelStyles2.errorHeader, children: [
3869
+ /* @__PURE__ */ jsx6("code", { style: panelStyles2.errorCode, children: error.code }),
3870
+ /* @__PURE__ */ jsx6(
3871
+ "span",
3872
+ {
3873
+ style: {
3874
+ ...panelStyles2.errorBadge,
3875
+ ...error.isBlocking ? panelStyles2.blockingBadge : panelStyles2.nonBlockingBadge
3876
+ },
3877
+ children: error.isBlocking ? "Blocking" : "Non-Blocking"
3878
+ }
3879
+ )
3880
+ ] }),
3881
+ /* @__PURE__ */ jsx6("div", { style: panelStyles2.userMessage, children: error.userMessage }),
3882
+ /* @__PURE__ */ jsx6("div", { style: panelStyles2.subMessage, children: error.subMessage }),
3883
+ /* @__PURE__ */ jsx6("div", { style: panelStyles2.causeLabel, children: "Why this happens:" }),
3884
+ /* @__PURE__ */ jsx6("div", { style: panelStyles2.causeText, children: error.cause })
3885
+ ]
3886
+ },
3887
+ error.code
3888
+ );
3889
+ return /* @__PURE__ */ jsxs6("div", { style: panelStyles2.container, className, "data-testid": "error-types-panel", children: [
3890
+ /* @__PURE__ */ jsxs6("div", { style: panelStyles2.header, children: [
3891
+ /* @__PURE__ */ jsx6("h2", { style: panelStyles2.title, children: "Error Types Reference" }),
3892
+ /* @__PURE__ */ jsx6("p", { style: panelStyles2.subtitle, children: "List of all error types that can occur in the quiz components, with user-facing messages and technical causes." })
3893
+ ] }),
3894
+ /* @__PURE__ */ jsxs6("div", { style: panelStyles2.section, children: [
3895
+ /* @__PURE__ */ jsxs6("h3", { style: panelStyles2.sectionTitle, children: [
3896
+ "Blocking Errors (",
3897
+ blockingErrors.length,
3898
+ ")"
3899
+ ] }),
3900
+ /* @__PURE__ */ jsx6("p", { style: { ...panelStyles2.subtitle, marginBottom: "12px" }, children: "These errors prevent the quiz from loading or continuing. Users see a full-screen error message." }),
3901
+ /* @__PURE__ */ jsx6("div", { style: panelStyles2.errorList, children: blockingErrors.map(renderErrorCard) })
3902
+ ] }),
3903
+ /* @__PURE__ */ jsxs6("div", { style: panelStyles2.section, children: [
3904
+ /* @__PURE__ */ jsxs6("h3", { style: panelStyles2.sectionTitle, children: [
3905
+ "Non-Blocking Errors (",
3906
+ nonBlockingErrors.length,
3907
+ ")"
3908
+ ] }),
3909
+ /* @__PURE__ */ jsx6("p", { style: { ...panelStyles2.subtitle, marginBottom: "12px" }, children: "These errors affect specific features but allow the quiz to continue. Users may see a toast notification." }),
3910
+ /* @__PURE__ */ jsx6("div", { style: panelStyles2.errorList, children: nonBlockingErrors.map(renderErrorCard) })
3911
+ ] })
3912
+ ] });
3913
+ }
3914
+
3915
+ // src/ErrorLogsPanel.tsx
3916
+ import { useState as useState5, useEffect as useEffect5 } from "react";
3917
+ import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
3918
+ var panelStyles3 = {
3919
+ container: {
3920
+ fontFamily: "system-ui, -apple-system, sans-serif",
3921
+ padding: "24px",
3922
+ backgroundColor: "#ffffff",
3923
+ borderRadius: "12px",
3924
+ maxWidth: "1000px"
3925
+ },
3926
+ header: {
3927
+ marginBottom: "24px"
3928
+ },
3929
+ title: {
3930
+ fontSize: "20px",
3931
+ fontWeight: "600",
3932
+ color: "#111827",
3933
+ marginBottom: "8px"
3934
+ },
3935
+ subtitle: {
3936
+ fontSize: "14px",
3937
+ color: "#6b7280"
3938
+ },
3939
+ tabs: {
3940
+ display: "flex",
3941
+ gap: "8px",
3942
+ marginBottom: "16px",
3943
+ borderBottom: "1px solid #e5e7eb",
3944
+ paddingBottom: "12px"
3945
+ },
3946
+ tab: {
3947
+ padding: "8px 16px",
3948
+ fontSize: "14px",
3949
+ fontWeight: "500",
3950
+ borderRadius: "6px",
3951
+ cursor: "pointer",
3952
+ border: "none",
3953
+ backgroundColor: "transparent",
3954
+ color: "#6b7280"
3955
+ },
3956
+ tabActive: {
3957
+ backgroundColor: "#6721b0",
3958
+ color: "#ffffff"
3959
+ },
3960
+ stats: {
3961
+ display: "flex",
3962
+ gap: "16px",
3963
+ marginBottom: "20px"
3964
+ },
3965
+ statCard: {
3966
+ padding: "12px 16px",
3967
+ backgroundColor: "#f9fafb",
3968
+ borderRadius: "8px",
3969
+ flex: 1
3970
+ },
3971
+ statValue: {
3972
+ fontSize: "24px",
3973
+ fontWeight: "700",
3974
+ color: "#111827"
3975
+ },
3976
+ statLabel: {
3977
+ fontSize: "12px",
3978
+ color: "#6b7280",
3979
+ textTransform: "uppercase",
3980
+ letterSpacing: "0.05em"
3981
+ },
3982
+ errorList: {
3983
+ display: "flex",
3984
+ flexDirection: "column",
3985
+ gap: "12px"
3986
+ },
3987
+ errorCard: {
3988
+ padding: "16px",
3989
+ backgroundColor: "#f9fafb",
3990
+ borderRadius: "8px",
3991
+ border: "1px solid #e5e7eb"
3992
+ },
3993
+ errorCardRecent: {
3994
+ borderLeft: "4px solid #ef4444",
3995
+ backgroundColor: "#fef2f2"
3996
+ },
3997
+ errorCardOld: {
3998
+ borderLeft: "4px solid #9ca3af",
3999
+ opacity: 0.7
4000
+ },
4001
+ errorHeader: {
4002
+ display: "flex",
4003
+ justifyContent: "space-between",
4004
+ alignItems: "flex-start",
4005
+ marginBottom: "8px"
4006
+ },
4007
+ errorLeft: {
4008
+ flex: 1
4009
+ },
4010
+ errorCode: {
4011
+ fontSize: "13px",
4012
+ fontWeight: "600",
4013
+ color: "#1f2937",
4014
+ fontFamily: "monospace",
4015
+ backgroundColor: "#e5e7eb",
4016
+ padding: "2px 8px",
4017
+ borderRadius: "4px",
4018
+ display: "inline-block"
4019
+ },
4020
+ countBadge: {
4021
+ fontSize: "14px",
4022
+ fontWeight: "700",
4023
+ padding: "4px 12px",
4024
+ borderRadius: "16px",
4025
+ backgroundColor: "#ef4444",
4026
+ color: "#ffffff"
4027
+ },
4028
+ countBadgeLow: {
4029
+ backgroundColor: "#f59e0b"
4030
+ },
4031
+ contextBadge: {
4032
+ fontSize: "11px",
4033
+ fontWeight: "500",
4034
+ padding: "2px 8px",
4035
+ borderRadius: "4px",
4036
+ marginLeft: "8px",
4037
+ backgroundColor: "#dbeafe",
4038
+ color: "#1d4ed8"
4039
+ },
4040
+ userMessage: {
4041
+ fontSize: "15px",
4042
+ fontWeight: "500",
4043
+ color: "#111827",
4044
+ marginTop: "8px",
4045
+ marginBottom: "4px"
4046
+ },
4047
+ resourceId: {
4048
+ fontSize: "12px",
4049
+ color: "#6b7280",
4050
+ fontFamily: "monospace",
4051
+ marginTop: "4px"
4052
+ },
4053
+ resourceLink: {
4054
+ color: "#6721b0",
4055
+ textDecoration: "underline",
4056
+ cursor: "pointer"
4057
+ },
4058
+ timestamps: {
4059
+ display: "flex",
4060
+ gap: "16px",
4061
+ marginTop: "8px",
4062
+ fontSize: "12px",
4063
+ color: "#9ca3af"
4064
+ },
4065
+ dismissButton: {
4066
+ padding: "6px 12px",
4067
+ fontSize: "12px",
4068
+ fontWeight: "500",
4069
+ borderRadius: "4px",
4070
+ cursor: "pointer",
4071
+ border: "1px solid #e5e7eb",
4072
+ backgroundColor: "#ffffff",
4073
+ color: "#6b7280",
4074
+ marginTop: "8px"
4075
+ },
4076
+ dismissButtonHover: {
4077
+ backgroundColor: "#f3f4f6"
4078
+ },
4079
+ emptyState: {
4080
+ textAlign: "center",
4081
+ padding: "40px",
4082
+ color: "#9ca3af",
4083
+ fontSize: "14px"
4084
+ },
4085
+ loading: {
4086
+ textAlign: "center",
4087
+ padding: "40px",
4088
+ color: "#6b7280",
4089
+ fontSize: "14px"
4090
+ },
4091
+ pagination: {
4092
+ display: "flex",
4093
+ justifyContent: "center",
4094
+ gap: "8px",
4095
+ marginTop: "20px"
4096
+ },
4097
+ pageButton: {
4098
+ padding: "8px 12px",
4099
+ fontSize: "14px",
4100
+ borderRadius: "4px",
4101
+ cursor: "pointer",
4102
+ border: "1px solid #e5e7eb",
4103
+ backgroundColor: "#ffffff",
4104
+ color: "#374151"
4105
+ },
4106
+ pageButtonDisabled: {
4107
+ opacity: 0.5,
4108
+ cursor: "not-allowed"
4109
+ }
4110
+ };
4111
+ function formatRelativeTime(dateStr) {
4112
+ const date = new Date(dateStr);
4113
+ const now = /* @__PURE__ */ new Date();
4114
+ const diffMs = now.getTime() - date.getTime();
4115
+ const diffMins = Math.floor(diffMs / 6e4);
4116
+ const diffHours = Math.floor(diffMs / 36e5);
4117
+ const diffDays = Math.floor(diffMs / 864e5);
4118
+ if (diffMins < 1) return "Just now";
4119
+ if (diffMins < 60) return `${diffMins}m ago`;
4120
+ if (diffHours < 24) return `${diffHours}h ago`;
4121
+ if (diffDays < 7) return `${diffDays}d ago`;
4122
+ return date.toLocaleDateString();
4123
+ }
4124
+ function isRecent(dateStr) {
4125
+ const date = new Date(dateStr);
4126
+ const now = /* @__PURE__ */ new Date();
4127
+ const diffMs = now.getTime() - date.getTime();
4128
+ const diffHours = diffMs / 36e5;
4129
+ return diffHours < 24;
4130
+ }
4131
+ function ErrorLogsPanel({ apiBaseUrl, authToken, onResourceClick }) {
4132
+ const [logs, setLogs] = useState5([]);
4133
+ const [loading, setLoading] = useState5(true);
4134
+ const [showDismissed, setShowDismissed] = useState5(false);
4135
+ const [page, setPage] = useState5(1);
4136
+ const [totalPages, setTotalPages] = useState5(1);
4137
+ const [total, setTotal] = useState5(0);
4138
+ useEffect5(() => {
4139
+ fetchLogs();
4140
+ }, [showDismissed, page]);
4141
+ async function fetchLogs() {
4142
+ setLoading(true);
4143
+ try {
4144
+ const params = new URLSearchParams();
4145
+ params.set("dismissed", showDismissed ? "true" : "false");
4146
+ params.set("page", page.toString());
4147
+ params.set("limit", "20");
4148
+ const response = await fetch(`${apiBaseUrl}/api/admin/error-logs?${params}`, {
4149
+ headers: authToken ? { Authorization: `Bearer ${authToken}` } : {}
4150
+ });
4151
+ if (response.ok) {
4152
+ const data = await response.json();
4153
+ setLogs(data.items || []);
4154
+ setTotalPages(data.totalPages || 1);
4155
+ setTotal(data.total || 0);
4156
+ }
4157
+ } catch (err) {
4158
+ console.error("Failed to fetch error logs:", err);
4159
+ } finally {
4160
+ setLoading(false);
4161
+ }
4162
+ }
4163
+ async function handleDismiss(id) {
4164
+ try {
4165
+ const response = await fetch(`${apiBaseUrl}/api/admin/error-logs/${id}/dismiss`, {
4166
+ method: "PATCH",
4167
+ headers: authToken ? { Authorization: `Bearer ${authToken}` } : {}
4168
+ });
4169
+ if (response.ok) {
4170
+ fetchLogs();
4171
+ }
4172
+ } catch (err) {
4173
+ console.error("Failed to dismiss error:", err);
4174
+ }
4175
+ }
4176
+ async function handleUndismiss(id) {
4177
+ try {
4178
+ const response = await fetch(`${apiBaseUrl}/api/admin/error-logs/${id}/undismiss`, {
4179
+ method: "PATCH",
4180
+ headers: authToken ? { Authorization: `Bearer ${authToken}` } : {}
4181
+ });
4182
+ if (response.ok) {
4183
+ fetchLogs();
4184
+ }
4185
+ } catch (err) {
4186
+ console.error("Failed to undismiss error:", err);
4187
+ }
4188
+ }
4189
+ function getErrorDefinition(code) {
4190
+ return ERROR_DEFINITIONS[code];
4191
+ }
4192
+ const totalErrors = logs.reduce((sum, log) => sum + log.count, 0);
4193
+ const recentCount = logs.filter((log) => isRecent(log.lastSeenAt)).length;
4194
+ return /* @__PURE__ */ jsxs7("div", { style: panelStyles3.container, "data-testid": "error-logs-panel", children: [
4195
+ /* @__PURE__ */ jsxs7("div", { style: panelStyles3.header, children: [
4196
+ /* @__PURE__ */ jsx7("h2", { style: panelStyles3.title, children: "Error Tracking" }),
4197
+ /* @__PURE__ */ jsx7("p", { style: panelStyles3.subtitle, children: "Aggregated errors from QuizPlayer and AttemptViewer components, sorted by occurrence count" })
4198
+ ] }),
4199
+ /* @__PURE__ */ jsxs7("div", { style: panelStyles3.tabs, children: [
4200
+ /* @__PURE__ */ jsx7(
4201
+ "button",
4202
+ {
4203
+ style: {
4204
+ ...panelStyles3.tab,
4205
+ ...showDismissed ? {} : panelStyles3.tabActive
4206
+ },
4207
+ onClick: () => {
4208
+ setShowDismissed(false);
4209
+ setPage(1);
4210
+ },
4211
+ "data-testid": "tab-active-errors",
4212
+ children: "Active Errors"
4213
+ }
4214
+ ),
4215
+ /* @__PURE__ */ jsx7(
4216
+ "button",
4217
+ {
4218
+ style: {
4219
+ ...panelStyles3.tab,
4220
+ ...showDismissed ? panelStyles3.tabActive : {}
4221
+ },
4222
+ onClick: () => {
4223
+ setShowDismissed(true);
4224
+ setPage(1);
4225
+ },
4226
+ "data-testid": "tab-dismissed-errors",
4227
+ children: "Dismissed"
4228
+ }
4229
+ )
4230
+ ] }),
4231
+ !showDismissed && /* @__PURE__ */ jsxs7("div", { style: panelStyles3.stats, children: [
4232
+ /* @__PURE__ */ jsxs7("div", { style: panelStyles3.statCard, children: [
4233
+ /* @__PURE__ */ jsx7("div", { style: panelStyles3.statValue, children: total }),
4234
+ /* @__PURE__ */ jsx7("div", { style: panelStyles3.statLabel, children: "Unique Errors" })
4235
+ ] }),
4236
+ /* @__PURE__ */ jsxs7("div", { style: panelStyles3.statCard, children: [
4237
+ /* @__PURE__ */ jsx7("div", { style: panelStyles3.statValue, children: totalErrors }),
4238
+ /* @__PURE__ */ jsx7("div", { style: panelStyles3.statLabel, children: "Total Occurrences" })
4239
+ ] }),
4240
+ /* @__PURE__ */ jsxs7("div", { style: panelStyles3.statCard, children: [
4241
+ /* @__PURE__ */ jsx7("div", { style: { ...panelStyles3.statValue, color: recentCount > 0 ? "#ef4444" : "#22c55e" }, children: recentCount }),
4242
+ /* @__PURE__ */ jsx7("div", { style: panelStyles3.statLabel, children: "Last 24h" })
4243
+ ] })
4244
+ ] }),
4245
+ loading ? /* @__PURE__ */ jsx7("div", { style: panelStyles3.loading, children: "Loading..." }) : logs.length === 0 ? /* @__PURE__ */ jsx7("div", { style: panelStyles3.emptyState, children: showDismissed ? "No dismissed errors" : "No active errors" }) : /* @__PURE__ */ jsx7("div", { style: panelStyles3.errorList, children: logs.map((log) => {
4246
+ const def = getErrorDefinition(log.errorCode);
4247
+ const recent = isRecent(log.lastSeenAt);
4248
+ return /* @__PURE__ */ jsxs7(
4249
+ "div",
4250
+ {
4251
+ style: {
4252
+ ...panelStyles3.errorCard,
4253
+ ...recent ? panelStyles3.errorCardRecent : panelStyles3.errorCardOld
4254
+ },
4255
+ "data-testid": `error-log-${log.id}`,
4256
+ children: [
4257
+ /* @__PURE__ */ jsxs7("div", { style: panelStyles3.errorHeader, children: [
4258
+ /* @__PURE__ */ jsxs7("div", { style: panelStyles3.errorLeft, children: [
4259
+ /* @__PURE__ */ jsx7("span", { style: panelStyles3.errorCode, children: log.errorCode }),
4260
+ /* @__PURE__ */ jsx7("span", { style: panelStyles3.contextBadge, children: log.context }),
4261
+ /* @__PURE__ */ jsx7("span", { style: { ...panelStyles3.contextBadge, backgroundColor: "#f3e8ff", color: "#7c3aed" }, children: log.component })
4262
+ ] }),
4263
+ /* @__PURE__ */ jsxs7(
4264
+ "span",
4265
+ {
4266
+ style: {
4267
+ ...panelStyles3.countBadge,
4268
+ ...log.count < 10 ? panelStyles3.countBadgeLow : {}
4269
+ },
4270
+ children: [
4271
+ log.count,
4272
+ "x"
4273
+ ]
4274
+ }
4275
+ )
4276
+ ] }),
4277
+ /* @__PURE__ */ jsx7("div", { style: panelStyles3.userMessage, children: def?.userMessage || log.lastMessage || "Unknown error" }),
4278
+ log.resourceId && /* @__PURE__ */ jsxs7("div", { style: panelStyles3.resourceId, children: [
4279
+ "Resource:",
4280
+ " ",
4281
+ onResourceClick ? /* @__PURE__ */ jsx7(
4282
+ "span",
4283
+ {
4284
+ style: panelStyles3.resourceLink,
4285
+ onClick: () => onResourceClick(log.resourceId, log.context),
4286
+ "data-testid": `link-resource-${log.id}`,
4287
+ children: log.resourceId
4288
+ }
4289
+ ) : log.resourceId
4290
+ ] }),
4291
+ /* @__PURE__ */ jsxs7("div", { style: panelStyles3.timestamps, children: [
4292
+ /* @__PURE__ */ jsxs7("span", { children: [
4293
+ "First: ",
4294
+ formatRelativeTime(log.firstSeenAt)
4295
+ ] }),
4296
+ /* @__PURE__ */ jsxs7("span", { children: [
4297
+ "Last: ",
4298
+ formatRelativeTime(log.lastSeenAt)
4299
+ ] })
4300
+ ] }),
4301
+ /* @__PURE__ */ jsx7(
4302
+ "button",
4303
+ {
4304
+ style: panelStyles3.dismissButton,
4305
+ onClick: () => showDismissed ? handleUndismiss(log.id) : handleDismiss(log.id),
4306
+ "data-testid": `button-dismiss-${log.id}`,
4307
+ children: showDismissed ? "Restore" : "Dismiss"
4308
+ }
4309
+ )
4310
+ ]
4311
+ },
4312
+ log.id
4313
+ );
4314
+ }) }),
4315
+ totalPages > 1 && /* @__PURE__ */ jsxs7("div", { style: panelStyles3.pagination, children: [
4316
+ /* @__PURE__ */ jsx7(
4317
+ "button",
4318
+ {
4319
+ style: {
4320
+ ...panelStyles3.pageButton,
4321
+ ...page <= 1 ? panelStyles3.pageButtonDisabled : {}
4322
+ },
4323
+ onClick: () => setPage((p) => Math.max(1, p - 1)),
4324
+ disabled: page <= 1,
4325
+ "data-testid": "button-prev-page",
4326
+ children: "Previous"
4327
+ }
4328
+ ),
4329
+ /* @__PURE__ */ jsxs7("span", { style: { padding: "8px 12px", color: "#6b7280" }, children: [
4330
+ "Page ",
4331
+ page,
4332
+ " of ",
4333
+ totalPages
4334
+ ] }),
4335
+ /* @__PURE__ */ jsx7(
4336
+ "button",
4337
+ {
4338
+ style: {
4339
+ ...panelStyles3.pageButton,
4340
+ ...page >= totalPages ? panelStyles3.pageButtonDisabled : {}
4341
+ },
4342
+ onClick: () => setPage((p) => Math.min(totalPages, p + 1)),
4343
+ disabled: page >= totalPages,
4344
+ "data-testid": "button-next-page",
4345
+ children: "Next"
4346
+ }
4347
+ )
4348
+ ] })
4349
+ ] });
4350
+ }
2954
4351
  export {
2955
4352
  AttemptViewer,
4353
+ ERROR_DEFINITIONS,
4354
+ ErrorLogsPanel,
4355
+ ErrorTypesPanel,
4356
+ MaintenanceScreen,
2956
4357
  QuizApiClient,
2957
4358
  QuizPlayer,
2958
4359
  TextToSpeech,
2959
4360
  calculateScore,
2960
4361
  checkAnswer,
2961
4362
  createAnswerDetail,
2962
- formatTime
4363
+ formatTime,
4364
+ getErrorFromHttpStatus,
4365
+ getErrorFromMessage
2963
4366
  };
2964
4367
  //# sourceMappingURL=index.mjs.map