@schoolio/player 1.4.1 → 1.4.2

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.js CHANGED
@@ -113,6 +113,12 @@ var QuizApiClient = class {
113
113
  `/api/external/question-chat/${questionId}/${childId}`
114
114
  );
115
115
  }
116
+ async getChatsByAttempt(attemptId) {
117
+ return this.request(
118
+ "GET",
119
+ `/api/external/quiz-attempts/${attemptId}/chats`
120
+ );
121
+ }
116
122
  async getTextToSpeech(text, voice = "nova") {
117
123
  const headers = {
118
124
  "Content-Type": "application/json"
@@ -695,7 +701,8 @@ function QuestionChatPanel({
695
701
  childId,
696
702
  parentId,
697
703
  lessonId,
698
- courseId
704
+ courseId,
705
+ answerResult
699
706
  }) {
700
707
  const [messages, setMessages] = (0, import_react2.useState)([]);
701
708
  const [inputValue, setInputValue] = (0, import_react2.useState)("");
@@ -705,6 +712,7 @@ function QuestionChatPanel({
705
712
  const [isListening, setIsListening] = (0, import_react2.useState)(false);
706
713
  const [speakingIndex, setSpeakingIndex] = (0, import_react2.useState)(null);
707
714
  const [audioReadyMap, setAudioReadyMap] = (0, import_react2.useState)(/* @__PURE__ */ new Map());
715
+ const [hasOfferedHelp, setHasOfferedHelp] = (0, import_react2.useState)(false);
708
716
  const messagesContainerRef = (0, import_react2.useRef)(null);
709
717
  const messagesEndRef = (0, import_react2.useRef)(null);
710
718
  const recognitionRef = (0, import_react2.useRef)(null);
@@ -824,6 +832,7 @@ function QuestionChatPanel({
824
832
  setMessages([]);
825
833
  setChatId(null);
826
834
  setInputValue("");
835
+ setHasOfferedHelp(false);
827
836
  const loadHistory = async () => {
828
837
  try {
829
838
  const history = await apiClient.getChatHistory(question.id, childId);
@@ -838,6 +847,20 @@ function QuestionChatPanel({
838
847
  };
839
848
  loadHistory();
840
849
  }, [question.id, childId, apiClient, preCacheAudio]);
850
+ (0, import_react2.useEffect)(() => {
851
+ if (answerResult?.wasIncorrect && !hasOfferedHelp) {
852
+ setHasOfferedHelp(true);
853
+ const selectedAnswerText = answerResult.selectedAnswer || "that answer";
854
+ const helpMessage = `Looks like you chose "${selectedAnswerText}" which was incorrect. Would you like me to help explain the correct answer?`;
855
+ const assistantMessage = {
856
+ role: "assistant",
857
+ content: helpMessage,
858
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
859
+ };
860
+ setMessages((prev) => [...prev, assistantMessage]);
861
+ preCacheAudio(helpMessage);
862
+ }
863
+ }, [answerResult, hasOfferedHelp, preCacheAudio]);
841
864
  const initializeChat = async () => {
842
865
  if (chatId) return chatId;
843
866
  try {
@@ -1030,15 +1053,28 @@ var defaultStyles = {
1030
1053
  container: {
1031
1054
  fontFamily: "system-ui, -apple-system, sans-serif",
1032
1055
  width: "100%",
1056
+ height: "100%",
1033
1057
  padding: "20px",
1034
1058
  backgroundColor: "#ffffff",
1035
1059
  borderRadius: "12px",
1036
- boxSizing: "border-box"
1060
+ boxSizing: "border-box",
1061
+ display: "flex",
1062
+ flexDirection: "column"
1037
1063
  },
1038
1064
  header: {
1039
1065
  marginBottom: "20px",
1040
1066
  borderBottom: "1px solid #e5e7eb",
1041
- paddingBottom: "16px"
1067
+ paddingBottom: "16px",
1068
+ display: "flex",
1069
+ flexDirection: "column"
1070
+ },
1071
+ headerTop: {
1072
+ display: "flex",
1073
+ justifyContent: "space-between",
1074
+ alignItems: "flex-start"
1075
+ },
1076
+ headerLeft: {
1077
+ flex: 1
1042
1078
  },
1043
1079
  title: {
1044
1080
  fontSize: "24px",
@@ -1050,7 +1086,8 @@ var defaultStyles = {
1050
1086
  color: "#6b7280"
1051
1087
  },
1052
1088
  progressBar: {
1053
- width: "100%",
1089
+ width: "50%",
1090
+ maxWidth: "300px",
1054
1091
  height: "8px",
1055
1092
  backgroundColor: "#e5e7eb",
1056
1093
  borderRadius: "4px",
@@ -1165,16 +1202,21 @@ var defaultStyles = {
1165
1202
  },
1166
1203
  mainLayout: {
1167
1204
  display: "flex",
1168
- gap: "24px"
1205
+ gap: "24px",
1206
+ flex: 1,
1207
+ minHeight: 0,
1208
+ alignItems: "stretch"
1169
1209
  },
1170
1210
  quizContent: {
1171
1211
  flex: 1,
1172
- minWidth: 0
1212
+ minWidth: 0,
1213
+ overflow: "auto"
1173
1214
  },
1174
1215
  chatPanel: {
1175
1216
  width: "320px",
1176
1217
  flexShrink: 0,
1177
- height: "460px"
1218
+ display: "flex",
1219
+ flexDirection: "column"
1178
1220
  },
1179
1221
  timer: {
1180
1222
  fontSize: "14px",
@@ -1382,6 +1424,16 @@ function QuizPlayer({
1382
1424
  const apiClient = (0, import_react3.useRef)(null);
1383
1425
  const timerRef = (0, import_react3.useRef)(null);
1384
1426
  const startTimeRef = (0, import_react3.useRef)(0);
1427
+ const onCompleteRef = (0, import_react3.useRef)(onComplete);
1428
+ const onErrorRef = (0, import_react3.useRef)(onError);
1429
+ const onProgressRef = (0, import_react3.useRef)(onProgress);
1430
+ const onGenerateMoreQuestionsRef = (0, import_react3.useRef)(onGenerateMoreQuestions);
1431
+ (0, import_react3.useEffect)(() => {
1432
+ onCompleteRef.current = onComplete;
1433
+ onErrorRef.current = onError;
1434
+ onProgressRef.current = onProgress;
1435
+ onGenerateMoreQuestionsRef.current = onGenerateMoreQuestions;
1436
+ });
1385
1437
  (0, import_react3.useEffect)(() => {
1386
1438
  apiClient.current = new QuizApiClient({ baseUrl: apiBaseUrl, authToken });
1387
1439
  }, [apiBaseUrl, authToken]);
@@ -1428,11 +1480,11 @@ function QuizPlayer({
1428
1480
  const message = err instanceof Error ? err.message : "Failed to load quiz";
1429
1481
  setError(message);
1430
1482
  setIsLoading(false);
1431
- onError?.(err instanceof Error ? err : new Error(message));
1483
+ onErrorRef.current?.(err instanceof Error ? err : new Error(message));
1432
1484
  }
1433
1485
  }
1434
1486
  initialize();
1435
- }, [quizId, lessonId, assignLessonId, courseId, childId, parentId, forceNewAttempt, onError]);
1487
+ }, [quizId, lessonId, assignLessonId, courseId, childId, parentId, forceNewAttempt]);
1436
1488
  (0, import_react3.useEffect)(() => {
1437
1489
  if (timerStarted && !isCompleted && !error) {
1438
1490
  startTimeRef.current = Date.now();
@@ -1458,14 +1510,14 @@ function QuizPlayer({
1458
1510
  const totalQuestions = allQuestions.length;
1459
1511
  const maxQuestions = 50;
1460
1512
  (0, import_react3.useEffect)(() => {
1461
- if (quiz && onProgress) {
1462
- onProgress({
1513
+ if (quiz && onProgressRef.current) {
1514
+ onProgressRef.current({
1463
1515
  currentQuestion: currentQuestionIndex + 1,
1464
1516
  totalQuestions,
1465
1517
  answeredQuestions: answers.size
1466
1518
  });
1467
1519
  }
1468
- }, [currentQuestionIndex, answers.size, quiz, onProgress, totalQuestions]);
1520
+ }, [currentQuestionIndex, answers.size, quiz, totalQuestions]);
1469
1521
  const currentQuestion = allQuestions[currentQuestionIndex];
1470
1522
  const handleAnswerChange = (0, import_react3.useCallback)((value) => {
1471
1523
  if (!currentQuestion) return;
@@ -1510,7 +1562,7 @@ function QuizPlayer({
1510
1562
  if (totalQuestions >= maxQuestions) return;
1511
1563
  setIsGeneratingExtra(true);
1512
1564
  try {
1513
- const result2 = await onGenerateMoreQuestions(attempt.id, totalQuestions);
1565
+ const result2 = await onGenerateMoreQuestionsRef.current(attempt.id, totalQuestions);
1514
1566
  if (result2.extraQuestions && result2.extraQuestions.length > 0) {
1515
1567
  const slotsAvailable = maxQuestions - totalQuestions;
1516
1568
  const questionsToAppend = result2.extraQuestions.slice(0, slotsAvailable);
@@ -1523,11 +1575,11 @@ function QuizPlayer({
1523
1575
  }
1524
1576
  } catch (err) {
1525
1577
  console.error("Failed to generate extra questions:", err);
1526
- onError?.(err instanceof Error ? err : new Error("Failed to generate extra questions"));
1578
+ onErrorRef.current?.(err instanceof Error ? err : new Error("Failed to generate extra questions"));
1527
1579
  } finally {
1528
1580
  setIsGeneratingExtra(false);
1529
1581
  }
1530
- }, [attempt, onGenerateMoreQuestions, isGeneratingExtra, totalQuestions, maxQuestions, onError]);
1582
+ }, [attempt, isGeneratingExtra, totalQuestions, maxQuestions]);
1531
1583
  const handleSubmit = (0, import_react3.useCallback)(async () => {
1532
1584
  if (!quiz || !attempt || !apiClient.current) return;
1533
1585
  setIsSubmitting(true);
@@ -1566,15 +1618,15 @@ function QuizPlayer({
1566
1618
  if (timerRef.current) {
1567
1619
  clearInterval(timerRef.current);
1568
1620
  }
1569
- onComplete?.(quizResult);
1621
+ onCompleteRef.current?.(quizResult);
1570
1622
  } catch (err) {
1571
1623
  const message = err instanceof Error ? err.message : "Failed to submit quiz";
1572
1624
  setError(message);
1573
- onError?.(err instanceof Error ? err : new Error(message));
1625
+ onErrorRef.current?.(err instanceof Error ? err : new Error(message));
1574
1626
  } finally {
1575
1627
  setIsSubmitting(false);
1576
1628
  }
1577
- }, [quiz, attempt, currentQuestion, answers, answersDetail, onComplete, onError, totalQuestions, timerStarted, elapsedSeconds]);
1629
+ }, [quiz, attempt, currentQuestion, answers, answersDetail, totalQuestions, timerStarted, elapsedSeconds]);
1578
1630
  const isExtraQuestion = currentQuestion && extraQuestions.some((q) => q.id === currentQuestion.id);
1579
1631
  const handleSkipQuestion = (0, import_react3.useCallback)(async (reason, comment) => {
1580
1632
  if (!currentQuestion || !apiClient.current || !attempt) return;
@@ -1610,7 +1662,7 @@ function QuizPlayer({
1610
1662
  timeSpentSeconds: elapsedSeconds
1611
1663
  };
1612
1664
  setResult(quizResult);
1613
- onComplete?.(quizResult);
1665
+ onCompleteRef.current?.(quizResult);
1614
1666
  } else if (currentQuestionIndex >= newTotalQuestions) {
1615
1667
  setCurrentQuestionIndex(newTotalQuestions - 1);
1616
1668
  }
@@ -1622,7 +1674,7 @@ function QuizPlayer({
1622
1674
  } finally {
1623
1675
  setIsSkipping(false);
1624
1676
  }
1625
- }, [currentQuestion, apiClient, attempt, quiz, childId, parentId, lessonId, courseId, assignLessonId, skippedQuestionIds, extraQuestions, currentQuestionIndex, elapsedSeconds, onComplete]);
1677
+ }, [currentQuestion, apiClient, attempt, quiz, childId, parentId, lessonId, courseId, assignLessonId, skippedQuestionIds, extraQuestions, currentQuestionIndex, elapsedSeconds]);
1626
1678
  const handleReportQuestion = (0, import_react3.useCallback)(async (comment) => {
1627
1679
  if (!currentQuestion || !apiClient.current || !attempt || !comment.trim()) return;
1628
1680
  setIsReporting(true);
@@ -1992,533 +2044,537 @@ function QuizPlayer({
1992
2044
  const remainingSlots = maxQuestions - totalQuestions;
1993
2045
  const questionsToAdd = Math.min(5, remainingSlots);
1994
2046
  const canAddMore = onGenerateMoreQuestions && remainingSlots > 0;
1995
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className, style: defaultStyles.container, children: [
1996
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: defaultStyles.header, children: [
1997
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: defaultStyles.title, children: quiz.title }),
1998
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: defaultStyles.progress, children: [
1999
- "Question ",
2000
- currentQuestionIndex + 1,
2001
- " of ",
2002
- totalQuestions
2047
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className, style: defaultStyles.container, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: defaultStyles.mainLayout, children: [
2048
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: defaultStyles.quizContent, children: [
2049
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: defaultStyles.header, children: [
2050
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: defaultStyles.title, children: quiz.title }),
2051
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: defaultStyles.progress, children: [
2052
+ "Question ",
2053
+ currentQuestionIndex + 1,
2054
+ " of ",
2055
+ totalQuestions
2056
+ ] }),
2057
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: defaultStyles.progressBar, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { ...defaultStyles.progressFill, width: `${progressPercent}%` } }) })
2003
2058
  ] }),
2004
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: defaultStyles.progressBar, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { ...defaultStyles.progressFill, width: `${progressPercent}%` } }) })
2005
- ] }),
2006
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: defaultStyles.mainLayout, children: [
2007
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: defaultStyles.quizContent, children: [
2008
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { ...defaultStyles.question, position: "relative", paddingBottom: "40px" }, children: [
2009
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: defaultStyles.questionText, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TextToSpeech, { text: currentQuestion.question, inline: true, size: "md" }) }),
2010
- isExtraQuestion && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
2011
- "button",
2059
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { ...defaultStyles.question, position: "relative", paddingBottom: "40px" }, children: [
2060
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: defaultStyles.questionText, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TextToSpeech, { text: currentQuestion.question, inline: true, size: "md" }) }),
2061
+ isExtraQuestion && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
2062
+ "button",
2063
+ {
2064
+ onClick: () => setShowSkipModal(true),
2065
+ title: "Skip question",
2066
+ style: {
2067
+ position: "absolute",
2068
+ bottom: "8px",
2069
+ left: "0",
2070
+ background: "transparent",
2071
+ border: "none",
2072
+ cursor: "pointer",
2073
+ padding: "6px 10px",
2074
+ borderRadius: "6px",
2075
+ color: "#9ca3af",
2076
+ display: "flex",
2077
+ alignItems: "center",
2078
+ justifyContent: "center",
2079
+ gap: "4px",
2080
+ fontSize: "12px",
2081
+ opacity: 0.6,
2082
+ transition: "opacity 0.2s, color 0.2s"
2083
+ },
2084
+ onMouseEnter: (e) => {
2085
+ e.currentTarget.style.opacity = "1";
2086
+ e.currentTarget.style.color = "#6b7280";
2087
+ },
2088
+ onMouseLeave: (e) => {
2089
+ e.currentTarget.style.opacity = "0.6";
2090
+ e.currentTarget.style.color = "#9ca3af";
2091
+ },
2092
+ "data-testid": "button-skip-question",
2093
+ children: [
2094
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2095
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("polygon", { points: "5 4 15 12 5 20 5 4" }),
2096
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "19", y1: "5", x2: "19", y2: "19" })
2097
+ ] }),
2098
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "Skip" })
2099
+ ]
2100
+ }
2101
+ ),
2102
+ !isExtraQuestion && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
2103
+ "button",
2104
+ {
2105
+ onClick: () => setShowReportModal(true),
2106
+ title: "Report an issue with this question",
2107
+ style: {
2108
+ position: "absolute",
2109
+ bottom: "8px",
2110
+ left: "0",
2111
+ background: "transparent",
2112
+ border: "none",
2113
+ cursor: "pointer",
2114
+ padding: "6px 10px",
2115
+ borderRadius: "6px",
2116
+ color: "#9ca3af",
2117
+ display: "flex",
2118
+ alignItems: "center",
2119
+ justifyContent: "center",
2120
+ gap: "4px",
2121
+ fontSize: "12px",
2122
+ opacity: 0.6,
2123
+ transition: "opacity 0.2s, color 0.2s"
2124
+ },
2125
+ onMouseEnter: (e) => {
2126
+ e.currentTarget.style.opacity = "1";
2127
+ e.currentTarget.style.color = "#ef4444";
2128
+ },
2129
+ onMouseLeave: (e) => {
2130
+ e.currentTarget.style.opacity = "0.6";
2131
+ e.currentTarget.style.color = "#9ca3af";
2132
+ },
2133
+ "data-testid": "button-report-question",
2134
+ children: [
2135
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2136
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("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" }),
2137
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "4", y1: "22", x2: "4", y2: "15" })
2138
+ ] }),
2139
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "Report" })
2140
+ ]
2141
+ }
2142
+ ),
2143
+ (currentQuestion.type === "single" || currentQuestion.type === "true-false") && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: defaultStyles.options, children: currentQuestion.options?.map((option, idx) => {
2144
+ const isSelected = selectedAnswer === option;
2145
+ const isCorrectOption = currentQuestion.correctAnswer === option;
2146
+ let optionStyle = { ...defaultStyles.option };
2147
+ if (showFeedback) {
2148
+ if (isCorrectOption) {
2149
+ optionStyle = { ...optionStyle, ...defaultStyles.optionCorrect };
2150
+ } else if (isSelected && !isCorrectOption) {
2151
+ optionStyle = { ...optionStyle, ...defaultStyles.optionIncorrect };
2152
+ }
2153
+ } else if (isSelected) {
2154
+ optionStyle = { ...optionStyle, ...defaultStyles.optionSelected };
2155
+ }
2156
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
2157
+ "div",
2012
2158
  {
2013
- onClick: () => setShowSkipModal(true),
2014
- title: "Skip question",
2015
2159
  style: {
2016
- position: "absolute",
2017
- bottom: "8px",
2018
- left: "0",
2019
- background: "transparent",
2020
- border: "none",
2021
- cursor: "pointer",
2022
- padding: "6px 10px",
2023
- borderRadius: "6px",
2024
- color: "#9ca3af",
2160
+ ...optionStyle,
2161
+ cursor: showFeedback ? "default" : "pointer",
2025
2162
  display: "flex",
2026
2163
  alignItems: "center",
2027
- justifyContent: "center",
2028
- gap: "4px",
2029
- fontSize: "12px",
2030
- opacity: 0.6,
2031
- transition: "opacity 0.2s, color 0.2s"
2032
- },
2033
- onMouseEnter: (e) => {
2034
- e.currentTarget.style.opacity = "1";
2035
- e.currentTarget.style.color = "#6b7280";
2164
+ gap: "8px"
2036
2165
  },
2037
- onMouseLeave: (e) => {
2038
- e.currentTarget.style.opacity = "0.6";
2039
- e.currentTarget.style.color = "#9ca3af";
2040
- },
2041
- "data-testid": "button-skip-question",
2166
+ onClick: () => !showFeedback && handleAnswerChange(option),
2042
2167
  children: [
2043
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2044
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("polygon", { points: "5 4 15 12 5 20 5 4" }),
2045
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "19", y1: "5", x2: "19", y2: "19" })
2046
- ] }),
2047
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "Skip" })
2168
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TextToSpeech, { text: option, size: "sm" }) }),
2169
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { flex: 1 }, children: option })
2048
2170
  ]
