@schoolio/player 1.4.4 → 1.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -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
@@ -1023,8 +1030,191 @@ function QuestionChatPanel({
1023
1030
  ] });
1024
1031
  }
1025
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
+
1026
1216
  // src/QuizPlayer.tsx
1027
- 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";
1028
1218
  var defaultStyles = {
1029
1219
  container: {
1030
1220
  fontFamily: "system-ui, -apple-system, sans-serif",
@@ -1093,7 +1283,9 @@ var defaultStyles = {
1093
1283
  option: {
1094
1284
  width: "100%",
1095
1285
  padding: "12px 16px",
1096
- border: "2px solid #e5e7eb",
1286
+ borderWidth: "2px",
1287
+ borderStyle: "solid",
1288
+ borderColor: "#e5e7eb",
1097
1289
  borderRadius: "8px",
1098
1290
  cursor: "pointer",
1099
1291
  transition: "all 0.2s ease",
@@ -1387,7 +1579,7 @@ function SortingDragDrop({ items, currentOrder, correctOrder, showFeedback, onOr
1387
1579
  setDraggedIndex(null);
1388
1580
  setDragOverIndex(null);
1389
1581
  };
1390
- return /* @__PURE__ */ jsx3("div", { style: defaultStyles.options, children: currentOrder.map((itemIndex, position) => {
1582
+ return /* @__PURE__ */ jsx4("div", { style: defaultStyles.options, children: currentOrder.map((itemIndex, position) => {
1391
1583
  const isCorrectPosition = correctOrder?.[position] === itemIndex;
1392
1584
  const isDragging = draggedIndex === position;
1393
1585
  const isDragOver = dragOverIndex === position;
@@ -1410,7 +1602,7 @@ function SortingDragDrop({ items, currentOrder, correctOrder, showFeedback, onOr
1410
1602
  } else if (isDragOver) {
1411
1603
  itemStyle = { ...itemStyle, borderColor: "#6366f1", backgroundColor: "#eef2ff" };
1412
1604
  }
1413
- return /* @__PURE__ */ jsxs3(
1605
+ return /* @__PURE__ */ jsxs4(
1414
1606
  "div",
1415
1607
  {
1416
1608
  style: itemStyle,
@@ -1422,34 +1614,34 @@ function SortingDragDrop({ items, currentOrder, correctOrder, showFeedback, onOr
1422
1614
  onDrop: (e) => handleDrop(e, position),
1423
1615
  onDragEnd: handleDragEnd,
1424
1616
  children: [
1425
- !showFeedback && /* @__PURE__ */ jsx3("div", { style: {
1617
+ !showFeedback && /* @__PURE__ */ jsx4("div", { style: {
1426
1618
  cursor: "grab",
1427
1619
  padding: "4px",
1428
1620
  display: "flex",
1429
1621
  alignItems: "center",
1430
1622
  color: "#9ca3af"
1431
- }, children: /* @__PURE__ */ jsxs3("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1432
- /* @__PURE__ */ jsx3("circle", { cx: "9", cy: "5", r: "1" }),
1433
- /* @__PURE__ */ jsx3("circle", { cx: "9", cy: "12", r: "1" }),
1434
- /* @__PURE__ */ jsx3("circle", { cx: "9", cy: "19", r: "1" }),
1435
- /* @__PURE__ */ jsx3("circle", { cx: "15", cy: "5", r: "1" }),
1436
- /* @__PURE__ */ jsx3("circle", { cx: "15", cy: "12", r: "1" }),
1437
- /* @__PURE__ */ jsx3("circle", { cx: "15", cy: "19", r: "1" })
1623
+ }, children: /* @__PURE__ */ jsxs4("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1624
+ /* @__PURE__ */ jsx4("circle", { cx: "9", cy: "5", r: "1" }),
1625
+ /* @__PURE__ */ jsx4("circle", { cx: "9", cy: "12", r: "1" }),
1626
+ /* @__PURE__ */ jsx4("circle", { cx: "9", cy: "19", r: "1" }),
1627
+ /* @__PURE__ */ jsx4("circle", { cx: "15", cy: "5", r: "1" }),
1628
+ /* @__PURE__ */ jsx4("circle", { cx: "15", cy: "12", r: "1" }),
1629
+ /* @__PURE__ */ jsx4("circle", { cx: "15", cy: "19", r: "1" })
1438
1630
  ] }) }),
1439
- showFeedback && /* @__PURE__ */ jsx3("div", { style: {
1631
+ showFeedback && /* @__PURE__ */ jsx4("div", { style: {
1440
1632
  display: "flex",
1441
1633
  alignItems: "center",
1442
1634
  color: isCorrectPosition ? "#22c55e" : "#ef4444"
1443
- }, children: isCorrectPosition ? /* @__PURE__ */ jsxs3("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1444
- /* @__PURE__ */ jsx3("path", { d: "M22 11.08V12a10 10 0 1 1-5.93-9.14" }),
1445
- /* @__PURE__ */ jsx3("polyline", { points: "22 4 12 14.01 9 11.01" })
1446
- ] }) : /* @__PURE__ */ jsxs3("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1447
- /* @__PURE__ */ jsx3("circle", { cx: "12", cy: "12", r: "10" }),
1448
- /* @__PURE__ */ jsx3("line", { x1: "15", y1: "9", x2: "9", y2: "15" }),
1449
- /* @__PURE__ */ jsx3("line", { x1: "9", y1: "9", x2: "15", y2: "15" })
1635
+ }, 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: [
1636
+ /* @__PURE__ */ jsx4("path", { d: "M22 11.08V12a10 10 0 1 1-5.93-9.14" }),
1637
+ /* @__PURE__ */ jsx4("polyline", { points: "22 4 12 14.01 9 11.01" })
1638
+ ] }) : /* @__PURE__ */ jsxs4("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1639
+ /* @__PURE__ */ jsx4("circle", { cx: "12", cy: "12", r: "10" }),
1640
+ /* @__PURE__ */ jsx4("line", { x1: "15", y1: "9", x2: "9", y2: "15" }),
1641
+ /* @__PURE__ */ jsx4("line", { x1: "9", y1: "9", x2: "15", y2: "15" })
1450
1642
  ] }) }),
1451
- /* @__PURE__ */ jsx3("span", { style: { flex: 1 }, children: items[itemIndex] }),
1452
- /* @__PURE__ */ jsx3("span", { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsx3(TextToSpeech, { text: items[itemIndex], size: "sm" }) })
1643
+ /* @__PURE__ */ jsx4("span", { style: { flex: 1 }, children: items[itemIndex] }),
1644
+ /* @__PURE__ */ jsx4("span", { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsx4(TextToSpeech, { text: items[itemIndex], size: "sm" }) })
1453
1645
  ]
1454
1646
  },
1455
1647
  itemIndex
@@ -1503,9 +1695,9 @@ function MatchingDragDrop({ leftItems, rightItems, currentMatches, correctMatche
1503
1695
  delete newMatches[leftItem];
1504
1696
  onMatchChange(newMatches);
1505
1697
  };
1506
- return /* @__PURE__ */ jsxs3("div", { style: { display: "flex", gap: "24px", flexWrap: "wrap" }, children: [
1507
- /* @__PURE__ */ jsxs3("div", { style: { flex: 1, minWidth: "200px", display: "flex", flexDirection: "column", gap: "8px" }, children: [
1508
- /* @__PURE__ */ jsx3("div", { style: { fontSize: "14px", fontWeight: "600", color: "#6b7280", marginBottom: "4px" }, children: "Match these items:" }),
1698
+ return /* @__PURE__ */ jsxs4("div", { style: { display: "flex", gap: "24px", flexWrap: "wrap" }, children: [
1699
+ /* @__PURE__ */ jsxs4("div", { style: { flex: 1, minWidth: "200px", display: "flex", flexDirection: "column", gap: "8px" }, children: [
1700
+ /* @__PURE__ */ jsx4("div", { style: { fontSize: "14px", fontWeight: "600", color: "#6b7280", marginBottom: "4px" }, children: "Match these items:" }),
1509
1701
  leftItems.map((leftItem, idx) => {
1510
1702
  const matchedRight = currentMatches[leftItem];
1511
1703
  const correctMatch = correctMatches?.[leftItem];
@@ -1516,7 +1708,9 @@ function MatchingDragDrop({ leftItems, rightItems, currentMatches, correctMatche
1516
1708
  alignItems: "center",
1517
1709
  gap: "12px",
1518
1710
  padding: "12px 16px",
1519
- border: "2px dashed #e5e7eb",
1711
+ borderWidth: "2px",
1712
+ borderStyle: "dashed",
1713
+ borderColor: "#e5e7eb",
1520
1714
  borderRadius: "8px",
1521
1715
  backgroundColor: "#ffffff",
1522
1716
  minHeight: "56px",
@@ -1534,7 +1728,7 @@ function MatchingDragDrop({ leftItems, rightItems, currentMatches, correctMatche
1534
1728
  } else if (matchedRight) {
1535
1729
  rowStyle = { ...rowStyle, borderStyle: "solid", borderColor: "#22c55e" };
1536
1730
  }
1537
- return /* @__PURE__ */ jsxs3(
1731
+ return /* @__PURE__ */ jsxs4(
1538
1732
  "div",
1539
1733
  {
1540
1734
  style: rowStyle,
@@ -1543,9 +1737,9 @@ function MatchingDragDrop({ leftItems, rightItems, currentMatches, correctMatche
1543
1737
  onDragLeave: handleDragLeave,
1544
1738
  onDrop: (e) => handleDrop(e, leftItem),
1545
1739
  children: [
1546
- /* @__PURE__ */ jsx3("span", { style: { flex: 1, fontWeight: "500" }, children: leftItem }),
1547
- /* @__PURE__ */ jsx3("span", { style: { color: "#6b7280" }, children: "\u2192" }),
1548
- matchedRight ? /* @__PURE__ */ jsxs3("div", { style: {
1740
+ /* @__PURE__ */ jsx4("span", { style: { flex: 1, fontWeight: "500" }, children: leftItem }),
1741
+ /* @__PURE__ */ jsx4("span", { style: { color: "#6b7280" }, children: "\u2192" }),
1742
+ matchedRight ? /* @__PURE__ */ jsxs4("div", { style: {
1549
1743
  display: "flex",
1550
1744
  alignItems: "center",
1551
1745
  gap: "8px",
@@ -1554,8 +1748,8 @@ function MatchingDragDrop({ leftItems, rightItems, currentMatches, correctMatche
1554
1748
  borderRadius: "6px",
1555
1749
  fontSize: "14px"
1556
1750
  }, children: [
1557
- /* @__PURE__ */ jsx3("span", { children: matchedRight }),
1558
- !showFeedback && /* @__PURE__ */ jsx3(
1751
+ /* @__PURE__ */ jsx4("span", { children: matchedRight }),
1752
+ !showFeedback && /* @__PURE__ */ jsx4(
1559
1753
  "button",
1560
1754
  {
1561
1755
  onClick: () => handleClearMatch(leftItem),
@@ -1568,18 +1762,18 @@ function MatchingDragDrop({ leftItems, rightItems, currentMatches, correctMatche
1568
1762
  color: "#6b7280"
1569
1763
  },
1570
1764
  "aria-label": "Remove match",
1571
- children: /* @__PURE__ */ jsxs3("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1572
- /* @__PURE__ */ jsx3("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1573
- /* @__PURE__ */ jsx3("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1765
+ children: /* @__PURE__ */ jsxs4("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1766
+ /* @__PURE__ */ jsx4("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1767
+ /* @__PURE__ */ jsx4("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1574
1768
  ] })
1575
1769
  }
1576
1770
  ),
1577
- showFeedback && (isCorrect ? /* @__PURE__ */ jsx3("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "#22c55e", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx3("polyline", { points: "20 6 9 17 4 12" }) }) : /* @__PURE__ */ jsxs3("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "#ef4444", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1578
- /* @__PURE__ */ jsx3("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1579
- /* @__PURE__ */ jsx3("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1771
+ 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: [
1772
+ /* @__PURE__ */ jsx4("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1773
+ /* @__PURE__ */ jsx4("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1580
1774
  ] }))
1581
- ] }) : /* @__PURE__ */ jsx3("span", { style: { color: "#9ca3af", fontSize: "14px", fontStyle: "italic" }, children: "Drop here" }),
1582
- showFeedback && !isCorrect && correctMatch && /* @__PURE__ */ jsxs3("span", { style: { color: "#166534", fontSize: "13px", marginLeft: "8px" }, children: [
1775
+ ] }) : /* @__PURE__ */ jsx4("span", { style: { color: "#9ca3af", fontSize: "14px", fontStyle: "italic" }, children: "Drop here" }),
1776
+ showFeedback && !isCorrect && correctMatch && /* @__PURE__ */ jsxs4("span", { style: { color: "#166534", fontSize: "13px", marginLeft: "8px" }, children: [
1583
1777
  "(Correct: ",
1584
1778
  correctMatch,
1585
1779
  ")"
@@ -1590,16 +1784,18 @@ function MatchingDragDrop({ leftItems, rightItems, currentMatches, correctMatche
1590
1784
  );
1591
1785
  })
1592
1786
  ] }),
1593
- /* @__PURE__ */ jsxs3("div", { style: { flex: 1, minWidth: "200px", display: "flex", flexDirection: "column", gap: "8px" }, children: [
1594
- /* @__PURE__ */ jsx3("div", { style: { fontSize: "14px", fontWeight: "600", color: "#6b7280", marginBottom: "4px" }, children: "Drag to match:" }),
1787
+ /* @__PURE__ */ jsxs4("div", { style: { flex: 1, minWidth: "200px", display: "flex", flexDirection: "column", gap: "8px" }, children: [
1788
+ /* @__PURE__ */ jsx4("div", { style: { fontSize: "14px", fontWeight: "600", color: "#6b7280", marginBottom: "4px" }, children: "Drag to match:" }),
1595
1789
  unmatchedRightItems.length > 0 ? unmatchedRightItems.map((rightItem, idx) => {
1596
1790
  const isDragging = draggedItem === rightItem;
1597
- return /* @__PURE__ */ jsxs3(
1791
+ return /* @__PURE__ */ jsxs4(
1598
1792
  "div",
1599
1793
  {
1600
1794
  style: {
1601
1795
  padding: "12px 16px",
1602
- border: "2px solid #e5e7eb",
1796
+ borderWidth: "2px",
1797
+ borderStyle: "solid",
1798
+ borderColor: "#e5e7eb",
1603
1799
  borderRadius: "8px",
1604
1800
  backgroundColor: "#ffffff",
1605
1801
  cursor: showFeedback ? "default" : "grab",
@@ -1614,20 +1810,20 @@ function MatchingDragDrop({ leftItems, rightItems, currentMatches, correctMatche
1614
1810
  onDragEnd: handleDragEnd,
1615
1811
  "data-testid": `draggable-right-${idx}`,
1616
1812
  children: [
1617
- !showFeedback && /* @__PURE__ */ jsx3("div", { style: { color: "#9ca3af", display: "flex" }, children: /* @__PURE__ */ jsxs3("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1618
- /* @__PURE__ */ jsx3("circle", { cx: "9", cy: "5", r: "1" }),
1619
- /* @__PURE__ */ jsx3("circle", { cx: "9", cy: "12", r: "1" }),
1620
- /* @__PURE__ */ jsx3("circle", { cx: "9", cy: "19", r: "1" }),
1621
- /* @__PURE__ */ jsx3("circle", { cx: "15", cy: "5", r: "1" }),
1622
- /* @__PURE__ */ jsx3("circle", { cx: "15", cy: "12", r: "1" }),
1623
- /* @__PURE__ */ jsx3("circle", { cx: "15", cy: "19", r: "1" })
1813
+ !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: [
1814
+ /* @__PURE__ */ jsx4("circle", { cx: "9", cy: "5", r: "1" }),
1815
+ /* @__PURE__ */ jsx4("circle", { cx: "9", cy: "12", r: "1" }),
1816
+ /* @__PURE__ */ jsx4("circle", { cx: "9", cy: "19", r: "1" }),
1817
+ /* @__PURE__ */ jsx4("circle", { cx: "15", cy: "5", r: "1" }),
1818
+ /* @__PURE__ */ jsx4("circle", { cx: "15", cy: "12", r: "1" }),
1819
+ /* @__PURE__ */ jsx4("circle", { cx: "15", cy: "19", r: "1" })
1624
1820
  ] }) }),
1625
- /* @__PURE__ */ jsx3("span", { style: { flex: 1 }, children: rightItem })
1821
+ /* @__PURE__ */ jsx4("span", { style: { flex: 1 }, children: rightItem })
1626
1822
  ]
1627
1823
  },
1628
1824
  idx
1629
1825
  );
1630
- }) : /* @__PURE__ */ jsx3("div", { style: {
1826
+ }) : /* @__PURE__ */ jsx4("div", { style: {
1631
1827
  padding: "16px",
1632
1828
  textAlign: "center",
1633
1829
  color: "#22c55e",
@@ -1637,7 +1833,7 @@ function MatchingDragDrop({ leftItems, rightItems, currentMatches, correctMatche
1637
1833
  ] });
1638
1834
  }
1639
1835
  function Spinner({ size = 16, color = "#ffffff" }) {
1640
- return /* @__PURE__ */ jsx3(
1836
+ return /* @__PURE__ */ jsx4(
1641
1837
  "span",
1642
1838
  {
1643
1839
  style: {
@@ -1649,7 +1845,7 @@ function Spinner({ size = 16, color = "#ffffff" }) {
1649
1845
  borderRadius: "50%",
1650
1846
  animation: "spin 0.8s linear infinite"
1651
1847
  },
1652
- children: /* @__PURE__ */ jsx3("style", { children: `@keyframes spin { to { transform: rotate(360deg); } }` })
1848
+ children: /* @__PURE__ */ jsx4("style", { children: `@keyframes spin { to { transform: rotate(360deg); } }` })
1653
1849
  }
1654
1850
  );
1655
1851
  }
@@ -1667,7 +1863,8 @@ function QuizPlayer({
1667
1863
  onProgress,
1668
1864
  onGenerateMoreQuestions,
1669
1865
  className,
1670
- forceNewAttempt = true
1866
+ forceNewAttempt = true,
1867
+ hideScore = false
1671
1868
  }) {
1672
1869
  const [quiz, setQuiz] = useState3(null);
1673
1870
  const [attempt, setAttempt] = useState3(null);
@@ -1678,10 +1875,14 @@ function QuizPlayer({
1678
1875
  const [isNavigating, setIsNavigating] = useState3(false);
1679
1876
  const [isCompleted, setIsCompleted] = useState3(false);
1680
1877
  const [result, setResult] = useState3(null);
1681
- const [error, setError] = useState3(null);
1878
+ const [errorCode, setErrorCode] = useState3(null);
1682
1879
  const [isLoading, setIsLoading] = useState3(true);
1683
1880
  const [elapsedSeconds, setElapsedSeconds] = useState3(0);
1684
1881
  const [showIntro, setShowIntro] = useState3(true);
1882
+ const [showResumeChoice, setShowResumeChoice] = useState3(false);
1883
+ const [hasExistingProgress, setHasExistingProgress] = useState3(false);
1884
+ const [existingProgressCount, setExistingProgressCount] = useState3(0);
1885
+ const [isStartingFresh, setIsStartingFresh] = useState3(false);
1685
1886
  const [timerStarted, setTimerStarted] = useState3(false);
1686
1887
  const [showFeedback, setShowFeedback] = useState3(false);
1687
1888
  const [currentAnswerDetail, setCurrentAnswerDetail] = useState3(null);
@@ -1695,6 +1896,7 @@ function QuizPlayer({
1695
1896
  const [showReportModal, setShowReportModal] = useState3(false);
1696
1897
  const [isReporting, setIsReporting] = useState3(false);
1697
1898
  const [reportComment, setReportComment] = useState3("");
1899
+ const [retryKey, setRetryKey] = useState3(0);
1698
1900
  const apiClient = useRef3(null);
1699
1901
  const timerRef = useRef3(null);
1700
1902
  const startTimeRef = useRef3(0);
@@ -1716,7 +1918,7 @@ function QuizPlayer({
1716
1918
  if (!apiClient.current) return;
1717
1919
  try {
1718
1920
  setIsLoading(true);
1719
- setError(null);
1921
+ setErrorCode(null);
1720
1922
  const quizData = await apiClient.current.getQuiz(quizId);
1721
1923
  setQuiz(quizData);
1722
1924
  const attemptData = await apiClient.current.createAttempt({
@@ -1729,7 +1931,10 @@ function QuizPlayer({
1729
1931
  forceNew: forceNewAttempt
1730
1932
  });
1731
1933
  setAttempt(attemptData);
1732
- if (!forceNewAttempt && attemptData.answers && attemptData.answers.length > 0) {
1934
+ if (!forceNewAttempt && attemptData.answers && attemptData.answers.length > 0 && attemptData.status === "in_progress") {
1935
+ setHasExistingProgress(true);
1936
+ setExistingProgressCount(attemptData.answers.length);
1937
+ setShowResumeChoice(true);
1733
1938
  setAnswersDetail(attemptData.answers);
1734
1939
  const answersMap = /* @__PURE__ */ new Map();
1735
1940
  attemptData.answers.forEach((a) => {
@@ -1752,15 +1957,23 @@ function QuizPlayer({
1752
1957
  setIsLoading(false);
1753
1958
  } catch (err) {
1754
1959
  const message = err instanceof Error ? err.message : "Failed to load quiz";
1755
- setError(message);
1960
+ const code = getErrorFromMessage(message, "quiz");
1961
+ setErrorCode(code);
1962
+ apiClient.current?.logError({
1963
+ errorCode: code,
1964
+ context: "quiz",
1965
+ resourceId: quizId,
1966
+ component: "QuizPlayer",
1967
+ message
1968
+ });
1756
1969
  setIsLoading(false);
1757
1970
  onErrorRef.current?.(err instanceof Error ? err : new Error(message));
1758
1971
  }
1759
1972
  }
1760
1973
  initialize();
1761
- }, [quizId, lessonId, assignLessonId, courseId, childId, parentId, forceNewAttempt]);
1974
+ }, [quizId, lessonId, assignLessonId, courseId, childId, parentId, forceNewAttempt, retryKey]);
1762
1975
  useEffect3(() => {
1763
- if (timerStarted && !isCompleted && !error) {
1976
+ if (timerStarted && !isCompleted && !errorCode) {
1764
1977
  startTimeRef.current = Date.now();
1765
1978
  timerRef.current = setInterval(() => {
1766
1979
  setElapsedSeconds(Math.floor((Date.now() - startTimeRef.current) / 1e3));
@@ -1771,11 +1984,62 @@ function QuizPlayer({
1771
1984
  clearInterval(timerRef.current);
1772
1985
  }
1773
1986
  };
1774
- }, [timerStarted, isCompleted, error]);
1987
+ }, [timerStarted, isCompleted, errorCode]);
1775
1988
  const handleStart = useCallback2(() => {
1776
1989
  setShowIntro(false);
1990
+ setShowResumeChoice(false);
1777
1991
  setTimerStarted(true);
1778
1992
  }, []);
1993
+ const handleResumePrevious = useCallback2(() => {
1994
+ if (quiz && answers.size > 0) {
1995
+ const answeredIds = new Set(answers.keys());
1996
+ const allQs = [...quiz.questions, ...extraQuestions].filter((q) => !skippedQuestionIds.has(q.id));
1997
+ let resumeIndex = 0;
1998
+ for (let i = 0; i < allQs.length; i++) {
1999
+ if (!answeredIds.has(allQs[i].id)) {
2000
+ resumeIndex = i;
2001
+ break;
2002
+ }
2003
+ resumeIndex = allQs.length - 1;
2004
+ }
2005
+ setCurrentQuestionIndex(resumeIndex);
2006
+ }
2007
+ setShowIntro(false);
2008
+ setShowResumeChoice(false);
2009
+ setTimerStarted(true);
2010
+ }, [quiz, answers, extraQuestions, skippedQuestionIds]);
2011
+ const handleStartFresh = useCallback2(async () => {
2012
+ if (!apiClient.current || !attempt) return;
2013
+ setIsStartingFresh(true);
2014
+ try {
2015
+ await apiClient.current.updateAttempt(attempt.id, {
2016
+ status: "abandoned"
2017
+ });
2018
+ const newAttemptData = await apiClient.current.createAttempt({
2019
+ quizId,
2020
+ lessonId,
2021
+ assignLessonId,
2022
+ courseId,
2023
+ childId,
2024
+ parentId,
2025
+ forceNew: true
2026
+ });
2027
+ setAttempt(newAttemptData);
2028
+ setAnswers(/* @__PURE__ */ new Map());
2029
+ setAnswersDetail([]);
2030
+ setCurrentQuestionIndex(0);
2031
+ setHasExistingProgress(false);
2032
+ setExistingProgressCount(0);
2033
+ setShowResumeChoice(false);
2034
+ setShowIntro(false);
2035
+ setTimerStarted(true);
2036
+ } catch (err) {
2037
+ const message = err instanceof Error ? err.message : "Failed to start fresh";
2038
+ onErrorRef.current?.(new Error(message));
2039
+ } finally {
2040
+ setIsStartingFresh(false);
2041
+ }
2042
+ }, [attempt, quizId, lessonId, assignLessonId, courseId, childId, parentId]);
1779
2043
  useEffect3(() => {
1780
2044
  setShowFeedback(false);
1781
2045
  setCurrentAnswerDetail(null);
@@ -1895,7 +2159,15 @@ function QuizPlayer({
1895
2159
  onCompleteRef.current?.(quizResult);
1896
2160
  } catch (err) {
1897
2161
  const message = err instanceof Error ? err.message : "Failed to submit quiz";
1898
- setError(message);
2162
+ const code = getErrorFromMessage(message, "quiz");
2163
+ setErrorCode(code);
2164
+ apiClient.current?.logError({
2165
+ errorCode: code,
2166
+ context: "quiz",
2167
+ resourceId: quizId,
2168
+ component: "QuizPlayer",
2169
+ message
2170
+ });
1899
2171
  onErrorRef.current?.(err instanceof Error ? err : new Error(message));
1900
2172
  } finally {
1901
2173
  setIsSubmitting(false);
@@ -1973,14 +2245,43 @@ function QuizPlayer({
1973
2245
  setIsReporting(false);
1974
2246
  }
1975
2247
  }, [currentQuestion, apiClient, attempt, quiz, childId, parentId, lessonId, courseId, assignLessonId]);
2248
+ const handleRetryQuiz = useCallback2(() => {
2249
+ setCurrentQuestionIndex(0);
2250
+ setAnswers(/* @__PURE__ */ new Map());
2251
+ setAnswersDetail([]);
2252
+ setIsCompleted(false);
2253
+ setResult(null);
2254
+ setErrorCode(null);
2255
+ setShowIntro(true);
2256
+ setShowFeedback(false);
2257
+ setCurrentAnswerDetail(null);
2258
+ setTimerStarted(false);
2259
+ setElapsedSeconds(0);
2260
+ startTimeRef.current = 0;
2261
+ setExtraQuestions([]);
2262
+ setSkippedQuestionIds(/* @__PURE__ */ new Set());
2263
+ setAttempt(null);
2264
+ setShowResumeChoice(false);
2265
+ setHasExistingProgress(false);
2266
+ setExistingProgressCount(0);
2267
+ setIsSubmitting(false);
2268
+ setIsNavigating(false);
2269
+ setIsGeneratingExtra(false);
2270
+ setIsStartingFresh(false);
2271
+ setShowSkipModal(false);
2272
+ setIsSkipping(false);
2273
+ setSkipComment("");
2274
+ setSelectedSkipReason(null);
2275
+ setShowReportModal(false);
2276
+ setIsReporting(false);
2277
+ setReportComment("");
2278
+ setRetryKey((prev) => prev + 1);
2279
+ }, []);
1976
2280
  if (isLoading) {
1977
- return /* @__PURE__ */ jsx3("div", { className, style: defaultStyles.container, children: /* @__PURE__ */ jsx3("div", { style: defaultStyles.loading, children: "Loading quiz..." }) });
2281
+ return /* @__PURE__ */ jsx4("div", { className, style: defaultStyles.container, children: /* @__PURE__ */ jsx4("div", { style: defaultStyles.loading, children: "Loading quiz..." }) });
1978
2282
  }
1979
- if (error) {
1980
- return /* @__PURE__ */ jsx3("div", { className, style: defaultStyles.container, children: /* @__PURE__ */ jsx3("div", { style: defaultStyles.error, children: /* @__PURE__ */ jsxs3("p", { children: [
1981
- "Error: ",
1982
- error
1983
- ] }) }) });
2283
+ if (errorCode) {
2284
+ return /* @__PURE__ */ jsx4("div", { className, style: defaultStyles.container, children: /* @__PURE__ */ jsx4(MaintenanceScreen, { errorCode }) });
1984
2285
  }
1985
2286
  if (isCompleted && result) {
1986
2287
  const percentage = result.totalQuestions > 0 ? Math.round(result.correctAnswers / result.totalQuestions * 100) : 0;
@@ -2038,7 +2339,7 @@ function QuizPlayer({
2038
2339
  rotation: Math.random() * 360,
2039
2340
  size: 6 + Math.random() * 8
2040
2341
  }));
2041
- const StarIcon = ({ filled, delay }) => /* @__PURE__ */ jsx3(
2342
+ const StarIcon = ({ filled, delay }) => /* @__PURE__ */ jsx4(
2042
2343
  "svg",
2043
2344
  {
2044
2345
  width: "36",
@@ -2049,7 +2350,7 @@ function QuizPlayer({
2049
2350
  animationDelay: `${delay}s`,
2050
2351
  opacity: 0
2051
2352
  },
2052
- children: /* @__PURE__ */ jsx3(
2353
+ children: /* @__PURE__ */ jsx4(
2053
2354
  "path",
2054
2355
  {
2055
2356
  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",
@@ -2060,62 +2361,23 @@ function QuizPlayer({
2060
2361
  )
2061
2362
  }
2062
2363
  );
2063
- const MascotOwl = ({ mood }) => {
2064
- const getEyeExpression = () => {
2065
- switch (mood) {
2066
- case "celebrating":
2067
- return { leftEye: ">", rightEye: "<", pupilY: 42 };
2068
- // Squinting happy
2069
- case "happy":
2070
- return { leftEye: null, rightEye: null, pupilY: 42 };
2071
- // Normal happy
2072
- case "encouraging":
2073
- return { leftEye: null, rightEye: null, pupilY: 44 };
2074
- // Looking down warmly
2075
- default:
2076
- return { leftEye: null, rightEye: null, pupilY: 42 };
2077
- }
2078
- };
2079
- const eyeExpr = getEyeExpression();
2080
- return /* @__PURE__ */ jsxs3(
2081
- "svg",
2364
+ const Mascot = ({ mood }) => {
2365
+ return /* @__PURE__ */ jsx4(
2366
+ "img",
2082
2367
  {
2083
- width: "120",
2084
- height: "120",
2085
- viewBox: "0 0 100 100",
2368
+ src: astronautImage,
2369
+ alt: "Astronaut mascot",
2370
+ width: "180",
2371
+ height: "180",
2086
2372
  style: {
2087
- animation: mood === "celebrating" ? "bounce 0.6s ease-in-out infinite" : "gentleBob 2s ease-in-out infinite"
2088
- },
2089
- children: [
2090
- /* @__PURE__ */ jsx3("ellipse", { cx: "50", cy: "60", rx: "35", ry: "30", fill: "#8b5cf6" }),
2091
- /* @__PURE__ */ jsx3("ellipse", { cx: "50", cy: "65", rx: "25", ry: "20", fill: "#c4b5fd" }),
2092
- /* @__PURE__ */ jsx3("circle", { cx: "50", cy: "35", r: "28", fill: "#a78bfa" }),
2093
- /* @__PURE__ */ jsx3("polygon", { points: "28,15 35,30 22,28", fill: "#7c3aed" }),
2094
- /* @__PURE__ */ jsx3("polygon", { points: "72,15 65,30 78,28", fill: "#7c3aed" }),
2095
- /* @__PURE__ */ jsx3("ellipse", { cx: "38", cy: "38", rx: "10", ry: "12", fill: "white" }),
2096
- /* @__PURE__ */ jsx3("ellipse", { cx: "62", cy: "38", rx: "10", ry: "12", fill: "white" }),
2097
- 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" }),
2098
- 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" }),
2099
- /* @__PURE__ */ jsx3("polygon", { points: "50,45 45,52 55,52", fill: "#fbbf24" }),
2100
- (mood === "celebrating" || mood === "happy") && /* @__PURE__ */ jsxs3(Fragment2, { children: [
2101
- /* @__PURE__ */ jsx3("ellipse", { cx: "28", cy: "45", rx: "5", ry: "3", fill: "#fda4af", opacity: "0.6" }),
2102
- /* @__PURE__ */ jsx3("ellipse", { cx: "72", cy: "45", rx: "5", ry: "3", fill: "#fda4af", opacity: "0.6" })
2103
- ] }),
2104
- mood === "celebrating" ? /* @__PURE__ */ jsxs3(Fragment2, { children: [
2105
- /* @__PURE__ */ jsx3("ellipse", { cx: "18", cy: "55", rx: "8", ry: "15", fill: "#7c3aed", transform: "rotate(-30 18 55)" }),
2106
- /* @__PURE__ */ jsx3("ellipse", { cx: "82", cy: "55", rx: "8", ry: "15", fill: "#7c3aed", transform: "rotate(30 82 55)" })
2107
- ] }) : /* @__PURE__ */ jsxs3(Fragment2, { children: [
2108
- /* @__PURE__ */ jsx3("ellipse", { cx: "20", cy: "60", rx: "8", ry: "15", fill: "#7c3aed" }),
2109
- /* @__PURE__ */ jsx3("ellipse", { cx: "80", cy: "60", rx: "8", ry: "15", fill: "#7c3aed" })
2110
- ] }),
2111
- /* @__PURE__ */ jsx3("ellipse", { cx: "40", cy: "88", rx: "8", ry: "4", fill: "#fbbf24" }),
2112
- /* @__PURE__ */ jsx3("ellipse", { cx: "60", cy: "88", rx: "8", ry: "4", fill: "#fbbf24" })
2113
- ]
2373
+ animation: mood === "celebrating" ? "bounce 0.6s ease-in-out infinite" : "gentleBob 2s ease-in-out infinite",
2374
+ objectFit: "contain"
2375
+ }
2114
2376
  }
2115
2377
  );
2116
2378
  };
2117
- return /* @__PURE__ */ jsxs3("div", { className, style: defaultStyles.container, children: [
2118
- /* @__PURE__ */ jsx3("style", { children: `
2379
+ return /* @__PURE__ */ jsxs4("div", { className, style: defaultStyles.container, children: [
2380
+ /* @__PURE__ */ jsx4("style", { children: `
2119
2381
  @keyframes confettiFall {
2120
2382
  0% {
2121
2383
  transform: translateY(-10px) rotate(0deg);
@@ -2178,9 +2440,19 @@ function QuizPlayer({
2178
2440
  opacity: 1;
2179
2441
  }
2180
2442
  }
2443
+ @keyframes buttonFadeIn {
2444
+ 0% {
2445
+ opacity: 0;
2446
+ transform: translateY(10px);
2447
+ }
2448
+ 100% {
2449
+ opacity: 1;
2450
+ transform: translateY(0);
2451
+ }
2452
+ }
2181
2453
  ` }),
2182
- /* @__PURE__ */ jsxs3("div", { style: defaultStyles.results, children: [
2183
- percentage >= 60 && /* @__PURE__ */ jsx3("div", { style: defaultStyles.confettiContainer, children: confettiPieces.map((piece) => /* @__PURE__ */ jsx3(
2454
+ /* @__PURE__ */ jsxs4("div", { style: defaultStyles.results, children: [
2455
+ percentage >= 60 && /* @__PURE__ */ jsx4("div", { style: defaultStyles.confettiContainer, children: confettiPieces.map((piece) => /* @__PURE__ */ jsx4(
2184
2456
  "div",
2185
2457
  {
2186
2458
  style: {
@@ -2197,15 +2469,70 @@ function QuizPlayer({
2197
2469
  },
2198
2470
  piece.id
2199
2471
  )) }),
2200
- /* @__PURE__ */ jsx3("div", { style: { ...defaultStyles.resultsBackground, background: theme.bgGradient } }),
2201
- /* @__PURE__ */ jsxs3("div", { style: defaultStyles.resultsContent, children: [
2202
- /* @__PURE__ */ jsxs3("div", { style: defaultStyles.resultStars, children: [
2203
- /* @__PURE__ */ jsx3(StarIcon, { filled: theme.stars >= 1, delay: 0.3 }),
2204
- /* @__PURE__ */ jsx3(StarIcon, { filled: theme.stars >= 2, delay: 0.5 }),
2205
- /* @__PURE__ */ jsx3(StarIcon, { filled: theme.stars >= 3, delay: 0.7 })
2472
+ /* @__PURE__ */ jsx4("div", { style: { ...defaultStyles.resultsBackground, background: theme.bgGradient } }),
2473
+ /* @__PURE__ */ jsx4("div", { style: defaultStyles.resultsContent, children: hideScore ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
2474
+ /* @__PURE__ */ jsx4("div", { style: { marginBottom: "24px" }, children: /* @__PURE__ */ jsx4(Mascot, { mood: "happy" }) }),
2475
+ /* @__PURE__ */ jsx4(
2476
+ "div",
2477
+ {
2478
+ style: {
2479
+ background: "linear-gradient(135deg, #dcfce7 0%, #bbf7d0 100%)",
2480
+ padding: "12px 28px",
2481
+ borderRadius: "50px",
2482
+ boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
2483
+ marginBottom: "20px",
2484
+ animation: "badgePop 0.6s ease-out 0.2s forwards",
2485
+ opacity: 0,
2486
+ border: "3px solid #22c55e"
2487
+ },
2488
+ children: /* @__PURE__ */ jsx4(
2489
+ "span",
2490
+ {
2491
+ style: {
2492
+ fontSize: "22px",
2493
+ fontWeight: "700",
2494
+ color: "#1f2937",
2495
+ textShadow: "0 1px 2px rgba(255,255,255,0.5)"
2496
+ },
2497
+ children: "All Done!"
2498
+ }
2499
+ )
2500
+ }
2501
+ ),
2502
+ /* @__PURE__ */ jsx4(
2503
+ "div",
2504
+ {
2505
+ style: {
2506
+ animation: "scoreSlideIn 0.5s ease-out 0.4s forwards",
2507
+ opacity: 0
2508
+ },
2509
+ children: /* @__PURE__ */ jsx4(
2510
+ "div",
2511
+ {
2512
+ style: {
2513
+ fontSize: "24px",
2514
+ fontWeight: "600",
2515
+ color: "#22c55e",
2516
+ lineHeight: "1.4",
2517
+ marginBottom: "12px"
2518
+ },
2519
+ children: "The quiz was submitted successfully!"
2520
+ }
2521
+ )
2522
+ }
2523
+ ),
2524
+ /* @__PURE__ */ jsxs4("div", { style: { ...defaultStyles.resultDetails, marginTop: "8px" }, children: [
2525
+ "Time: ",
2526
+ formatTime(result.timeSpentSeconds)
2527
+ ] })
2528
+ ] }) : /* @__PURE__ */ jsxs4(Fragment2, { children: [
2529
+ /* @__PURE__ */ jsxs4("div", { style: defaultStyles.resultStars, children: [
2530
+ /* @__PURE__ */ jsx4(StarIcon, { filled: theme.stars >= 1, delay: 0.3 }),
2531
+ /* @__PURE__ */ jsx4(StarIcon, { filled: theme.stars >= 2, delay: 0.5 }),
2532
+ /* @__PURE__ */ jsx4(StarIcon, { filled: theme.stars >= 3, delay: 0.7 })
2206
2533
  ] }),
2207
- /* @__PURE__ */ jsx3("div", { style: { marginBottom: "16px" }, children: /* @__PURE__ */ jsx3(MascotOwl, { mood: theme.mascotMood }) }),
2208
- /* @__PURE__ */ jsx3(
2534
+ /* @__PURE__ */ jsx4("div", { style: { marginBottom: "16px" }, children: /* @__PURE__ */ jsx4(Mascot, { mood: theme.mascotMood }) }),
2535
+ /* @__PURE__ */ jsx4(
2209
2536
  "div",
2210
2537
  {
2211
2538
  style: {
@@ -2218,7 +2545,7 @@ function QuizPlayer({
2218
2545
  opacity: 0,
2219
2546
  border: `3px solid ${theme.badgeColor}`
2220
2547
  },
2221
- children: /* @__PURE__ */ jsx3(
2548
+ children: /* @__PURE__ */ jsx4(
2222
2549
  "span",
2223
2550
  {
2224
2551
  style: {
@@ -2232,7 +2559,7 @@ function QuizPlayer({
2232
2559
  )
2233
2560
  }
2234
2561
  ),
2235
- /* @__PURE__ */ jsxs3(
2562
+ /* @__PURE__ */ jsxs4(
2236
2563
  "div",
2237
2564
  {
2238
2565
  style: {
@@ -2240,7 +2567,7 @@ function QuizPlayer({
2240
2567
  opacity: 0
2241
2568
  },
2242
2569
  children: [
2243
- /* @__PURE__ */ jsxs3(
2570
+ /* @__PURE__ */ jsxs4(
2244
2571
  "div",
2245
2572
  {
2246
2573
  style: {
@@ -2257,7 +2584,7 @@ function QuizPlayer({
2257
2584
  ]
2258
2585
  }
2259
2586
  ),
2260
- /* @__PURE__ */ jsx3(
2587
+ /* @__PURE__ */ jsx4(
2261
2588
  "div",
2262
2589
  {
2263
2590
  style: {
@@ -2272,25 +2599,116 @@ function QuizPlayer({
2272
2599
  ]
2273
2600
  }
2274
2601
  ),
2275
- /* @__PURE__ */ jsxs3("div", { style: { ...defaultStyles.resultDetails, marginTop: "8px" }, children: [
2602
+ /* @__PURE__ */ jsxs4("div", { style: { ...defaultStyles.resultDetails, marginTop: "8px" }, children: [
2276
2603
  "Time: ",
2277
2604
  formatTime(result.timeSpentSeconds)
2278
- ] })
2279
- ] })
2605
+ ] }),
2606
+ /* @__PURE__ */ jsx4(
2607
+ "button",
2608
+ {
2609
+ style: {
2610
+ marginTop: "24px",
2611
+ padding: "14px 32px",
2612
+ fontSize: "16px",
2613
+ fontWeight: "600",
2614
+ color: "#7c3aed",
2615
+ background: "white",
2616
+ border: "2px solid #7c3aed",
2617
+ borderRadius: "12px",
2618
+ cursor: "pointer",
2619
+ transition: "all 0.2s ease",
2620
+ animation: "buttonFadeIn 0.5s ease-out 0.8s forwards",
2621
+ opacity: 0
2622
+ },
2623
+ onClick: handleRetryQuiz,
2624
+ onMouseOver: (e) => {
2625
+ e.currentTarget.style.background = "#7c3aed";
2626
+ e.currentTarget.style.color = "white";
2627
+ e.currentTarget.style.transform = "translateY(-2px)";
2628
+ },
2629
+ onMouseOut: (e) => {
2630
+ e.currentTarget.style.background = "white";
2631
+ e.currentTarget.style.color = "#7c3aed";
2632
+ e.currentTarget.style.transform = "translateY(0)";
2633
+ },
2634
+ "data-testid": "button-retry-quiz",
2635
+ children: "Try Again"
2636
+ }
2637
+ )
2638
+ ] }) })
2280
2639
  ] })
2281
2640
  ] });
2282
2641
  }
2642
+ if (quiz && showIntro && showResumeChoice && hasExistingProgress) {
2643
+ return /* @__PURE__ */ jsx4("div", { className, style: defaultStyles.container, children: /* @__PURE__ */ jsxs4("div", { style: defaultStyles.intro, children: [
2644
+ /* @__PURE__ */ jsx4("div", { style: defaultStyles.introTitle, children: "Welcome Back!" }),
2645
+ /* @__PURE__ */ jsx4("div", { style: defaultStyles.introSubtitle, children: "You have an unfinished quiz. Would you like to continue or start over?" }),
2646
+ /* @__PURE__ */ jsxs4("div", { style: defaultStyles.introQuestionCount, children: [
2647
+ existingProgressCount,
2648
+ " of ",
2649
+ quiz.questions.length,
2650
+ " question",
2651
+ quiz.questions.length !== 1 ? "s" : "",
2652
+ " answered"
2653
+ ] }),
2654
+ /* @__PURE__ */ jsxs4("div", { style: { display: "flex", flexDirection: "column", gap: "12px", marginTop: "8px" }, children: [
2655
+ /* @__PURE__ */ jsx4(
2656
+ "button",
2657
+ {
2658
+ style: defaultStyles.startButton,
2659
+ onClick: handleResumePrevious,
2660
+ onMouseOver: (e) => {
2661
+ e.currentTarget.style.transform = "translateY(-2px)";
2662
+ e.currentTarget.style.boxShadow = "0 6px 20px rgba(124, 58, 237, 0.5)";
2663
+ },
2664
+ onMouseOut: (e) => {
2665
+ e.currentTarget.style.transform = "translateY(0)";
2666
+ e.currentTarget.style.boxShadow = "0 4px 14px rgba(124, 58, 237, 0.4)";
2667
+ },
2668
+ "data-testid": "button-continue-quiz",
2669
+ children: "Continue Where I Left Off"
2670
+ }
2671
+ ),
2672
+ /* @__PURE__ */ jsx4(
2673
+ "button",
2674
+ {
2675
+ style: {
2676
+ ...defaultStyles.startButton,
2677
+ background: "transparent",
2678
+ color: "#7c3aed",
2679
+ border: "2px solid #7c3aed",
2680
+ boxShadow: "none"
2681
+ },
2682
+ onClick: handleStartFresh,
2683
+ disabled: isStartingFresh,
2684
+ onMouseOver: (e) => {
2685
+ if (!isStartingFresh) {
2686
+ e.currentTarget.style.transform = "translateY(-2px)";
2687
+ e.currentTarget.style.background = "rgba(124, 58, 237, 0.1)";
2688
+ }
2689
+ },
2690
+ onMouseOut: (e) => {
2691
+ e.currentTarget.style.transform = "translateY(0)";
2692
+ e.currentTarget.style.background = "transparent";
2693
+ },
2694
+ "data-testid": "button-start-fresh",
2695
+ children: isStartingFresh ? "Starting..." : "Start Fresh"
2696
+ }
2697
+ )
2698
+ ] })
2699
+ ] }) });
2700
+ }
2283
2701
  if (quiz && showIntro) {
2284
- return /* @__PURE__ */ jsx3("div", { className, style: defaultStyles.container, children: /* @__PURE__ */ jsxs3("div", { style: defaultStyles.intro, children: [
2285
- /* @__PURE__ */ jsx3("div", { style: defaultStyles.introTitle, children: quiz.title }),
2286
- /* @__PURE__ */ jsx3("div", { style: defaultStyles.introSubtitle, children: "Ready to test your knowledge?" }),
2287
- /* @__PURE__ */ jsxs3("div", { style: defaultStyles.introQuestionCount, children: [
2702
+ return /* @__PURE__ */ jsx4("div", { className, style: defaultStyles.container, children: /* @__PURE__ */ jsxs4("div", { style: defaultStyles.intro, children: [
2703
+ /* @__PURE__ */ jsx4("div", { style: defaultStyles.introTitle, children: quiz.title }),
2704
+ /* @__PURE__ */ jsx4("div", { style: defaultStyles.introSubtitle, children: "Ready to test your knowledge?" }),
2705
+ /* @__PURE__ */ jsxs4("div", { style: defaultStyles.introQuestionCount, children: [
2288
2706
  quiz.questions.length,
2289
2707
  " question",
2290
2708
  quiz.questions.length !== 1 ? "s" : "",
2291
2709
  " to answer"
2292
2710
  ] }),
2293
- /* @__PURE__ */ jsx3(
2711
+ /* @__PURE__ */ jsx4(
2294
2712
  "button",
2295
2713
  {
2296
2714
  style: defaultStyles.startButton,
@@ -2310,7 +2728,7 @@ function QuizPlayer({
2310
2728
  ] }) });
2311
2729
  }
2312
2730
  if (!quiz || !currentQuestion) {
2313
- return /* @__PURE__ */ jsx3("div", { className, style: defaultStyles.container, children: /* @__PURE__ */ jsx3("div", { style: defaultStyles.error, children: "No quiz data available" }) });
2731
+ return /* @__PURE__ */ jsx4("div", { className, style: defaultStyles.container, children: /* @__PURE__ */ jsx4("div", { style: defaultStyles.error, children: "No quiz data available" }) });
2314
2732
  }
2315
2733
  const selectedAnswer = answers.get(currentQuestion.id);
2316
2734
  const isLastQuestion = currentQuestionIndex === totalQuestions - 1;
@@ -2318,294 +2736,166 @@ function QuizPlayer({
2318
2736
  const remainingSlots = maxQuestions - totalQuestions;
2319
2737
  const questionsToAdd = Math.min(5, remainingSlots);
2320
2738
  const canAddMore = onGenerateMoreQuestions && remainingSlots > 0;
2321
- return /* @__PURE__ */ jsx3("div", { className, style: defaultStyles.container, children: /* @__PURE__ */ jsxs3("div", { style: defaultStyles.mainLayout, children: [
2322
- /* @__PURE__ */ jsxs3("div", { style: defaultStyles.quizContent, children: [
2323
- /* @__PURE__ */ jsxs3("div", { style: defaultStyles.header, children: [
2324
- /* @__PURE__ */ jsx3("div", { style: defaultStyles.title, children: quiz.title }),
2325
- /* @__PURE__ */ jsxs3("div", { style: defaultStyles.progress, children: [
2326
- "Question ",
2327
- currentQuestionIndex + 1,
2328
- " of ",
2329
- totalQuestions
2330
- ] }),
2331
- /* @__PURE__ */ jsx3("div", { style: defaultStyles.progressBar, children: /* @__PURE__ */ jsx3("div", { style: { ...defaultStyles.progressFill, width: `${progressPercent}%` } }) })
2332
- ] }),
2333
- /* @__PURE__ */ jsxs3("div", { style: { ...defaultStyles.question, position: "relative", paddingBottom: "40px" }, children: [
2334
- /* @__PURE__ */ jsx3("div", { style: defaultStyles.questionText, children: /* @__PURE__ */ jsx3(TextToSpeech, { text: currentQuestion.question, inline: true, size: "md" }) }),
2335
- isExtraQuestion && /* @__PURE__ */ jsxs3(
2336
- "button",
2337
- {
2338
- onClick: () => setShowSkipModal(true),
2339
- title: "Skip question",
2340
- style: {
2341
- position: "absolute",
2342
- bottom: "8px",
2343
- left: "0",
2344
- background: "transparent",
2345
- border: "none",
2346
- cursor: "pointer",
2347
- padding: "6px 10px",
2348
- borderRadius: "6px",
2349
- color: "#9ca3af",
2350
- display: "flex",
2351
- alignItems: "center",
2352
- justifyContent: "center",
2353
- gap: "4px",
2354
- fontSize: "12px",
2355
- opacity: 0.6,
2356
- transition: "opacity 0.2s, color 0.2s"
2357
- },
2358
- onMouseEnter: (e) => {
2359
- e.currentTarget.style.opacity = "1";
2360
- e.currentTarget.style.color = "#6b7280";
2361
- },
2362
- onMouseLeave: (e) => {
2363
- e.currentTarget.style.opacity = "0.6";
2364
- e.currentTarget.style.color = "#9ca3af";
2365
- },
2366
- "data-testid": "button-skip-question",
2367
- children: [
2368
- /* @__PURE__ */ jsxs3("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2369
- /* @__PURE__ */ jsx3("polygon", { points: "5 4 15 12 5 20 5 4" }),
2370
- /* @__PURE__ */ jsx3("line", { x1: "19", y1: "5", x2: "19", y2: "19" })
2371
- ] }),
2372
- /* @__PURE__ */ jsx3("span", { children: "Skip" })
2373
- ]
2374
- }
2375
- ),
2376
- !isExtraQuestion && /* @__PURE__ */ jsxs3(
2377
- "button",
2378
- {
2379
- onClick: () => setShowReportModal(true),
2380
- title: "Report an issue with this question",
2381
- style: {
2382
- position: "absolute",
2383
- bottom: "8px",
2384
- left: "0",
2385
- background: "transparent",
2386
- border: "none",
2387
- cursor: "pointer",
2388
- padding: "6px 10px",
2389
- borderRadius: "6px",
2390
- color: "#9ca3af",
2391
- display: "flex",
2392
- alignItems: "center",
2393
- justifyContent: "center",
2394
- gap: "4px",
2395
- fontSize: "12px",
2396
- opacity: 0.6,
2397
- transition: "opacity 0.2s, color 0.2s"
2398
- },
2399
- onMouseEnter: (e) => {
2400
- e.currentTarget.style.opacity = "1";
2401
- e.currentTarget.style.color = "#ef4444";
2402
- },
2403
- onMouseLeave: (e) => {
2404
- e.currentTarget.style.opacity = "0.6";
2405
- e.currentTarget.style.color = "#9ca3af";
2406
- },
2407
- "data-testid": "button-report-question",
2408
- children: [
2409
- /* @__PURE__ */ jsxs3("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2410
- /* @__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" }),
2411
- /* @__PURE__ */ jsx3("line", { x1: "4", y1: "22", x2: "4", y2: "15" })
2412
- ] }),
2413
- /* @__PURE__ */ jsx3("span", { children: "Report" })
2414
- ]
2739
+ return /* @__PURE__ */ jsxs4("div", { className, style: defaultStyles.container, children: [
2740
+ /* @__PURE__ */ jsx4("style", { children: `
2741
+ .quiz-option:focus,
2742
+ .quiz-option:active,
2743
+ .quiz-option:focus-visible,
2744
+ .quiz-option:focus-within {
2745
+ outline: none !important;
2746
+ box-shadow: none !important;
2415
2747
  }
2416
- ),
2417
- (currentQuestion.type === "single" || currentQuestion.type === "true-false") && /* @__PURE__ */ jsx3("div", { style: defaultStyles.options, children: currentQuestion.options?.map((option, idx) => {
2418
- const isSelected = selectedAnswer === option;
2419
- const isCorrectOption = currentQuestion.correctAnswer === option;
2420
- let optionStyle = { ...defaultStyles.option };
2421
- if (showFeedback) {
2422
- if (isCorrectOption) {
2423
- optionStyle = { ...optionStyle, ...defaultStyles.optionCorrect };
2424
- } else if (isSelected && !isCorrectOption) {
2425
- optionStyle = { ...optionStyle, ...defaultStyles.optionIncorrect };
2426
- }
2427
- } else if (isSelected) {
2428
- optionStyle = { ...optionStyle, ...defaultStyles.optionSelected };
2748
+ .quiz-option {
2749
+ -webkit-tap-highlight-color: transparent;
2429
2750
  }
2430
- return /* @__PURE__ */ jsxs3(
2431
- "div",
2751
+ ` }),
2752
+ /* @__PURE__ */ jsxs4("div", { style: defaultStyles.mainLayout, children: [
2753
+ /* @__PURE__ */ jsxs4("div", { style: defaultStyles.quizContent, children: [
2754
+ /* @__PURE__ */ jsxs4("div", { style: defaultStyles.header, children: [
2755
+ /* @__PURE__ */ jsx4("div", { style: defaultStyles.title, children: quiz.title }),
2756
+ /* @__PURE__ */ jsxs4("div", { style: defaultStyles.progress, children: [
2757
+ "Question ",
2758
+ currentQuestionIndex + 1,
2759
+ " of ",
2760
+ totalQuestions
2761
+ ] }),
2762
+ /* @__PURE__ */ jsx4("div", { style: defaultStyles.progressBar, children: /* @__PURE__ */ jsx4("div", { style: { ...defaultStyles.progressFill, width: `${progressPercent}%` } }) })
2763
+ ] }),
2764
+ /* @__PURE__ */ jsxs4("div", { style: { ...defaultStyles.question, position: "relative", paddingBottom: "40px" }, children: [
2765
+ /* @__PURE__ */ jsx4("div", { style: defaultStyles.questionText, children: /* @__PURE__ */ jsx4(TextToSpeech, { text: currentQuestion.question, inline: true, size: "md" }) }),
2766
+ isExtraQuestion && /* @__PURE__ */ jsxs4(
2767
+ "button",
2432
2768
  {
2769
+ onClick: () => setShowSkipModal(true),
2770
+ title: "Skip question",
2433
2771
  style: {
2434
- ...optionStyle,
2435
- cursor: showFeedback ? "default" : "pointer",
2772
+ position: "absolute",
2773
+ bottom: "8px",
2774
+ left: "0",
2775
+ background: "transparent",
2776
+ border: "none",
2777
+ cursor: "pointer",
2778
+ padding: "6px 10px",
2779
+ borderRadius: "6px",
2780
+ color: "#9ca3af",
2436
2781
  display: "flex",
2437
2782
  alignItems: "center",
2438
- gap: "8px"
2783
+ justifyContent: "center",
2784
+ gap: "4px",
2785
+ fontSize: "12px",
2786
+ opacity: 0.6,
2787
+ transition: "opacity 0.2s, color 0.2s"
2788
+ },
2789
+ onMouseEnter: (e) => {
2790
+ e.currentTarget.style.opacity = "1";
2791
+ e.currentTarget.style.color = "#6b7280";
2792
+ },
2793
+ onMouseLeave: (e) => {
2794
+ e.currentTarget.style.opacity = "0.6";
2795
+ e.currentTarget.style.color = "#9ca3af";
2439
2796
  },
2440
- onClick: () => !showFeedback && handleAnswerChange(option),
2797
+ "data-testid": "button-skip-question",
2441
2798
  children: [
2442
- /* @__PURE__ */ jsx3("span", { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsx3(TextToSpeech, { text: option, size: "sm" }) }),
2443
- /* @__PURE__ */ jsx3("span", { style: { flex: 1 }, children: option })
2799
+ /* @__PURE__ */ jsxs4("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2800
+ /* @__PURE__ */ jsx4("polygon", { points: "5 4 15 12 5 20 5 4" }),
2801
+ /* @__PURE__ */ jsx4("line", { x1: "19", y1: "5", x2: "19", y2: "19" })
2802
+ ] }),
2803
+ /* @__PURE__ */ jsx4("span", { children: "Skip" })
2444
2804
  ]
2445
- },
2446
- idx
2447
- );
2448
- }) }),
2449
- currentQuestion.type === "multiple" && /* @__PURE__ */ jsx3("div", { style: defaultStyles.options, children: currentQuestion.options?.map((option, idx) => {
2450
- const selected = Array.isArray(selectedAnswer) && selectedAnswer.includes(option);
2451
- const correctAnswers = Array.isArray(currentQuestion.correctAnswer) ? currentQuestion.correctAnswer : currentQuestion.correctAnswer ? [currentQuestion.correctAnswer] : [];
2452
- const isCorrectOption = correctAnswers.includes(option);
2453
- let optionStyle = { ...defaultStyles.option };
2454
- if (showFeedback) {
2455
- if (isCorrectOption) {
2456
- optionStyle = { ...optionStyle, ...defaultStyles.optionCorrect };
2457
- } else if (selected && !isCorrectOption) {
2458
- optionStyle = { ...optionStyle, ...defaultStyles.optionIncorrect };
2459
2805
  }
2460
- } else if (selected) {
2461
- optionStyle = { ...optionStyle, ...defaultStyles.optionSelected };
2462
- }
2463
- return /* @__PURE__ */ jsxs3(
2464
- "div",
2806
+ ),
2807
+ !isExtraQuestion && /* @__PURE__ */ jsxs4(
2808
+ "button",
2465
2809
  {
2810
+ onClick: () => setShowReportModal(true),
2811
+ title: "Report an issue with this question",
2466
2812
  style: {
2467
- ...optionStyle,
2468
- cursor: showFeedback ? "default" : "pointer",
2813
+ position: "absolute",
2814
+ bottom: "8px",
2815
+ left: "0",
2816
+ background: "transparent",
2817
+ border: "none",
2818
+ cursor: "pointer",
2819
+ padding: "6px 10px",
2820
+ borderRadius: "6px",
2821
+ color: "#9ca3af",
2469
2822
  display: "flex",
2470
2823
  alignItems: "center",
2471
- gap: "8px"
2824
+ justifyContent: "center",
2825
+ gap: "4px",
2826
+ fontSize: "12px",
2827
+ opacity: 0.6,
2828
+ transition: "opacity 0.2s, color 0.2s"
2472
2829
  },
2473
- onClick: () => {
2474
- if (showFeedback) return;
2475
- const current = Array.isArray(selectedAnswer) ? selectedAnswer : [];
2476
- if (selected) {
2477
- handleAnswerChange(current.filter((o) => o !== option));
2478
- } else {
2479
- handleAnswerChange([...current, option]);
2480
- }
2830
+ onMouseEnter: (e) => {
2831
+ e.currentTarget.style.opacity = "1";
2832
+ e.currentTarget.style.color = "#ef4444";
2481
2833
  },
2834
+ onMouseLeave: (e) => {
2835
+ e.currentTarget.style.opacity = "0.6";
2836
+ e.currentTarget.style.color = "#9ca3af";
2837
+ },
2838
+ "data-testid": "button-report-question",
2482
2839
  children: [
2483
- /* @__PURE__ */ jsx3("span", { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsx3(TextToSpeech, { text: option, size: "sm" }) }),
2484
- /* @__PURE__ */ jsx3("span", { style: { flex: 1 }, children: option })
2840
+ /* @__PURE__ */ jsxs4("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2841
+ /* @__PURE__ */ jsx4("path", { d: "M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z" }),
2842
+ /* @__PURE__ */ jsx4("line", { x1: "4", y1: "22", x2: "4", y2: "15" })
2843
+ ] }),
2844
+ /* @__PURE__ */ jsx4("span", { children: "Report" })
2485
2845
  ]
2486
- },
2487
- idx
2488
- );
2489
- }) }),
2490
- (currentQuestion.type === "free" || currentQuestion.type === "essay") && /* @__PURE__ */ jsx3(
2491
- "textarea",
2492
- {
2493
- style: { ...defaultStyles.input, minHeight: currentQuestion.type === "essay" ? "150px" : "60px" },
2494
- value: selectedAnswer || "",
2495
- onChange: (e) => handleAnswerChange(e.target.value),
2496
- placeholder: "Type your answer here...",
2497
- disabled: showFeedback
2498
- }
2499
- ),
2500
- currentQuestion.type === "fill" && /* @__PURE__ */ jsx3("div", { style: defaultStyles.options, children: currentQuestion.blanks?.map((_, idx) => /* @__PURE__ */ jsx3(
2501
- "input",
2502
- {
2503
- style: defaultStyles.input,
2504
- value: (Array.isArray(selectedAnswer) ? selectedAnswer[idx] : "") || "",
2505
- onChange: (e) => {
2506
- const current = Array.isArray(selectedAnswer) ? [...selectedAnswer] : [];
2507
- current[idx] = e.target.value;
2508
- handleAnswerChange(current);
2509
- },
2510
- placeholder: `Blank ${idx + 1}`,
2511
- disabled: showFeedback
2512
- },
2513
- idx
2514
- )) }),
2515
- currentQuestion.type === "sorting" && currentQuestion.items && /* @__PURE__ */ jsx3(
2516
- SortingDragDrop,
2517
- {
2518
- items: currentQuestion.items,
2519
- currentOrder: Array.isArray(selectedAnswer) ? selectedAnswer : currentQuestion.items.map((_, i) => i),
2520
- correctOrder: currentQuestion.correctOrder,
2521
- showFeedback,
2522
- onOrderChange: handleAnswerChange
2523
- }
2524
- ),
2525
- currentQuestion.type === "matrix" && currentQuestion.leftItems && currentQuestion.rightItems && /* @__PURE__ */ jsx3(
2526
- MatchingDragDrop,
2527
- {
2528
- leftItems: currentQuestion.leftItems,
2529
- rightItems: currentQuestion.rightItems,
2530
- currentMatches: typeof selectedAnswer === "object" && selectedAnswer !== null && !Array.isArray(selectedAnswer) ? selectedAnswer : {},
2531
- correctMatches: currentQuestion.correctMatches,
2532
- showFeedback,
2533
- onMatchChange: handleAnswerChange
2534
- }
2535
- ),
2536
- currentQuestion.type === "assessment" && /* @__PURE__ */ jsx3("div", { style: defaultStyles.options, children: (() => {
2537
- const scaleType = currentQuestion.scaleType || "likert";
2538
- if (scaleType === "yes-no") {
2539
- const options = ["Yes", "No"];
2540
- return options.map((option, idx) => {
2541
- const isSelected = selectedAnswer === option;
2542
- let optionStyle = { ...defaultStyles.option };
2543
- if (isSelected) {
2544
- optionStyle = { ...optionStyle, ...defaultStyles.optionSelected };
2846
+ }
2847
+ ),
2848
+ (currentQuestion.type === "single" || currentQuestion.type === "true-false") && /* @__PURE__ */ jsx4("div", { style: defaultStyles.options, children: currentQuestion.options?.map((option, idx) => {
2849
+ const isSelected = selectedAnswer === option;
2850
+ const isCorrectOption = currentQuestion.correctAnswer === option;
2851
+ let optionStyle = { ...defaultStyles.option };
2852
+ if (showFeedback) {
2853
+ if (isCorrectOption) {
2854
+ optionStyle = { ...optionStyle, ...defaultStyles.optionCorrect };
2855
+ } else if (isSelected && !isCorrectOption) {
2856
+ optionStyle = { ...optionStyle, ...defaultStyles.optionIncorrect };
2545
2857
  }
2546
- return /* @__PURE__ */ jsx3(
2547
- "div",
2548
- {
2549
- style: {
2550
- ...optionStyle,
2551
- cursor: showFeedback ? "default" : "pointer",
2552
- display: "flex",
2553
- alignItems: "center",
2554
- gap: "8px"
2555
- },
2556
- onClick: () => !showFeedback && handleAnswerChange(option),
2557
- "data-testid": `assessment-option-${option.toLowerCase()}`,
2558
- children: /* @__PURE__ */ jsx3("span", { style: { flex: 1 }, children: option })
2559
- },
2560
- idx
2561
- );
2562
- });
2563
- }
2564
- if (scaleType === "rating") {
2565
- const min = currentQuestion.scaleMin || 1;
2566
- const max = currentQuestion.scaleMax || 5;
2567
- const ratings = Array.from({ length: max - min + 1 }, (_, i) => min + i);
2568
- return /* @__PURE__ */ jsx3("div", { style: { display: "flex", gap: "8px", flexWrap: "wrap", justifyContent: "center" }, children: ratings.map((rating) => {
2569
- const isSelected = selectedAnswer === rating;
2570
- return /* @__PURE__ */ jsx3(
2571
- "button",
2572
- {
2573
- onClick: () => !showFeedback && handleAnswerChange(rating),
2574
- disabled: showFeedback,
2575
- style: {
2576
- width: "48px",
2577
- height: "48px",
2578
- borderRadius: "50%",
2579
- border: isSelected ? "2px solid #6721b0" : "2px solid #e5e7eb",
2580
- backgroundColor: isSelected ? "#f3e8ff" : "#ffffff",
2581
- cursor: showFeedback ? "not-allowed" : "pointer",
2582
- fontSize: "18px",
2583
- fontWeight: "600",
2584
- color: isSelected ? "#6721b0" : "#374151"
2585
- },
2586
- "data-testid": `assessment-rating-${rating}`,
2587
- children: rating
2858
+ } else if (isSelected) {
2859
+ optionStyle = { ...optionStyle, ...defaultStyles.optionSelected };
2860
+ }
2861
+ return /* @__PURE__ */ jsxs4(
2862
+ "div",
2863
+ {
2864
+ className: "quiz-option",
2865
+ style: {
2866
+ ...optionStyle,
2867
+ cursor: showFeedback ? "default" : "pointer",
2868
+ display: "flex",
2869
+ alignItems: "center",
2870
+ gap: "8px"
2588
2871
  },
2589
- rating
2590
- );
2591
- }) });
2592
- }
2593
- const likertOptions = [
2594
- "Strongly Disagree",
2595
- "Disagree",
2596
- "Neutral",
2597
- "Agree",
2598
- "Strongly Agree"
2599
- ];
2600
- return likertOptions.map((option, idx) => {
2601
- const isSelected = selectedAnswer === option;
2872
+ onClick: () => !showFeedback && handleAnswerChange(option),
2873
+ children: [
2874
+ /* @__PURE__ */ jsx4("span", { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsx4(TextToSpeech, { text: option, size: "sm" }) }),
2875
+ /* @__PURE__ */ jsx4("span", { style: { flex: 1 }, children: option })
2876
+ ]
2877
+ },
2878
+ idx
2879
+ );
2880
+ }) }),
2881
+ currentQuestion.type === "multiple" && /* @__PURE__ */ jsx4("div", { style: defaultStyles.options, children: currentQuestion.options?.map((option, idx) => {
2882
+ const selected = Array.isArray(selectedAnswer) && selectedAnswer.includes(option);
2883
+ const correctAnswers = Array.isArray(currentQuestion.correctAnswer) ? currentQuestion.correctAnswer : currentQuestion.correctAnswer ? [currentQuestion.correctAnswer] : [];
2884
+ const isCorrectOption = correctAnswers.includes(option);
2602
2885
  let optionStyle = { ...defaultStyles.option };
2603
- if (isSelected) {
2886
+ if (showFeedback) {
2887
+ if (isCorrectOption) {
2888
+ optionStyle = { ...optionStyle, ...defaultStyles.optionCorrect };
2889
+ } else if (selected && !isCorrectOption) {
2890
+ optionStyle = { ...optionStyle, ...defaultStyles.optionIncorrect };
2891
+ }
2892
+ } else if (selected) {
2604
2893
  optionStyle = { ...optionStyle, ...defaultStyles.optionSelected };
2605
2894
  }
2606
- return /* @__PURE__ */ jsx3(
2895
+ return /* @__PURE__ */ jsxs4(
2607
2896
  "div",
2608
2897
  {
2898
+ className: "quiz-option",
2609
2899
  style: {
2610
2900
  ...optionStyle,
2611
2901
  cursor: showFeedback ? "default" : "pointer",
@@ -2613,356 +2903,504 @@ function QuizPlayer({
2613
2903
  alignItems: "center",
2614
2904
  gap: "8px"
2615
2905
  },
2616
- onClick: () => !showFeedback && handleAnswerChange(option),
2617
- "data-testid": `assessment-likert-${idx}`,
2618
- children: /* @__PURE__ */ jsx3("span", { style: { flex: 1 }, children: option })
2906
+ onClick: () => {
2907
+ if (showFeedback) return;
2908
+ const current = Array.isArray(selectedAnswer) ? selectedAnswer : [];
2909
+ if (selected) {
2910
+ handleAnswerChange(current.filter((o) => o !== option));
2911
+ } else {
2912
+ handleAnswerChange([...current, option]);
2913
+ }
2914
+ },
2915
+ children: [
2916
+ /* @__PURE__ */ jsx4("span", { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsx4(TextToSpeech, { text: option, size: "sm" }) }),
2917
+ /* @__PURE__ */ jsx4("span", { style: { flex: 1 }, children: option })
2918
+ ]
2619
2919
  },
2620
2920
  idx
2621
2921
  );
2622
- });
2623
- })() }),
2624
- showFeedback && currentAnswerDetail && /* @__PURE__ */ jsxs3("div", { style: {
2625
- ...defaultStyles.feedback,
2626
- ...currentQuestion.type === "assessment" ? defaultStyles.feedbackNeutral : currentAnswerDetail.isCorrect ? defaultStyles.feedbackCorrect : defaultStyles.feedbackIncorrect
2627
- }, children: [
2628
- /* @__PURE__ */ jsx3("div", { style: {
2629
- ...defaultStyles.feedbackTitle,
2630
- ...currentQuestion.type === "assessment" ? defaultStyles.feedbackTitleNeutral : currentAnswerDetail.isCorrect ? defaultStyles.feedbackTitleCorrect : defaultStyles.feedbackTitleIncorrect
2631
- }, children: currentQuestion.type === "assessment" ? "\u2713 Response recorded" : currentAnswerDetail.isCorrect ? "\u2713 Correct!" : "\u2717 Incorrect" }),
2632
- currentQuestion.explanation && /* @__PURE__ */ jsx3("div", { style: defaultStyles.feedbackExplanation, children: currentQuestion.explanation })
2633
- ] })
2634
- ] }),
2635
- showSkipModal && /* @__PURE__ */ jsx3("div", { style: {
2636
- position: "fixed",
2637
- top: 0,
2638
- left: 0,
2639
- right: 0,
2640
- bottom: 0,
2641
- backgroundColor: "rgba(0, 0, 0, 0.5)",
2642
- display: "flex",
2643
- alignItems: "center",
2644
- justifyContent: "center",
2645
- zIndex: 1e3
2646
- }, children: /* @__PURE__ */ jsxs3("div", { style: {
2647
- backgroundColor: "#ffffff",
2648
- borderRadius: "12px",
2649
- padding: "24px",
2650
- maxWidth: "400px",
2651
- width: "90%",
2652
- boxShadow: "0 20px 40px rgba(0, 0, 0, 0.2)"
2653
- }, children: [
2654
- /* @__PURE__ */ jsx3("h3", { style: { margin: "0 0 8px 0", fontSize: "18px", fontWeight: "600", color: "#1f2937" }, children: "Skip Question" }),
2655
- /* @__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." }),
2656
- /* @__PURE__ */ jsxs3("div", { style: { display: "flex", flexDirection: "column", gap: "8px", marginBottom: "16px" }, children: [
2657
- /* @__PURE__ */ jsx3(
2658
- "button",
2922
+ }) }),
2923
+ (currentQuestion.type === "free" || currentQuestion.type === "essay") && /* @__PURE__ */ jsx4(
2924
+ "textarea",
2659
2925
  {
2660
- onClick: () => setSelectedSkipReason("question_issue"),
2661
- disabled: isSkipping,
2662
- style: {
2663
- padding: "12px 16px",
2664
- borderRadius: "8px",
2665
- border: selectedSkipReason === "question_issue" ? "2px solid #8b5cf6" : "1px solid #e5e7eb",
2666
- backgroundColor: selectedSkipReason === "question_issue" ? "#f5f3ff" : "#f9fafb",
2667
- cursor: isSkipping ? "not-allowed" : "pointer",
2668
- fontSize: "14px",
2669
- fontWeight: "500",
2670
- color: "#374151",
2671
- textAlign: "left",
2672
- opacity: isSkipping ? 0.6 : 1
2673
- },
2674
- "data-testid": "button-skip-reason-issue",
2675
- children: "Question has an issue"
2926
+ style: { ...defaultStyles.input, minHeight: currentQuestion.type === "essay" ? "150px" : "60px" },
2927
+ value: selectedAnswer || "",
2928
+ onChange: (e) => handleAnswerChange(e.target.value),
2929
+ placeholder: "Type your answer here...",
2930
+ disabled: showFeedback
2676
2931
  }
2677
2932
  ),
2678
- /* @__PURE__ */ jsx3(
2679
- "button",
2933
+ currentQuestion.type === "fill" && /* @__PURE__ */ jsx4("div", { style: defaultStyles.options, children: currentQuestion.blanks?.map((_, idx) => /* @__PURE__ */ jsx4(
2934
+ "input",
2680
2935
  {
2681
- onClick: () => setSelectedSkipReason("dont_know"),
2682
- disabled: isSkipping,
2683
- style: {
2684
- padding: "12px 16px",
2685
- borderRadius: "8px",
2686
- border: selectedSkipReason === "dont_know" ? "2px solid #8b5cf6" : "1px solid #e5e7eb",
2687
- backgroundColor: selectedSkipReason === "dont_know" ? "#f5f3ff" : "#f9fafb",
2688
- cursor: isSkipping ? "not-allowed" : "pointer",
2689
- fontSize: "14px",
2690
- fontWeight: "500",
2691
- color: "#374151",
2692
- textAlign: "left",
2693
- opacity: isSkipping ? 0.6 : 1
2936
+ style: defaultStyles.input,
2937
+ value: (Array.isArray(selectedAnswer) ? selectedAnswer[idx] : "") || "",
2938
+ onChange: (e) => {
2939
+ const current = Array.isArray(selectedAnswer) ? [...selectedAnswer] : [];
2940
+ current[idx] = e.target.value;
2941
+ handleAnswerChange(current);
2694
2942
  },
2695
- "data-testid": "button-skip-reason-dont-know",
2696
- children: "I don't know the answer"
2697
- }
2698
- )
2699
- ] }),
2700
- /* @__PURE__ */ jsxs3("div", { style: { marginBottom: "16px" }, children: [
2701
- /* @__PURE__ */ jsx3("label", { style: { display: "block", fontSize: "13px", fontWeight: "500", color: "#374151", marginBottom: "6px" }, children: "Additional details (optional)" }),
2702
- /* @__PURE__ */ jsx3(
2703
- "textarea",
2943
+ placeholder: `Blank ${idx + 1}`,
2944
+ disabled: showFeedback
2945
+ },
2946
+ idx
2947
+ )) }),
2948
+ currentQuestion.type === "sorting" && currentQuestion.items && /* @__PURE__ */ jsx4(
2949
+ SortingDragDrop,
2704
2950
  {
2705
- value: skipComment,
2706
- onChange: (e) => setSkipComment(e.target.value.slice(0, 200)),
2707
- placeholder: "Tell us more about the issue...",
2708
- disabled: isSkipping,
2709
- style: {
2710
- width: "100%",
2711
- minHeight: "80px",
2712
- padding: "10px 12px",
2713
- borderRadius: "8px",
2714
- border: "1px solid #e5e7eb",
2715
- fontSize: "14px",
2716
- resize: "vertical",
2717
- fontFamily: "inherit",
2718
- boxSizing: "border-box"
2719
- },
2720
- "data-testid": "input-skip-comment"
2951
+ items: currentQuestion.items,
2952
+ currentOrder: Array.isArray(selectedAnswer) ? selectedAnswer : currentQuestion.items.map((_, i) => i),
2953
+ correctOrder: currentQuestion.correctOrder,
2954
+ showFeedback,
2955
+ onOrderChange: handleAnswerChange
2721
2956
  }
2722
2957
  ),
2723
- /* @__PURE__ */ jsxs3("div", { style: { fontSize: "12px", color: "#9ca3af", marginTop: "4px", textAlign: "right" }, children: [
2724
- skipComment.length,
2725
- "/200"
2726
- ] })
2727
- ] }),
2728
- /* @__PURE__ */ jsxs3("div", { style: { display: "flex", gap: "10px" }, children: [
2729
- /* @__PURE__ */ jsx3(
2730
- "button",
2958
+ currentQuestion.type === "matrix" && currentQuestion.leftItems && currentQuestion.rightItems && /* @__PURE__ */ jsx4(
2959
+ MatchingDragDrop,
2731
2960
  {
2732
- onClick: () => {
2733
- setShowSkipModal(false);
2734
- setSkipComment("");
2735
- setSelectedSkipReason(null);
2736
- },
2737
- style: {
2738
- flex: 1,
2739
- padding: "10px 16px",
2740
- borderRadius: "8px",
2741
- border: "1px solid #e5e7eb",
2742
- backgroundColor: "#ffffff",
2743
- cursor: "pointer",
2744
- fontSize: "14px",
2745
- fontWeight: "500",
2746
- color: "#6b7280"
2747
- },
2748
- "data-testid": "button-skip-cancel",
2749
- children: "Cancel"
2961
+ leftItems: currentQuestion.leftItems,
2962
+ rightItems: currentQuestion.rightItems,
2963
+ currentMatches: typeof selectedAnswer === "object" && selectedAnswer !== null && !Array.isArray(selectedAnswer) ? selectedAnswer : {},
2964
+ correctMatches: currentQuestion.correctMatches,
2965
+ showFeedback,
2966
+ onMatchChange: handleAnswerChange
2750
2967
  }
2751
2968
  ),
2752
- /* @__PURE__ */ jsx3(
2753
- "button",
2754
- {
2755
- onClick: () => selectedSkipReason && handleSkipQuestion(selectedSkipReason, skipComment),
2756
- disabled: isSkipping || !selectedSkipReason,
2757
- style: {
2758
- flex: 1,
2759
- padding: "10px 16px",
2760
- borderRadius: "8px",
2761
- border: "none",
2762
- backgroundColor: selectedSkipReason ? "#8b5cf6" : "#d1d5db",
2763
- cursor: isSkipping || !selectedSkipReason ? "not-allowed" : "pointer",
2764
- fontSize: "14px",
2765
- fontWeight: "500",
2766
- color: "#ffffff",
2767
- opacity: isSkipping ? 0.6 : 1
2768
- },
2769
- "data-testid": "button-skip-submit",
2770
- children: isSkipping ? "Skipping..." : "Skip Question"
2969
+ currentQuestion.type === "assessment" && /* @__PURE__ */ jsx4("div", { style: defaultStyles.options, children: (() => {
2970
+ const scaleType = currentQuestion.scaleType || "likert";
2971
+ if (scaleType === "yes-no") {
2972
+ const options = ["Yes", "No"];
2973
+ return options.map((option, idx) => {
2974
+ const isSelected = selectedAnswer === option;
2975
+ let optionStyle = { ...defaultStyles.option };
2976
+ if (isSelected) {
2977
+ optionStyle = { ...optionStyle, ...defaultStyles.optionSelected };
2978
+ }
2979
+ return /* @__PURE__ */ jsx4(
2980
+ "div",
2981
+ {
2982
+ className: "quiz-option",
2983
+ style: {
2984
+ ...optionStyle,
2985
+ cursor: showFeedback ? "default" : "pointer",
2986
+ display: "flex",
2987
+ alignItems: "center",
2988
+ gap: "8px"
2989
+ },
2990
+ onClick: () => !showFeedback && handleAnswerChange(option),
2991
+ "data-testid": `assessment-option-${option.toLowerCase()}`,
2992
+ children: /* @__PURE__ */ jsx4("span", { style: { flex: 1 }, children: option })
2993
+ },
2994
+ idx
2995
+ );
2996
+ });
2771
2997
  }
2772
- )
2773
- ] })
2774
- ] }) }),
2775
- showReportModal && /* @__PURE__ */ jsx3("div", { style: {
2776
- position: "fixed",
2777
- top: 0,
2778
- left: 0,
2779
- right: 0,
2780
- bottom: 0,
2781
- backgroundColor: "rgba(0, 0, 0, 0.5)",
2782
- display: "flex",
2783
- alignItems: "center",
2784
- justifyContent: "center",
2785
- zIndex: 1e3
2786
- }, children: /* @__PURE__ */ jsxs3("div", { style: {
2787
- backgroundColor: "#ffffff",
2788
- borderRadius: "12px",
2789
- padding: "24px",
2790
- maxWidth: "400px",
2791
- width: "90%",
2792
- boxShadow: "0 20px 40px rgba(0, 0, 0, 0.2)"
2793
- }, children: [
2794
- /* @__PURE__ */ jsx3("h3", { style: { margin: "0 0 8px 0", fontSize: "18px", fontWeight: "600", color: "#1f2937" }, children: "Report Question" }),
2795
- /* @__PURE__ */ jsx3("p", { style: { margin: "0 0 16px 0", fontSize: "14px", color: "#6b7280" }, children: "What's wrong with this question?" }),
2796
- /* @__PURE__ */ jsxs3("div", { style: { marginBottom: "16px" }, children: [
2797
- /* @__PURE__ */ jsx3(
2798
- "textarea",
2799
- {
2800
- value: reportComment,
2801
- onChange: (e) => setReportComment(e.target.value.slice(0, 300)),
2802
- placeholder: "Describe the issue with this question...",
2803
- disabled: isReporting,
2804
- style: {
2805
- width: "100%",
2806
- minHeight: "120px",
2807
- padding: "10px 12px",
2808
- borderRadius: "8px",
2809
- border: "1px solid #e5e7eb",
2810
- fontSize: "14px",
2811
- resize: "vertical",
2812
- fontFamily: "inherit",
2813
- boxSizing: "border-box"
2814
- },
2815
- "data-testid": "input-report-comment"
2998
+ if (scaleType === "rating") {
2999
+ const min = currentQuestion.scaleMin || 1;
3000
+ const max = currentQuestion.scaleMax || 5;
3001
+ const ratings = Array.from({ length: max - min + 1 }, (_, i) => min + i);
3002
+ return /* @__PURE__ */ jsx4("div", { style: { display: "flex", gap: "8px", flexWrap: "wrap", justifyContent: "center" }, children: ratings.map((rating) => {
3003
+ const isSelected = selectedAnswer === rating;
3004
+ return /* @__PURE__ */ jsx4(
3005
+ "button",
3006
+ {
3007
+ className: "quiz-option",
3008
+ onClick: () => !showFeedback && handleAnswerChange(rating),
3009
+ disabled: showFeedback,
3010
+ style: {
3011
+ width: "48px",
3012
+ height: "48px",
3013
+ borderRadius: "50%",
3014
+ border: isSelected ? "2px solid #6721b0" : "2px solid #e5e7eb",
3015
+ backgroundColor: isSelected ? "#f3e8ff" : "#ffffff",
3016
+ cursor: showFeedback ? "not-allowed" : "pointer",
3017
+ fontSize: "18px",
3018
+ fontWeight: "600",
3019
+ color: isSelected ? "#6721b0" : "#374151",
3020
+ outline: "none"
3021
+ },
3022
+ "data-testid": `assessment-rating-${rating}`,
3023
+ children: rating
3024
+ },
3025
+ rating
3026
+ );
3027
+ }) });
2816
3028
  }
2817
- ),
2818
- /* @__PURE__ */ jsxs3("div", { style: { fontSize: "12px", color: "#9ca3af", marginTop: "4px", textAlign: "right" }, children: [
2819
- reportComment.length,
2820
- "/300"
3029
+ const likertOptions = [
3030
+ "Strongly Disagree",
3031
+ "Disagree",
3032
+ "Neutral",
3033
+ "Agree",
3034
+ "Strongly Agree"
3035
+ ];
3036
+ return likertOptions.map((option, idx) => {
3037
+ const isSelected = selectedAnswer === option;
3038
+ let optionStyle = { ...defaultStyles.option };
3039
+ if (isSelected) {
3040
+ optionStyle = { ...optionStyle, ...defaultStyles.optionSelected };
3041
+ }
3042
+ return /* @__PURE__ */ jsx4(
3043
+ "div",
3044
+ {
3045
+ className: "quiz-option",
3046
+ style: {
3047
+ ...optionStyle,
3048
+ cursor: showFeedback ? "default" : "pointer",
3049
+ display: "flex",
3050
+ alignItems: "center",
3051
+ gap: "8px"
3052
+ },
3053
+ onClick: () => !showFeedback && handleAnswerChange(option),
3054
+ "data-testid": `assessment-likert-${idx}`,
3055
+ children: /* @__PURE__ */ jsx4("span", { style: { flex: 1 }, children: option })
3056
+ },
3057
+ idx
3058
+ );
3059
+ });
3060
+ })() }),
3061
+ showFeedback && currentAnswerDetail && /* @__PURE__ */ jsxs4("div", { style: {
3062
+ ...defaultStyles.feedback,
3063
+ ...currentQuestion.type === "assessment" ? defaultStyles.feedbackNeutral : currentAnswerDetail.isCorrect ? defaultStyles.feedbackCorrect : defaultStyles.feedbackIncorrect
3064
+ }, children: [
3065
+ /* @__PURE__ */ jsx4("div", { style: {
3066
+ ...defaultStyles.feedbackTitle,
3067
+ ...currentQuestion.type === "assessment" ? defaultStyles.feedbackTitleNeutral : currentAnswerDetail.isCorrect ? defaultStyles.feedbackTitleCorrect : defaultStyles.feedbackTitleIncorrect
3068
+ }, children: currentQuestion.type === "assessment" ? "\u2713 Response recorded" : currentAnswerDetail.isCorrect ? "\u2713 Correct!" : "\u2717 Incorrect" }),
3069
+ currentQuestion.explanation && /* @__PURE__ */ jsx4("div", { style: defaultStyles.feedbackExplanation, children: currentQuestion.explanation })
2821
3070
  ] })
2822
3071
  ] }),
2823
- /* @__PURE__ */ jsxs3("div", { style: { display: "flex", gap: "10px" }, children: [
2824
- /* @__PURE__ */ jsx3(
3072
+ showSkipModal && /* @__PURE__ */ jsx4("div", { style: {
3073
+ position: "fixed",
3074
+ top: 0,
3075
+ left: 0,
3076
+ right: 0,
3077
+ bottom: 0,
3078
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
3079
+ display: "flex",
3080
+ alignItems: "center",
3081
+ justifyContent: "center",
3082
+ zIndex: 1e3
3083
+ }, children: /* @__PURE__ */ jsxs4("div", { style: {
3084
+ backgroundColor: "#ffffff",
3085
+ borderRadius: "12px",
3086
+ padding: "24px",
3087
+ maxWidth: "400px",
3088
+ width: "90%",
3089
+ boxShadow: "0 20px 40px rgba(0, 0, 0, 0.2)"
3090
+ }, children: [
3091
+ /* @__PURE__ */ jsx4("h3", { style: { margin: "0 0 8px 0", fontSize: "18px", fontWeight: "600", color: "#1f2937" }, children: "Skip Question" }),
3092
+ /* @__PURE__ */ jsx4("p", { style: { margin: "0 0 16px 0", fontSize: "14px", color: "#6b7280" }, children: "Help us improve by telling us why you're skipping this question." }),
3093
+ /* @__PURE__ */ jsxs4("div", { style: { display: "flex", flexDirection: "column", gap: "8px", marginBottom: "16px" }, children: [
3094
+ /* @__PURE__ */ jsx4(
3095
+ "button",
3096
+ {
3097
+ onClick: () => setSelectedSkipReason("question_issue"),
3098
+ disabled: isSkipping,
3099
+ style: {
3100
+ padding: "12px 16px",
3101
+ borderRadius: "8px",
3102
+ border: selectedSkipReason === "question_issue" ? "2px solid #8b5cf6" : "1px solid #e5e7eb",
3103
+ backgroundColor: selectedSkipReason === "question_issue" ? "#f5f3ff" : "#f9fafb",
3104
+ cursor: isSkipping ? "not-allowed" : "pointer",
3105
+ fontSize: "14px",
3106
+ fontWeight: "500",
3107
+ color: "#374151",
3108
+ textAlign: "left",
3109
+ opacity: isSkipping ? 0.6 : 1
3110
+ },
3111
+ "data-testid": "button-skip-reason-issue",
3112
+ children: "Question has an issue"
3113
+ }
3114
+ ),
3115
+ /* @__PURE__ */ jsx4(
3116
+ "button",
3117
+ {
3118
+ onClick: () => setSelectedSkipReason("dont_know"),
3119
+ disabled: isSkipping,
3120
+ style: {
3121
+ padding: "12px 16px",
3122
+ borderRadius: "8px",
3123
+ border: selectedSkipReason === "dont_know" ? "2px solid #8b5cf6" : "1px solid #e5e7eb",
3124
+ backgroundColor: selectedSkipReason === "dont_know" ? "#f5f3ff" : "#f9fafb",
3125
+ cursor: isSkipping ? "not-allowed" : "pointer",
3126
+ fontSize: "14px",
3127
+ fontWeight: "500",
3128
+ color: "#374151",
3129
+ textAlign: "left",
3130
+ opacity: isSkipping ? 0.6 : 1
3131
+ },
3132
+ "data-testid": "button-skip-reason-dont-know",
3133
+ children: "I don't know the answer"
3134
+ }
3135
+ )
3136
+ ] }),
3137
+ /* @__PURE__ */ jsxs4("div", { style: { marginBottom: "16px" }, children: [
3138
+ /* @__PURE__ */ jsx4("label", { style: { display: "block", fontSize: "13px", fontWeight: "500", color: "#374151", marginBottom: "6px" }, children: "Additional details (optional)" }),
3139
+ /* @__PURE__ */ jsx4(
3140
+ "textarea",
3141
+ {
3142
+ value: skipComment,
3143
+ onChange: (e) => setSkipComment(e.target.value.slice(0, 200)),
3144
+ placeholder: "Tell us more about the issue...",
3145
+ disabled: isSkipping,
3146
+ style: {
3147
+ width: "100%",
3148
+ minHeight: "80px",
3149
+ padding: "10px 12px",
3150
+ borderRadius: "8px",
3151
+ border: "1px solid #e5e7eb",
3152
+ fontSize: "14px",
3153
+ resize: "vertical",
3154
+ fontFamily: "inherit",
3155
+ boxSizing: "border-box"
3156
+ },
3157
+ "data-testid": "input-skip-comment"
3158
+ }
3159
+ ),
3160
+ /* @__PURE__ */ jsxs4("div", { style: { fontSize: "12px", color: "#9ca3af", marginTop: "4px", textAlign: "right" }, children: [
3161
+ skipComment.length,
3162
+ "/200"
3163
+ ] })
3164
+ ] }),
3165
+ /* @__PURE__ */ jsxs4("div", { style: { display: "flex", gap: "10px" }, children: [
3166
+ /* @__PURE__ */ jsx4(
3167
+ "button",
3168
+ {
3169
+ onClick: () => {
3170
+ setShowSkipModal(false);
3171
+ setSkipComment("");
3172
+ setSelectedSkipReason(null);
3173
+ },
3174
+ style: {
3175
+ flex: 1,
3176
+ padding: "10px 16px",
3177
+ borderRadius: "8px",
3178
+ border: "1px solid #e5e7eb",
3179
+ backgroundColor: "#ffffff",
3180
+ cursor: "pointer",
3181
+ fontSize: "14px",
3182
+ fontWeight: "500",
3183
+ color: "#6b7280"
3184
+ },
3185
+ "data-testid": "button-skip-cancel",
3186
+ children: "Cancel"
3187
+ }
3188
+ ),
3189
+ /* @__PURE__ */ jsx4(
3190
+ "button",
3191
+ {
3192
+ onClick: () => selectedSkipReason && handleSkipQuestion(selectedSkipReason, skipComment),
3193
+ disabled: isSkipping || !selectedSkipReason,
3194
+ style: {
3195
+ flex: 1,
3196
+ padding: "10px 16px",
3197
+ borderRadius: "8px",
3198
+ border: "none",
3199
+ backgroundColor: selectedSkipReason ? "#8b5cf6" : "#d1d5db",
3200
+ cursor: isSkipping || !selectedSkipReason ? "not-allowed" : "pointer",
3201
+ fontSize: "14px",
3202
+ fontWeight: "500",
3203
+ color: "#ffffff",
3204
+ opacity: isSkipping ? 0.6 : 1
3205
+ },
3206
+ "data-testid": "button-skip-submit",
3207
+ children: isSkipping ? "Skipping..." : "Skip Question"
3208
+ }
3209
+ )
3210
+ ] })
3211
+ ] }) }),
3212
+ showReportModal && /* @__PURE__ */ jsx4("div", { style: {
3213
+ position: "fixed",
3214
+ top: 0,
3215
+ left: 0,
3216
+ right: 0,
3217
+ bottom: 0,
3218
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
3219
+ display: "flex",
3220
+ alignItems: "center",
3221
+ justifyContent: "center",
3222
+ zIndex: 1e3
3223
+ }, children: /* @__PURE__ */ jsxs4("div", { style: {
3224
+ backgroundColor: "#ffffff",
3225
+ borderRadius: "12px",
3226
+ padding: "24px",
3227
+ maxWidth: "400px",
3228
+ width: "90%",
3229
+ boxShadow: "0 20px 40px rgba(0, 0, 0, 0.2)"
3230
+ }, children: [
3231
+ /* @__PURE__ */ jsx4("h3", { style: { margin: "0 0 8px 0", fontSize: "18px", fontWeight: "600", color: "#1f2937" }, children: "Report Question" }),
3232
+ /* @__PURE__ */ jsx4("p", { style: { margin: "0 0 16px 0", fontSize: "14px", color: "#6b7280" }, children: "What's wrong with this question?" }),
3233
+ /* @__PURE__ */ jsxs4("div", { style: { marginBottom: "16px" }, children: [
3234
+ /* @__PURE__ */ jsx4(
3235
+ "textarea",
3236
+ {
3237
+ value: reportComment,
3238
+ onChange: (e) => setReportComment(e.target.value.slice(0, 300)),
3239
+ placeholder: "Describe the issue with this question...",
3240
+ disabled: isReporting,
3241
+ style: {
3242
+ width: "100%",
3243
+ minHeight: "120px",
3244
+ padding: "10px 12px",
3245
+ borderRadius: "8px",
3246
+ border: "1px solid #e5e7eb",
3247
+ fontSize: "14px",
3248
+ resize: "vertical",
3249
+ fontFamily: "inherit",
3250
+ boxSizing: "border-box"
3251
+ },
3252
+ "data-testid": "input-report-comment"
3253
+ }
3254
+ ),
3255
+ /* @__PURE__ */ jsxs4("div", { style: { fontSize: "12px", color: "#9ca3af", marginTop: "4px", textAlign: "right" }, children: [
3256
+ reportComment.length,
3257
+ "/300"
3258
+ ] })
3259
+ ] }),
3260
+ /* @__PURE__ */ jsxs4("div", { style: { display: "flex", gap: "10px" }, children: [
3261
+ /* @__PURE__ */ jsx4(
3262
+ "button",
3263
+ {
3264
+ onClick: () => {
3265
+ setShowReportModal(false);
3266
+ setReportComment("");
3267
+ },
3268
+ style: {
3269
+ flex: 1,
3270
+ padding: "10px 16px",
3271
+ borderRadius: "8px",
3272
+ border: "1px solid #e5e7eb",
3273
+ backgroundColor: "#ffffff",
3274
+ cursor: "pointer",
3275
+ fontSize: "14px",
3276
+ fontWeight: "500",
3277
+ color: "#6b7280"
3278
+ },
3279
+ "data-testid": "button-report-cancel",
3280
+ children: "Cancel"
3281
+ }
3282
+ ),
3283
+ /* @__PURE__ */ jsx4(
3284
+ "button",
3285
+ {
3286
+ onClick: () => handleReportQuestion(reportComment),
3287
+ disabled: isReporting || !reportComment.trim(),
3288
+ style: {
3289
+ flex: 1,
3290
+ padding: "10px 16px",
3291
+ borderRadius: "8px",
3292
+ border: "none",
3293
+ backgroundColor: reportComment.trim() ? "#ef4444" : "#d1d5db",
3294
+ cursor: isReporting || !reportComment.trim() ? "not-allowed" : "pointer",
3295
+ fontSize: "14px",
3296
+ fontWeight: "500",
3297
+ color: "#ffffff",
3298
+ opacity: isReporting ? 0.6 : 1
3299
+ },
3300
+ "data-testid": "button-report-submit",
3301
+ children: isReporting ? "Reporting..." : "Report"
3302
+ }
3303
+ )
3304
+ ] })
3305
+ ] }) }),
3306
+ /* @__PURE__ */ jsxs4("div", { style: defaultStyles.buttonsColumn, children: [
3307
+ showFeedback && isLastQuestion && canAddMore && /* @__PURE__ */ jsx4(
2825
3308
  "button",
2826
3309
  {
2827
- onClick: () => {
2828
- setShowReportModal(false);
2829
- setReportComment("");
2830
- },
2831
3310
  style: {
2832
- flex: 1,
2833
- padding: "10px 16px",
2834
- borderRadius: "8px",
2835
- border: "1px solid #e5e7eb",
2836
- backgroundColor: "#ffffff",
2837
- cursor: "pointer",
2838
- fontSize: "14px",
2839
- fontWeight: "500",
2840
- color: "#6b7280"
3311
+ ...defaultStyles.buttonAddMore,
3312
+ ...isGeneratingExtra ? defaultStyles.buttonAddMoreDisabled : {}
2841
3313
  },
2842
- "data-testid": "button-report-cancel",
2843
- children: "Cancel"
3314
+ onClick: handleAddMoreQuestions,
3315
+ disabled: isGeneratingExtra,
3316
+ "data-testid": "button-add-more-questions",
3317
+ children: isGeneratingExtra ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
3318
+ /* @__PURE__ */ jsx4(Spinner, { size: 16, color: "#9ca3af" }),
3319
+ "Generating Questions..."
3320
+ ] }) : /* @__PURE__ */ jsxs4(Fragment2, { children: [
3321
+ "+ Add ",
3322
+ questionsToAdd,
3323
+ " More Question",
3324
+ questionsToAdd !== 1 ? "s" : ""
3325
+ ] })
2844
3326
  }
2845
3327
  ),
2846
- /* @__PURE__ */ jsx3(
2847
- "button",
2848
- {
2849
- onClick: () => handleReportQuestion(reportComment),
2850
- disabled: isReporting || !reportComment.trim(),
2851
- style: {
2852
- flex: 1,
2853
- padding: "10px 16px",
2854
- borderRadius: "8px",
2855
- border: "none",
2856
- backgroundColor: reportComment.trim() ? "#ef4444" : "#d1d5db",
2857
- cursor: isReporting || !reportComment.trim() ? "not-allowed" : "pointer",
2858
- fontSize: "14px",
2859
- fontWeight: "500",
2860
- color: "#ffffff",
2861
- opacity: isReporting ? 0.6 : 1
2862
- },
2863
- "data-testid": "button-report-submit",
2864
- children: isReporting ? "Reporting..." : "Report"
2865
- }
2866
- )
3328
+ /* @__PURE__ */ jsx4("div", { style: { ...defaultStyles.buttons, justifyContent: "flex-end" }, children: showFeedback ? (
3329
+ // After viewing feedback
3330
+ isLastQuestion ? /* @__PURE__ */ jsx4(
3331
+ "button",
3332
+ {
3333
+ style: {
3334
+ ...defaultStyles.button,
3335
+ ...isSubmitting || isGeneratingExtra ? defaultStyles.buttonDisabled : defaultStyles.buttonPrimary
3336
+ },
3337
+ onClick: handleSubmit,
3338
+ disabled: isSubmitting || isGeneratingExtra,
3339
+ "data-testid": "button-submit-quiz",
3340
+ children: isSubmitting ? /* @__PURE__ */ jsx4(Spinner, { size: 16, color: "#9ca3af" }) : "Submit Quiz"
3341
+ }
3342
+ ) : /* @__PURE__ */ jsx4(
3343
+ "button",
3344
+ {
3345
+ style: {
3346
+ ...defaultStyles.button,
3347
+ ...defaultStyles.buttonPrimary
3348
+ },
3349
+ onClick: handleContinue,
3350
+ "data-testid": "button-continue",
3351
+ children: "Continue"
3352
+ }
3353
+ )
3354
+ ) : (
3355
+ // Before checking answer
3356
+ /* @__PURE__ */ jsx4(
3357
+ "button",
3358
+ {
3359
+ style: {
3360
+ ...defaultStyles.button,
3361
+ ...isNavigating || selectedAnswer === void 0 ? defaultStyles.buttonDisabled : defaultStyles.buttonPrimary
3362
+ },
3363
+ onClick: handleCheckAnswer,
3364
+ disabled: isNavigating || selectedAnswer === void 0,
3365
+ "data-testid": "button-check-answer",
3366
+ children: isNavigating ? /* @__PURE__ */ jsx4(Spinner, { size: 16, color: "#9ca3af" }) : "Check Answer"
3367
+ }
3368
+ )
3369
+ ) })
2867
3370
  ] })
2868
- ] }) }),
2869
- /* @__PURE__ */ jsxs3("div", { style: defaultStyles.buttonsColumn, children: [
2870
- showFeedback && isLastQuestion && canAddMore && /* @__PURE__ */ jsx3(
2871
- "button",
2872
- {
2873
- style: {
2874
- ...defaultStyles.buttonAddMore,
2875
- ...isGeneratingExtra ? defaultStyles.buttonAddMoreDisabled : {}
2876
- },
2877
- onClick: handleAddMoreQuestions,
2878
- disabled: isGeneratingExtra,
2879
- "data-testid": "button-add-more-questions",
2880
- children: isGeneratingExtra ? /* @__PURE__ */ jsxs3(Fragment2, { children: [
2881
- /* @__PURE__ */ jsx3(Spinner, { size: 16, color: "#9ca3af" }),
2882
- "Generating Questions..."
2883
- ] }) : /* @__PURE__ */ jsxs3(Fragment2, { children: [
2884
- "+ Add ",
2885
- questionsToAdd,
2886
- " More Question",
2887
- questionsToAdd !== 1 ? "s" : ""
2888
- ] })
2889
- }
2890
- ),
2891
- /* @__PURE__ */ jsx3("div", { style: { ...defaultStyles.buttons, justifyContent: "flex-end" }, children: showFeedback ? (
2892
- // After viewing feedback
2893
- isLastQuestion ? /* @__PURE__ */ jsx3(
2894
- "button",
2895
- {
2896
- style: {
2897
- ...defaultStyles.button,
2898
- ...isSubmitting || isGeneratingExtra ? defaultStyles.buttonDisabled : defaultStyles.buttonPrimary
2899
- },
2900
- onClick: handleSubmit,
2901
- disabled: isSubmitting || isGeneratingExtra,
2902
- "data-testid": "button-submit-quiz",
2903
- children: isSubmitting ? /* @__PURE__ */ jsx3(Spinner, { size: 16, color: "#9ca3af" }) : "Submit Quiz"
2904
- }
2905
- ) : /* @__PURE__ */ jsx3(
2906
- "button",
2907
- {
2908
- style: {
2909
- ...defaultStyles.button,
2910
- ...defaultStyles.buttonPrimary
2911
- },
2912
- onClick: handleContinue,
2913
- "data-testid": "button-continue",
2914
- children: "Continue"
2915
- }
2916
- )
2917
- ) : (
2918
- // Before checking answer
2919
- /* @__PURE__ */ jsx3(
2920
- "button",
2921
- {
2922
- style: {
2923
- ...defaultStyles.button,
2924
- ...isNavigating || selectedAnswer === void 0 ? defaultStyles.buttonDisabled : defaultStyles.buttonPrimary
2925
- },
2926
- onClick: handleCheckAnswer,
2927
- disabled: isNavigating || selectedAnswer === void 0,
2928
- "data-testid": "button-check-answer",
2929
- children: isNavigating ? /* @__PURE__ */ jsx3(Spinner, { size: 16, color: "#9ca3af" }) : "Check Answer"
2930
- }
2931
- )
2932
- ) })
2933
- ] })
2934
- ] }),
2935
- /* @__PURE__ */ jsx3("div", { style: defaultStyles.chatPanel, children: apiClient.current && /* @__PURE__ */ jsx3(
2936
- QuestionChatPanel,
2937
- {
2938
- apiClient: apiClient.current,
2939
- question: {
2940
- id: currentQuestion.id,
2941
- question: currentQuestion.question,
2942
- type: currentQuestion.type,
2943
- options: currentQuestion.options,
2944
- correctAnswer: currentQuestion.correctAnswer,
2945
- explanation: currentQuestion.explanation
2946
- },
2947
- quizId: quiz.id,
2948
- childId,
2949
- parentId,
2950
- lessonId,
2951
- courseId,
2952
- answerResult: showFeedback && currentAnswerDetail ? {
2953
- wasIncorrect: currentQuestion.type !== "assessment" && !currentAnswerDetail.isCorrect,
2954
- selectedAnswer: typeof selectedAnswer === "string" ? selectedAnswer : Array.isArray(selectedAnswer) ? selectedAnswer.join(", ") : void 0,
2955
- correctAnswer: typeof currentQuestion.correctAnswer === "string" ? currentQuestion.correctAnswer : Array.isArray(currentQuestion.correctAnswer) ? currentQuestion.correctAnswer.join(", ") : void 0,
2956
- explanation: currentQuestion.explanation
2957
- } : void 0
2958
- }
2959
- ) })
2960
- ] }) });
3371
+ ] }),
3372
+ /* @__PURE__ */ jsx4("div", { style: defaultStyles.chatPanel, children: apiClient.current && /* @__PURE__ */ jsx4(
3373
+ QuestionChatPanel,
3374
+ {
3375
+ apiClient: apiClient.current,
3376
+ question: {
3377
+ id: currentQuestion.id,
3378
+ question: currentQuestion.question,
3379
+ type: currentQuestion.type,
3380
+ options: currentQuestion.options,
3381
+ correctAnswer: currentQuestion.correctAnswer,
3382
+ explanation: currentQuestion.explanation
3383
+ },
3384
+ quizId: quiz.id,
3385
+ childId,
3386
+ parentId,
3387
+ lessonId,
3388
+ courseId,
3389
+ answerResult: showFeedback && currentAnswerDetail ? {
3390
+ wasIncorrect: currentQuestion.type !== "assessment" && !currentAnswerDetail.isCorrect,
3391
+ selectedAnswer: typeof selectedAnswer === "string" ? selectedAnswer : Array.isArray(selectedAnswer) ? selectedAnswer.join(", ") : void 0,
3392
+ correctAnswer: typeof currentQuestion.correctAnswer === "string" ? currentQuestion.correctAnswer : Array.isArray(currentQuestion.correctAnswer) ? currentQuestion.correctAnswer.join(", ") : void 0,
3393
+ explanation: currentQuestion.explanation
3394
+ } : void 0
3395
+ }
3396
+ ) })
3397
+ ] })
3398
+ ] });
2961
3399
  }
2962
3400
 
2963
3401
  // src/AttemptViewer.tsx
2964
- import { useState as useState4, useEffect as useEffect4 } from "react";
2965
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
3402
+ import { useState as useState4, useEffect as useEffect4, useRef as useRef4 } from "react";
3403
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
2966
3404
  var defaultStyles2 = {
2967
3405
  container: {
2968
3406
  fontFamily: "system-ui, -apple-system, sans-serif",
@@ -3105,7 +3543,12 @@ var defaultStyles2 = {
3105
3543
  marginTop: "12px",
3106
3544
  display: "flex",
3107
3545
  flexDirection: "column",
3108
- gap: "8px"
3546
+ gap: "8px",
3547
+ backgroundColor: "#ffffff",
3548
+ padding: "16px",
3549
+ borderRadius: "8px",
3550
+ border: "1px solid #e5e7eb",
3551
+ boxShadow: "0 1px 3px rgba(0, 0, 0, 0.05)"
3109
3552
  },
3110
3553
  chatMessage: {
3111
3554
  padding: "8px 12px",
@@ -3215,23 +3658,39 @@ function AttemptViewer({
3215
3658
  }) {
3216
3659
  const [attempt, setAttempt] = useState4(null);
3217
3660
  const [loading, setLoading] = useState4(true);
3218
- const [error, setError] = useState4(null);
3661
+ const [errorCode, setErrorCode] = useState4(null);
3219
3662
  const [chatHistories, setChatHistories] = useState4({});
3220
3663
  const [expandedChats, setExpandedChats] = useState4(/* @__PURE__ */ new Set());
3664
+ const [fetchedAttemptId, setFetchedAttemptId] = useState4(null);
3665
+ const onErrorRef = useRef4(onError);
3666
+ onErrorRef.current = onError;
3221
3667
  useEffect4(() => {
3668
+ if (fetchedAttemptId === attemptId) return;
3222
3669
  const apiClient = new QuizApiClient({
3223
3670
  baseUrl: apiBaseUrl,
3224
3671
  authToken
3225
3672
  });
3226
3673
  async function fetchAttempt() {
3227
3674
  setLoading(true);
3228
- setError(null);
3675
+ setErrorCode(null);
3229
3676
  try {
3230
3677
  const response = await fetch(`${apiBaseUrl}/api/external/quiz-attempts/${attemptId}`, {
3231
3678
  headers: authToken ? { Authorization: `Bearer ${authToken}` } : {}
3232
3679
  });
3233
3680
  if (!response.ok) {
3234
- throw new Error(`Failed to fetch attempt: ${response.statusText}`);
3681
+ const code = getErrorFromHttpStatus(response.status, "attempt");
3682
+ setErrorCode(code);
3683
+ apiClient.logError({
3684
+ errorCode: code,
3685
+ context: "attempt",
3686
+ resourceId: attemptId,
3687
+ component: "AttemptViewer",
3688
+ message: `HTTP ${response.status}: ${response.statusText}`
3689
+ });
3690
+ onErrorRef.current?.(new Error(`Failed to fetch attempt: ${response.statusText}`));
3691
+ setLoading(false);
3692
+ setFetchedAttemptId(attemptId);
3693
+ return;
3235
3694
  }
3236
3695
  const data = await response.json();
3237
3696
  setAttempt(data);
@@ -3245,14 +3704,23 @@ function AttemptViewer({
3245
3704
  }
3246
3705
  } catch (err) {
3247
3706
  const errorMessage = err instanceof Error ? err.message : "Failed to load attempt";
3248
- setError(errorMessage);
3249
- onError?.(err instanceof Error ? err : new Error(errorMessage));
3707
+ const code = getErrorFromMessage(errorMessage, "attempt");
3708
+ setErrorCode(code);
3709
+ apiClient.logError({
3710
+ errorCode: code,
3711
+ context: "attempt",
3712
+ resourceId: attemptId,
3713
+ component: "AttemptViewer",
3714
+ message: errorMessage
3715
+ });
3716
+ onErrorRef.current?.(err instanceof Error ? err : new Error(errorMessage));
3250
3717
  } finally {
3251
3718
  setLoading(false);
3719
+ setFetchedAttemptId(attemptId);
3252
3720
  }
3253
3721
  }
3254
3722
  fetchAttempt();
3255
- }, [attemptId, apiBaseUrl, authToken, onError, showConversation]);
3723
+ }, [attemptId, apiBaseUrl, authToken, showConversation, fetchedAttemptId]);
3256
3724
  const toggleChatExpanded = (questionId) => {
3257
3725
  setExpandedChats((prev) => {
3258
3726
  const newSet = new Set(prev);
@@ -3266,53 +3734,49 @@ function AttemptViewer({
3266
3734
  };
3267
3735
  const handleRetry = () => {
3268
3736
  setLoading(true);
3269
- setError(null);
3737
+ setErrorCode(null);
3270
3738
  window.location.reload();
3271
3739
  };
3272
3740
  if (loading) {
3273
- return /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.container, className, children: [
3274
- /* @__PURE__ */ jsx4("style", { children: spinnerKeyframes }),
3275
- /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.loading, children: [
3276
- /* @__PURE__ */ jsx4("div", { style: defaultStyles2.spinner }),
3277
- /* @__PURE__ */ jsx4("p", { style: { marginTop: "16px", color: "#6b7280" }, children: "Loading attempt..." })
3741
+ return /* @__PURE__ */ jsxs5("div", { style: defaultStyles2.container, className, children: [
3742
+ /* @__PURE__ */ jsx5("style", { children: spinnerKeyframes }),
3743
+ /* @__PURE__ */ jsxs5("div", { style: defaultStyles2.loading, children: [
3744
+ /* @__PURE__ */ jsx5("div", { style: defaultStyles2.spinner }),
3745
+ /* @__PURE__ */ jsx5("p", { style: { marginTop: "16px", color: "#6b7280" }, children: "Loading attempt..." })
3278
3746
  ] })
3279
3747
  ] });
3280
3748
  }
3281
- if (error || !attempt) {
3282
- return /* @__PURE__ */ jsx4("div", { style: defaultStyles2.container, className, children: /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.error, children: [
3283
- /* @__PURE__ */ jsx4("p", { style: { fontSize: "18px", fontWeight: "500" }, children: "Failed to load attempt" }),
3284
- /* @__PURE__ */ jsx4("p", { style: { marginTop: "8px", color: "#6b7280" }, children: error }),
3285
- /* @__PURE__ */ jsx4("button", { style: defaultStyles2.retryButton, onClick: handleRetry, children: "Try Again" })
3286
- ] }) });
3749
+ if (errorCode || !attempt) {
3750
+ return /* @__PURE__ */ jsx5("div", { style: defaultStyles2.container, className, children: /* @__PURE__ */ jsx5(MaintenanceScreen, { errorCode: errorCode || "ATTEMPT_NOT_FOUND" }) });
3287
3751
  }
3288
3752
  const scorePercentage = attempt.score ?? 0;
3289
3753
  const correctCount = attempt.correctAnswers ?? 0;
3290
3754
  const totalQuestions = attempt.totalQuestions;
3291
3755
  const timeSpent = attempt.timeSpentSeconds ?? 0;
3292
- return /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.container, className, children: [
3293
- /* @__PURE__ */ jsx4("style", { children: spinnerKeyframes }),
3294
- /* @__PURE__ */ jsx4("div", { style: defaultStyles2.header, children: /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.summaryGrid, children: [
3295
- /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.summaryCard, children: [
3296
- /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.summaryValue, children: [
3756
+ return /* @__PURE__ */ jsxs5("div", { style: defaultStyles2.container, className, children: [
3757
+ /* @__PURE__ */ jsx5("style", { children: spinnerKeyframes }),
3758
+ /* @__PURE__ */ jsx5("div", { style: defaultStyles2.header, children: /* @__PURE__ */ jsxs5("div", { style: defaultStyles2.summaryGrid, children: [
3759
+ /* @__PURE__ */ jsxs5("div", { style: defaultStyles2.summaryCard, children: [
3760
+ /* @__PURE__ */ jsxs5("div", { style: defaultStyles2.summaryValue, children: [
3297
3761
  scorePercentage,
3298
3762
  "%"
3299
3763
  ] }),
3300
- /* @__PURE__ */ jsx4("div", { style: defaultStyles2.summaryLabel, children: "Score" })
3764
+ /* @__PURE__ */ jsx5("div", { style: defaultStyles2.summaryLabel, children: "Score" })
3301
3765
  ] }),
3302
- /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.summaryCard, children: [
3303
- /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.summaryValue, children: [
3766
+ /* @__PURE__ */ jsxs5("div", { style: defaultStyles2.summaryCard, children: [
3767
+ /* @__PURE__ */ jsxs5("div", { style: defaultStyles2.summaryValue, children: [
3304
3768
  correctCount,
3305
3769
  "/",
3306
3770
  totalQuestions
3307
3771
  ] }),
3308
- /* @__PURE__ */ jsx4("div", { style: defaultStyles2.summaryLabel, children: "Correct" })
3772
+ /* @__PURE__ */ jsx5("div", { style: defaultStyles2.summaryLabel, children: "Correct" })
3309
3773
  ] }),
3310
- /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.summaryCard, children: [
3311
- /* @__PURE__ */ jsx4("div", { style: defaultStyles2.summaryValue, children: formatTime(timeSpent) }),
3312
- /* @__PURE__ */ jsx4("div", { style: defaultStyles2.summaryLabel, children: "Time" })
3774
+ /* @__PURE__ */ jsxs5("div", { style: defaultStyles2.summaryCard, children: [
3775
+ /* @__PURE__ */ jsx5("div", { style: defaultStyles2.summaryValue, children: formatTime(timeSpent) }),
3776
+ /* @__PURE__ */ jsx5("div", { style: defaultStyles2.summaryLabel, children: "Time" })
3313
3777
  ] })
3314
3778
  ] }) }),
3315
- /* @__PURE__ */ jsx4("div", { style: defaultStyles2.questionsList, children: attempt.answers.map((answer, index) => /* @__PURE__ */ jsxs4(
3779
+ /* @__PURE__ */ jsx5("div", { style: defaultStyles2.questionsList, children: attempt.answers.map((answer, index) => /* @__PURE__ */ jsxs5(
3316
3780
  "div",
3317
3781
  {
3318
3782
  style: {
@@ -3320,12 +3784,12 @@ function AttemptViewer({
3320
3784
  ...answer.isCorrect ? defaultStyles2.questionCardCorrect : defaultStyles2.questionCardIncorrect
3321
3785
  },
3322
3786
  children: [
3323
- /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.questionHeader, children: [
3324
- /* @__PURE__ */ jsxs4("span", { style: defaultStyles2.questionNumber, children: [
3787
+ /* @__PURE__ */ jsxs5("div", { style: defaultStyles2.questionHeader, children: [
3788
+ /* @__PURE__ */ jsxs5("span", { style: defaultStyles2.questionNumber, children: [
3325
3789
  "Question ",
3326
3790
  index + 1
3327
3791
  ] }),
3328
- /* @__PURE__ */ jsx4(
3792
+ /* @__PURE__ */ jsx5(
3329
3793
  "span",
3330
3794
  {
3331
3795
  style: {
@@ -3336,35 +3800,35 @@ function AttemptViewer({
3336
3800
  }
3337
3801
  )
3338
3802
  ] }),
3339
- /* @__PURE__ */ jsx4("div", { style: defaultStyles2.questionText, children: answer.questionText }),
3340
- /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.answerSection, children: [
3341
- /* @__PURE__ */ jsx4("span", { style: defaultStyles2.answerLabel, children: "Your answer:" }),
3342
- /* @__PURE__ */ jsx4("span", { style: defaultStyles2.studentAnswer, children: formatAnswer(answer.selectedAnswer, answer.questionType, answer.items, answer.leftItems) })
3803
+ /* @__PURE__ */ jsx5("div", { style: defaultStyles2.questionText, children: answer.questionText }),
3804
+ /* @__PURE__ */ jsxs5("div", { style: defaultStyles2.answerSection, children: [
3805
+ /* @__PURE__ */ jsx5("span", { style: defaultStyles2.answerLabel, children: "Your answer:" }),
3806
+ /* @__PURE__ */ jsx5("span", { style: defaultStyles2.studentAnswer, children: formatAnswer(answer.selectedAnswer, answer.questionType, answer.items, answer.leftItems) })
3343
3807
  ] }),
3344
- !answer.isCorrect && answer.correctAnswer && /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.answerSection, children: [
3345
- /* @__PURE__ */ jsx4("span", { style: defaultStyles2.answerLabel, children: "Correct answer:" }),
3346
- /* @__PURE__ */ jsx4("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) })
3808
+ !answer.isCorrect && answer.correctAnswer && /* @__PURE__ */ jsxs5("div", { style: defaultStyles2.answerSection, children: [
3809
+ /* @__PURE__ */ jsx5("span", { style: defaultStyles2.answerLabel, children: "Correct answer:" }),
3810
+ /* @__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) })
3347
3811
  ] }),
3348
- /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.points, children: [
3812
+ /* @__PURE__ */ jsxs5("div", { style: defaultStyles2.points, children: [
3349
3813
  answer.pointsEarned,
3350
3814
  " / ",
3351
3815
  answer.points,
3352
3816
  " points"
3353
3817
  ] }),
3354
- showExplanations && answer.explanation && /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.explanation, children: [
3355
- /* @__PURE__ */ jsx4("strong", { children: "Explanation:" }),
3818
+ showExplanations && answer.explanation && /* @__PURE__ */ jsxs5("div", { style: defaultStyles2.explanation, children: [
3819
+ /* @__PURE__ */ jsx5("strong", { children: "Explanation:" }),
3356
3820
  " ",
3357
3821
  answer.explanation
3358
3822
  ] }),
3359
- showConversation && chatHistories[answer.questionId] && chatHistories[answer.questionId].messages.length > 0 && /* @__PURE__ */ jsxs4("div", { style: defaultStyles2.chatHistorySection, children: [
3360
- /* @__PURE__ */ jsxs4(
3823
+ showConversation && chatHistories[answer.questionId] && chatHistories[answer.questionId].messages.length > 0 && /* @__PURE__ */ jsxs5("div", { style: defaultStyles2.chatHistorySection, children: [
3824
+ /* @__PURE__ */ jsxs5(
3361
3825
  "button",
3362
3826
  {
3363
3827
  style: defaultStyles2.chatToggleButton,
3364
3828
  onClick: () => toggleChatExpanded(answer.questionId),
3365
3829
  "data-testid": `button-toggle-chat-${answer.questionId}`,
3366
3830
  children: [
3367
- /* @__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" }) }),
3831
+ /* @__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" }) }),
3368
3832
  expandedChats.has(answer.questionId) ? "Hide" : "View",
3369
3833
  " Chat History (",
3370
3834
  chatHistories[answer.questionId].messages.length,
@@ -3372,7 +3836,7 @@ function AttemptViewer({
3372
3836
  ]
3373
3837
  }
3374
3838
  ),
3375
- expandedChats.has(answer.questionId) && /* @__PURE__ */ jsx4("div", { style: defaultStyles2.chatMessages, children: chatHistories[answer.questionId].messages.map((msg, msgIndex) => /* @__PURE__ */ jsx4(
3839
+ expandedChats.has(answer.questionId) && /* @__PURE__ */ jsx5("div", { style: defaultStyles2.chatMessages, children: chatHistories[answer.questionId].messages.map((msg, msgIndex) => /* @__PURE__ */ jsx5(
3376
3840
  "div",
3377
3841
  {
3378
3842
  style: {
@@ -3390,14 +3854,620 @@ function AttemptViewer({
3390
3854
  )) })
3391
3855
  ] });
3392
3856
  }
3857
+
3858
+ // src/ErrorTypesPanel.tsx
3859
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
3860
+ var panelStyles2 = {
3861
+ container: {
3862
+ fontFamily: "system-ui, -apple-system, sans-serif",
3863
+ padding: "24px",
3864
+ backgroundColor: "#ffffff",
3865
+ borderRadius: "12px",
3866
+ maxWidth: "800px"
3867
+ },
3868
+ header: {
3869
+ marginBottom: "24px"
3870
+ },
3871
+ title: {
3872
+ fontSize: "20px",
3873
+ fontWeight: "600",
3874
+ color: "#111827",
3875
+ marginBottom: "8px"
3876
+ },
3877
+ subtitle: {
3878
+ fontSize: "14px",
3879
+ color: "#6b7280"
3880
+ },
3881
+ section: {
3882
+ marginBottom: "24px"
3883
+ },
3884
+ sectionTitle: {
3885
+ fontSize: "14px",
3886
+ fontWeight: "600",
3887
+ color: "#374151",
3888
+ marginBottom: "12px",
3889
+ textTransform: "uppercase",
3890
+ letterSpacing: "0.05em"
3891
+ },
3892
+ errorList: {
3893
+ display: "flex",
3894
+ flexDirection: "column",
3895
+ gap: "12px"
3896
+ },
3897
+ errorCard: {
3898
+ padding: "16px",
3899
+ backgroundColor: "#f9fafb",
3900
+ borderRadius: "8px",
3901
+ border: "1px solid #e5e7eb"
3902
+ },
3903
+ errorCardBlocking: {
3904
+ borderLeft: "4px solid #ef4444"
3905
+ },
3906
+ errorCardNonBlocking: {
3907
+ borderLeft: "4px solid #f59e0b"
3908
+ },
3909
+ errorHeader: {
3910
+ display: "flex",
3911
+ justifyContent: "space-between",
3912
+ alignItems: "flex-start",
3913
+ marginBottom: "8px"
3914
+ },
3915
+ errorCode: {
3916
+ fontSize: "13px",
3917
+ fontWeight: "600",
3918
+ color: "#1f2937",
3919
+ fontFamily: "monospace",
3920
+ backgroundColor: "#e5e7eb",
3921
+ padding: "2px 8px",
3922
+ borderRadius: "4px"
3923
+ },
3924
+ errorBadge: {
3925
+ fontSize: "11px",
3926
+ fontWeight: "500",
3927
+ padding: "2px 8px",
3928
+ borderRadius: "12px"
3929
+ },
3930
+ blockingBadge: {
3931
+ backgroundColor: "#fee2e2",
3932
+ color: "#dc2626"
3933
+ },
3934
+ nonBlockingBadge: {
3935
+ backgroundColor: "#fef3c7",
3936
+ color: "#d97706"
3937
+ },
3938
+ userMessage: {
3939
+ fontSize: "15px",
3940
+ fontWeight: "500",
3941
+ color: "#111827",
3942
+ marginBottom: "4px"
3943
+ },
3944
+ subMessage: {
3945
+ fontSize: "13px",
3946
+ color: "#6b7280",
3947
+ marginBottom: "8px"
3948
+ },
3949
+ causeLabel: {
3950
+ fontSize: "11px",
3951
+ fontWeight: "600",
3952
+ color: "#9ca3af",
3953
+ textTransform: "uppercase",
3954
+ marginBottom: "4px"
3955
+ },
3956
+ causeText: {
3957
+ fontSize: "13px",
3958
+ color: "#4b5563",
3959
+ fontStyle: "italic"
3960
+ }
3961
+ };
3962
+ function ErrorTypesPanel({ className }) {
3963
+ const blockingErrors = Object.values(ERROR_DEFINITIONS).filter((e) => e.isBlocking);
3964
+ const nonBlockingErrors = Object.values(ERROR_DEFINITIONS).filter((e) => !e.isBlocking);
3965
+ const renderErrorCard = (error) => /* @__PURE__ */ jsxs6(
3966
+ "div",
3967
+ {
3968
+ style: {
3969
+ ...panelStyles2.errorCard,
3970
+ ...error.isBlocking ? panelStyles2.errorCardBlocking : panelStyles2.errorCardNonBlocking
3971
+ },
3972
+ "data-testid": `error-card-${error.code}`,
3973
+ children: [
3974
+ /* @__PURE__ */ jsxs6("div", { style: panelStyles2.errorHeader, children: [
3975
+ /* @__PURE__ */ jsx6("code", { style: panelStyles2.errorCode, children: error.code }),
3976
+ /* @__PURE__ */ jsx6(
3977
+ "span",
3978
+ {
3979
+ style: {
3980
+ ...panelStyles2.errorBadge,
3981
+ ...error.isBlocking ? panelStyles2.blockingBadge : panelStyles2.nonBlockingBadge
3982
+ },
3983
+ children: error.isBlocking ? "Blocking" : "Non-Blocking"
3984
+ }
3985
+ )
3986
+ ] }),
3987
+ /* @__PURE__ */ jsx6("div", { style: panelStyles2.userMessage, children: error.userMessage }),
3988
+ /* @__PURE__ */ jsx6("div", { style: panelStyles2.subMessage, children: error.subMessage }),
3989
+ /* @__PURE__ */ jsx6("div", { style: panelStyles2.causeLabel, children: "Why this happens:" }),
3990
+ /* @__PURE__ */ jsx6("div", { style: panelStyles2.causeText, children: error.cause })
3991
+ ]
3992
+ },
3993
+ error.code
3994
+ );
3995
+ return /* @__PURE__ */ jsxs6("div", { style: panelStyles2.container, className, "data-testid": "error-types-panel", children: [
3996
+ /* @__PURE__ */ jsxs6("div", { style: panelStyles2.header, children: [
3997
+ /* @__PURE__ */ jsx6("h2", { style: panelStyles2.title, children: "Error Types Reference" }),
3998
+ /* @__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." })
3999
+ ] }),
4000
+ /* @__PURE__ */ jsxs6("div", { style: panelStyles2.section, children: [
4001
+ /* @__PURE__ */ jsxs6("h3", { style: panelStyles2.sectionTitle, children: [
4002
+ "Blocking Errors (",
4003
+ blockingErrors.length,
4004
+ ")"
4005
+ ] }),
4006
+ /* @__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." }),
4007
+ /* @__PURE__ */ jsx6("div", { style: panelStyles2.errorList, children: blockingErrors.map(renderErrorCard) })
4008
+ ] }),
4009
+ /* @__PURE__ */ jsxs6("div", { style: panelStyles2.section, children: [
4010
+ /* @__PURE__ */ jsxs6("h3", { style: panelStyles2.sectionTitle, children: [
4011
+ "Non-Blocking Errors (",
4012
+ nonBlockingErrors.length,
4013
+ ")"
4014
+ ] }),
4015
+ /* @__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." }),
4016
+ /* @__PURE__ */ jsx6("div", { style: panelStyles2.errorList, children: nonBlockingErrors.map(renderErrorCard) })
4017
+ ] })
4018
+ ] });
4019
+ }
4020
+
4021
+ // src/ErrorLogsPanel.tsx
4022
+ import { useState as useState5, useEffect as useEffect5 } from "react";
4023
+ import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
4024
+ var panelStyles3 = {
4025
+ container: {
4026
+ fontFamily: "system-ui, -apple-system, sans-serif",
4027
+ padding: "24px",
4028
+ backgroundColor: "#ffffff",
4029
+ borderRadius: "12px",
4030
+ maxWidth: "1000px"
4031
+ },
4032
+ header: {
4033
+ marginBottom: "24px"
4034
+ },
4035
+ title: {
4036
+ fontSize: "20px",
4037
+ fontWeight: "600",
4038
+ color: "#111827",
4039
+ marginBottom: "8px"
4040
+ },
4041
+ subtitle: {
4042
+ fontSize: "14px",
4043
+ color: "#6b7280"
4044
+ },
4045
+ tabs: {
4046
+ display: "flex",
4047
+ gap: "8px",
4048
+ marginBottom: "16px",
4049
+ borderBottom: "1px solid #e5e7eb",
4050
+ paddingBottom: "12px"
4051
+ },
4052
+ tab: {
4053
+ padding: "8px 16px",
4054
+ fontSize: "14px",
4055
+ fontWeight: "500",
4056
+ borderRadius: "6px",
4057
+ cursor: "pointer",
4058
+ border: "none",
4059
+ backgroundColor: "transparent",
4060
+ color: "#6b7280"
4061
+ },
4062
+ tabActive: {
4063
+ backgroundColor: "#6721b0",
4064
+ color: "#ffffff"
4065
+ },
4066
+ stats: {
4067
+ display: "flex",
4068
+ gap: "16px",
4069
+ marginBottom: "20px"
4070
+ },
4071
+ statCard: {
4072
+ padding: "12px 16px",
4073
+ backgroundColor: "#f9fafb",
4074
+ borderRadius: "8px",
4075
+ flex: 1
4076
+ },
4077
+ statValue: {
4078
+ fontSize: "24px",
4079
+ fontWeight: "700",
4080
+ color: "#111827"
4081
+ },
4082
+ statLabel: {
4083
+ fontSize: "12px",
4084
+ color: "#6b7280",
4085
+ textTransform: "uppercase",
4086
+ letterSpacing: "0.05em"
4087
+ },
4088
+ errorList: {
4089
+ display: "flex",
4090
+ flexDirection: "column",
4091
+ gap: "12px"
4092
+ },
4093
+ errorCard: {
4094
+ padding: "16px",
4095
+ backgroundColor: "#f9fafb",
4096
+ borderRadius: "8px",
4097
+ border: "1px solid #e5e7eb"
4098
+ },
4099
+ errorCardRecent: {
4100
+ borderLeft: "4px solid #ef4444",
4101
+ backgroundColor: "#fef2f2"
4102
+ },
4103
+ errorCardOld: {
4104
+ borderLeft: "4px solid #9ca3af",
4105
+ opacity: 0.7
4106
+ },
4107
+ errorHeader: {
4108
+ display: "flex",
4109
+ justifyContent: "space-between",
4110
+ alignItems: "flex-start",
4111
+ marginBottom: "8px"
4112
+ },
4113
+ errorLeft: {
4114
+ flex: 1
4115
+ },
4116
+ errorCode: {
4117
+ fontSize: "13px",
4118
+ fontWeight: "600",
4119
+ color: "#1f2937",
4120
+ fontFamily: "monospace",
4121
+ backgroundColor: "#e5e7eb",
4122
+ padding: "2px 8px",
4123
+ borderRadius: "4px",
4124
+ display: "inline-block"
4125
+ },
4126
+ countBadge: {
4127
+ fontSize: "14px",
4128
+ fontWeight: "700",
4129
+ padding: "4px 12px",
4130
+ borderRadius: "16px",
4131
+ backgroundColor: "#ef4444",
4132
+ color: "#ffffff"
4133
+ },
4134
+ countBadgeLow: {
4135
+ backgroundColor: "#f59e0b"
4136
+ },
4137
+ contextBadge: {
4138
+ fontSize: "11px",
4139
+ fontWeight: "500",
4140
+ padding: "2px 8px",
4141
+ borderRadius: "4px",
4142
+ marginLeft: "8px",
4143
+ backgroundColor: "#dbeafe",
4144
+ color: "#1d4ed8"
4145
+ },
4146
+ userMessage: {
4147
+ fontSize: "15px",
4148
+ fontWeight: "500",
4149
+ color: "#111827",
4150
+ marginTop: "8px",
4151
+ marginBottom: "4px"
4152
+ },
4153
+ resourceId: {
4154
+ fontSize: "12px",
4155
+ color: "#6b7280",
4156
+ fontFamily: "monospace",
4157
+ marginTop: "4px"
4158
+ },
4159
+ resourceLink: {
4160
+ color: "#6721b0",
4161
+ textDecoration: "underline",
4162
+ cursor: "pointer"
4163
+ },
4164
+ timestamps: {
4165
+ display: "flex",
4166
+ gap: "16px",
4167
+ marginTop: "8px",
4168
+ fontSize: "12px",
4169
+ color: "#9ca3af"
4170
+ },
4171
+ dismissButton: {
4172
+ padding: "6px 12px",
4173
+ fontSize: "12px",
4174
+ fontWeight: "500",
4175
+ borderRadius: "4px",
4176
+ cursor: "pointer",
4177
+ border: "1px solid #e5e7eb",
4178
+ backgroundColor: "#ffffff",
4179
+ color: "#6b7280",
4180
+ marginTop: "8px"
4181
+ },
4182
+ dismissButtonHover: {
4183
+ backgroundColor: "#f3f4f6"
4184
+ },
4185
+ emptyState: {
4186
+ textAlign: "center",
4187
+ padding: "40px",
4188
+ color: "#9ca3af",
4189
+ fontSize: "14px"
4190
+ },
4191
+ loading: {
4192
+ textAlign: "center",
4193
+ padding: "40px",
4194
+ color: "#6b7280",
4195
+ fontSize: "14px"
4196
+ },
4197
+ pagination: {
4198
+ display: "flex",
4199
+ justifyContent: "center",
4200
+ gap: "8px",
4201
+ marginTop: "20px"
4202
+ },
4203
+ pageButton: {
4204
+ padding: "8px 12px",
4205
+ fontSize: "14px",
4206
+ borderRadius: "4px",
4207
+ cursor: "pointer",
4208
+ border: "1px solid #e5e7eb",
4209
+ backgroundColor: "#ffffff",
4210
+ color: "#374151"
4211
+ },
4212
+ pageButtonDisabled: {
4213
+ opacity: 0.5,
4214
+ cursor: "not-allowed"
4215
+ }
4216
+ };
4217
+ function formatRelativeTime(dateStr) {
4218
+ const date = new Date(dateStr);
4219
+ const now = /* @__PURE__ */ new Date();
4220
+ const diffMs = now.getTime() - date.getTime();
4221
+ const diffMins = Math.floor(diffMs / 6e4);
4222
+ const diffHours = Math.floor(diffMs / 36e5);
4223
+ const diffDays = Math.floor(diffMs / 864e5);
4224
+ if (diffMins < 1) return "Just now";
4225
+ if (diffMins < 60) return `${diffMins}m ago`;
4226
+ if (diffHours < 24) return `${diffHours}h ago`;
4227
+ if (diffDays < 7) return `${diffDays}d ago`;
4228
+ return date.toLocaleDateString();
4229
+ }
4230
+ function isRecent(dateStr) {
4231
+ const date = new Date(dateStr);
4232
+ const now = /* @__PURE__ */ new Date();
4233
+ const diffMs = now.getTime() - date.getTime();
4234
+ const diffHours = diffMs / 36e5;
4235
+ return diffHours < 24;
4236
+ }
4237
+ function ErrorLogsPanel({ apiBaseUrl, authToken, onResourceClick }) {
4238
+ const [logs, setLogs] = useState5([]);
4239
+ const [loading, setLoading] = useState5(true);
4240
+ const [showDismissed, setShowDismissed] = useState5(false);
4241
+ const [page, setPage] = useState5(1);
4242
+ const [totalPages, setTotalPages] = useState5(1);
4243
+ const [total, setTotal] = useState5(0);
4244
+ useEffect5(() => {
4245
+ fetchLogs();
4246
+ }, [showDismissed, page]);
4247
+ async function fetchLogs() {
4248
+ setLoading(true);
4249
+ try {
4250
+ const params = new URLSearchParams();
4251
+ params.set("dismissed", showDismissed ? "true" : "false");
4252
+ params.set("page", page.toString());
4253
+ params.set("limit", "20");
4254
+ const response = await fetch(`${apiBaseUrl}/api/admin/error-logs?${params}`, {
4255
+ headers: authToken ? { Authorization: `Bearer ${authToken}` } : {}
4256
+ });
4257
+ if (response.ok) {
4258
+ const data = await response.json();
4259
+ setLogs(data.items || []);
4260
+ setTotalPages(data.totalPages || 1);
4261
+ setTotal(data.total || 0);
4262
+ }
4263
+ } catch (err) {
4264
+ console.error("Failed to fetch error logs:", err);
4265
+ } finally {
4266
+ setLoading(false);
4267
+ }
4268
+ }
4269
+ async function handleDismiss(id) {
4270
+ try {
4271
+ const response = await fetch(`${apiBaseUrl}/api/admin/error-logs/${id}/dismiss`, {
4272
+ method: "PATCH",
4273
+ headers: authToken ? { Authorization: `Bearer ${authToken}` } : {}
4274
+ });
4275
+ if (response.ok) {
4276
+ fetchLogs();
4277
+ }
4278
+ } catch (err) {
4279
+ console.error("Failed to dismiss error:", err);
4280
+ }
4281
+ }
4282
+ async function handleUndismiss(id) {
4283
+ try {
4284
+ const response = await fetch(`${apiBaseUrl}/api/admin/error-logs/${id}/undismiss`, {
4285
+ method: "PATCH",
4286
+ headers: authToken ? { Authorization: `Bearer ${authToken}` } : {}
4287
+ });
4288
+ if (response.ok) {
4289
+ fetchLogs();
4290
+ }
4291
+ } catch (err) {
4292
+ console.error("Failed to undismiss error:", err);
4293
+ }
4294
+ }
4295
+ function getErrorDefinition(code) {
4296
+ return ERROR_DEFINITIONS[code];
4297
+ }
4298
+ const totalErrors = logs.reduce((sum, log) => sum + log.count, 0);
4299
+ const recentCount = logs.filter((log) => isRecent(log.lastSeenAt)).length;
4300
+ return /* @__PURE__ */ jsxs7("div", { style: panelStyles3.container, "data-testid": "error-logs-panel", children: [
4301
+ /* @__PURE__ */ jsxs7("div", { style: panelStyles3.header, children: [
4302
+ /* @__PURE__ */ jsx7("h2", { style: panelStyles3.title, children: "Error Tracking" }),
4303
+ /* @__PURE__ */ jsx7("p", { style: panelStyles3.subtitle, children: "Aggregated errors from QuizPlayer and AttemptViewer components, sorted by occurrence count" })
4304
+ ] }),
4305
+ /* @__PURE__ */ jsxs7("div", { style: panelStyles3.tabs, children: [
4306
+ /* @__PURE__ */ jsx7(
4307
+ "button",
4308
+ {
4309
+ style: {
4310
+ ...panelStyles3.tab,
4311
+ ...showDismissed ? {} : panelStyles3.tabActive
4312
+ },
4313
+ onClick: () => {
4314
+ setShowDismissed(false);
4315
+ setPage(1);
4316
+ },
4317
+ "data-testid": "tab-active-errors",
4318
+ children: "Active Errors"
4319
+ }
4320
+ ),
4321
+ /* @__PURE__ */ jsx7(
4322
+ "button",
4323
+ {
4324
+ style: {
4325
+ ...panelStyles3.tab,
4326
+ ...showDismissed ? panelStyles3.tabActive : {}
4327
+ },
4328
+ onClick: () => {
4329
+ setShowDismissed(true);
4330
+ setPage(1);
4331
+ },
4332
+ "data-testid": "tab-dismissed-errors",
4333
+ children: "Dismissed"
4334
+ }
4335
+ )
4336
+ ] }),
4337
+ !showDismissed && /* @__PURE__ */ jsxs7("div", { style: panelStyles3.stats, children: [
4338
+ /* @__PURE__ */ jsxs7("div", { style: panelStyles3.statCard, children: [
4339
+ /* @__PURE__ */ jsx7("div", { style: panelStyles3.statValue, children: total }),
4340
+ /* @__PURE__ */ jsx7("div", { style: panelStyles3.statLabel, children: "Unique Errors" })
4341
+ ] }),
4342
+ /* @__PURE__ */ jsxs7("div", { style: panelStyles3.statCard, children: [
4343
+ /* @__PURE__ */ jsx7("div", { style: panelStyles3.statValue, children: totalErrors }),
4344
+ /* @__PURE__ */ jsx7("div", { style: panelStyles3.statLabel, children: "Total Occurrences" })
4345
+ ] }),
4346
+ /* @__PURE__ */ jsxs7("div", { style: panelStyles3.statCard, children: [
4347
+ /* @__PURE__ */ jsx7("div", { style: { ...panelStyles3.statValue, color: recentCount > 0 ? "#ef4444" : "#22c55e" }, children: recentCount }),
4348
+ /* @__PURE__ */ jsx7("div", { style: panelStyles3.statLabel, children: "Last 24h" })
4349
+ ] })
4350
+ ] }),
4351
+ 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) => {
4352
+ const def = getErrorDefinition(log.errorCode);
4353
+ const recent = isRecent(log.lastSeenAt);
4354
+ return /* @__PURE__ */ jsxs7(
4355
+ "div",
4356
+ {
4357
+ style: {
4358
+ ...panelStyles3.errorCard,
4359
+ ...recent ? panelStyles3.errorCardRecent : panelStyles3.errorCardOld
4360
+ },
4361
+ "data-testid": `error-log-${log.id}`,
4362
+ children: [
4363
+ /* @__PURE__ */ jsxs7("div", { style: panelStyles3.errorHeader, children: [
4364
+ /* @__PURE__ */ jsxs7("div", { style: panelStyles3.errorLeft, children: [
4365
+ /* @__PURE__ */ jsx7("span", { style: panelStyles3.errorCode, children: log.errorCode }),
4366
+ /* @__PURE__ */ jsx7("span", { style: panelStyles3.contextBadge, children: log.context }),
4367
+ /* @__PURE__ */ jsx7("span", { style: { ...panelStyles3.contextBadge, backgroundColor: "#f3e8ff", color: "#7c3aed" }, children: log.component })
4368
+ ] }),
4369
+ /* @__PURE__ */ jsxs7(
4370
+ "span",
4371
+ {
4372
+ style: {
4373
+ ...panelStyles3.countBadge,
4374
+ ...log.count < 10 ? panelStyles3.countBadgeLow : {}
4375
+ },
4376
+ children: [
4377
+ log.count,
4378
+ "x"
4379
+ ]
4380
+ }
4381
+ )
4382
+ ] }),
4383
+ /* @__PURE__ */ jsx7("div", { style: panelStyles3.userMessage, children: def?.userMessage || log.lastMessage || "Unknown error" }),
4384
+ log.resourceId && /* @__PURE__ */ jsxs7("div", { style: panelStyles3.resourceId, children: [
4385
+ "Resource:",
4386
+ " ",
4387
+ onResourceClick ? /* @__PURE__ */ jsx7(
4388
+ "span",
4389
+ {
4390
+ style: panelStyles3.resourceLink,
4391
+ onClick: () => onResourceClick(log.resourceId, log.context),
4392
+ "data-testid": `link-resource-${log.id}`,
4393
+ children: log.resourceId
4394
+ }
4395
+ ) : log.resourceId
4396
+ ] }),
4397
+ /* @__PURE__ */ jsxs7("div", { style: panelStyles3.timestamps, children: [
4398
+ /* @__PURE__ */ jsxs7("span", { children: [
4399
+ "First: ",
4400
+ formatRelativeTime(log.firstSeenAt)
4401
+ ] }),
4402
+ /* @__PURE__ */ jsxs7("span", { children: [
4403
+ "Last: ",
4404
+ formatRelativeTime(log.lastSeenAt)
4405
+ ] })
4406
+ ] }),
4407
+ /* @__PURE__ */ jsx7(
4408
+ "button",
4409
+ {
4410
+ style: panelStyles3.dismissButton,
4411
+ onClick: () => showDismissed ? handleUndismiss(log.id) : handleDismiss(log.id),
4412
+ "data-testid": `button-dismiss-${log.id}`,
4413
+ children: showDismissed ? "Restore" : "Dismiss"
4414
+ }
4415
+ )
4416
+ ]
4417
+ },
4418
+ log.id
4419
+ );
4420
+ }) }),
4421
+ totalPages > 1 && /* @__PURE__ */ jsxs7("div", { style: panelStyles3.pagination, children: [
4422
+ /* @__PURE__ */ jsx7(
4423
+ "button",
4424
+ {
4425
+ style: {
4426
+ ...panelStyles3.pageButton,
4427
+ ...page <= 1 ? panelStyles3.pageButtonDisabled : {}
4428
+ },
4429
+ onClick: () => setPage((p) => Math.max(1, p - 1)),
4430
+ disabled: page <= 1,
4431
+ "data-testid": "button-prev-page",
4432
+ children: "Previous"
4433
+ }
4434
+ ),
4435
+ /* @__PURE__ */ jsxs7("span", { style: { padding: "8px 12px", color: "#6b7280" }, children: [
4436
+ "Page ",
4437
+ page,
4438
+ " of ",
4439
+ totalPages
4440
+ ] }),
4441
+ /* @__PURE__ */ jsx7(
4442
+ "button",
4443
+ {
4444
+ style: {
4445
+ ...panelStyles3.pageButton,
4446
+ ...page >= totalPages ? panelStyles3.pageButtonDisabled : {}
4447
+ },
4448
+ onClick: () => setPage((p) => Math.min(totalPages, p + 1)),
4449
+ disabled: page >= totalPages,
4450
+ "data-testid": "button-next-page",
4451
+ children: "Next"
4452
+ }
4453
+ )
4454
+ ] })
4455
+ ] });
4456
+ }
3393
4457
  export {
3394
4458
  AttemptViewer,
4459
+ ERROR_DEFINITIONS,
4460
+ ErrorLogsPanel,
4461
+ ErrorTypesPanel,
4462
+ MaintenanceScreen,
3395
4463
  QuizApiClient,
3396
4464
  QuizPlayer,
3397
4465
  TextToSpeech,
3398
4466
  calculateScore,
3399
4467
  checkAnswer,
3400
4468
  createAnswerDetail,
3401
- formatTime
4469
+ formatTime,
4470
+ getErrorFromHttpStatus,
4471
+ getErrorFromMessage
3402
4472
  };
3403
4473
  //# sourceMappingURL=index.mjs.map