2171
+ },
2172
+ idx
2173
+ );
2174
+ }) }),
2175
+ currentQuestion.type === "multiple" && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: defaultStyles.options, children: currentQuestion.options?.map((option, idx) => {
2176
+ const selected = Array.isArray(selectedAnswer) && selectedAnswer.includes(option);
2177
+ const correctAnswers = Array.isArray(currentQuestion.correctAnswer) ? currentQuestion.correctAnswer : currentQuestion.correctAnswer ? [currentQuestion.correctAnswer] : [];
2178
+ const isCorrectOption = correctAnswers.includes(option);
2179
+ let optionStyle = { ...defaultStyles.option };
2180
+ if (showFeedback) {
2181
+ if (isCorrectOption) {
2182
+ optionStyle = { ...optionStyle, ...defaultStyles.optionCorrect };
2183
+ } else if (selected && !isCorrectOption) {
2184
+ optionStyle = { ...optionStyle, ...defaultStyles.optionIncorrect };
2049
2185
  }
2050
- ),
2051
- !isExtraQuestion && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
2052
- "button",
2186
+ } else if (selected) {
2187
+ optionStyle = { ...optionStyle, ...defaultStyles.optionSelected };
2188
+ }
2189
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
2190
+ "div",
2053
2191
  {
2054
- onClick: () => setShowReportModal(true),
2055
- title: "Report an issue with this question",
2056
2192
  style: {
2057
- position: "absolute",
2058
- bottom: "8px",
2059
- left: "0",
2060
- background: "transparent",
2061
- border: "none",
2062
- cursor: "pointer",
2063
- padding: "6px 10px",
2064
- borderRadius: "6px",
2065
- color: "#9ca3af",
2193
+ ...optionStyle,
2194
+ cursor: showFeedback ? "default" : "pointer",
2066
2195
  display: "flex",
2067
2196
  alignItems: "center",
2068
- justifyContent: "center",
2069
- gap: "4px",
2070
- fontSize: "12px",
2071
- opacity: 0.6,
2072
- transition: "opacity 0.2s, color 0.2s"
2197
+ gap: "8px"
2073
2198
  },
2074
- onMouseEnter: (e) => {
2075
- e.currentTarget.style.opacity = "1";
2076
- e.currentTarget.style.color = "#ef4444";
2077
- },
2078
- onMouseLeave: (e) => {
2079
- e.currentTarget.style.opacity = "0.6";
2080
- e.currentTarget.style.color = "#9ca3af";
2199
+ onClick: () => {
2200
+ if (showFeedback) return;
2201
+ const current = Array.isArray(selectedAnswer) ? selectedAnswer : [];
2202
+ if (selected) {
2203
+ handleAnswerChange(current.filter((o) => o !== option));
2204
+ } else {
2205
+ handleAnswerChange([...current, option]);
2206
+ }
2081
2207
  },
2082
- "data-testid": "button-report-question",
2083
2208
  children: [
2084
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2085
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("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" }),
2086
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "4", y1: "22", x2: "4", y2: "15" })
2087
- ] }),
2088
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "Report" })
2209
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TextToSpeech, { text: option, size: "sm" }) }),
2210
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { flex: 1 }, children: option })
2089
2211
  ]
2212
+ },
2213
+ idx
2214
+ );
2215
+ }) }),
2216
+ (currentQuestion.type === "free" || currentQuestion.type === "essay") && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2217
+ "textarea",
2218
+ {
2219
+ style: { ...defaultStyles.input, minHeight: currentQuestion.type === "essay" ? "150px" : "60px" },
2220
+ value: selectedAnswer || "",
2221
+ onChange: (e) => handleAnswerChange(e.target.value),
2222
+ placeholder: "Type your answer here...",
2223
+ disabled: showFeedback
2224
+ }
2225
+ ),
2226
+ currentQuestion.type === "fill" && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: defaultStyles.options, children: currentQuestion.blanks?.map((_, idx) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2227
+ "input",
2228
+ {
2229
+ style: defaultStyles.input,
2230
+ value: (Array.isArray(selectedAnswer) ? selectedAnswer[idx] : "") || "",
2231
+ onChange: (e) => {
2232
+ const current = Array.isArray(selectedAnswer) ? [...selectedAnswer] : [];
2233
+ current[idx] = e.target.value;
2234
+ handleAnswerChange(current);
2235
+ },
2236
+ placeholder: `Blank ${idx + 1}`,
2237
+ disabled: showFeedback
2238
+ },
2239
+ idx
2240
+ )) }),
2241
+ showFeedback && currentAnswerDetail && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: {
2242
+ ...defaultStyles.feedback,
2243
+ ...currentAnswerDetail.isCorrect ? defaultStyles.feedbackCorrect : defaultStyles.feedbackIncorrect
2244
+ }, children: [
2245
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: {
2246
+ ...defaultStyles.feedbackTitle,
2247
+ ...currentAnswerDetail.isCorrect ? defaultStyles.feedbackTitleCorrect : defaultStyles.feedbackTitleIncorrect
2248
+ }, children: currentAnswerDetail.isCorrect ? "\u2713 Correct!" : "\u2717 Incorrect" }),
2249
+ currentQuestion.explanation && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: defaultStyles.feedbackExplanation, children: currentQuestion.explanation })
2250
+ ] })
2251
+ ] }),
2252
+ showSkipModal && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: {
2253
+ position: "fixed",
2254
+ top: 0,
2255
+ left: 0,
2256
+ right: 0,
2257
+ bottom: 0,
2258
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
2259
+ display: "flex",
2260
+ alignItems: "center",
2261
+ justifyContent: "center",
2262
+ zIndex: 1e3
2263
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: {
2264
+ backgroundColor: "#ffffff",
2265
+ borderRadius: "12px",
2266
+ padding: "24px",
2267
+ maxWidth: "400px",
2268
+ width: "90%",
2269
+ boxShadow: "0 20px 40px rgba(0, 0, 0, 0.2)"
2270
+ }, children: [
2271
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { style: { margin: "0 0 8px 0", fontSize: "18px", fontWeight: "600", color: "#1f2937" }, children: "Skip Question" }),
2272
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { style: { margin: "0 0 16px 0", fontSize: "14px", color: "#6b7280" }, children: "Help us improve by telling us why you're skipping this question." }),
2273
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "8px", marginBottom: "16px" }, children: [
2274
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2275
+ "button",
2276
+ {
2277
+ onClick: () => setSelectedSkipReason("question_issue"),
2278
+ disabled: isSkipping,
2279
+ style: {
2280
+ padding: "12px 16px",
2281
+ borderRadius: "8px",
2282
+ border: selectedSkipReason === "question_issue" ? "2px solid #8b5cf6" : "1px solid #e5e7eb",
2283
+ backgroundColor: selectedSkipReason === "question_issue" ? "#f5f3ff" : "#f9fafb",
2284
+ cursor: isSkipping ? "not-allowed" : "pointer",
2285
+ fontSize: "14px",
2286
+ fontWeight: "500",
2287
+ color: "#374151",
2288
+ textAlign: "left",
2289
+ opacity: isSkipping ? 0.6 : 1
2290
+ },
2291
+ "data-testid": "button-skip-reason-issue",
2292
+ children: "Question has an issue"
2090
2293
  }
2091
2294
  ),
2092
- (currentQuestion.type === "single" || currentQuestion.type === "true-false") && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: defaultStyles.options, children: currentQuestion.options?.map((option, idx) => {
2093
- const isSelected = selectedAnswer === option;
2094
- const isCorrectOption = currentQuestion.correctAnswer === option;
2095
- let optionStyle = { ...defaultStyles.option };
2096
- if (showFeedback) {
2097
- if (isCorrectOption) {
2098
- optionStyle = { ...optionStyle, ...defaultStyles.optionCorrect };
2099
- } else if (isSelected && !isCorrectOption) {
2100
- optionStyle = { ...optionStyle, ...defaultStyles.optionIncorrect };
2101
- }
2102
- } else if (isSelected) {
2103
- optionStyle = { ...optionStyle, ...defaultStyles.optionSelected };
2104
- }
2105
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
2106
- "div",
2107
- {
2108
- style: {
2109
- ...optionStyle,
2110
- cursor: showFeedback ? "default" : "pointer",
2111
- display: "flex",
2112
- alignItems: "center",
2113
- gap: "8px"
2114
- },
2115
- onClick: () => !showFeedback && handleAnswerChange(option),
2116
- children: [
2117
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TextToSpeech, { text: option, size: "sm" }) }),
2118
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { flex: 1 }, children: option })
2119
- ]
2295
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2296
+ "button",
2297
+ {
2298
+ onClick: () => setSelectedSkipReason("dont_know"),
2299
+ disabled: isSkipping,
2300
+ style: {
2301
+ padding: "12px 16px",
2302
+ borderRadius: "8px",
2303
+ border: selectedSkipReason === "dont_know" ? "2px solid #8b5cf6" : "1px solid #e5e7eb",
2304
+ backgroundColor: selectedSkipReason === "dont_know" ? "#f5f3ff" : "#f9fafb",
2305
+ cursor: isSkipping ? "not-allowed" : "pointer",
2306
+ fontSize: "14px",
2307
+ fontWeight: "500",
2308
+ color: "#374151",
2309
+ textAlign: "left",
2310
+ opacity: isSkipping ? 0.6 : 1
2120
2311
  },
2121
- idx
2122
- );
2123
- }) }),
2124
- currentQuestion.type === "multiple" && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: defaultStyles.options, children: currentQuestion.options?.map((option, idx) => {
2125
- const selected = Array.isArray(selectedAnswer) && selectedAnswer.includes(option);
2126
- const correctAnswers = Array.isArray(currentQuestion.correctAnswer) ? currentQuestion.correctAnswer : currentQuestion.correctAnswer ? [currentQuestion.correctAnswer] : [];
2127
- const isCorrectOption = correctAnswers.includes(option);
2128
- let optionStyle = { ...defaultStyles.option };
2129
- if (showFeedback) {
2130
- if (isCorrectOption) {
2131
- optionStyle = { ...optionStyle, ...defaultStyles.optionCorrect };
2132
- } else if (selected && !isCorrectOption) {
2133
- optionStyle = { ...optionStyle, ...defaultStyles.optionIncorrect };
2134
- }
2135
- } else if (selected) {
2136
- optionStyle = { ...optionStyle, ...defaultStyles.optionSelected };
2312
+ "data-testid": "button-skip-reason-dont-know",
2313
+ children: "I don't know the answer"
2137
2314
  }
2138
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
2139
- "div",
2140
- {
2141
- style: {
2142
- ...optionStyle,
2143
- cursor: showFeedback ? "default" : "pointer",
2144
- display: "flex",
2145
- alignItems: "center",
2146
- gap: "8px"
2147
- },
2148
- onClick: () => {
2149
- if (showFeedback) return;
2150
- const current = Array.isArray(selectedAnswer) ? selectedAnswer : [];
2151
- if (selected) {
2152
- handleAnswerChange(current.filter((o) => o !== option));
2153
- } else {
2154
- handleAnswerChange([...current, option]);
2155
- }
2156
- },
2157
- children: [
2158
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TextToSpeech, { text: option, size: "sm" }) }),
2159
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { flex: 1 }, children: option })
2160
- ]
2161
- },
2162
- idx
2163
- );
2164
- }) }),
2165
- (currentQuestion.type === "free" || currentQuestion.type === "essay") && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2315
+ )
2316
+ ] }),
2317
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { marginBottom: "16px" }, children: [
2318
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("label", { style: { display: "block", fontSize: "13px", fontWeight: "500", color: "#374151", marginBottom: "6px" }, children: "Additional details (optional)" }),
2319
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2166
2320
  "textarea",
2167
2321
  {
2168
- style: { ...defaultStyles.input, minHeight: currentQuestion.type === "essay" ? "150px" : "60px" },
2169
- value: selectedAnswer || "",
2170
- onChange: (e) => handleAnswerChange(e.target.value),
2171
- placeholder: "Type your answer here...",
2172
- disabled: showFeedback
2322
+ value: skipComment,
2323
+ onChange: (e) => setSkipComment(e.target.value.slice(0, 200)),
2324
+ placeholder: "Tell us more about the issue...",
2325
+ disabled: isSkipping,
2326
+ style: {
2327
+ width: "100%",
2328
+ minHeight: "80px",
2329
+ padding: "10px 12px",
2330
+ borderRadius: "8px",
2331
+ border: "1px solid #e5e7eb",
2332
+ fontSize: "14px",
2333
+ resize: "vertical",
2334
+ fontFamily: "inherit",
2335
+ boxSizing: "border-box"
2336
+ },
2337
+ "data-testid": "input-skip-comment"
2173
2338
  }
2174
2339
  ),
2175
- currentQuestion.type === "fill" && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: defaultStyles.options, children: currentQuestion.blanks?.map((_, idx) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2176
- "input",
2340
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { fontSize: "12px", color: "#9ca3af", marginTop: "4px", textAlign: "right" }, children: [
2341
+ skipComment.length,
2342
+ "/200"
2343
+ ] })
2344
+ ] }),
2345
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { display: "flex", gap: "10px" }, children: [
2346
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2347
+ "button",
2177
2348
  {
2178
- style: defaultStyles.input,
2179
- value: (Array.isArray(selectedAnswer) ? selectedAnswer[idx] : "") || "",
2180
- onChange: (e) => {
2181
- const current = Array.isArray(selectedAnswer) ? [...selectedAnswer] : [];
2182
- current[idx] = e.target.value;
2183
- handleAnswerChange(current);
2349
+ onClick: () => {
2350
+ setShowSkipModal(false);
2351
+ setSkipComment("");
2352
+ setSelectedSkipReason(null);
2184
2353
  },
2185
- placeholder: `Blank ${idx + 1}`,
2186
- disabled: showFeedback
2187
- },
2188
- idx
2189
- )) }),
2190
- showFeedback && currentAnswerDetail && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: {
2191
- ...defaultStyles.feedback,
2192
- ...currentAnswerDetail.isCorrect ? defaultStyles.feedbackCorrect : defaultStyles.feedbackIncorrect
2193
- }, children: [
2194
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: {
2195
- ...defaultStyles.feedbackTitle,
2196
- ...currentAnswerDetail.isCorrect ? defaultStyles.feedbackTitleCorrect : defaultStyles.feedbackTitleIncorrect
2197
- }, children: currentAnswerDetail.isCorrect ? "\u2713 Correct!" : "\u2717 Incorrect" }),
2198
- currentQuestion.explanation && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: defaultStyles.feedbackExplanation, children: currentQuestion.explanation })
2354
+ style: {
2355
+ flex: 1,
2356
+ padding: "10px 16px",
2357
+ borderRadius: "8px",
2358
+ border: "1px solid #e5e7eb",
2359
+ backgroundColor: "#ffffff",
2360
+ cursor: "pointer",
2361
+ fontSize: "14px",
2362
+ fontWeight: "500",
2363
+ color: "#6b7280"
2364
+ },
2365
+ "data-testid": "button-skip-cancel",
2366
+ children: "Cancel"
2367
+ }
2368
+ ),
2369
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2370
+ "button",
2371
+ {
2372
+ onClick: () => selectedSkipReason && handleSkipQuestion(selectedSkipReason, skipComment),
2373
+ disabled: isSkipping || !selectedSkipReason,
2374
+ style: {
2375
+ flex: 1,
2376
+ padding: "10px 16px",
2377
+ borderRadius: "8px",
2378
+ border: "none",
2379
+ backgroundColor: selectedSkipReason ? "#8b5cf6" : "#d1d5db",
2380
+ cursor: isSkipping || !selectedSkipReason ? "not-allowed" : "pointer",
2381
+ fontSize: "14px",
2382
+ fontWeight: "500",
2383
+ color: "#ffffff",
2384
+ opacity: isSkipping ? 0.6 : 1
2385
+ },
2386
+ "data-testid": "button-skip-submit",
2387
+ children: isSkipping ? "Skipping..." : "Skip Question"
2388
+ }
2389
+ )
2390
+ ] })
2391
+ ] }) }),
2392
+ showReportModal && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: {
2393
+ position: "fixed",
2394
+ top: 0,
2395
+ left: 0,
2396
+ right: 0,
2397
+ bottom: 0,
2398
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
2399
+ display: "flex",
2400
+ alignItems: "center",
2401
+ justifyContent: "center",
2402
+ zIndex: 1e3
2403
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: {
2404
+ backgroundColor: "#ffffff",
2405
+ borderRadius: "12px",
2406
+ padding: "24px",
2407
+ maxWidth: "400px",
2408
+ width: "90%",
2409
+ boxShadow: "0 20px 40px rgba(0, 0, 0, 0.2)"
2410
+ }, children: [
2411
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { style: { margin: "0 0 8px 0", fontSize: "18px", fontWeight: "600", color: "#1f2937" }, children: "Report Question" }),
2412
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { style: { margin: "0 0 16px 0", fontSize: "14px", color: "#6b7280" }, children: "What's wrong with this question?" }),
2413
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { marginBottom: "16px" }, children: [
2414
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2415
+ "textarea",
2416
+ {
2417
+ value: reportComment,
2418
+ onChange: (e) => setReportComment(e.target.value.slice(0, 300)),
2419
+ placeholder: "Describe the issue with this question...",
2420
+ disabled: isReporting,
2421
+ style: {
2422
+ width: "100%",
2423
+ minHeight: "120px",
2424
+ padding: "10px 12px",
2425
+ borderRadius: "8px",
2426
+ border: "1px solid #e5e7eb",
2427
+ fontSize: "14px",
2428
+ resize: "vertical",
2429
+ fontFamily: "inherit",
2430
+ boxSizing: "border-box"
2431
+ },
2432
+ "data-testid": "input-report-comment"
2433
+ }
2434
+ ),
2435
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { fontSize: "12px", color: "#9ca3af", marginTop: "4px", textAlign: "right" }, children: [
2436
+ reportComment.length,
2437
+ "/300"
2199
2438
  ] })
2200
2439
  ] }),
2201
- showSkipModal && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: {
2202
- position: "fixed",
2203
- top: 0,
2204
- left: 0,
2205
- right: 0,
2206
- bottom: 0,
2207
- backgroundColor: "rgba(0, 0, 0, 0.5)",
2208
- display: "flex",
2209
- alignItems: "center",
2210
- justifyContent: "center",
2211
- zIndex: 1e3
2212
- }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: {
2213
- backgroundColor: "#ffffff",
2214
- borderRadius: "12px",
2215
- padding: "24px",
2216
- maxWidth: "400px",
2217
- width: "90%",
2218
- boxShadow: "0 20px 40px rgba(0, 0, 0, 0.2)"
2219
- }, children: [
2220
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { style: { margin: "0 0 8px 0", fontSize: "18px", fontWeight: "600", color: "#1f2937" }, children: "Skip Question" }),
2221
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { style: { margin: "0 0 16px 0", fontSize: "14px", color: "#6b7280" }, children: "Help us improve by telling us why you're skipping this question." }),
2222
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "8px", marginBottom: "16px" }, children: [
2223
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2224
- "button",
2225
- {
2226
- onClick: () => setSelectedSkipReason("question_issue"),
2227
- disabled: isSkipping,
2228
- style: {
2229
- padding: "12px 16px",
2230
- borderRadius: "8px",
2231
- border: selectedSkipReason === "question_issue" ? "2px solid #8b5cf6" : "1px solid #e5e7eb",
2232
- backgroundColor: selectedSkipReason === "question_issue" ? "#f5f3ff" : "#f9fafb",
2233
- cursor: isSkipping ? "not-allowed" : "pointer",
2234
- fontSize: "14px",
2235
- fontWeight: "500",
2236
- color: "#374151",
2237
- textAlign: "left",
2238
- opacity: isSkipping ? 0.6 : 1
2239
- },
2240
- "data-testid": "button-skip-reason-issue",
2241
- children: "Question has an issue"
2242
- }
2243
- ),
2244
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2245
- "button",
2246
- {
2247
- onClick: () => setSelectedSkipReason("dont_know"),
2248
- disabled: isSkipping,
2249
- style: {
2250
- padding: "12px 16px",
2251
- borderRadius: "8px",
2252
- border: selectedSkipReason === "dont_know" ? "2px solid #8b5cf6" : "1px solid #e5e7eb",
2253
- backgroundColor: selectedSkipReason === "dont_know" ? "#f5f3ff" : "#f9fafb",
2254
- cursor: isSkipping ? "not-allowed" : "pointer",
2255
- fontSize: "14px",
2256
- fontWeight: "500",
2257
- color: "#374151",
2258
- textAlign: "left",
2259
- opacity: isSkipping ? 0.6 : 1
2260
- },
2261
- "data-testid": "button-skip-reason-dont-know",
2262
- children: "I don't know the answer"
2263
- }
2264
- )
2265
- ] }),
2266
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { marginBottom: "16px" }, children: [
2267
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("label", { style: { display: "block", fontSize: "13px", fontWeight: "500", color: "#374151", marginBottom: "6px" }, children: "Additional details (optional)" }),
2268
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2269
- "textarea",
2270
- {
2271
- value: skipComment,
2272
- onChange: (e) => setSkipComment(e.target.value.slice(0, 200)),
2273
- placeholder: "Tell us more about the issue...",
2274
- disabled: isSkipping,
2275
- style: {
2276
- width: "100%",
2277
- minHeight: "80px",
2278
- padding: "10px 12px",
2279
- borderRadius: "8px",
2280
- border: "1px solid #e5e7eb",
2281
- fontSize: "14px",
2282
- resize: "vertical",
2283
- fontFamily: "inherit",
2284
- boxSizing: "border-box"
2285
- },
2286
- "data-testid": "input-skip-comment"
2287
- }
2288
- ),
2289
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { fontSize: "12px", color: "#9ca3af", marginTop: "4px", textAlign: "right" }, children: [
2290
- skipComment.length,
2291
- "/200"
2292
- ] })
2293
- ] }),
2294
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { display: "flex", gap: "10px" }, children: [
2295
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2296
- "button",
2297
- {
2298
- onClick: () => {
2299
- setShowSkipModal(false);
2300
- setSkipComment("");
2301
- setSelectedSkipReason(null);
2302
- },
2303
- style: {
2304
- flex: 1,
2305
- padding: "10px 16px",
2306
- borderRadius: "8px",
2307
- border: "1px solid #e5e7eb",
2308
- backgroundColor: "#ffffff",
2309
- cursor: "pointer",
2310
- fontSize: "14px",
2311
- fontWeight: "500",
2312
- color: "#6b7280"
2313
- },
2314
- "data-testid": "button-skip-cancel",
2315
- children: "Cancel"
2316
- }
2317
- ),
2318
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2319
- "button",
2320
- {
2321
- onClick: () => selectedSkipReason && handleSkipQuestion(selectedSkipReason, skipComment),
2322
- disabled: isSkipping || !selectedSkipReason,
2323
- style: {
2324
- flex: 1,
2325
- padding: "10px 16px",
2326
- borderRadius: "8px",
2327
- border: "none",
2328
- backgroundColor: selectedSkipReason ? "#8b5cf6" : "#d1d5db",
2329
- cursor: isSkipping || !selectedSkipReason ? "not-allowed" : "pointer",
2330
- fontSize: "14px",
2331
- fontWeight: "500",
2332
- color: "#ffffff",
2333
- opacity: isSkipping ? 0.6 : 1
2334
- },
2335
- "data-testid": "button-skip-submit",
2336
- children: isSkipping ? "Skipping..." : "Skip Question"
2337
- }
2338
- )
2339
- ] })
2340
- ] }) }),
2341
- showReportModal && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: {
2342
- position: "fixed",
2343
- top: 0,
2344
- left: 0,
2345
- right: 0,
2346
- bottom: 0,
2347
- backgroundColor: "rgba(0, 0, 0, 0.5)",
2348
- display: "flex",
2349
- alignItems: "center",
2350
- justifyContent: "center",
2351
- zIndex: 1e3
2352
- }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: {
2353
- backgroundColor: "#ffffff",
2354
- borderRadius: "12px",
2355
- padding: "24px",
2356
- maxWidth: "400px",
2357
- width: "90%",
2358
- boxShadow: "0 20px 40px rgba(0, 0, 0, 0.2)"
2359
- }, children: [
2360
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { style: { margin: "0 0 8px 0", fontSize: "18px", fontWeight: "600", color: "#1f2937" }, children: "Report Question" }),
2361
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { style: { margin: "0 0 16px 0", fontSize: "14px", color: "#6b7280" }, children: "What's wrong with this question?" }),
2362
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { marginBottom: "16px" }, children: [
2363
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2364
- "textarea",
2365
- {
2366
- value: reportComment,
2367
- onChange: (e) => setReportComment(e.target.value.slice(0, 300)),
2368
- placeholder: "Describe the issue with this question...",
2369
- disabled: isReporting,
2370
- style: {
2371
- width: "100%",
2372
- minHeight: "120px",
2373
- padding: "10px 12px",
2374
- borderRadius: "8px",
2375
- border: "1px solid #e5e7eb",
2376
- fontSize: "14px",
2377
- resize: "vertical",
2378
- fontFamily: "inherit",
2379
- boxSizing: "border-box"
2380
- },
2381
- "data-testid": "input-report-comment"
2382
- }
2383
- ),
2384
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { fontSize: "12px", color: "#9ca3af", marginTop: "4px", textAlign: "right" }, children: [
2385
- reportComment.length,
2386
- "/300"
2387
- ] })
2388
- ] }),
2389
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { display: "flex", gap: "10px" }, children: [
2390
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2391
- "button",
2392
- {
2393
- onClick: () => {
2394
- setShowReportModal(false);
2395
- setReportComment("");
2396
- },
2397
- style: {
2398
- flex: 1,
2399
- padding: "10px 16px",
2400
- borderRadius: "8px",
2401
- border: "1px solid #e5e7eb",
2402
- backgroundColor: "#ffffff",
2403
- cursor: "pointer",
2404
- fontSize: "14px",
2405
- fontWeight: "500",
2406
- color: "#6b7280"
2407
- },
2408
- "data-testid": "button-report-cancel",
2409
- children: "Cancel"
2410
- }
2411
- ),
2412
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2413
- "button",
2414
- {
2415
- onClick: () => handleReportQuestion(reportComment),
2416
- disabled: isReporting || !reportComment.trim(),
2417
- style: {
2418
- flex: 1,
2419
- padding: "10px 16px",
2420
- borderRadius: "8px",
2421
- border: "none",
2422
- backgroundColor: reportComment.trim() ? "#ef4444" : "#d1d5db",
2423
- cursor: isReporting || !reportComment.trim() ? "not-allowed" : "pointer",
2424
- fontSize: "14px",
2425
- fontWeight: "500",
2426
- color: "#ffffff",
2427
- opacity: isReporting ? 0.6 : 1
2428
- },
2429
- "data-testid": "button-report-submit",
2430
- children: isReporting ? "Reporting..." : "Report"
2431
- }
2432
- )
2433
- ] })
2434
- ] }) }),
2435
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: defaultStyles.buttonsColumn, children: [
2436
- showFeedback && isLastQuestion && canAddMore && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2440
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { display: "flex", gap: "10px" }, children: [
2441
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2437
2442
  "button",
2438
2443
  {
2444
+ onClick: () => {
2445
+ setShowReportModal(false);
2446
+ setReportComment("");
2447
+ },
2439
2448
  style: {
2440
- ...defaultStyles.buttonAddMore,
2441
- ...isGeneratingExtra ? defaultStyles.buttonAddMoreDisabled : {}
2449
+ flex: 1,
2450
+ padding: "10px 16px",
2451
+ borderRadius: "8px",
2452
+ border: "1px solid #e5e7eb",
2453
+ backgroundColor: "#ffffff",
2454
+ cursor: "pointer",
2455
+ fontSize: "14px",
2456
+ fontWeight: "500",
2457
+ color: "#6b7280"
2442
2458
  },
2443
- onClick: handleAddMoreQuestions,
2444
- disabled: isGeneratingExtra,
2445
- "data-testid": "button-add-more-questions",
2446
- children: isGeneratingExtra ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
2447
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Spinner, { size: 16, color: "#9ca3af" }),
2448
- "Generating Questions..."
2449
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
2450
- "+ Add ",
2451
- questionsToAdd,
2452
- " More Question",
2453
- questionsToAdd !== 1 ? "s" : ""
2454
- ] })
2459
+ "data-testid": "button-report-cancel",
2460
+ children: "Cancel"
2455
2461
  }
2456
2462
  ),
2457
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { ...defaultStyles.buttons, justifyContent: "flex-end" }, children: showFeedback ? (
2458
- // After viewing feedback
2459
- isLastQuestion ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2460
- "button",
2461
- {
2462
- style: {
2463
- ...defaultStyles.button,
2464
- ...isSubmitting || isGeneratingExtra ? defaultStyles.buttonDisabled : defaultStyles.buttonPrimary
2465
- },
2466
- onClick: handleSubmit,
2467
- disabled: isSubmitting || isGeneratingExtra,
2468
- "data-testid": "button-submit-quiz",
2469
- children: isSubmitting ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Spinner, { size: 16, color: "#9ca3af" }) : "Submit Quiz"
2470
- }
2471
- ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2472
- "button",
2473
- {
2474
- style: {
2475
- ...defaultStyles.button,
2476
- ...defaultStyles.buttonPrimary
2477
- },
2478
- onClick: handleContinue,
2479
- "data-testid": "button-continue",
2480
- children: "Continue"
2481
- }
2482
- )
2483
- ) : (
2484
- // Before checking answer
2485
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2486
- "button",
2487
- {
2488
- style: {
2489
- ...defaultStyles.button,
2490
- ...isNavigating || selectedAnswer === void 0 ? defaultStyles.buttonDisabled : defaultStyles.buttonPrimary
2491
- },
2492
- onClick: handleCheckAnswer,
2493
- disabled: isNavigating || selectedAnswer === void 0,
2494
- "data-testid": "button-check-answer",
2495
- children: isNavigating ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Spinner, { size: 16, color: "#9ca3af" }) : "Check Answer"
2496
- }
2497
- )
2498
- ) })
2463
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2464
+ "button",
2465
+ {
2466
+ onClick: () => handleReportQuestion(reportComment),
2467
+ disabled: isReporting || !reportComment.trim(),
2468
+ style: {
2469
+ flex: 1,
2470
+ padding: "10px 16px",
2471
+ borderRadius: "8px",
2472
+ border: "none",
2473
+ backgroundColor: reportComment.trim() ? "#ef4444" : "#d1d5db",
2474
+ cursor: isReporting || !reportComment.trim() ? "not-allowed" : "pointer",
2475
+ fontSize: "14px",
2476
+ fontWeight: "500",
2477
+ color: "#ffffff",
2478
+ opacity: isReporting ? 0.6 : 1
2479
+ },
2480
+ "data-testid": "button-report-submit",
2481
+ children: isReporting ? "Reporting..." : "Report"
2482
+ }
2483
+ )
2499
2484
  ] })
2500
- ] }),
2501
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: defaultStyles.chatPanel, children: apiClient.current && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2502
- QuestionChatPanel,
2503
- {
2504
- apiClient: apiClient.current,
2505
- question: {
2506
- id: currentQuestion.id,
2507
- question: currentQuestion.question,
2508
- type: currentQuestion.type,
2509
- options: currentQuestion.options,
2510
- correctAnswer: currentQuestion.correctAnswer,
2511
- explanation: currentQuestion.explanation
2512
- },
2513
- quizId: quiz.id,
2514
- childId,
2515
- parentId,
2516
- lessonId,
2517
- courseId
2518
- }
2519
- ) })
2520
- ] })
2521
- ] });
2485
+ ] }) }),
2486
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: defaultStyles.buttonsColumn, children: [
2487
+ showFeedback && isLastQuestion && canAddMore && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2488
+ "button",
2489
+ {
2490
+ style: {
2491
+ ...defaultStyles.buttonAddMore,
2492
+ ...isGeneratingExtra ? defaultStyles.buttonAddMoreDisabled : {}
2493
+ },
2494
+ onClick: handleAddMoreQuestions,
2495
+ disabled: isGeneratingExtra,
2496
+ "data-testid": "button-add-more-questions",
2497
+ children: isGeneratingExtra ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
2498
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Spinner, { size: 16, color: "#9ca3af" }),
2499
+ "Generating Questions..."
2500
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
2501
+ "+ Add ",
2502
+ questionsToAdd,
2503
+ " More Question",
2504
+ questionsToAdd !== 1 ? "s" : ""
2505
+ ] })
2506
+ }
2507
+ ),
2508
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { ...defaultStyles.buttons, justifyContent: "flex-end" }, children: showFeedback ? (
2509
+ // After viewing feedback
2510
+ isLastQuestion ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2511
+ "button",
2512
+ {
2513
+ style: {
2514
+ ...defaultStyles.button,
2515
+ ...isSubmitting || isGeneratingExtra ? defaultStyles.buttonDisabled : defaultStyles.buttonPrimary
2516
+ },
2517
+ onClick: handleSubmit,
2518
+ disabled: isSubmitting || isGeneratingExtra,
2519
+ "data-testid": "button-submit-quiz",
2520
+ children: isSubmitting ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Spinner, { size: 16, color: "#9ca3af" }) : "Submit Quiz"
2521
+ }
2522
+ ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2523
+ "button",
2524
+ {
2525
+ style: {
2526
+ ...defaultStyles.button,
2527
+ ...defaultStyles.buttonPrimary
2528
+ },
2529
+ onClick: handleContinue,
2530
+ "data-testid": "button-continue",
2531
+ children: "Continue"
2532
+ }
2533
+ )
2534
+ ) : (
2535
+ // Before checking answer
2536
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2537
+ "button",
2538
+ {
2539
+ style: {
2540
+ ...defaultStyles.button,
2541
+ ...isNavigating || selectedAnswer === void 0 ? defaultStyles.buttonDisabled : defaultStyles.buttonPrimary
2542
+ },
2543
+ onClick: handleCheckAnswer,
2544
+ disabled: isNavigating || selectedAnswer === void 0,
2545
+ "data-testid": "button-check-answer",
2546
+ children: isNavigating ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Spinner, { size: 16, color: "#9ca3af" }) : "Check Answer"
2547
+ }
2548
+ )
2549
+ ) })
2550
+ ] })
2551
+ ] }),
2552
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: defaultStyles.chatPanel, children: apiClient.current && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2553
+ QuestionChatPanel,
2554
+ {
2555
+ apiClient: apiClient.current,
2556
+ question: {
2557
+ id: currentQuestion.id,
2558
+ question: currentQuestion.question,
2559
+ type: currentQuestion.type,
2560
+ options: currentQuestion.options,
2561
+ correctAnswer: currentQuestion.correctAnswer,
2562
+ explanation: currentQuestion.explanation
2563
+ },
2564
+ quizId: quiz.id,
2565
+ childId,
2566
+ parentId,
2567
+ lessonId,
2568
+ courseId,
2569
+ answerResult: showFeedback && currentAnswerDetail ? {
2570
+ wasIncorrect: !currentAnswerDetail.isCorrect,
2571
+ selectedAnswer: typeof selectedAnswer === "string" ? selectedAnswer : Array.isArray(selectedAnswer) ? selectedAnswer.join(", ") : void 0,
2572
+ correctAnswer: typeof currentQuestion.correctAnswer === "string" ? currentQuestion.correctAnswer : Array.isArray(currentQuestion.correctAnswer) ? currentQuestion.correctAnswer.join(", ") : void 0,
2573
+ explanation: currentQuestion.explanation
2574
+ } : void 0
2575
+ }
2576
+ ) })
2577
+ ] }) });
2522
2578
  }
2523
2579
 
2524
2580
  // src/AttemptViewer.tsx
@@ -2644,6 +2700,46 @@ var defaultStyles2 = {
2644
2700
  fontSize: "14px",
2645
2701
  color: "#581c87"
2646
2702
  },
2703
+ chatHistorySection: {
2704
+ marginTop: "12px",
2705
+ borderTop: "1px solid #e5e7eb",
2706
+ paddingTop: "12px"
2707
+ },
2708
+ chatToggleButton: {
2709
+ display: "flex",
2710
+ alignItems: "center",
2711
+ gap: "6px",
2712
+ padding: "6px 12px",
2713
+ backgroundColor: "#f3f4f6",
2714
+ border: "none",
2715
+ borderRadius: "6px",
2716
+ fontSize: "13px",
2717
+ color: "#6b7280",
2718
+ cursor: "pointer",
2719
+ fontWeight: "500"
2720
+ },
2721
+ chatMessages: {
2722
+ marginTop: "12px",
2723
+ display: "flex",
2724
+ flexDirection: "column",
2725
+ gap: "8px"
2726
+ },
2727
+ chatMessage: {
2728
+ padding: "8px 12px",
2729
+ borderRadius: "8px",
2730
+ fontSize: "13px",
2731
+ maxWidth: "85%"
2732
+ },
2733
+ chatMessageUser: {
2734
+ backgroundColor: "#6721b0",
2735
+ color: "#ffffff",
2736
+ alignSelf: "flex-end"
2737
+ },
2738
+ chatMessageAssistant: {
2739
+ backgroundColor: "#f3f4f6",
2740
+ color: "#111827",
2741
+ alignSelf: "flex-start"
2742
+ },
2647
2743
  loading: {
2648
2744
  textAlign: "center",
2649
2745
  padding: "40px 20px"
@@ -2701,11 +2797,14 @@ function AttemptViewer({
2701
2797
  onError,
2702
2798
  className,
2703
2799
  showExplanations = true,
2800
+ showConversation = false,
2704
2801
  title
2705
2802
  }) {
2706
2803
  const [attempt, setAttempt] = (0, import_react4.useState)(null);
2707
2804
  const [loading, setLoading] = (0, import_react4.useState)(true);
2708
2805
  const [error, setError] = (0, import_react4.useState)(null);
2806
+ const [chatHistories, setChatHistories] = (0, import_react4.useState)({});
2807
+ const [expandedChats, setExpandedChats] = (0, import_react4.useState)(/* @__PURE__ */ new Set());
2709
2808
  (0, import_react4.useEffect)(() => {
2710
2809
  const apiClient = new QuizApiClient({
2711
2810
  baseUrl: apiBaseUrl,
@@ -2723,6 +2822,14 @@ function AttemptViewer({
2723
2822
  }
2724
2823
  const data = await response.json();
2725
2824
  setAttempt(data);
2825
+ if (showConversation) {
2826
+ try {
2827
+ const chats = await apiClient.getChatsByAttempt(attemptId);
2828
+ setChatHistories(chats);
2829
+ } catch (chatErr) {
2830
+ console.error("Failed to load chat histories:", chatErr);
2831
+ }
2832
+ }
2726
2833
  } catch (err) {
2727
2834
  const errorMessage = err instanceof Error ? err.message : "Failed to load attempt";
2728
2835
  setError(errorMessage);
@@ -2732,7 +2839,18 @@ function AttemptViewer({
2732
2839
  }
2733
2840
  }
2734
2841
  fetchAttempt();
2735
- }, [attemptId, apiBaseUrl, authToken, onError]);
2842
+ }, [attemptId, apiBaseUrl, authToken, onError, showConversation]);
2843
+ const toggleChatExpanded = (questionId) => {
2844
+ setExpandedChats((prev) => {
2845
+ const newSet = new Set(prev);
2846
+ if (newSet.has(questionId)) {
2847
+ newSet.delete(questionId);
2848
+ } else {
2849
+ newSet.add(questionId);
2850
+ }
2851
+ return newSet;
2852
+ });
2853
+ };
2736
2854
  const handleRetry = () => {
2737
2855
  setLoading(true);
2738
2856
  setError(null);
@@ -2824,6 +2942,34 @@ function AttemptViewer({
2824
2942
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("strong", { children: "Explanation:" }),
2825
2943
  " ",
2826
2944
  answer.explanation
2945
+ ] }),
2946
+ showConversation && chatHistories[answer.questionId] && chatHistories[answer.questionId].messages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: defaultStyles2.chatHistorySection, children: [
2947
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
2948
+ "button",
2949
+ {
2950
+ style: defaultStyles2.chatToggleButton,
2951
+ onClick: () => toggleChatExpanded(answer.questionId),
2952
+ "data-testid": `button-toggle-chat-${answer.questionId}`,
2953
+ children: [
2954
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" }) }),
2955
+ expandedChats.has(answer.questionId) ? "Hide" : "View",
2956
+ " Chat History (",
2957
+ chatHistories[answer.questionId].messages.length,
2958
+ " messages)"
2959
+ ]
2960
+ }
2961
+ ),
2962
+ expandedChats.has(answer.questionId) && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: defaultStyles2.chatMessages, children: chatHistories[answer.questionId].messages.map((msg, msgIndex) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2963
+ "div",
2964
+ {
2965
+ style: {
2966
+ ...defaultStyles2.chatMessage,
2967
+ ...msg.role === "user" ? defaultStyles2.chatMessageUser : defaultStyles2.chatMessageAssistant
2968
+ },
2969
+ children: msg.content
2970
+ },
2971
+ msgIndex
2972
+ )) })
2827
2973
  ] })
2828
2974
  ]
2829
2975
  },