analytica-frontend-lib 1.6.21 → 1.6.22

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.
Files changed (405) hide show
  1. package/dist/AccessReportModal/index.js +1 -1
  2. package/dist/AccessReportModal/index.mjs +1 -1
  3. package/dist/AccessibilityWidget/index.js +1 -1
  4. package/dist/AccessibilityWidget/index.mjs +1 -1
  5. package/dist/Accordation/index.js +1 -1
  6. package/dist/Accordation/index.mjs +1 -1
  7. package/dist/ActivitiesHistory/index.js +19 -19
  8. package/dist/ActivitiesHistory/index.mjs +18 -18
  9. package/dist/ActivityCardQuestionBanks/index.js +19 -19
  10. package/dist/ActivityCardQuestionBanks/index.mjs +18 -18
  11. package/dist/ActivityCardQuestionPreview/index.js +19 -19
  12. package/dist/ActivityCardQuestionPreview/index.mjs +18 -18
  13. package/dist/ActivityCreate/ActivityCreate.utils/index.js +3 -3
  14. package/dist/ActivityCreate/ActivityCreate.utils/index.mjs +2 -2
  15. package/dist/ActivityCreate/ActivityCreateContent/index.js +19 -19
  16. package/dist/ActivityCreate/ActivityCreateContent/index.mjs +18 -18
  17. package/dist/ActivityCreate/index.js +19 -19
  18. package/dist/ActivityCreate/index.mjs +18 -18
  19. package/dist/ActivityDetails/index.js +19 -19
  20. package/dist/ActivityDetails/index.mjs +18 -18
  21. package/dist/ActivityFilters/index.js +19 -19
  22. package/dist/ActivityFilters/index.mjs +18 -18
  23. package/dist/ActivityPageLayout/index.js +19 -19
  24. package/dist/ActivityPageLayout/index.mjs +18 -18
  25. package/dist/ActivityPreview/index.js +19 -19
  26. package/dist/ActivityPreview/index.mjs +18 -18
  27. package/dist/Alert/index.js +1 -1
  28. package/dist/Alert/index.mjs +1 -1
  29. package/dist/AlertDialog/index.js +1 -1
  30. package/dist/AlertDialog/index.mjs +1 -1
  31. package/dist/AlertManager/index.js +19 -19
  32. package/dist/AlertManager/index.mjs +18 -18
  33. package/dist/AlertManagerView/index.js +1 -1
  34. package/dist/AlertManagerView/index.mjs +1 -1
  35. package/dist/Alternative/index.js +1 -1
  36. package/dist/Alternative/index.mjs +1 -1
  37. package/dist/AnnouncementModal/index.js +1 -1
  38. package/dist/AnnouncementModal/index.mjs +1 -1
  39. package/dist/AnnouncementsGate/index.js +1 -1
  40. package/dist/AnnouncementsGate/index.mjs +1 -1
  41. package/dist/AnswerKeyModal/index.js +1 -1
  42. package/dist/AnswerKeyModal/index.mjs +1 -1
  43. package/dist/AppHeader/index.js +1 -1
  44. package/dist/AppHeader/index.mjs +1 -1
  45. package/dist/AppLayout/index.js +1 -1
  46. package/dist/AppLayout/index.mjs +1 -1
  47. package/dist/Avatar/index.js +1 -1
  48. package/dist/Avatar/index.mjs +1 -1
  49. package/dist/Badge/index.js +1 -1
  50. package/dist/Badge/index.mjs +1 -1
  51. package/dist/BreadcrumbMenu/index.js +1 -1
  52. package/dist/BreadcrumbMenu/index.mjs +1 -1
  53. package/dist/Button/index.js +1 -1
  54. package/dist/Button/index.mjs +1 -1
  55. package/dist/Calendar/index.js +1 -1
  56. package/dist/Calendar/index.mjs +1 -1
  57. package/dist/CalendarCard/index.js +1 -1
  58. package/dist/CalendarCard/index.mjs +1 -1
  59. package/dist/Card/index.js +1 -1
  60. package/dist/Card/index.mjs +1 -1
  61. package/dist/ChartComponents/index.js +1 -1
  62. package/dist/ChartComponents/index.mjs +1 -1
  63. package/dist/Chat/index.js +1 -1
  64. package/dist/Chat/index.mjs +1 -1
  65. package/dist/Chatbot/index.js +1 -1
  66. package/dist/Chatbot/index.mjs +1 -1
  67. package/dist/CheckBox/index.js +1 -1
  68. package/dist/CheckBox/index.mjs +1 -1
  69. package/dist/CheckBoxGroup/index.js +19 -19
  70. package/dist/CheckBoxGroup/index.mjs +18 -18
  71. package/dist/Chips/index.js +1 -1
  72. package/dist/Chips/index.mjs +1 -1
  73. package/dist/ChoroplethMap/index.js +1 -1
  74. package/dist/ChoroplethMap/index.mjs +1 -1
  75. package/dist/ColorPicker/index.js +1 -1
  76. package/dist/ColorPicker/index.mjs +1 -1
  77. package/dist/ComparatorChart/ComparatorView/index.js +1 -1
  78. package/dist/ComparatorChart/ComparatorView/index.mjs +1 -1
  79. package/dist/CorrectActivityModal/index.js +6 -6
  80. package/dist/CorrectActivityModal/index.mjs +5 -5
  81. package/dist/Divider/index.js +1 -1
  82. package/dist/Divider/index.mjs +1 -1
  83. package/dist/DownloadButton/index.js +1 -1
  84. package/dist/DownloadButton/index.mjs +1 -1
  85. package/dist/DownloadModal/index.js +1 -1
  86. package/dist/DownloadModal/index.mjs +1 -1
  87. package/dist/DragHandleButton/index.js +1 -1
  88. package/dist/DragHandleButton/index.mjs +1 -1
  89. package/dist/DropdownMenu/index.js +1 -1
  90. package/dist/DropdownMenu/index.mjs +1 -1
  91. package/dist/EmptyState/index.js +1 -1
  92. package/dist/EmptyState/index.mjs +1 -1
  93. package/dist/EnemClassroomStartModal/index.d.ts +0 -2
  94. package/dist/EnemClassroomStartModal/index.d.ts.map +1 -1
  95. package/dist/EnemClassroomStartModal/index.js +4 -6
  96. package/dist/EnemClassroomStartModal/index.js.map +1 -1
  97. package/dist/EnemClassroomStartModal/index.mjs +3 -5
  98. package/dist/EssayThemePicker/index.js +1 -1
  99. package/dist/EssayThemePicker/index.mjs +1 -1
  100. package/dist/ExamDetailsLayout/ExamDetailsPage/index.js +19 -19
  101. package/dist/ExamDetailsLayout/ExamDetailsPage/index.mjs +18 -18
  102. package/dist/ExamPageLayout/examsTableConfig/index.js +1 -1
  103. package/dist/ExamPageLayout/examsTableConfig/index.mjs +1 -1
  104. package/dist/ExamPageLayout/index.js +19 -19
  105. package/dist/ExamPageLayout/index.mjs +18 -18
  106. package/dist/FileAttachment/index.js +1 -1
  107. package/dist/FileAttachment/index.mjs +1 -1
  108. package/dist/FileDropzone/index.js +1 -1
  109. package/dist/FileDropzone/index.mjs +1 -1
  110. package/dist/Forum/index.js +4 -4
  111. package/dist/Forum/index.mjs +3 -3
  112. package/dist/HtmlMathRenderer/index.js +1 -1
  113. package/dist/HtmlMathRenderer/index.mjs +1 -1
  114. package/dist/IconButton/index.js +1 -1
  115. package/dist/IconButton/index.mjs +1 -1
  116. package/dist/IconRoundedButton/index.js +1 -1
  117. package/dist/IconRoundedButton/index.mjs +1 -1
  118. package/dist/ImagePreviewCard/index.js +1 -1
  119. package/dist/ImagePreviewCard/index.mjs +1 -1
  120. package/dist/ImageUpload/index.js +1 -1
  121. package/dist/ImageUpload/index.mjs +1 -1
  122. package/dist/LatexRenderer/index.js +1 -1
  123. package/dist/LatexRenderer/index.mjs +1 -1
  124. package/dist/LevelBar/index.js +1 -1
  125. package/dist/LevelBar/index.mjs +1 -1
  126. package/dist/Menu/index.js +1 -1
  127. package/dist/Menu/index.mjs +1 -1
  128. package/dist/MetricBox/index.js +1 -1
  129. package/dist/MetricBox/index.mjs +1 -1
  130. package/dist/Modal/index.js +1 -1
  131. package/dist/Modal/index.mjs +1 -1
  132. package/dist/ModalComponents/index.js +1 -1
  133. package/dist/ModalComponents/index.mjs +1 -1
  134. package/dist/MultiSearchSelect/index.js +1 -1
  135. package/dist/MultiSearchSelect/index.mjs +1 -1
  136. package/dist/MultipleChoice/index.js +1 -1
  137. package/dist/MultipleChoice/index.mjs +1 -1
  138. package/dist/NavButton/index.js +1 -1
  139. package/dist/NavButton/index.mjs +1 -1
  140. package/dist/NoSearchResult/index.js +1 -1
  141. package/dist/NoSearchResult/index.mjs +1 -1
  142. package/dist/NotFound/index.js +1 -1
  143. package/dist/NotFound/index.mjs +1 -1
  144. package/dist/NotificationCard/index.js +1 -1
  145. package/dist/NotificationCard/index.mjs +1 -1
  146. package/dist/PerformanceDistributionChart/index.js +1 -1
  147. package/dist/PerformanceDistributionChart/index.mjs +1 -1
  148. package/dist/PerformanceQuestionsData/index.js +1 -1
  149. package/dist/PerformanceQuestionsData/index.mjs +1 -1
  150. package/dist/PerformanceRanking/index.js +1 -1
  151. package/dist/PerformanceRanking/index.mjs +1 -1
  152. package/dist/PerformanceReport/index.js +1 -1
  153. package/dist/PerformanceReport/index.mjs +1 -1
  154. package/dist/PerformanceReportModal/index.js +1 -1
  155. package/dist/PerformanceReportModal/index.mjs +1 -1
  156. package/dist/PeriodSelector/index.js +1 -1
  157. package/dist/PeriodSelector/index.mjs +1 -1
  158. package/dist/PrintableUsersTable/index.js +19 -19
  159. package/dist/PrintableUsersTable/index.mjs +18 -18
  160. package/dist/ProficiencyChart/index.js +1 -1
  161. package/dist/ProficiencyChart/index.mjs +1 -1
  162. package/dist/ProgressBar/index.js +1 -1
  163. package/dist/ProgressBar/index.mjs +1 -1
  164. package/dist/ProgressCircle/index.js +1 -1
  165. package/dist/ProgressCircle/index.mjs +1 -1
  166. package/dist/ProgressModal/index.js +1 -1
  167. package/dist/ProgressModal/index.mjs +1 -1
  168. package/dist/QuestionsData/index.js +1 -1
  169. package/dist/QuestionsData/index.mjs +1 -1
  170. package/dist/QuestionsPerformanceCard/index.js +19 -19
  171. package/dist/QuestionsPerformanceCard/index.mjs +18 -18
  172. package/dist/Quiz/QuizResult/index.d.ts.map +1 -1
  173. package/dist/Quiz/QuizResult/index.js +4 -4
  174. package/dist/Quiz/QuizResult/index.mjs +3 -3
  175. package/dist/Quiz/TeacherFeedbackSection/index.js +3 -3
  176. package/dist/Quiz/TeacherFeedbackSection/index.mjs +2 -2
  177. package/dist/Quiz/TeacherQuestionComment/index.js +3 -3
  178. package/dist/Quiz/TeacherQuestionComment/index.mjs +2 -2
  179. package/dist/Quiz/index.d.ts.map +1 -1
  180. package/dist/Quiz/index.js +6 -6
  181. package/dist/Quiz/index.mjs +5 -5
  182. package/dist/Quiz/useQuizStore/index.d.ts +6 -0
  183. package/dist/Quiz/useQuizStore/index.d.ts.map +1 -1
  184. package/dist/Quiz/useQuizStore/index.js +2 -2
  185. package/dist/Quiz/useQuizStore/index.mjs +1 -1
  186. package/dist/QuizTimer/index.js +3 -3
  187. package/dist/QuizTimer/index.mjs +2 -2
  188. package/dist/Radio/index.js +1 -1
  189. package/dist/Radio/index.mjs +1 -1
  190. package/dist/RangeGauge/index.js +1 -1
  191. package/dist/RangeGauge/index.mjs +1 -1
  192. package/dist/RecommendedLessonCreate/index.js +19 -19
  193. package/dist/RecommendedLessonCreate/index.mjs +18 -18
  194. package/dist/RecommendedLessonDetails/index.js +1 -1
  195. package/dist/RecommendedLessonDetails/index.mjs +1 -1
  196. package/dist/RecommendedLessonsHistory/index.js +19 -19
  197. package/dist/RecommendedLessonsHistory/index.mjs +18 -18
  198. package/dist/ReportDetailModal/index.js +1 -1
  199. package/dist/ReportDetailModal/index.mjs +1 -1
  200. package/dist/RestrictedAccess/index.js +1 -1
  201. package/dist/RestrictedAccess/index.mjs +1 -1
  202. package/dist/RichEditor/index.js +3 -3
  203. package/dist/RichEditor/index.mjs +2 -2
  204. package/dist/{RichEditorCore-F5QPQLEK.js → RichEditorCore-NEIZKFKE.js} +2 -2
  205. package/dist/{RichEditorCore-F5QPQLEK.js.map → RichEditorCore-NEIZKFKE.js.map} +1 -1
  206. package/dist/{RichEditorCore-QZYPHNRY.mjs → RichEditorCore-TLAFZ5XG.mjs} +2 -2
  207. package/dist/ScoreCircle/index.js +1 -1
  208. package/dist/ScoreCircle/index.mjs +1 -1
  209. package/dist/Search/index.js +1 -1
  210. package/dist/Search/index.mjs +1 -1
  211. package/dist/SearchSelect/index.js +1 -1
  212. package/dist/SearchSelect/index.mjs +1 -1
  213. package/dist/Select/index.js +1 -1
  214. package/dist/Select/index.mjs +1 -1
  215. package/dist/SelectionButton/index.js +1 -1
  216. package/dist/SelectionButton/index.mjs +1 -1
  217. package/dist/SendActivityModal/SendActivityModal.js +19 -19
  218. package/dist/SendActivityModal/SendActivityModal.mjs +18 -18
  219. package/dist/SendActivityModal/index.js +19 -19
  220. package/dist/SendActivityModal/index.mjs +18 -18
  221. package/dist/SendLessonModal/index.js +19 -19
  222. package/dist/SendLessonModal/index.mjs +18 -18
  223. package/dist/SimpleBarChart/index.js +1 -1
  224. package/dist/SimpleBarChart/index.mjs +1 -1
  225. package/dist/SimulatedPerformance/SimulatedPerformanceView/index.js +19 -19
  226. package/dist/SimulatedPerformance/SimulatedPerformanceView/index.mjs +18 -18
  227. package/dist/SimulatedPerformance/useSimulatedPerformance/index.js +1 -1
  228. package/dist/SimulatedPerformance/useSimulatedPerformance/index.mjs +1 -1
  229. package/dist/SimulatedStudentSimulationsModal/index.js +19 -19
  230. package/dist/SimulatedStudentSimulationsModal/index.mjs +5 -5
  231. package/dist/SimulationsPage/index.js +19 -19
  232. package/dist/SimulationsPage/index.mjs +18 -18
  233. package/dist/Skeleton/index.js +1 -1
  234. package/dist/Skeleton/index.mjs +1 -1
  235. package/dist/StatisticsCard/index.js +1 -1
  236. package/dist/StatisticsCard/index.mjs +1 -1
  237. package/dist/Stepper/index.js +1 -1
  238. package/dist/Stepper/index.mjs +1 -1
  239. package/dist/StudentLessonProgressModal/index.js +1 -1
  240. package/dist/StudentLessonProgressModal/index.mjs +1 -1
  241. package/dist/StudentPerformanceDetailsModal/index.js +1 -1
  242. package/dist/StudentPerformanceDetailsModal/index.mjs +1 -1
  243. package/dist/StudentRanking/index.js +1 -1
  244. package/dist/StudentRanking/index.mjs +1 -1
  245. package/dist/SubjectIcons/index.js +1 -1
  246. package/dist/SubjectIcons/index.mjs +1 -1
  247. package/dist/SubjectMenuOverflow/index.js +1 -1
  248. package/dist/SubjectMenuOverflow/index.mjs +1 -1
  249. package/dist/Support/TicketModal/index.js +1 -1
  250. package/dist/Support/TicketModal/index.mjs +1 -1
  251. package/dist/Support/index.js +1 -1
  252. package/dist/Support/index.mjs +1 -1
  253. package/dist/Table/TablePagination/index.js +1 -1
  254. package/dist/Table/TablePagination/index.mjs +1 -1
  255. package/dist/Table/index.js +1 -1
  256. package/dist/Table/index.mjs +1 -1
  257. package/dist/TableProvider/index.js +19 -19
  258. package/dist/TableProvider/index.mjs +18 -18
  259. package/dist/Text/index.js +1 -1
  260. package/dist/Text/index.mjs +1 -1
  261. package/dist/TextArea/index.js +1 -1
  262. package/dist/TextArea/index.mjs +1 -1
  263. package/dist/ThemeToggle/index.js +1 -1
  264. package/dist/ThemeToggle/index.mjs +1 -1
  265. package/dist/TimeChart/index.js +1 -1
  266. package/dist/TimeChart/index.mjs +1 -1
  267. package/dist/TimeReport/index.js +1 -1
  268. package/dist/TimeReport/index.mjs +1 -1
  269. package/dist/Toast/Toaster/index.js +1 -1
  270. package/dist/Toast/Toaster/index.mjs +1 -1
  271. package/dist/Toast/index.js +1 -1
  272. package/dist/Toast/index.mjs +1 -1
  273. package/dist/ToggleSwitch/index.js +1 -1
  274. package/dist/ToggleSwitch/index.mjs +1 -1
  275. package/dist/TokenValidation/index.js +1 -1
  276. package/dist/TokenValidation/index.mjs +1 -1
  277. package/dist/Tooltip/index.js +1 -1
  278. package/dist/Tooltip/index.mjs +1 -1
  279. package/dist/TruncatedText/index.js +1 -1
  280. package/dist/TruncatedText/index.mjs +1 -1
  281. package/dist/TypeSelector/index.js +1 -1
  282. package/dist/TypeSelector/index.mjs +1 -1
  283. package/dist/UnifiedDraftModelPage/index.js +19 -19
  284. package/dist/UnifiedDraftModelPage/index.mjs +18 -18
  285. package/dist/UnifiedHistoryPage/index.js +19 -19
  286. package/dist/UnifiedHistoryPage/index.mjs +18 -18
  287. package/dist/VerticalBarChart/index.js +1 -1
  288. package/dist/VerticalBarChart/index.mjs +1 -1
  289. package/dist/VideoPlayer/index.js +1 -1
  290. package/dist/VideoPlayer/index.mjs +1 -1
  291. package/dist/Whiteboard/index.js +1 -1
  292. package/dist/Whiteboard/index.mjs +1 -1
  293. package/dist/{chunk-JBAGQ7L5.js → chunk-3VG5MEMY.js} +14 -13
  294. package/dist/chunk-3VG5MEMY.js.map +1 -0
  295. package/dist/{chunk-ED23HOE6.mjs → chunk-5NIU4XJY.mjs} +7 -6
  296. package/dist/chunk-5NIU4XJY.mjs.map +1 -0
  297. package/dist/{chunk-DDZDNGBU.mjs → chunk-64WGFT5E.mjs} +3 -1
  298. package/dist/chunk-64WGFT5E.mjs.map +1 -0
  299. package/dist/{chunk-QN32O3J3.js → chunk-6MK23BTK.js} +62 -62
  300. package/dist/{chunk-QN32O3J3.js.map → chunk-6MK23BTK.js.map} +1 -1
  301. package/dist/{chunk-XX4WE4TL.js → chunk-726PIA5M.js} +1 -1
  302. package/dist/chunk-726PIA5M.js.map +1 -0
  303. package/dist/{chunk-VZJKHIHN.mjs → chunk-7KALNPIG.mjs} +4 -4
  304. package/dist/{chunk-NQNEG4KR.mjs → chunk-7VKFZHWP.mjs} +11 -10
  305. package/dist/chunk-7VKFZHWP.mjs.map +1 -0
  306. package/dist/{chunk-GYQUB3VW.js → chunk-BBFV3NDF.js} +8 -6
  307. package/dist/chunk-BBFV3NDF.js.map +1 -0
  308. package/dist/{chunk-I3Z2BHGN.js → chunk-BJHYT75K.js} +3 -3
  309. package/dist/{chunk-I3Z2BHGN.js.map → chunk-BJHYT75K.js.map} +1 -1
  310. package/dist/{chunk-CFTQ24UT.mjs → chunk-CMYBNZ74.mjs} +2 -2
  311. package/dist/{chunk-R7NS5KFE.mjs → chunk-CWUNF7U6.mjs} +3 -3
  312. package/dist/{chunk-NAOHJW6H.mjs → chunk-DLHV7CZN.mjs} +6 -6
  313. package/dist/{chunk-7EXSCXPK.mjs → chunk-DMYETMZG.mjs} +2 -2
  314. package/dist/{chunk-RQPSA4QV.js → chunk-GQUTHDV2.js} +3 -3
  315. package/dist/{chunk-RQPSA4QV.js.map → chunk-GQUTHDV2.js.map} +1 -1
  316. package/dist/{chunk-OZWPOXVU.mjs → chunk-GVGDUCVF.mjs} +2 -2
  317. package/dist/{chunk-QFWY46XU.js → chunk-IMDS5NQL.js} +16 -16
  318. package/dist/{chunk-QFWY46XU.js.map → chunk-IMDS5NQL.js.map} +1 -1
  319. package/dist/{chunk-KYGFYAU7.js → chunk-JHN35HPH.js} +3 -3
  320. package/dist/{chunk-KYGFYAU7.js.map → chunk-JHN35HPH.js.map} +1 -1
  321. package/dist/{chunk-DMZTDCUF.js → chunk-JPQI2RIV.js} +3 -3
  322. package/dist/{chunk-DMZTDCUF.js.map → chunk-JPQI2RIV.js.map} +1 -1
  323. package/dist/{chunk-LXX5KU3O.mjs → chunk-LMDAF6LA.mjs} +2 -2
  324. package/dist/{chunk-FL4W4S6J.mjs → chunk-MOSP7FR5.mjs} +1 -1
  325. package/dist/chunk-MOSP7FR5.mjs.map +1 -0
  326. package/dist/{chunk-HZXXADG4.js → chunk-NLPBW3SW.js} +44 -43
  327. package/dist/chunk-NLPBW3SW.js.map +1 -0
  328. package/dist/{chunk-TAABXGZL.mjs → chunk-O3JP6ZMQ.mjs} +2 -2
  329. package/dist/{chunk-MFO4S7T5.js → chunk-PJOBOBNJ.js} +3 -3
  330. package/dist/{chunk-MFO4S7T5.js.map → chunk-PJOBOBNJ.js.map} +1 -1
  331. package/dist/{chunk-CWGYVJTQ.mjs → chunk-PORNR2NU.mjs} +3 -3
  332. package/dist/chunk-QF3UKRIJ.js +33 -0
  333. package/dist/chunk-QF3UKRIJ.js.map +1 -0
  334. package/dist/chunk-RAHXO5YU.mjs +33 -0
  335. package/dist/chunk-RAHXO5YU.mjs.map +1 -0
  336. package/dist/{chunk-BTZANNVO.js → chunk-RQ65U5G2.js} +3 -3
  337. package/dist/{chunk-BTZANNVO.js.map → chunk-RQ65U5G2.js.map} +1 -1
  338. package/dist/{chunk-Q56I63FO.mjs → chunk-RVGLLMWG.mjs} +2 -2
  339. package/dist/{chunk-VVRRAF6H.js → chunk-S2S7TK3L.js} +49 -36
  340. package/dist/chunk-S2S7TK3L.js.map +1 -0
  341. package/dist/{chunk-INIH23HU.js → chunk-VF6QXUX3.js} +2 -2
  342. package/dist/{chunk-INIH23HU.js.map → chunk-VF6QXUX3.js.map} +1 -1
  343. package/dist/{chunk-QWC5GC2Q.mjs → chunk-WY7V5UJN.mjs} +2 -2
  344. package/dist/{chunk-OCKO7T7L.js → chunk-XQAYZBLL.js} +3 -3
  345. package/dist/{chunk-OCKO7T7L.js.map → chunk-XQAYZBLL.js.map} +1 -1
  346. package/dist/{chunk-ATGLKKXI.js → chunk-Y7ZBWTD7.js} +17 -17
  347. package/dist/{chunk-ATGLKKXI.js.map → chunk-Y7ZBWTD7.js.map} +1 -1
  348. package/dist/{chunk-7XWWI5EY.js → chunk-YFIB3YNQ.js} +11 -11
  349. package/dist/{chunk-7XWWI5EY.js.map → chunk-YFIB3YNQ.js.map} +1 -1
  350. package/dist/{chunk-UCWTF336.mjs → chunk-YWGJAB63.mjs} +2 -2
  351. package/dist/{chunk-4MPXVPBQ.mjs → chunk-YYHS2TM6.mjs} +43 -30
  352. package/dist/chunk-YYHS2TM6.mjs.map +1 -0
  353. package/dist/components/Quiz/Quiz.utils.d.ts +8 -0
  354. package/dist/components/Quiz/Quiz.utils.d.ts.map +1 -1
  355. package/dist/hooks/useAppContent/index.js +19 -19
  356. package/dist/hooks/useAppContent/index.mjs +18 -18
  357. package/dist/hooks/useComparator/index.js +1 -1
  358. package/dist/hooks/useComparator/index.mjs +1 -1
  359. package/dist/hooks/useDraftAutoSave/index.js +3 -3
  360. package/dist/hooks/useDraftAutoSave/index.mjs +2 -2
  361. package/dist/index.js +19 -19
  362. package/dist/index.mjs +18 -18
  363. package/dist/types/enemClassroom/index.d.ts +29 -2
  364. package/dist/types/enemClassroom/index.d.ts.map +1 -1
  365. package/dist/types/enemClassroom/index.js +4 -2
  366. package/dist/types/enemClassroom/index.js.map +1 -1
  367. package/dist/types/enemClassroom/index.mjs +3 -1
  368. package/dist/types/enemClassroom.d.ts +29 -2
  369. package/dist/types/enemClassroom.d.ts.map +1 -1
  370. package/dist/types/questionTypes/index.js +1 -1
  371. package/dist/types/questionTypes/index.mjs +1 -1
  372. package/dist/utils/index.js +1 -1
  373. package/dist/utils/index.mjs +1 -1
  374. package/dist/utils/renderSubjectCell/index.js +1 -1
  375. package/dist/utils/renderSubjectCell/index.mjs +1 -1
  376. package/dist/utils/renderTextCell/index.js +1 -1
  377. package/dist/utils/renderTextCell/index.mjs +1 -1
  378. package/package.json +1 -1
  379. package/dist/chunk-4MPXVPBQ.mjs.map +0 -1
  380. package/dist/chunk-DDZDNGBU.mjs.map +0 -1
  381. package/dist/chunk-ED23HOE6.mjs.map +0 -1
  382. package/dist/chunk-FL4W4S6J.mjs.map +0 -1
  383. package/dist/chunk-GYQUB3VW.js.map +0 -1
  384. package/dist/chunk-HZXXADG4.js.map +0 -1
  385. package/dist/chunk-JBAGQ7L5.js.map +0 -1
  386. package/dist/chunk-ND5M3DZA.mjs +0 -21
  387. package/dist/chunk-ND5M3DZA.mjs.map +0 -1
  388. package/dist/chunk-NQNEG4KR.mjs.map +0 -1
  389. package/dist/chunk-NYKBCQUO.js +0 -21
  390. package/dist/chunk-NYKBCQUO.js.map +0 -1
  391. package/dist/chunk-VVRRAF6H.js.map +0 -1
  392. package/dist/chunk-XX4WE4TL.js.map +0 -1
  393. /package/dist/{RichEditorCore-QZYPHNRY.mjs.map → RichEditorCore-TLAFZ5XG.mjs.map} +0 -0
  394. /package/dist/{chunk-VZJKHIHN.mjs.map → chunk-7KALNPIG.mjs.map} +0 -0
  395. /package/dist/{chunk-CFTQ24UT.mjs.map → chunk-CMYBNZ74.mjs.map} +0 -0
  396. /package/dist/{chunk-R7NS5KFE.mjs.map → chunk-CWUNF7U6.mjs.map} +0 -0
  397. /package/dist/{chunk-NAOHJW6H.mjs.map → chunk-DLHV7CZN.mjs.map} +0 -0
  398. /package/dist/{chunk-7EXSCXPK.mjs.map → chunk-DMYETMZG.mjs.map} +0 -0
  399. /package/dist/{chunk-OZWPOXVU.mjs.map → chunk-GVGDUCVF.mjs.map} +0 -0
  400. /package/dist/{chunk-LXX5KU3O.mjs.map → chunk-LMDAF6LA.mjs.map} +0 -0
  401. /package/dist/{chunk-TAABXGZL.mjs.map → chunk-O3JP6ZMQ.mjs.map} +0 -0
  402. /package/dist/{chunk-CWGYVJTQ.mjs.map → chunk-PORNR2NU.mjs.map} +0 -0
  403. /package/dist/{chunk-Q56I63FO.mjs.map → chunk-RVGLLMWG.mjs.map} +0 -0
  404. /package/dist/{chunk-QWC5GC2Q.mjs.map → chunk-WY7V5UJN.mjs.map} +0 -0
  405. /package/dist/{chunk-UCWTF336.mjs.map → chunk-YWGJAB63.mjs.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/Quiz/useQuizStore.ts"],"sourcesContent":["import { create } from 'zustand';\nimport { devtools } from 'zustand/middleware';\nimport { QuizVariant } from './Quiz.types';\n\nexport enum QUESTION_DIFFICULTY {\n FACIL = 'FACIL',\n MEDIO = 'MEDIO',\n DIFICIL = 'DIFICIL',\n}\n\n// Enum para tipos de quiz\nexport enum QUIZ_TYPE {\n SIMULADO = 'SIMULADO',\n QUESTIONARIO = 'QUESTIONARIO',\n ATIVIDADE = 'ATIVIDADE',\n AULA_RECOMENDADA = 'AULA_RECOMENDADA',\n}\n\nexport enum QUESTION_TYPE {\n ALTERNATIVA = 'ALTERNATIVA',\n DISSERTATIVA = 'DISSERTATIVA',\n MULTIPLA_ESCOLHA = 'MULTIPLA_ESCOLHA',\n VERDADEIRO_FALSO = 'VERDADEIRO_FALSO',\n RELACIONAR = 'RELACIONAR',\n PREENCHER_LACUNAS = 'PREENCHER_LACUNAS',\n IMAGEM = 'IMAGEM',\n}\n\n/**\n * Determines if a user answer has meaningful content.\n * For option-based questions: checks if optionId is not null\n * For multiple choice questions: checks if selectedOptionIds has items\n * For free-text questions (DISSERTATIVA): checks if answer is non-empty string\n * For structured questions (RELACIONAR, PREENCHER_LACUNAS): checks if answer is valid JSON with values\n *\n * @param answer - The user answer item to check (can be null/undefined)\n * @returns true if the answer has meaningful content, false otherwise\n */\nexport const hasMeaningfulAnswer = (\n answer:\n | {\n optionId: string | null;\n answer: string | null;\n questionType: QUESTION_TYPE;\n selectedOptionIds?: string[] | null;\n }\n | null\n | undefined\n): boolean => {\n if (!answer) return false;\n\n // For MULTIPLA_ESCOLHA, check selectedOptionIds array or legacy optionId\n if (answer.questionType === QUESTION_TYPE.MULTIPLA_ESCOLHA) {\n return (\n (Array.isArray(answer.selectedOptionIds) &&\n answer.selectedOptionIds.length > 0) ||\n Boolean(answer.optionId)\n );\n }\n\n // For free-text question types, check the answer field\n const freeTextTypes = [\n QUESTION_TYPE.DISSERTATIVA,\n QUESTION_TYPE.RELACIONAR,\n QUESTION_TYPE.PREENCHER_LACUNAS,\n QUESTION_TYPE.IMAGEM,\n QUESTION_TYPE.VERDADEIRO_FALSO,\n ];\n\n if (freeTextTypes.includes(answer.questionType)) {\n // Check if answer has content (non-empty string)\n if (!answer.answer || answer.answer.trim() === '') return false;\n\n // For RELACIONAR/PREENCHER_LACUNAS/VERDADEIRO_FALSO, also check if JSON has actual values\n if (\n answer.questionType === QUESTION_TYPE.RELACIONAR ||\n answer.questionType === QUESTION_TYPE.PREENCHER_LACUNAS ||\n answer.questionType === QUESTION_TYPE.VERDADEIRO_FALSO\n ) {\n try {\n const parsed = JSON.parse(answer.answer);\n return typeof parsed === 'object' && Object.keys(parsed).length > 0;\n } catch {\n return false;\n }\n }\n\n // For DISSERTATIVA, non-empty string is meaningful\n return true;\n }\n\n // For option-based question types, check optionId (not null and not empty string)\n return answer.optionId !== null && answer.optionId !== '';\n};\n\nexport enum QUESTION_STATUS {\n PENDENTE_AVALIACAO = 'PENDENTE_AVALIACAO',\n RESPOSTA_CORRETA = 'RESPOSTA_CORRETA',\n RESPOSTA_INCORRETA = 'RESPOSTA_INCORRETA',\n NAO_RESPONDIDO = 'NAO_RESPONDIDO',\n}\n\nexport enum ANSWER_STATUS {\n RESPOSTA_CORRETA = 'RESPOSTA_CORRETA',\n RESPOSTA_INCORRETA = 'RESPOSTA_INCORRETA',\n PENDENTE_AVALIACAO = 'PENDENTE_AVALIACAO',\n NAO_RESPONDIDO = 'NAO_RESPONDIDO',\n}\n\n/**\n * Who produced the correction stored on a dissertative answer.\n *\n * Drives the tag shown next to the feedback. `IA_PROFESSOR` is not a third kind\n * of correction — it is an AI correction a teacher has since reviewed.\n */\nexport enum CORRECTION_SOURCE {\n /** Corrected by the AI, not yet reviewed by a teacher. */\n IA = 'IA',\n /** Corrected by the AI and afterwards reviewed by a teacher. */\n IA_PROFESSOR = 'IA_PROFESSOR',\n /** Corrected by a teacher, with no AI involvement. */\n PROFESSOR = 'PROFESSOR',\n}\n\n/**\n * Lifecycle of the asynchronous AI correction of a dissertative answer.\n *\n * `null` on an answer means the AI was never in play for it — the institution\n * has the feature off — which reads differently from `FAILED`: the first waits\n * on a teacher, the second fell back to waiting on one.\n */\nexport enum AI_CORRECTION_STATUS {\n /** Submitted; the AI correction is still running. */\n PENDING = 'PENDING',\n /** The AI returned a verdict. */\n DONE = 'DONE',\n /** The AI call failed; the answer awaits manual correction. */\n FAILED = 'FAILED',\n}\n\nexport enum SUBTYPE_ENUM {\n PROVA = 'PROVA',\n ENEM_PROVA_1 = 'ENEM_PROVA_1',\n ENEM_PROVA_2 = 'ENEM_PROVA_2',\n VESTIBULAR = 'VESTIBULAR',\n SIMULADO = 'SIMULADO',\n SIMULADAO = 'SIMULADAO',\n}\n\nexport interface QuestionResult {\n answers: {\n id: string;\n questionId: string;\n answer: string | null;\n selectedOptions: {\n optionId: string;\n option?: string;\n isCorrect?: boolean;\n correctValue?: string | null;\n }[];\n answerStatus: ANSWER_STATUS;\n statement: string;\n additionalContent: string | null;\n questionType: QUESTION_TYPE;\n difficultyLevel: QUESTION_DIFFICULTY;\n solutionExplanation: string | null;\n correctOption: string;\n createdAt: string;\n updatedAt: string;\n options?: {\n id: string;\n option: string;\n isCorrect: boolean;\n correctValue?: string | null;\n }[];\n matchingAnswers?: {\n optionId: string;\n selectedValue: string;\n }[];\n fillAnswers?: Record<string, string>;\n knowledgeMatrix: {\n areaKnowledge: {\n id: string;\n name: string;\n } | null;\n subject: {\n id: string;\n name: string;\n color: string;\n icon: string;\n } | null;\n topic: {\n id: string;\n name: string;\n } | null;\n subtopic: {\n id: string;\n name: string;\n } | null;\n content: {\n id: string;\n name: string;\n } | null;\n }[];\n teacherFeedback: string | null;\n /**\n * DISSERTATIVA only: what the AI wrote, kept apart from `teacherFeedback`\n * so a teacher's review never destroys the original verdict. The feedback\n * to render is `teacherFeedback ?? aiFeedback`; `correctionSource` says\n * which of the two produced it.\n */\n aiFeedback?: string | null;\n /** DISSERTATIVA only: the AI's original verdict, before any teacher review. */\n aiIsCorrect?: boolean | null;\n /** DISSERTATIVA only: whether the AI correction is running, done or failed. */\n aiCorrectionStatus?: AI_CORRECTION_STATUS | null;\n /** DISSERTATIVA only: drives the correction tag. */\n correctionSource?: CORRECTION_SOURCE | null;\n /** IMAGEM only: where the student clicked, in image percentage points. */\n imageAnswer?: { coordinateX: number; coordinateY: number } | null;\n /**\n * IMAGEM only: radius within which a click counts as correct, in the same\n * percentage space. Sent by the backend so the drawn target circle matches\n * the grade instead of each client inventing its own.\n */\n imageTolerance?: number | null;\n attachment: string | null;\n score: number | null;\n gradedAt: string | null;\n gradedBy: string | null;\n }[];\n statistics: {\n totalAnswered: number;\n correctAnswers: number;\n incorrectAnswers: number;\n pendingAnswers: number;\n score: number;\n timeSpent: number;\n };\n}\n\nexport interface Question {\n id: string;\n statement: string;\n questionType: QUESTION_TYPE;\n difficultyLevel: QUESTION_DIFFICULTY;\n description: string;\n examBoard: string | null;\n examYear: string | null;\n solutionExplanation: string | null;\n additionalContent: string | null;\n answer: null;\n answerStatus: ANSWER_STATUS;\n options: {\n id: string;\n option: string;\n correctValue?: string | null;\n }[];\n knowledgeMatrix: {\n areaKnowledge: {\n id: string;\n name: string;\n };\n subject: {\n id: string;\n name: string;\n color: string;\n icon: string;\n };\n topic: {\n id: string;\n name: string;\n };\n subtopic: {\n id: string;\n name: string;\n };\n content: {\n id: string;\n name: string;\n };\n }[];\n correctOptionIds?: string[];\n}\n\nexport interface QuizInterface {\n id: string;\n title: string;\n type: QUIZ_TYPE;\n subtype: SUBTYPE_ENUM | string;\n difficulty: string | null;\n notification: string | null;\n status: string;\n startDate: string | null;\n finalDate: string | null;\n canRetry: boolean;\n createdAt: string | null;\n updatedAt: string | null;\n questions: Question[];\n}\n\nexport interface UserAnswerItem {\n questionId: string;\n activityId: string;\n userId: string;\n answer: string | null;\n optionId: string | null;\n selectedOptionIds?: string[] | null;\n questionType: QUESTION_TYPE;\n answerStatus: ANSWER_STATUS;\n}\n\n/**\n * Draft answer item from the backend API\n * Used when loading saved drafts\n */\nexport interface DraftAnswerItem {\n questionId: string;\n answer: string | null;\n optionId: string | null;\n selectedOptionIds?: string[] | null;\n fillAnswers?: Record<string, string> | null;\n matchingAnswers?: Array<{ optionId: string; selectedValue: string }> | null;\n imageAnswer?: { coordinateX: number; coordinateY: number } | null;\n sequence?: number;\n timeSpent?: number;\n}\n\n/**\n * Payload for saving drafts to the backend\n */\nexport interface SaveDraftPayload {\n answers: Array<{\n questionId: string;\n answer?: string | null;\n optionId?: string | null;\n selectedOptionIds?: string[] | null;\n fillAnswers?: Record<string, string> | null;\n matchingAnswers?: Array<{ optionId: string; selectedValue: string }> | null;\n imageAnswer?: { coordinateX: number; coordinateY: number } | null;\n }>;\n}\n\n/**\n * API client interface for draft operations\n * Pass this to the store to enable auto-save functionality\n */\nexport interface DraftApiClient {\n /**\n * Persists the draft.\n *\n * `activityGone` reports that the activity no longer exists — the backend\n * answers 404 for it. The store uses that to stop autosaving instead of\n * retrying a request that can never succeed.\n */\n saveDraft: (\n activityId: string,\n payload: SaveDraftPayload\n ) => Promise<{ success: boolean; activityGone?: boolean }>;\n loadDraft: (activityId: string) => Promise<{\n hasDraft: boolean;\n answers: DraftAnswerItem[];\n } | null>;\n}\n\nexport interface QuizState {\n // Data\n quiz: QuizInterface | null;\n\n // UI State\n currentQuestionIndex: number;\n selectedAnswers: Record<string, string>;\n userAnswers: UserAnswerItem[];\n timeElapsed: number;\n isStarted: boolean;\n isFinished: boolean;\n userId: string;\n variant: QuizVariant;\n minuteCallback: (() => void) | null;\n dissertativeCharLimit?: number;\n timeLimit: number | null;\n onTimeUp: (() => void) | null;\n timeWarningThreshold: number | null;\n onTimeWarning: (() => void) | null;\n hasTimeWarningFired: boolean;\n // Actions\n setQuiz: (quiz: QuizInterface) => void;\n setQuestionResult: (questionResult: QuestionResult) => void;\n setUserId: (userId: string) => void;\n setUserAnswers: (userAnswers: UserAnswerItem[]) => void;\n setVariant: (variant: QuizVariant) => void;\n setDissertativeCharLimit: (limit?: number) => void;\n getDissertativeCharLimit: () => number | undefined;\n // Quiz Navigation\n goToNextQuestion: () => void;\n goToPreviousQuestion: () => void;\n goToQuestion: (index: number) => void;\n\n // Quiz Actions\n selectAnswer: (questionId: string, answerId: string) => void;\n selectMultipleAnswer: (questionId: string, answerIds: string[]) => void;\n selectDissertativeAnswer: (questionId: string, answer: string) => void;\n skipQuestion: () => void;\n skipCurrentQuestionIfUnanswered: () => void;\n addUserAnswer: (questionId: string, answerId?: string) => void;\n startQuiz: (options?: { initialElapsedSeconds?: number }) => void;\n finishQuiz: () => void;\n resetQuiz: () => void;\n\n // Timer\n updateTime: (time: number) => void;\n startTimer: () => void;\n stopTimer: () => void;\n setTimeLimit: (seconds: number | null) => void;\n setOnTimeUp: (callback: (() => void) | null) => void;\n getRemainingTime: () => number | null;\n setTimeWarning: (\n seconds: number | null,\n callback?: (() => void) | null\n ) => void;\n isTimeExceeded: () => boolean;\n\n // Minute Callback\n setMinuteCallback: (callback: (() => void) | null) => void;\n startMinuteCallback: () => void;\n stopMinuteCallback: () => void;\n\n // Getters\n getCurrentQuestion: () => Question | null;\n getTotalQuestions: () => number;\n getAnsweredQuestions: () => number;\n getUnansweredQuestions: () => number[];\n getSkippedQuestions: () => number;\n getProgress: () => number;\n isQuestionAnswered: (questionId: string) => boolean;\n isQuestionSkipped: (questionId: string) => boolean;\n getCurrentAnswer: () => UserAnswerItem | undefined;\n getAllCurrentAnswer: () => UserAnswerItem[] | undefined;\n getQuizTitle: () => string;\n formatTime: (seconds: number) => string;\n getUserAnswers: () => UserAnswerItem[];\n getUnansweredQuestionsFromUserAnswers: () => number[];\n getQuestionsGroupedBySubject: () => {\n [key: string]: (Question | QuestionResult['answers'][number])[];\n };\n getUserId: () => string;\n setCurrentQuestion: (question: Question) => void;\n\n // New methods for userAnswers\n getQuestionIndex: (questionId: string) => number;\n getUserAnswerByQuestionId: (questionId: string) => UserAnswerItem | null;\n isQuestionAnsweredByUserAnswers: (questionId: string) => boolean;\n getQuestionStatusFromUserAnswers: (\n questionId: string\n ) => 'answered' | 'unanswered' | 'skipped';\n getUserAnswersForActivity: () => UserAnswerItem[];\n // Answer status management\n setAnswerStatus: (questionId: string, status: ANSWER_STATUS) => void;\n getAnswerStatus: (questionId: string) => ANSWER_STATUS | null;\n\n // Question Result\n questionsResult: QuestionResult | null;\n currentQuestionResult: QuestionResult['answers'] | null;\n setQuestionsResult: (questionsResult: QuestionResult) => void;\n setCurrentQuestionResult: (\n currentQuestionResult: QuestionResult['answers']\n ) => void;\n getQuestionResultByQuestionId: (\n questionId: string\n ) => QuestionResult['answers'][number] | null;\n getQuestionResultStatistics: () => QuestionResult['statistics'] | null;\n getQuestionResult: () => QuestionResult | null;\n getCurrentQuestionResult: () => QuestionResult['answers'] | null;\n\n // Draft management\n applyDraftAnswers: (draftAnswers: DraftAnswerItem[]) => void;\n prepareDraftPayload: () => SaveDraftPayload;\n hasDraftChanges: () => boolean;\n\n // Draft API client (for auto-save functionality)\n draftApiClient: DraftApiClient | null;\n setDraftApiClient: (client: DraftApiClient | null) => void;\n saveDraft: () => Promise<void>;\n loadAndApplyDraft: () => Promise<void>;\n\n // Internal refs for draft management (not exposed, but tracked in state for reactivity)\n lastSavedDraftPayload: string;\n isSavingDraft: boolean;\n /**\n * Set once the backend reports the activity no longer exists. Autosave stops\n * for the rest of the session: `lastSavedDraftPayload` only advances on\n * success, so without this every question navigation and every\n * `visibilitychange` resends the same doomed payload — one student produced\n * 160 such requests in a day.\n */\n isDraftUnavailable: boolean;\n\n // Activity-level teacher feedback (general observation)\n activityFeedback: {\n teacherFeedback: string | null;\n attachment: string | null;\n } | null;\n setActivityFeedback: (\n feedback: {\n teacherFeedback: string | null;\n attachment: string | null;\n } | null\n ) => void;\n getActivityFeedback: () => {\n teacherFeedback: string | null;\n attachment: string | null;\n } | null;\n}\n\n// Constants\nexport const MINUTE_INTERVAL_MS = 60000; // 60 seconds = 1 minute\n\nexport const useQuizStore = create<QuizState>()(\n devtools(\n (set, get) => {\n let timerInterval: ReturnType<typeof setInterval> | null = null;\n let minuteCallbackInterval: ReturnType<typeof setInterval> | null = null;\n let timerStartedAt: number | null = null;\n let timerBaseElapsed = 0;\n\n const clampElapsed = (elapsed: number) => {\n const { timeLimit } = get();\n return timeLimit === null ? elapsed : Math.min(elapsed, timeLimit);\n };\n\n const handleVisibilityChange = () => {\n if (document.visibilityState === 'visible' && timerStartedAt !== null) {\n const now = Date.now();\n const elapsed = clampElapsed(\n timerBaseElapsed + Math.floor((now - timerStartedAt) / 1000)\n );\n set({ timeElapsed: elapsed });\n checkTimeThresholds(elapsed);\n }\n };\n\n /**\n * Soft threshold: notifies once and lets the clock keep running.\n *\n * Deliberately separate from `timeLimit` below, which is a hard stop that\n * submits the quiz. A progressive exam timer needs the opposite — the\n * student is told they went over the expected duration and carries on.\n */\n const checkTimeWarning = (elapsed: number) => {\n const { timeWarningThreshold, hasTimeWarningFired, onTimeWarning } =\n get();\n\n if (\n timeWarningThreshold !== null &&\n elapsed >= timeWarningThreshold &&\n !hasTimeWarningFired\n ) {\n set({ hasTimeWarningFired: true });\n onTimeWarning?.();\n }\n };\n\n const checkTimeThresholds = (elapsed: number) => {\n checkTimeWarning(elapsed);\n\n const { timeLimit, isFinished, onTimeUp } = get();\n if (timeLimit !== null && elapsed >= timeLimit && !isFinished) {\n get().finishQuiz();\n onTimeUp?.();\n }\n };\n\n const startTimer = () => {\n if (get().isFinished) {\n return;\n }\n\n if (timerInterval) {\n clearInterval(timerInterval);\n }\n\n timerStartedAt = Date.now();\n timerBaseElapsed = get().timeElapsed;\n\n document.addEventListener('visibilitychange', handleVisibilityChange);\n\n timerInterval = setInterval(() => {\n if (timerStartedAt === null) return;\n const now = Date.now();\n const elapsed = clampElapsed(\n timerBaseElapsed + Math.floor((now - timerStartedAt) / 1000)\n );\n set({ timeElapsed: elapsed });\n checkTimeThresholds(elapsed);\n }, 1000);\n };\n\n const stopTimer = () => {\n if (timerInterval) {\n clearInterval(timerInterval);\n timerInterval = null;\n }\n timerStartedAt = null;\n timerBaseElapsed = 0;\n document.removeEventListener(\n 'visibilitychange',\n handleVisibilityChange\n );\n };\n\n const setMinuteCallback = (callback: (() => void) | null) => {\n set({ minuteCallback: callback });\n };\n\n const startMinuteCallback = () => {\n const { minuteCallback, isFinished } = get();\n\n if (isFinished || !minuteCallback) {\n return;\n }\n\n if (minuteCallbackInterval) {\n clearInterval(minuteCallbackInterval);\n }\n\n minuteCallbackInterval = setInterval(() => {\n const {\n minuteCallback: currentCallback,\n isFinished: currentIsFinished,\n } = get();\n\n if (currentIsFinished || !currentCallback) {\n stopMinuteCallback();\n return;\n }\n\n currentCallback();\n }, MINUTE_INTERVAL_MS);\n };\n\n const stopMinuteCallback = () => {\n if (minuteCallbackInterval) {\n clearInterval(minuteCallbackInterval);\n minuteCallbackInterval = null;\n }\n };\n\n return {\n // Initial State\n quiz: null,\n currentQuestionIndex: 0,\n selectedAnswers: {},\n userAnswers: [],\n timeElapsed: 0,\n isStarted: false,\n isFinished: false,\n userId: '',\n variant: QuizVariant.DEFAULT,\n minuteCallback: null,\n dissertativeCharLimit: undefined,\n timeLimit: null,\n onTimeUp: null,\n timeWarningThreshold: null,\n onTimeWarning: null,\n hasTimeWarningFired: false,\n questionsResult: null,\n currentQuestionResult: null,\n draftApiClient: null,\n lastSavedDraftPayload: '',\n isSavingDraft: false,\n isDraftUnavailable: false,\n activityFeedback: null,\n // Setters\n setQuiz: (quiz) => set({ quiz }),\n setUserId: (userId) => set({ userId }),\n setUserAnswers: (userAnswers) => set({ userAnswers }),\n getUserId: () => get().userId,\n setVariant: (variant) => set({ variant }),\n setQuestionResult: (questionsResult) => set({ questionsResult }),\n setDissertativeCharLimit: (limit?: number) =>\n set({ dissertativeCharLimit: limit }),\n getDissertativeCharLimit: () => get().dissertativeCharLimit,\n setDraftApiClient: (client) => set({ draftApiClient: client }),\n\n // Draft save - called automatically on navigation\n saveDraft: async () => {\n const {\n draftApiClient,\n quiz,\n hasDraftChanges,\n prepareDraftPayload,\n lastSavedDraftPayload,\n isSavingDraft,\n isDraftUnavailable,\n } = get();\n\n // Skip if no API client configured or no quiz\n if (!draftApiClient || !quiz) return;\n\n // The activity is gone; there is nothing to save into.\n if (isDraftUnavailable) return;\n\n // Skip if already saving\n if (isSavingDraft) return;\n\n // Skip if no changes\n if (!hasDraftChanges()) return;\n\n const payload = prepareDraftPayload();\n const payloadString = JSON.stringify(payload);\n\n // Skip if payload hasn't changed\n if (payloadString === lastSavedDraftPayload) return;\n\n try {\n set({ isSavingDraft: true });\n const result = await draftApiClient.saveDraft(quiz.id, payload);\n\n if (result?.activityGone) {\n set({ isDraftUnavailable: true });\n return;\n }\n\n set({ lastSavedDraftPayload: payloadString });\n } catch (error) {\n // Silent fail - don't interrupt user experience\n console.warn('Erro ao salvar rascunho:', error);\n } finally {\n set({ isSavingDraft: false });\n }\n },\n\n // Load draft and apply to quiz, navigate to first unanswered question\n loadAndApplyDraft: async () => {\n const {\n draftApiClient,\n quiz,\n applyDraftAnswers,\n prepareDraftPayload,\n } = get();\n\n // Skip if no API client configured or no quiz\n if (!draftApiClient || !quiz) return;\n\n try {\n const draftData = await draftApiClient.loadDraft(quiz.id);\n\n if (draftData?.hasDraft && draftData.answers?.length > 0) {\n applyDraftAnswers(draftData.answers);\n\n // Update last saved payload to prevent immediate re-save\n const payload = prepareDraftPayload();\n set({ lastSavedDraftPayload: JSON.stringify(payload) });\n\n // Navigate to first unanswered question\n const questions = get().quiz?.questions || [];\n const updatedAnswers = get().userAnswers;\n\n const firstUnansweredIndex = questions.findIndex((question) => {\n const answer = updatedAnswers.find(\n (a) => a.questionId === question.id\n );\n if (!answer) return true;\n if (answer.optionId) return false;\n if (\n answer.selectedOptionIds &&\n answer.selectedOptionIds.length > 0\n )\n return false;\n if (answer.answer && answer.answer.trim() !== '') return false;\n return true;\n });\n\n if (firstUnansweredIndex > 0) {\n // Navigate without triggering save (internal navigation)\n set({ currentQuestionIndex: firstUnansweredIndex });\n }\n }\n } catch (error) {\n // Silent fail - user can continue fresh\n console.warn('Erro ao carregar rascunho:', error);\n }\n },\n\n // Navigation\n goToNextQuestion: () => {\n const { currentQuestionIndex, getTotalQuestions, saveDraft } = get();\n const totalQuestions = getTotalQuestions();\n\n if (currentQuestionIndex < totalQuestions - 1) {\n // Save draft before navigating\n saveDraft();\n set({ currentQuestionIndex: currentQuestionIndex + 1 });\n }\n },\n\n goToPreviousQuestion: () => {\n const { currentQuestionIndex, saveDraft } = get();\n\n if (currentQuestionIndex > 0) {\n // Save draft before navigating\n saveDraft();\n set({ currentQuestionIndex: currentQuestionIndex - 1 });\n }\n },\n\n goToQuestion: (index) => {\n const { getTotalQuestions, currentQuestionIndex, saveDraft } = get();\n const totalQuestions = getTotalQuestions();\n\n if (\n index >= 0 &&\n index < totalQuestions &&\n index !== currentQuestionIndex\n ) {\n // Save draft before navigating\n saveDraft();\n set({ currentQuestionIndex: index });\n }\n },\n\n selectAnswer: (questionId, answerId) => {\n const { quiz, userAnswers } = get();\n\n if (!quiz) return;\n\n const activityId = quiz.id;\n const userId = get().getUserId();\n\n if (!userId || userId === '') {\n // Silent validation - userId not set\n return;\n }\n\n const question = quiz.questions.find((q) => q.id === questionId);\n if (!question) return;\n\n const existingAnswerIndex = userAnswers.findIndex(\n (answer) => answer.questionId === questionId\n );\n\n const newUserAnswer: UserAnswerItem = {\n questionId,\n activityId,\n userId,\n answer:\n question.questionType === QUESTION_TYPE.DISSERTATIVA\n ? answerId\n : null,\n optionId:\n question.questionType === QUESTION_TYPE.DISSERTATIVA\n ? null\n : answerId,\n questionType: question.questionType,\n answerStatus: ANSWER_STATUS.PENDENTE_AVALIACAO,\n };\n\n let updatedUserAnswers;\n if (existingAnswerIndex !== -1) {\n updatedUserAnswers = [...userAnswers];\n updatedUserAnswers[existingAnswerIndex] = newUserAnswer;\n } else {\n updatedUserAnswers = [...userAnswers, newUserAnswer];\n }\n\n set({\n userAnswers: updatedUserAnswers,\n });\n },\n\n selectMultipleAnswer: (questionId, answerIds) => {\n const { quiz, userAnswers } = get();\n\n if (!quiz) return;\n\n const activityId = quiz.id;\n const userId = get().getUserId();\n\n if (!userId || userId === '') {\n // Silent validation - userId not set\n return;\n }\n\n const question = quiz.questions.find((q) => q.id === questionId);\n if (!question) return;\n\n // Remove all existing answers for this questionId\n const filteredUserAnswers = userAnswers.filter(\n (answer) => answer.questionId !== questionId\n );\n\n // Don't persist empty MULTIPLA_ESCOLHA answers\n if (answerIds.length === 0) {\n set({\n userAnswers: filteredUserAnswers,\n });\n return;\n }\n\n // Create a single UserAnswerItem with selectedOptionIds array\n // This matches the backend API expected format for MULTIPLA_ESCOLHA\n // Also set optionId to first selection for backward compatibility\n const newUserAnswer: UserAnswerItem = {\n questionId,\n activityId,\n userId,\n answer: null,\n optionId: answerIds.length > 0 ? answerIds[0] : null,\n selectedOptionIds: answerIds,\n questionType: question.questionType,\n answerStatus: ANSWER_STATUS.PENDENTE_AVALIACAO,\n };\n\n const updatedUserAnswers = [...filteredUserAnswers, newUserAnswer];\n\n set({\n userAnswers: updatedUserAnswers,\n });\n },\n\n selectDissertativeAnswer: (questionId, answer) => {\n const { quiz, userAnswers, dissertativeCharLimit } = get();\n\n if (!quiz) return;\n\n const activityId = quiz.id;\n const userId = get().getUserId();\n\n if (!userId || userId === '') {\n // Silent validation - userId not set\n return;\n }\n\n const question = quiz.questions.find((q) => q.id === questionId);\n // Allow free-text question types: DISSERTATIVA, RELACIONAR, PREENCHER_LACUNAS, IMAGEM, VERDADEIRO_FALSO\n const allowedTypes = [\n QUESTION_TYPE.DISSERTATIVA,\n QUESTION_TYPE.RELACIONAR,\n QUESTION_TYPE.PREENCHER_LACUNAS,\n QUESTION_TYPE.IMAGEM,\n QUESTION_TYPE.VERDADEIRO_FALSO,\n ];\n if (!question || !allowedTypes.includes(question.questionType)) {\n // Silent validation - wrong question type\n return;\n }\n\n // Validate character limit if set (only for DISSERTATIVA)\n let validatedAnswer = answer;\n if (\n question.questionType === QUESTION_TYPE.DISSERTATIVA &&\n dissertativeCharLimit !== undefined &&\n answer.length > dissertativeCharLimit\n ) {\n validatedAnswer = answer.substring(0, dissertativeCharLimit);\n }\n\n const existingAnswerIndex = userAnswers.findIndex(\n (answerItem) => answerItem.questionId === questionId\n );\n\n const newUserAnswer: UserAnswerItem = {\n questionId,\n activityId,\n userId,\n answer: validatedAnswer,\n optionId: null,\n questionType: question.questionType,\n answerStatus: ANSWER_STATUS.PENDENTE_AVALIACAO,\n };\n\n let updatedUserAnswers;\n if (existingAnswerIndex !== -1) {\n updatedUserAnswers = [...userAnswers];\n updatedUserAnswers[existingAnswerIndex] = newUserAnswer;\n } else {\n updatedUserAnswers = [...userAnswers, newUserAnswer];\n }\n\n set({\n userAnswers: updatedUserAnswers,\n });\n },\n\n skipQuestion: () => {\n const { getCurrentQuestion, userAnswers, quiz } = get();\n const currentQuestion = getCurrentQuestion();\n\n if (!quiz) return;\n\n if (currentQuestion) {\n const activityId = quiz.id;\n const userId = get().getUserId();\n\n if (!userId || userId === '') {\n // Silent validation - userId not set\n return;\n }\n\n const existingAnswerIndex = userAnswers.findIndex(\n (answer) => answer.questionId === currentQuestion.id\n );\n const existingAnswer =\n existingAnswerIndex === -1\n ? null\n : userAnswers[existingAnswerIndex];\n\n // If the user already has an answer with meaningful content, preserve it\n if (hasMeaningfulAnswer(existingAnswer)) {\n // Keep existing answers - don't overwrite with empty skip\n return;\n }\n\n // Create empty \"skipped\" entry\n const newUserAnswer: UserAnswerItem = {\n questionId: currentQuestion.id,\n activityId,\n userId,\n answer: null,\n optionId: null,\n questionType: currentQuestion.questionType,\n answerStatus: ANSWER_STATUS.PENDENTE_AVALIACAO,\n };\n\n let updatedUserAnswers;\n if (existingAnswerIndex !== -1) {\n // Update existing empty entry to proper \"skipped\" format\n updatedUserAnswers = [...userAnswers];\n updatedUserAnswers[existingAnswerIndex] = newUserAnswer;\n } else {\n // Add new skipped entry\n updatedUserAnswers = [...userAnswers, newUserAnswer];\n }\n\n set({\n userAnswers: updatedUserAnswers,\n });\n }\n },\n\n skipCurrentQuestionIfUnanswered: () => {\n const { getCurrentQuestion, getCurrentAnswer, skipQuestion } = get();\n const currentQuestion = getCurrentQuestion();\n const currentAnswer = getCurrentAnswer();\n\n // Se não há questão atual, não faz nada\n if (!currentQuestion) return;\n\n // Se não há resposta ou a resposta está vazia (null), marca como pulada\n // Considera selectedOptionIds para MULTIPLA_ESCOLHA\n if (\n !currentAnswer ||\n (currentAnswer.optionId === null &&\n currentAnswer.answer === null &&\n (!currentAnswer.selectedOptionIds ||\n currentAnswer.selectedOptionIds.length === 0))\n ) {\n skipQuestion();\n }\n },\n\n addUserAnswer: (questionId, answerId) => {\n const { quiz, userAnswers } = get();\n\n if (!quiz) return;\n\n // Add to userAnswers array with new structure\n const activityId = quiz.id;\n const userId = get().getUserId();\n\n if (!userId || userId === '') {\n // Silent validation - userId not set\n return;\n }\n\n const question = quiz.questions.find((q) => q.id === questionId);\n if (!question) return;\n\n const existingAnswerIndex = userAnswers.findIndex(\n (answer) => answer.questionId === questionId\n );\n\n const newUserAnswer: UserAnswerItem = {\n questionId,\n activityId,\n userId,\n answer:\n question.questionType === QUESTION_TYPE.DISSERTATIVA\n ? answerId || null\n : null,\n optionId:\n question.questionType !== QUESTION_TYPE.DISSERTATIVA\n ? answerId || null\n : null,\n questionType: question.questionType,\n answerStatus: ANSWER_STATUS.PENDENTE_AVALIACAO,\n };\n\n if (existingAnswerIndex !== -1) {\n // Update existing answer\n const updatedUserAnswers = [...userAnswers];\n updatedUserAnswers[existingAnswerIndex] = newUserAnswer;\n set({ userAnswers: updatedUserAnswers });\n } else {\n // Add new answer\n set({ userAnswers: [...userAnswers, newUserAnswer] });\n }\n },\n\n startQuiz: (options) => {\n // `initialElapsedSeconds` seeds the stopwatch when resuming an exam\n // the student had already started, so the count picks up from the\n // second it stopped at instead of restarting. startTimer() reads\n // timeElapsed as its base, so setting it here is enough.\n const initialElapsedSeconds = options?.initialElapsedSeconds ?? 0;\n set({ isStarted: true, timeElapsed: initialElapsedSeconds });\n startTimer();\n startMinuteCallback();\n checkTimeWarning(initialElapsedSeconds);\n },\n\n finishQuiz: () => {\n set({ isFinished: true });\n stopTimer();\n stopMinuteCallback();\n },\n\n resetQuiz: () => {\n stopTimer();\n stopMinuteCallback();\n set({\n quiz: null,\n currentQuestionIndex: 0,\n selectedAnswers: {},\n userAnswers: [],\n timeElapsed: 0,\n isStarted: false,\n isFinished: false,\n userId: '',\n variant: QuizVariant.DEFAULT,\n minuteCallback: null,\n dissertativeCharLimit: undefined,\n timeLimit: null,\n onTimeUp: null,\n timeWarningThreshold: null,\n onTimeWarning: null,\n hasTimeWarningFired: false,\n questionsResult: null,\n currentQuestionResult: null,\n // Note: draftApiClient is NOT reset here - it's managed by useDraftAutoSave hook\n lastSavedDraftPayload: '',\n isSavingDraft: false,\n // Scoped to the activity that was open: the next quiz has its own\n // existence, so leaving this set would silently disable autosave\n // for it too.\n isDraftUnavailable: false,\n activityFeedback: null,\n });\n },\n\n // Timer\n updateTime: (time) => {\n timerBaseElapsed = time;\n if (timerStartedAt !== null) {\n timerStartedAt = Date.now();\n }\n set({ timeElapsed: time });\n checkTimeThresholds(time);\n },\n startTimer,\n stopTimer,\n setTimeLimit: (seconds) => set({ timeLimit: seconds }),\n setOnTimeUp: (callback) => set({ onTimeUp: callback }),\n getRemainingTime: () => {\n const { timeLimit, timeElapsed } = get();\n if (timeLimit === null) return null;\n return Math.max(0, timeLimit - timeElapsed);\n },\n setTimeWarning: (seconds, callback) =>\n set({\n timeWarningThreshold: seconds,\n onTimeWarning: callback ?? null,\n // A new threshold is a new warning: rearm it, otherwise raising the\n // limit mid-exam would leave the student without the notice.\n hasTimeWarningFired: false,\n }),\n isTimeExceeded: () => {\n const { timeWarningThreshold, timeElapsed } = get();\n if (timeWarningThreshold === null) return false;\n return timeElapsed >= timeWarningThreshold;\n },\n\n // Minute Callback\n setMinuteCallback,\n startMinuteCallback,\n stopMinuteCallback,\n\n // Getters\n getCurrentQuestion: () => {\n const { currentQuestionIndex, quiz } = get();\n\n if (!quiz) {\n return null;\n }\n\n return quiz.questions[currentQuestionIndex];\n },\n\n getTotalQuestions: () => {\n const { quiz } = get();\n\n return quiz?.questions?.length || 0;\n },\n\n getAnsweredQuestions: () => {\n const { userAnswers } = get();\n const answeredQuestionIds = new Set(\n userAnswers\n .filter((answer) => hasMeaningfulAnswer(answer))\n .map((answer) => answer.questionId)\n );\n return answeredQuestionIds.size;\n },\n\n getUnansweredQuestions: () => {\n const { quiz, userAnswers } = get();\n if (!quiz) return [];\n\n const unansweredQuestions: number[] = [];\n\n quiz.questions.forEach((question, index) => {\n const userAnswer = userAnswers.find(\n (answer) => answer.questionId === question.id\n );\n const isAnswered = hasMeaningfulAnswer(userAnswer);\n // Question is skipped if it has a userAnswer entry but no meaningful content\n const isSkipped = userAnswer && !hasMeaningfulAnswer(userAnswer);\n\n if (!isAnswered && !isSkipped) {\n unansweredQuestions.push(index + 1); // index + 1 para mostrar número da questão\n }\n });\n return unansweredQuestions;\n },\n\n getSkippedQuestions: () => {\n const { userAnswers } = get();\n const skippedQuestionIds = new Set(\n userAnswers\n .filter((answer) => !hasMeaningfulAnswer(answer))\n .map((answer) => answer.questionId)\n );\n return skippedQuestionIds.size;\n },\n\n getProgress: () => {\n const { getTotalQuestions, getAnsweredQuestions } = get();\n const total = getTotalQuestions();\n const answered = getAnsweredQuestions();\n\n return total > 0 ? (answered / total) * 100 : 0;\n },\n\n isQuestionAnswered: (questionId) => {\n const { userAnswers } = get();\n const userAnswer = userAnswers.find(\n (answer) => answer.questionId === questionId\n );\n return hasMeaningfulAnswer(userAnswer);\n },\n\n isQuestionSkipped: (questionId) => {\n const { userAnswers } = get();\n const userAnswer = userAnswers.find(\n (answer) => answer.questionId === questionId\n );\n // Question is skipped if it has a userAnswer entry but no meaningful content\n return userAnswer ? !hasMeaningfulAnswer(userAnswer) : false;\n },\n\n getCurrentAnswer: () => {\n const { getCurrentQuestion, userAnswers } = get();\n const currentQuestion = getCurrentQuestion();\n\n if (!currentQuestion) return undefined;\n\n const userAnswer = userAnswers.find(\n (answer) => answer.questionId === currentQuestion.id\n );\n\n // Retorna undefined se a resposta está vazia (não respondida)\n if (!hasMeaningfulAnswer(userAnswer)) {\n return undefined;\n }\n\n return userAnswer;\n },\n\n getAllCurrentAnswer: () => {\n const { getCurrentQuestion, userAnswers } = get();\n const currentQuestion = getCurrentQuestion();\n\n if (!currentQuestion) return undefined;\n\n const userAnswer = userAnswers.filter(\n (answer) => answer.questionId === currentQuestion.id\n );\n\n return userAnswer;\n },\n\n getQuizTitle: () => {\n const { quiz } = get();\n\n return quiz?.title || 'Quiz';\n },\n\n formatTime: (seconds: number) => {\n const minutes = Math.floor(seconds / 60);\n const remainingSeconds = seconds % 60;\n return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`;\n },\n\n getUserAnswers: () => {\n const { userAnswers } = get();\n return userAnswers;\n },\n\n getUnansweredQuestionsFromUserAnswers: () => {\n const { quiz, userAnswers } = get();\n if (!quiz) return [];\n\n const unansweredQuestions: number[] = [];\n\n quiz.questions.forEach((question, index) => {\n const userAnswer = userAnswers.find(\n (answer) => answer.questionId === question.id\n );\n const hasAnswer = hasMeaningfulAnswer(userAnswer);\n // Question is skipped if it has a userAnswer entry but no meaningful content\n const isSkipped = userAnswer && !hasMeaningfulAnswer(userAnswer);\n\n // Se não há resposta do usuário OU se a questão foi pulada\n if (!hasAnswer || isSkipped) {\n unansweredQuestions.push(index + 1); // index + 1 para mostrar número da questão\n }\n });\n\n return unansweredQuestions;\n },\n\n getQuestionsGroupedBySubject: () => {\n const { getQuestionResult, quiz, variant } = get();\n const questions =\n variant == 'result'\n ? getQuestionResult()?.answers\n : quiz?.questions;\n if (!questions) return {};\n const groupedQuestions: {\n [key: string]: (Question | QuestionResult['answers'][number])[];\n } = {};\n questions.forEach((question) => {\n const subjectId =\n question.knowledgeMatrix?.[0]?.subject?.id || 'Sem matéria';\n\n if (!groupedQuestions[subjectId]) {\n groupedQuestions[subjectId] = [];\n }\n\n groupedQuestions[subjectId].push(question);\n });\n\n return groupedQuestions;\n },\n\n // New methods for userAnswers\n getUserAnswerByQuestionId: (questionId) => {\n const { userAnswers } = get();\n return (\n userAnswers.find((answer) => answer.questionId === questionId) ||\n null\n );\n },\n isQuestionAnsweredByUserAnswers: (questionId) => {\n const { userAnswers } = get();\n const answer = userAnswers.find(\n (answer) => answer.questionId === questionId\n );\n return hasMeaningfulAnswer(answer);\n },\n getQuestionStatusFromUserAnswers: (questionId) => {\n const { userAnswers } = get();\n const answer = userAnswers.find(\n (answer) => answer.questionId === questionId\n );\n if (!answer) return 'unanswered';\n if (hasMeaningfulAnswer(answer)) return 'answered';\n return 'skipped';\n },\n getUserAnswersForActivity: () => {\n const { userAnswers } = get();\n return userAnswers;\n },\n setCurrentQuestion: (question) => {\n const { quiz, variant, questionsResult } = get();\n if (!quiz) return;\n let questionIndex: number;\n if (variant == 'result') {\n if (!questionsResult) return;\n const questionResult =\n questionsResult.answers.find((q) => q.id === question.id) ??\n questionsResult.answers.find((q) => q.questionId === question.id);\n if (!questionResult) return;\n questionIndex = quiz.questions.findIndex(\n (q) => q.id === questionResult.questionId\n );\n } else {\n questionIndex = quiz.questions.findIndex(\n (q) => q.id === question.id\n );\n }\n\n // Validate that the question was found before updating currentQuestionIndex\n if (questionIndex === -1) {\n // Silent validation - question not found\n return;\n }\n\n set({ currentQuestionIndex: questionIndex });\n },\n\n setAnswerStatus: (questionId, status) => {\n const { userAnswers } = get();\n const existingAnswerIndex = userAnswers.findIndex(\n (answer) => answer.questionId === questionId\n );\n\n if (existingAnswerIndex !== -1) {\n const updatedUserAnswers = [...userAnswers];\n updatedUserAnswers[existingAnswerIndex] = {\n ...updatedUserAnswers[existingAnswerIndex],\n answerStatus: status,\n };\n set({ userAnswers: updatedUserAnswers });\n }\n },\n\n getAnswerStatus: (questionId) => {\n const { userAnswers } = get();\n const userAnswer = userAnswers.find(\n (answer) => answer.questionId === questionId\n );\n return userAnswer ? userAnswer.answerStatus : null;\n },\n getQuestionIndex: (questionId) => {\n const { questionsResult, variant, quiz } = get();\n if (variant == 'result') {\n if (!questionsResult) return 0;\n\n let idx = questionsResult.answers.findIndex(\n (q) => q.questionId === questionId\n );\n if (idx === -1) {\n idx = questionsResult.answers.findIndex(\n (q) => q.id === questionId\n );\n }\n return idx !== -1 ? idx + 1 : 0;\n } else {\n if (!quiz) return 0;\n const idx = quiz.questions.findIndex((q) => q.id === questionId);\n return idx !== -1 ? idx + 1 : 0;\n }\n },\n\n // Question Result\n getQuestionResultByQuestionId: (questionId) => {\n const { questionsResult } = get();\n const question = questionsResult?.answers.find(\n (answer) => answer.questionId === questionId\n );\n\n return question || null;\n },\n getQuestionResultStatistics: () => {\n const { questionsResult } = get();\n return questionsResult?.statistics || null;\n },\n getQuestionResult: () => {\n const { questionsResult } = get();\n return questionsResult;\n },\n setQuestionsResult: (questionsResult) => {\n set({ questionsResult });\n },\n setCurrentQuestionResult: (currentQuestionResult) => {\n set({ currentQuestionResult });\n },\n getCurrentQuestionResult: () => {\n const { currentQuestionResult } = get();\n return currentQuestionResult;\n },\n\n // Draft management\n applyDraftAnswers: (draftAnswers) => {\n const { quiz, userId } = get();\n if (!quiz || !draftAnswers || draftAnswers.length === 0) return;\n\n const activityId = quiz.id;\n const newUserAnswers: UserAnswerItem[] = [];\n\n for (const draft of draftAnswers) {\n const question = quiz.questions.find(\n (q) => q.id === draft.questionId\n );\n if (!question) continue;\n\n // Parse answer if it's a JSON string (for complex answer types)\n let parsedAnswer = draft.answer;\n let selectedOptionIds = draft.selectedOptionIds;\n\n // Try to parse JSON answer for complex types\n if (draft.answer && !draft.optionId) {\n try {\n const parsed = JSON.parse(draft.answer);\n if (parsed.selectedOptionIds) {\n selectedOptionIds = parsed.selectedOptionIds;\n parsedAnswer = null;\n }\n } catch {\n // Not JSON, keep as plain text\n }\n }\n\n const userAnswer: UserAnswerItem = {\n questionId: draft.questionId,\n activityId,\n userId,\n answer: parsedAnswer,\n optionId: draft.optionId || null,\n selectedOptionIds: selectedOptionIds || null,\n questionType: question.questionType,\n answerStatus: ANSWER_STATUS.PENDENTE_AVALIACAO,\n };\n\n newUserAnswers.push(userAnswer);\n }\n\n set({ userAnswers: newUserAnswers });\n },\n\n prepareDraftPayload: () => {\n const { userAnswers } = get();\n\n const answers = userAnswers\n .filter((answer) => hasMeaningfulAnswer(answer))\n .map((answer) => {\n const draftAnswer: SaveDraftPayload['answers'][number] = {\n questionId: answer.questionId,\n };\n\n if (answer.optionId) {\n draftAnswer.optionId = answer.optionId;\n }\n\n if (answer.answer) {\n draftAnswer.answer = answer.answer;\n }\n\n if (\n answer.selectedOptionIds &&\n answer.selectedOptionIds.length > 0\n ) {\n draftAnswer.selectedOptionIds = answer.selectedOptionIds;\n }\n\n return draftAnswer;\n });\n\n return { answers };\n },\n\n hasDraftChanges: () => {\n const { userAnswers } = get();\n return userAnswers.some((answer) => hasMeaningfulAnswer(answer));\n },\n\n // Activity Feedback\n setActivityFeedback: (feedback) => set({ activityFeedback: feedback }),\n getActivityFeedback: () => get().activityFeedback,\n };\n },\n {\n name: 'quiz-store',\n }\n )\n);\n"],"mappings":"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","names":["QUESTION_DIFFICULTY","QUIZ_TYPE","QUESTION_TYPE","QUESTION_STATUS","ANSWER_STATUS","CORRECTION_SOURCE","AI_CORRECTION_STATUS","SUBTYPE_ENUM","answer"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-GYQUB3VW.js","../src/components/Quiz/Quiz.utils.ts"],"names":[],"mappings":"AAAA;ACcO,IAAM,eAAA,EAAiB,CAC5B,SAAA,EACA,QAAA,EAAA,GACW;AACX,EAAA,GAAA,CAAI,UAAA,GAAa,QAAA,EAAU;AACzB,IAAA,OAAO,CAAA,CAAA,EAAI,SAAS,CAAA,GAAA,EAAM,QAAQ,CAAA,CAAA,CAAA;AAAA,EACpC;AACA,EAAA,GAAA,CAAI,SAAA,EAAW;AACb,IAAA,OAAO,CAAA,CAAA,EAAI,SAAS,CAAA,CAAA,CAAA;AAAA,EACtB;AACA,EAAA,GAAA,CAAI,QAAA,EAAU;AACZ,IAAA,OAAO,CAAA,CAAA,EAAI,QAAQ,CAAA,CAAA,CAAA;AAAA,EACrB;AACA,EAAA,OAAO,EAAA;AACT,CAAA;AAMO,IAAM,gBAAA,EAAkB,CAAI,KAAA,EAAY,IAAA,EAAA,GAAsB;AACnE,EAAA,MAAM,SAAA,EAAW,CAAC,GAAG,KAAK,CAAA;AAE1B,EAAA,IAAI,KAAA,EAAO,CAAA;AACX,EAAA,IAAA,CAAA,IAAS,EAAA,EAAI,CAAA,EAAG,EAAA,EAAI,IAAA,CAAK,MAAA,EAAQ,CAAA,EAAA,EAAK;AACpC,IAAA,MAAM,KAAA,mBAAO,IAAA,CAAK,WAAA,CAAY,CAAC,CAAA,UAAK,GAAA;AACpC,IAAA,KAAA,EAAA,CAAQ,KAAA,GAAQ,CAAA,EAAA,EAAK,KAAA,EAAO,IAAA;AAC5B,IAAA,KAAA,EAAO,KAAA,EAAO,IAAA;AAAA,EAChB;AAEA,EAAA,MAAM,aAAA,EAAe,CAAC,GAAA,EAAA,GAAgB;AACpC,IAAA,KAAA,EAAQ,KAAA,EAAO,WAAA,EAAa,MAAA,EAAS,UAAA;AACrC,IAAA,OAAO,KAAA,EAAO,GAAA;AAAA,EAChB,CAAA;AACA,EAAA,IAAA,CAAA,IAAS,EAAA,EAAI,QAAA,CAAS,OAAA,EAAS,CAAA,EAAG,EAAA,EAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC5C,IAAA,MAAM,EAAA,EAAI,YAAA,CAAa,EAAA,EAAI,CAAC,CAAA;AAC5B,IAAA,CAAC,QAAA,CAAS,CAAC,CAAA,EAAG,QAAA,CAAS,CAAC,CAAC,EAAA,EAAI,CAAC,QAAA,CAAS,CAAC,CAAA,EAAG,QAAA,CAAS,CAAC,CAAC,CAAA;AAAA,EACxD;AACA,EAAA,OAAO,QAAA;AACT,CAAA;AAOO,IAAM,oBAAA,EAAsB,CAAC,MAAA,EAAgB,IAAA,EAAA,GAAyB;AAC3E,EAAA,GAAA,CAAI,IAAA,CAAK,IAAA,CAAK,CAAA,CAAE,UAAA,CAAW,KAAK,CAAA,EAAG;AACjC,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,WAAA,EAAa,CAAA,EAAA,EAAK,MAAM,CAAA,EAAA,CAAI,CAAA;AAAA,EAClD;AACA,EAAA,OAAO,CAAA,EAAA;AACT;AAMa;AAOL,EAAA;AACH,IAAA;AACH,EAAA;AACM,EAAA;AAMA,EAAA;AAGG,IAAA;AAEH,EAAA;AAGA,EAAA;AAKA,EAAA;AAMA,EAAA;AACA,IAAA;AACF,MAAA;AACF,IAAA;AACK,IAAA;AACH,MAAA;AACF,IAAA;AACA,IAAA;AACF,EAAA;AACM,EAAA;AAEA,EAAA;AAGA,EAAA;AACA,EAAA;AAIC,EAAA;AACL,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACF,EAAA;AACF;ADhEU;AACA;AACA;AACA;AACA;AACA;AACA","file":"/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-GYQUB3VW.js","sourcesContent":[null,"import {\n QuizVariant,\n type QuestionAnswerResult,\n type TrueOrFalseOptionState,\n} from './Quiz.types';\nimport { TrueFalseEnum } from '../../enums/Quiz';\nimport { OptionStatus } from '../../enums/Options';\n\n/**\n * Helper function to format exam info (bank - year)\n * @param examBoard - The exam board/bank name\n * @param examYear - The exam year\n * @returns Formatted string like \"(ENEM - 2023)\" or empty string if no info\n */\nexport const formatExamInfo = (\n examBoard: string | null | undefined,\n examYear: string | null | undefined\n): string => {\n if (examBoard && examYear) {\n return `(${examBoard} - ${examYear})`;\n }\n if (examBoard) {\n return `(${examBoard})`;\n }\n if (examYear) {\n return `(${examYear})`;\n }\n return '';\n};\n\n/**\n * Shuffle array using a seed for consistent ordering per question\n * Uses Fisher-Yates shuffle with seeded random for deterministic results\n */\nexport const shuffleWithSeed = <T>(array: T[], seed: string): T[] => {\n const shuffled = [...array];\n // Simple hash function to convert string seed to number\n let hash = 0;\n for (let i = 0; i < seed.length; i++) {\n const char = seed.codePointAt(i) ?? 0;\n hash = (hash << 5) - hash + char;\n hash = hash & hash; // Convert to 32bit integer\n }\n // Fisher-Yates shuffle with seeded random\n const seededRandom = (max: number) => {\n hash = (hash * 1103515245 + 12345) & 0x7fffffff;\n return hash % max;\n };\n for (let i = shuffled.length - 1; i > 0; i--) {\n const j = seededRandom(i + 1);\n [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];\n }\n return shuffled;\n};\n\n/**\n * Helper to prepend letter to HTML content (handles <p> tags)\n * @example prependLetterToHtml('a', '<p>Text</p>') => '<p>a) Text</p>'\n * @example prependLetterToHtml('a', 'Text') => 'a) Text'\n */\nexport const prependLetterToHtml = (letter: string, html: string): string => {\n if (html.trim().startsWith('<p>')) {\n return html.replace(/^(\\s*<p>)/, `$1${letter}) `);\n }\n return `${letter}) ${html}`;\n};\n\n/**\n * Compute state for a true/false option\n * Handles both interactive (default) and result modes\n */\nexport const getTrueOrFalseOptionState = (\n optionId: string,\n variant: string,\n currentQuestionResult: QuestionAnswerResult | null | undefined,\n localAnswers: Record<string, string>\n): TrueOrFalseOptionState => {\n // Get whether the statement is TRUE or FALSE from persisted result\n const correctAnswerOption = currentQuestionResult?.options?.find(\n (op) => op.id === optionId\n );\n const isStatementTrue =\n variant === QuizVariant.RESULT\n ? (correctAnswerOption?.isCorrect ?? false)\n : false;\n\n // Get student's selection from selectedOptions\n const studentSelection =\n variant === QuizVariant.RESULT\n ? currentQuestionResult?.selectedOptions?.find(\n (op) => op.optionId === optionId\n )\n : undefined;\n\n // Determine if answered and what was marked\n const hasAnswered =\n variant === QuizVariant.RESULT\n ? studentSelection !== undefined\n : !!localAnswers[optionId];\n\n const studentMarkedTrue =\n variant === QuizVariant.RESULT\n ? (studentSelection?.isCorrect ?? false)\n : localAnswers[optionId] === TrueFalseEnum.VERDADEIRO;\n\n // Compute display values\n const getStudentAnswerDisplay = (): string => {\n if (variant !== QuizVariant.RESULT) {\n return localAnswers[optionId] || '-';\n }\n if (!hasAnswered) {\n return '-';\n }\n return studentMarkedTrue ? TrueFalseEnum.VERDADEIRO : TrueFalseEnum.FALSO;\n };\n const studentAnswer = getStudentAnswerDisplay();\n\n const correctAnswer = isStatementTrue\n ? TrueFalseEnum.VERDADEIRO\n : TrueFalseEnum.FALSO;\n const isStudentCorrect = hasAnswered && studentMarkedTrue === isStatementTrue;\n const variantCorrect = isStudentCorrect\n ? OptionStatus.CORRECT\n : OptionStatus.INCORRECT;\n\n return {\n isStatementTrue,\n hasAnswered,\n studentMarkedTrue,\n studentAnswer,\n correctAnswer,\n isStudentCorrect,\n variantCorrect,\n };\n};\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-HZXXADG4.js","../src/components/Quiz/Quiz.tsx"],"names":[],"mappings":"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","file":"/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-HZXXADG4.js","sourcesContent":[null,"import { BookOpenIcon } from '@phosphor-icons/react/dist/csr/BookOpen';\nimport { CaretLeftIcon } from '@phosphor-icons/react/dist/csr/CaretLeft';\nimport { CaretRightIcon } from '@phosphor-icons/react/dist/csr/CaretRight';\nimport { SquaresFourIcon } from '@phosphor-icons/react/dist/csr/SquaresFour';\nimport { HeaderAlternative } from '../Alternative/Alternative';\nimport Button from '../Button/Button';\nimport IconButton from '../IconButton/IconButton';\nimport {\n forwardRef,\n ReactNode,\n useEffect,\n useState,\n ComponentType,\n} from 'react';\nimport {\n useQuizStore,\n QUESTION_TYPE,\n QUIZ_TYPE,\n AI_CORRECTION_STATUS,\n CORRECTION_SOURCE,\n} from './useQuizStore';\nimport CorrectionSourceTag from './CorrectionSourceTag';\nimport { resolveCorrectionText } from './correction.utils';\nimport { QuizVariant } from './Quiz.types';\nimport { AlertDialog } from '../AlertDialog/AlertDialog';\nimport Modal from '../Modal/Modal';\n\nimport Select, {\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '../Select/Select';\nimport { cn } from '../../utils/utils';\nimport {\n QuizAlternative,\n QuizConnectDots,\n QuizDissertative,\n QuizFill,\n QuizImageQuestion,\n QuizMultipleChoice,\n QuizTrueOrFalse,\n} from './QuizContent';\nimport { CardStatus } from '../Card/Card';\nimport Text from '../Text/Text';\nimport HtmlMathRenderer from '../HtmlMathRenderer/HtmlMathRenderer';\nimport { formatExamInfo } from './Quiz.utils';\nimport QuizTimer from '../QuizTimer/QuizTimer';\nimport { useMobile } from '../../hooks/useMobile';\n\n// Função para obter configuração do tipo de quiz\nexport const getQuizTypeConfig = (type: QUIZ_TYPE) => {\n // Configuração centralizada para cada tipo de quiz\n const QUIZ_TYPE_CONFIG = {\n [QUIZ_TYPE.SIMULADO]: {\n label: 'Simulado',\n article: 'o',\n preposition: 'do',\n },\n [QUIZ_TYPE.QUESTIONARIO]: {\n label: 'Questionário',\n article: 'o',\n preposition: 'do',\n },\n [QUIZ_TYPE.ATIVIDADE]: {\n label: 'Atividade',\n article: 'a',\n preposition: 'da',\n },\n [QUIZ_TYPE.AULA_RECOMENDADA]: {\n label: 'Aula recomendada',\n article: 'a',\n preposition: 'da',\n },\n } as const;\n\n const config = QUIZ_TYPE_CONFIG[type];\n return config || QUIZ_TYPE_CONFIG[QUIZ_TYPE.SIMULADO]; // fallback para simulado\n};\n\n// Função para obter o label do tipo\nexport const getTypeLabel = (type: QUIZ_TYPE) => {\n return getQuizTypeConfig(type).label;\n};\n\n// Função para obter o artigo (o/a)\nexport const getQuizArticle = (type: QUIZ_TYPE) => {\n return getQuizTypeConfig(type).article;\n};\n\n// Função para obter a preposição (do/da)\nexport const getQuizPreposition = (type: QUIZ_TYPE) => {\n return getQuizTypeConfig(type).preposition;\n};\n\n// Função para gerar título de conclusão\nexport const getCompletionTitle = (type: QUIZ_TYPE) => {\n const config = getQuizTypeConfig(type);\n return `Você concluiu ${config.article} ${config.label.toLowerCase()}!`;\n};\n\n// Função para gerar o rótulo do botão de retorno no modal de conclusão\nexport const getGoBackButtonLabel = (type: QUIZ_TYPE): string => {\n if (type === QUIZ_TYPE.SIMULADO) return 'Ir para simulados';\n if (type === QUIZ_TYPE.QUESTIONARIO) return 'Ir para aulas';\n if (type === QUIZ_TYPE.ATIVIDADE) return 'Ir para atividades';\n if (type === QUIZ_TYPE.AULA_RECOMENDADA) return 'Ir para aulas recomendadas';\n return 'Ir para simulados';\n};\n\n// Função para gerar texto de confirmação de saída\nexport const getExitConfirmationText = (type: QUIZ_TYPE) => {\n const config = getQuizTypeConfig(type);\n // QUESTIONARIO não tem rascunho: ao sair, as respostas são perdidas.\n // Demais tipos (SIMULADO, ATIVIDADE, AULA_RECOMENDADA e fallback) salvam o\n // progresso, então o aluno pode continuar depois de onde parou.\n if (type === QUIZ_TYPE.QUESTIONARIO) {\n return `Se você sair ${config.preposition} ${config.label.toLowerCase()} agora, todas as respostas serão perdidas.`;\n }\n return `Se você sair ${config.preposition} ${config.label.toLowerCase()} agora, poderá continuar de onde parou depois.`;\n};\n\n// Função para gerar texto de confirmação de finalização\nexport const getFinishConfirmationText = (type: QUIZ_TYPE) => {\n const config = getQuizTypeConfig(type);\n return `Tem certeza que deseja finalizar ${config.article} ${config.label.toLowerCase()}?`;\n};\n\nconst Quiz = forwardRef<\n HTMLDivElement,\n { children: ReactNode; className?: string; variant?: 'result' | 'default' }\n>(({ children, className, variant = QuizVariant.DEFAULT, ...props }, ref) => {\n const { setVariant } = useQuizStore();\n\n useEffect(() => {\n setVariant(variant as QuizVariant);\n }, [variant, setVariant]);\n\n return (\n <div ref={ref} className={cn('flex flex-col', className)} {...props}>\n {children}\n </div>\n );\n});\n\nconst QuizTitle = forwardRef<\n HTMLDivElement,\n { className?: string; onBack?: () => void; showTimer?: boolean }\n>(({ className, onBack, showTimer = false, ...props }, ref) => {\n const {\n quiz,\n currentQuestionIndex,\n getTotalQuestions,\n getQuizTitle,\n isStarted,\n } = useQuizStore();\n\n const [showExitConfirmation, setShowExitConfirmation] = useState(false);\n\n const totalQuestions = getTotalQuestions();\n const quizTitle = getQuizTitle();\n\n const handleBackClick = () => {\n if (isStarted) {\n setShowExitConfirmation(true);\n } else {\n actionOnBack();\n }\n };\n\n const handleConfirmExit = () => {\n setShowExitConfirmation(false);\n actionOnBack();\n };\n\n const actionOnBack = () => {\n if (onBack) {\n onBack();\n } else {\n globalThis.history.back();\n }\n };\n\n const handleCancelExit = () => {\n setShowExitConfirmation(false);\n };\n\n return (\n <>\n <div\n ref={ref}\n /*\n * Três colunas em vez de `justify-between`: as laterais são `1fr`\n * iguais, então o título fica centralizado na tela mesmo com o voltar\n * e o cronômetro tendo larguras diferentes. Com flex ele era empurrado\n * para a direita junto do cronômetro.\n */\n className={cn(\n 'grid grid-cols-[1fr_auto_1fr] items-center gap-2 relative p-2',\n className\n )}\n {...props}\n >\n <IconButton\n icon={<CaretLeftIcon size={24} />}\n size=\"md\"\n aria-label=\"Voltar\"\n onClick={handleBackClick}\n className=\"justify-self-start\"\n />\n <span className=\"flex flex-col gap-2 text-center\">\n <Text size=\"md\" weight=\"bold\" color=\"text-text-950\">\n {quizTitle}\n </Text>\n <Text size=\"xs\" color=\"text-text-600\">\n {totalQuestions > 0\n ? `${currentQuestionIndex + 1} de ${totalQuestions}`\n : '0 de 0'}\n </Text>\n </span>\n <div className=\"justify-self-end\">{showTimer && <QuizTimer />}</div>\n </div>\n\n <AlertDialog\n isOpen={showExitConfirmation}\n onChangeOpen={setShowExitConfirmation}\n title=\"Deseja sair?\"\n description={getExitConfirmationText(quiz?.type || QUIZ_TYPE.SIMULADO)}\n cancelButtonLabel=\"Voltar e revisar\"\n submitButtonLabel=\"Sair Mesmo Assim\"\n onSubmit={handleConfirmExit}\n onCancel={handleCancelExit}\n />\n </>\n );\n});\n\nconst QuizHeader = () => {\n const { getCurrentQuestion, getQuestionIndex, quiz } = useQuizStore();\n const currentQuestion = getCurrentQuestion();\n let currentId =\n currentQuestion && 'questionId' in currentQuestion\n ? (currentQuestion.questionId as string)\n : currentQuestion?.id;\n const questionIndex = getQuestionIndex(currentId!);\n\n const questionNumber = currentQuestion\n ? `Questão ${questionIndex.toString().padStart(2, '0')}`\n : 'Questão';\n\n // Only show exam info (banca/year) for SIMULADO type\n const shouldShowExamInfo = quiz?.type === QUIZ_TYPE.SIMULADO;\n const examInfo = shouldShowExamInfo\n ? formatExamInfo(currentQuestion?.examBoard, currentQuestion?.examYear)\n : '';\n\n const title = examInfo ? `${questionNumber} ${examInfo}` : questionNumber;\n\n return (\n <HeaderAlternative\n title={title}\n subTitle={currentQuestion?.knowledgeMatrix?.[0]?.topic?.name ?? ''}\n content={currentQuestion?.statement ?? ''}\n />\n );\n};\n\nconst QuizContent = ({ paddingBottom }: { paddingBottom?: string }) => {\n const { getCurrentQuestion } = useQuizStore();\n const { isMobile } = useMobile();\n const currentQuestion = getCurrentQuestion();\n\n // `QuizFooter` is `position: fixed`, so it sits on top of the content instead\n // of taking space in the flow — without room reserved here, the last\n // alternative ends up underneath it and unreadable. The bar is taller on a\n // phone, where its controls stack into two rows.\n const contentPaddingBottom = paddingBottom ?? (isMobile ? 'pb-32' : 'pb-24');\n const questionComponents: Record<\n string,\n ComponentType<QuizVariantInterface>\n > = {\n [QUESTION_TYPE.ALTERNATIVA]: QuizAlternative,\n [QUESTION_TYPE.MULTIPLA_ESCOLHA]: QuizMultipleChoice,\n [QUESTION_TYPE.DISSERTATIVA]: QuizDissertative,\n [QUESTION_TYPE.VERDADEIRO_FALSO]: QuizTrueOrFalse,\n [QUESTION_TYPE.RELACIONAR]: QuizConnectDots,\n [QUESTION_TYPE.PREENCHER_LACUNAS]: QuizFill,\n [QUESTION_TYPE.IMAGEM]: QuizImageQuestion,\n };\n\n const QuestionComponent = currentQuestion\n ? questionComponents[currentQuestion.questionType]\n : null;\n\n if (!QuestionComponent) {\n return (\n <Text size=\"md\" weight=\"medium\" className=\"text-text-950 text-md\">\n Tipo de questão não suportado\n </Text>\n );\n }\n\n // The teacher's comment is no longer echoed here: in the result variant it\n // lives behind the \"Ver comentário\" button in the footer, so it is not shown\n // twice on the same screen.\n return <QuestionComponent paddingBottom={contentPaddingBottom} />;\n};\n\ninterface QuizVariantInterface {\n paddingBottom?: string;\n}\n\nconst QuizQuestionList = ({\n filterType = 'all',\n onQuestionClick,\n}: {\n filterType?: string;\n onQuestionClick?: () => void;\n} = {}) => {\n const {\n getQuestionsGroupedBySubject,\n goToQuestion,\n getQuestionStatusFromUserAnswers,\n getQuestionIndex,\n quiz,\n } = useQuizStore();\n\n // Only show exam info (banca/year) for SIMULADO type\n const shouldShowExamInfo = quiz?.type === QUIZ_TYPE.SIMULADO;\n\n const groupedQuestions = getQuestionsGroupedBySubject();\n const getQuestionStatus = (questionId: string) => {\n return getQuestionStatusFromUserAnswers(questionId);\n };\n const filteredGroupedQuestions = Object.entries(groupedQuestions).reduce(\n (acc, [subjectId, questions]) => {\n const filteredQuestions = questions.filter((question) => {\n const status = getQuestionStatus(question.id);\n switch (filterType) {\n case 'answered':\n return status === 'answered';\n case 'unanswered':\n return status === 'unanswered' || status === 'skipped';\n default:\n return true;\n }\n });\n\n if (filteredQuestions.length > 0) {\n acc[subjectId] = filteredQuestions;\n }\n\n return acc;\n },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n {} as { [key: string]: any[] }\n );\n\n const getStatusLabel = (status: string) => {\n switch (status) {\n case 'answered':\n return 'Respondida';\n case 'skipped':\n return 'Em branco';\n default:\n return 'Em branco';\n }\n };\n return (\n <div className=\"space-y-6 px-4 h-full\">\n {Object.entries(filteredGroupedQuestions).length == 0 && (\n <div className=\"flex items-center justify-center text-gray-500 py-8 h-full\">\n <p className=\"text-lg\">Nenhum resultado</p>\n </div>\n )}\n {Object.entries(filteredGroupedQuestions).map(\n ([subjectId, questions]) => (\n <section key={subjectId} className=\"flex flex-col gap-2\">\n <span className=\"pt-6 pb-4 flex flex-row gap-2\">\n <div className=\"bg-primary-500 p-1 rounded-sm flex items-center justify-center\">\n <BookOpenIcon size={17} className=\"text-white\" />\n </div>\n <p className=\"text-text-800 font-bold text-lg\">\n {questions?.[0]?.knowledgeMatrix?.[0]?.subject?.name ??\n 'Sem componente curricular'}\n </p>\n </span>\n\n <ul className=\"flex flex-col gap-2\">\n {questions.map((question) => {\n const status = getQuestionStatus(question.id);\n const questionNumber = getQuestionIndex(question.id);\n const examInfo = shouldShowExamInfo\n ? formatExamInfo(question.examBoard, question.examYear)\n : '';\n const questionTitle = `Questão ${questionNumber.toString().padStart(2, '0')}`;\n const header = examInfo\n ? `${questionTitle} ${examInfo}`\n : questionTitle;\n return (\n <CardStatus\n key={question.id}\n header={header}\n label={getStatusLabel(status)}\n onClick={() => {\n goToQuestion(questionNumber - 1);\n onQuestionClick?.();\n }}\n />\n );\n })}\n </ul>\n </section>\n )\n )}\n </div>\n );\n};\n\n/**\n * Shared layout for the quiz result modals (generic result, all-correct and\n * all-incorrect questionnaire variants): a centered image, a title and a\n * footer with action buttons.\n */\nconst QuizResultModal = ({\n isOpen,\n onClose,\n image,\n showImagePlaceholder = true,\n title,\n description,\n footer,\n}: {\n isOpen: boolean;\n onClose: () => void;\n image?: ReactNode;\n showImagePlaceholder?: boolean;\n title: ReactNode;\n description: ReactNode;\n footer: ReactNode;\n}) => (\n <Modal\n isOpen={isOpen}\n onClose={onClose}\n title=\"\"\n closeOnEscape={false}\n hideCloseButton\n size={'md'}\n >\n <div className=\"flex flex-col w-full h-full items-center justify-center gap-4\">\n {image ? (\n <div className=\"w-[282px] h-auto\">{image}</div>\n ) : (\n showImagePlaceholder && (\n <div className=\"w-[282px] h-[200px] bg-gray-100 rounded-md flex items-center justify-center\">\n <Text as=\"span\" size=\"sm\" color=\"text-gray-500\">\n Imagem de resultado\n </Text>\n </div>\n )\n )}\n <div className=\"flex flex-col gap-2 text-center\">\n <Text as=\"h2\" size=\"lg\" weight=\"bold\">\n {title}\n </Text>\n {description}\n </div>\n {footer}\n </div>\n </Modal>\n);\n\n/**\n * Correction of the question currently on screen, resolved once.\n *\n * A dissertativa may have been graded by the AI. The teacher's text wins when it\n * exists, the AI's stands otherwise; the two are never merged — the backend\n * keeps them in separate columns precisely so a review does not destroy the\n * original verdict — and `correctionSource` says which one is on screen.\n *\n * It lives here, and not inline in `QuizFooter`, because both the footer (for\n * the modal body and title) and `QuizReviewActions` (for the buttons) need the\n * same four values, and deriving them twice would be two chances to disagree.\n *\n * @returns The effective comment plus the fields the tag and the title read\n */\nconst useCurrentCorrection = () => {\n const { getCurrentQuestion, getQuestionResultByQuestionId } = useQuizStore();\n\n const currentQuestion = getCurrentQuestion();\n const result = currentQuestion\n ? getQuestionResultByQuestionId(currentQuestion.id)\n : null;\n\n return {\n comment: resolveCorrectionText({ ...result }),\n correctionSource: result?.correctionSource,\n aiCorrectionStatus: result?.aiCorrectionStatus,\n };\n};\n\n/**\n * Title for the per-question feedback modal, phrased for whoever wrote it.\n *\n * Calling an AI correction \"Comentário do professor\" would be a lie the tag\n * inside the modal immediately contradicts, so both are derived from the same\n * `correctionSource`.\n *\n * @param correctionSource - Who produced the correction on display\n * @returns The modal title\n */\nconst getCorrectionModalTitle = (\n correctionSource?: CORRECTION_SOURCE | null\n): string => {\n if (correctionSource === CORRECTION_SOURCE.IA) {\n return 'Correção por IA';\n }\n\n if (correctionSource === CORRECTION_SOURCE.IA_PROFESSOR) {\n return 'Correção revisada pelo professor';\n }\n\n return 'Comentário do professor';\n};\n\n/**\n * The review bar's question-scoped actions: see the resolution, see the correction.\n *\n * Split out of `QuizFooter` because the two bars do different jobs — the\n * `default` one navigates between questions, this one reads a question already\n * graded — and because the four conditions the correction needs pushed the\n * footer past the cognitive-complexity limit while sitting in the middle of\n * unrelated navigation markup.\n *\n * @param props - Callbacks that open the footer's modals\n * @returns JSX element\n */\nconst QuizReviewActions = ({\n onOpenResolution,\n onOpenComment,\n className,\n}: {\n onOpenResolution: () => void;\n onOpenComment: () => void;\n readonly className?: string;\n}) => {\n const { getCurrentQuestion } = useQuizStore();\n const { comment, correctionSource, aiCorrectionStatus } =\n useCurrentCorrection();\n\n const currentQuestion = getCurrentQuestion();\n const hasResolution = Boolean(currentQuestion?.solutionExplanation);\n const isAiCorrecting = aiCorrectionStatus === AI_CORRECTION_STATUS.PENDING;\n const commentLabel =\n correctionSource === CORRECTION_SOURCE.IA\n ? 'Ver correção da IA'\n : 'Ver comentário';\n\n return (\n <div className={className}>\n {hasResolution && (\n <Button\n variant=\"solid\"\n action=\"primary\"\n size=\"large\"\n onClick={onOpenResolution}\n >\n Ver resolução\n </Button>\n )}\n {comment && (\n <Button\n variant=\"outline\"\n action=\"primary\"\n size=\"large\"\n onClick={onOpenComment}\n >\n {commentLabel}\n </Button>\n )}\n {/* Sem comentário ainda, mas a IA está corrigindo: o aluno acaba de\n entregar e chegou aqui antes do feedback existir. Dizer que está a\n caminho é melhor do que não mostrar nada. */}\n {!comment && isAiCorrecting && (\n <CorrectionSourceTag\n aiCorrectionStatus={aiCorrectionStatus}\n className=\"self-center\"\n />\n )}\n </div>\n );\n};\n\n/**\n * What the completion modal shows instead of the score.\n *\n * Some exams are not corrected on the spot — the in-classroom ENEM simulation\n * is graded later — so telling the student how many they got right would be\n * wrong. With this set, finishing opens a modal with only this content and\n * one button.\n */\nexport interface QuizCompletionOverride {\n title: ReactNode;\n description: ReactNode;\n buttonLabel: string;\n onConfirm: () => void;\n}\n\nconst QuizFooter = forwardRef<\n HTMLDivElement,\n {\n className?: string;\n onGoToSimulated?: () => void;\n onDetailResult?: () => void;\n handleFinishSimulated?: () => void;\n onGoToNextModule?: () => void;\n onRepeat?: () => void;\n onTryLater?: () => void;\n resultImageComponent?: ReactNode;\n resultIncorrectImageComponent?: ReactNode;\n /** Replaces the score modal; see `QuizCompletionOverride`. */\n completionOverride?: QuizCompletionOverride;\n }\n>(\n (\n {\n className,\n onGoToSimulated,\n onDetailResult,\n handleFinishSimulated,\n onGoToNextModule,\n onRepeat,\n onTryLater,\n resultImageComponent,\n resultIncorrectImageComponent,\n completionOverride,\n ...props\n },\n ref\n ) => {\n const {\n quiz,\n currentQuestionIndex,\n getTotalQuestions,\n goToNextQuestion,\n goToPreviousQuestion,\n getUnansweredQuestionsFromUserAnswers,\n getCurrentAnswer,\n skipQuestion,\n skipCurrentQuestionIfUnanswered,\n getCurrentQuestion,\n getQuestionStatusFromUserAnswers,\n variant,\n getQuestionResultStatistics,\n } = useQuizStore();\n\n // The review bar carries four controls. Below ~500px they no longer fit on\n // one line, so the actions and the pagination stack into two centred rows.\n const { isMobile } = useMobile();\n\n const totalQuestions = getTotalQuestions();\n const isFirstQuestion = currentQuestionIndex === 0;\n const isLastQuestion = currentQuestionIndex === totalQuestions - 1;\n const currentAnswer = getCurrentAnswer();\n const currentQuestion = getCurrentQuestion();\n const {\n comment: teacherComment,\n correctionSource,\n aiCorrectionStatus,\n } = useCurrentCorrection();\n const isCurrentQuestionSkipped = currentQuestion\n ? getQuestionStatusFromUserAnswers(currentQuestion.id) === 'skipped'\n : false;\n // Sistema unificado de controle de modais\n const [activeModal, setActiveModal] = useState<string | null>(null);\n const [filterType, setFilterType] = useState<string>('all');\n\n // Funções para controlar modais\n const openModal = (modalName: string) => setActiveModal(modalName);\n const closeModal = () => setActiveModal(null);\n const isModalOpen = (modalName: string) => activeModal === modalName;\n const unansweredQuestions = getUnansweredQuestionsFromUserAnswers();\n const allQuestions = getTotalQuestions();\n const stats = getQuestionResultStatistics();\n const correctAnswers = stats?.correctAnswers;\n const quizType = quiz?.type || QUIZ_TYPE.SIMULADO;\n const quizTypeLabel = getTypeLabel(quizType);\n // Real subtopic name, used to label the questionnaire completion modals.\n // The backend always populates the question knowledge matrix, so this is\n // available as soon as the quiz is loaded.\n const moduleName =\n quiz?.questions?.[0]?.knowledgeMatrix?.[0]?.subtopic?.name;\n\n // Submits the answers and opens the correct result modal. Statistics must\n // be read AFTER handleFinishSimulated, which is what populates\n // questionsResult in the store (the render-time values are still empty).\n const submitAndOpenResultModal = async () => {\n if (handleFinishSimulated) {\n await Promise.resolve(handleFinishSimulated());\n }\n\n if (completionOverride) {\n openModal('modalCompletionOverride');\n return;\n }\n\n const latestStats = getQuestionResultStatistics();\n const latestCorrect = latestStats?.correctAnswers;\n const latestTotal = latestStats?.totalAnswered;\n\n if (\n quizType === QUIZ_TYPE.QUESTIONARIO &&\n typeof latestCorrect === 'number' &&\n typeof latestTotal === 'number' &&\n latestCorrect === latestTotal\n ) {\n openModal('modalQuestionnaireAllCorrect');\n return;\n }\n\n if (\n quizType === QUIZ_TYPE.QUESTIONARIO &&\n typeof latestCorrect === 'number' &&\n latestCorrect === 0\n ) {\n openModal('modalQuestionnaireAllIncorrect');\n return;\n }\n\n openModal('modalResult');\n };\n\n const handleFinishQuiz = async () => {\n // Marca a questão atual como pulada se não foi respondida\n skipCurrentQuestionIfUnanswered();\n\n if (unansweredQuestions.length > 0) {\n openModal('alertDialog');\n return;\n }\n\n try {\n await submitAndOpenResultModal();\n } catch (err) {\n console.error('handleFinishSimulated failed:', err);\n }\n };\n\n const handleAlertSubmit = async () => {\n try {\n await submitAndOpenResultModal();\n } catch (err) {\n console.error('handleFinishSimulated failed:', err);\n closeModal();\n }\n };\n\n return (\n <>\n <footer\n ref={ref}\n className={cn(\n 'w-full px-2 bg-background lg:max-w-[1000px] not-lg:max-w-[calc(100vw-32px)] border-t border-border-50 fixed bottom-0 min-h-[80px] flex flex-row justify-between items-center',\n className\n )}\n {...props}\n >\n {variant === 'default' ? (\n <>\n <div className=\"flex flex-row items-center gap-1\">\n <IconButton\n icon={<SquaresFourIcon size={24} className=\"text-text-950\" />}\n size=\"md\"\n onClick={() => openModal('modalNavigate')}\n />\n\n {isFirstQuestion ? (\n <Button\n variant=\"outline\"\n size=\"small\"\n onClick={() => {\n skipQuestion();\n goToNextQuestion();\n }}\n >\n Pular\n </Button>\n ) : (\n <Button\n size=\"medium\"\n variant=\"link\"\n action=\"primary\"\n iconLeft={<CaretLeftIcon size={18} />}\n onClick={() => {\n goToPreviousQuestion();\n }}\n >\n Voltar\n </Button>\n )}\n </div>\n\n {!isFirstQuestion && !isLastQuestion && (\n <Button\n size=\"small\"\n variant=\"outline\"\n action=\"primary\"\n onClick={() => {\n skipQuestion();\n goToNextQuestion();\n }}\n >\n Pular\n </Button>\n )}\n\n {isLastQuestion ? (\n <Button\n size=\"medium\"\n variant=\"solid\"\n action=\"primary\"\n onClick={handleFinishQuiz}\n >\n Finalizar\n </Button>\n ) : (\n <Button\n size=\"medium\"\n variant=\"link\"\n action=\"primary\"\n iconRight={<CaretRightIcon size={18} />}\n disabled={!currentAnswer && !isCurrentQuestionSkipped}\n onClick={() => {\n goToNextQuestion();\n }}\n >\n Avançar\n </Button>\n )}\n </>\n ) : (\n <div\n className={cn(\n 'flex w-full items-center gap-2',\n isMobile ? 'flex-col py-2' : 'flex-row'\n )}\n >\n <QuizReviewActions\n className={cn(\n 'flex flex-row items-center gap-2',\n isMobile && 'justify-center'\n )}\n onOpenResolution={() => openModal('modalResolution')}\n onOpenComment={() => openModal('modalTeacherComment')}\n />\n {/* On a wide bar the pagination sits at the far end, away from the\n actions that act on the question being read; stacked, it is\n centred under them. */}\n <div\n className={cn(\n 'flex flex-row items-center gap-2',\n isMobile ? 'justify-center' : 'flex-1 justify-end'\n )}\n >\n <Button\n variant=\"outline\"\n action=\"primary\"\n size=\"medium\"\n aria-label=\"Questão anterior\"\n disabled={isFirstQuestion}\n onClick={goToPreviousQuestion}\n >\n <CaretLeftIcon size={18} />\n </Button>\n <Button\n variant=\"outline\"\n action=\"primary\"\n size=\"medium\"\n aria-label=\"Próxima questão\"\n disabled={isLastQuestion}\n onClick={goToNextQuestion}\n >\n <CaretRightIcon size={18} />\n </Button>\n </div>\n </div>\n )}\n </footer>\n\n <AlertDialog\n isOpen={isModalOpen('alertDialog')}\n onChangeOpen={(open) =>\n open ? openModal('alertDialog') : closeModal()\n }\n title={`Finalizar ${quizTypeLabel.toLowerCase()}?`}\n description={\n unansweredQuestions.length > 0\n ? `Você deixou as questões ${unansweredQuestions.join(', ')} sem resposta. Finalizar agora pode impactar seu desempenho.`\n : getFinishConfirmationText(quizType)\n }\n cancelButtonLabel=\"Voltar e revisar\"\n submitButtonLabel=\"Finalizar Mesmo Assim\"\n onSubmit={handleAlertSubmit}\n />\n\n <QuizResultModal\n isOpen={isModalOpen('modalResult')}\n onClose={closeModal}\n image={resultImageComponent}\n title={getCompletionTitle(quizType)}\n description={\n <Text as=\"p\" size=\"sm\" color=\"text-text-500\">\n Você acertou {correctAnswers ?? '--'} de {allQuestions} questões.\n </Text>\n }\n footer={\n <div className=\"px-6 flex flex-row items-center gap-2 w-full\">\n <Button\n variant=\"outline\"\n className=\"w-full\"\n size=\"small\"\n onClick={onGoToSimulated}\n >\n {getGoBackButtonLabel(quizType)}\n </Button>\n\n <Button className=\"w-full\" onClick={onDetailResult}>\n Detalhar resultado\n </Button>\n </div>\n }\n />\n\n {completionOverride && (\n <QuizResultModal\n isOpen={isModalOpen('modalCompletionOverride')}\n onClose={closeModal}\n image={resultImageComponent}\n title={completionOverride.title}\n description={\n <Text as=\"p\" size=\"sm\" color=\"text-text-500\">\n {completionOverride.description}\n </Text>\n }\n footer={\n <div className=\"px-6 flex flex-row items-center w-full\">\n <Button\n className=\"w-full\"\n onClick={completionOverride.onConfirm}\n data-testid=\"quiz-completion-override-confirm\"\n >\n {completionOverride.buttonLabel}\n </Button>\n </div>\n }\n />\n )}\n\n <Modal\n isOpen={isModalOpen('modalNavigate')}\n onClose={closeModal}\n title=\"Questões\"\n size={'lg'}\n >\n <div className=\"flex flex-col w-full not-lg:h-[calc(100vh-200px)] lg:max-h-[687px] lg:h-[687px]\">\n <div className=\"flex flex-row justify-between items-center py-6 pt-6 pb-4 border-b border-border-200 flex-shrink-0\">\n <p className=\"text-text-950 font-bold text-lg\">Filtrar por</p>\n <span className=\"max-w-[266px]\">\n <Select value={filterType} onValueChange={setFilterType}>\n <SelectTrigger\n variant=\"rounded\"\n className=\"max-w-[266px] min-w-[160px]\"\n >\n <SelectValue placeholder=\"Selecione uma opção\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">Todas</SelectItem>\n <SelectItem value=\"unanswered\">Em branco</SelectItem>\n <SelectItem value=\"answered\">Respondidas</SelectItem>\n </SelectContent>\n </Select>\n </span>\n </div>\n\n <div className=\"flex flex-col gap-2 flex-1 min-h-0 overflow-y-auto\">\n <QuizQuestionList\n filterType={filterType}\n onQuestionClick={closeModal}\n />\n </div>\n </div>\n </Modal>\n\n <Modal\n isOpen={isModalOpen('modalResolution')}\n onClose={closeModal}\n title=\"Resolução\"\n size={'lg'}\n >\n <HtmlMathRenderer\n content={currentQuestion?.solutionExplanation || ''}\n className=\"text-text-950 text-base\"\n />\n </Modal>\n\n <Modal\n isOpen={isModalOpen('modalTeacherComment')}\n onClose={closeModal}\n title={getCorrectionModalTitle(correctionSource)}\n size={'lg'}\n >\n {/* A tag fica dentro do modal, junto do texto: é ela que diz se o que\n está sendo lido saiu da IA, do professor, ou da IA revisada por\n ele. Sem isso o título sozinho teria que carregar essa informação\n em toda variação. */}\n <CorrectionSourceTag\n correctionSource={correctionSource}\n aiCorrectionStatus={aiCorrectionStatus}\n className=\"mb-3\"\n />\n {/* Plain text on purpose: the teacher writes this in a bare textarea,\n so running it through the HTML/LaTeX renderer would change what\n they typed. `whitespace-pre-wrap` keeps their line breaks. The AI\n feedback is plain text for the same reason. */}\n <Text\n size=\"md\"\n className=\"text-text-950 whitespace-pre-wrap break-words\"\n >\n {teacherComment}\n </Text>\n </Modal>\n\n <QuizResultModal\n isOpen={isModalOpen('modalQuestionnaireAllCorrect')}\n onClose={closeModal}\n image={resultImageComponent}\n title=\"🎉 Parabéns!\"\n description={\n <Text as=\"p\" size=\"sm\" color=\"text-text-500\">\n {moduleName\n ? `Você concluiu o módulo ${moduleName}.`\n : 'Você concluiu o questionário!'}\n </Text>\n }\n footer={\n <div className=\"px-6 flex flex-row items-center gap-2 w-full\">\n <Button className=\"w-full\" onClick={onGoToNextModule}>\n {getGoBackButtonLabel(quizType)}\n </Button>\n </div>\n }\n />\n\n <QuizResultModal\n isOpen={isModalOpen('modalQuestionnaireAllIncorrect')}\n onClose={closeModal}\n image={resultIncorrectImageComponent}\n showImagePlaceholder={false}\n title=\"😕 Não foi dessa vez...\"\n description={\n <>\n <Text as=\"p\" size=\"sm\" color=\"text-text-500\">\n Você tirou 0 no questionário, mas não se preocupe! Isso é apenas\n uma oportunidade de aprendizado.\n </Text>\n\n <Text as=\"p\" size=\"sm\" color=\"text-text-500\">\n Que tal tentar novamente para melhorar sua nota? Estamos aqui\n para te ajudar a entender o conteúdo e evoluir.\n </Text>\n\n {quiz?.canRetry && (\n <Text as=\"p\" size=\"sm\" color=\"text-text-500\">\n Clique em Repetir Questionário e mostre do que você é capaz!\n 💪\n </Text>\n )}\n </>\n }\n footer={\n <div className=\"flex flex-row justify-center items-center gap-2 w-full\">\n {quiz?.canRetry && (\n <Button\n type=\"button\"\n variant=\"link\"\n size=\"small\"\n className=\"w-auto\"\n onClick={() => {\n closeModal();\n openModal('alertDialogTryLater');\n }}\n >\n Tentar depois\n </Button>\n )}\n\n <Button\n variant=\"outline\"\n size=\"small\"\n className=\"w-auto\"\n onClick={onDetailResult}\n >\n Detalhar resultado\n </Button>\n\n {quiz?.canRetry ? (\n <Button className=\"w-auto\" size=\"small\" onClick={onRepeat}>\n Repetir questionário\n </Button>\n ) : (\n <Button\n className=\"w-auto\"\n size=\"small\"\n onClick={onGoToSimulated}\n >\n {getGoBackButtonLabel(quizType)}\n </Button>\n )}\n </div>\n }\n />\n\n <AlertDialog\n isOpen={isModalOpen('alertDialogTryLater')}\n onChangeOpen={(open) =>\n open ? openModal('alertDialogTryLater') : closeModal()\n }\n title=\"Tentar depois?\"\n description={\n 'Você optou por refazer o questionário mais tarde.\\n\\nLembre-se: enquanto não refazer o questionário, sua nota permanecerá 0 no sistema.'\n }\n cancelButtonLabel=\"Repetir questionário\"\n submitButtonLabel=\"Tentar depois\"\n onSubmit={() => {\n onTryLater?.();\n closeModal();\n }}\n onCancel={() => {\n onRepeat?.();\n closeModal();\n }}\n />\n </>\n );\n }\n);\n\nexport {\n QuizTitle,\n Quiz,\n QuizHeader,\n QuizContent,\n QuizFooter,\n QuizQuestionList,\n};\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-JBAGQ7L5.js","../src/components/Quiz/QuizResult.tsx"],"names":[],"mappings":"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","file":"/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-JBAGQ7L5.js","sourcesContent":[null,"import { forwardRef, useEffect, useState } from 'react';\nimport { CardResults, CardStatus } from '../Card/Card';\nimport {\n ANSWER_STATUS,\n Question,\n QuestionResult,\n QUESTION_DIFFICULTY,\n QUIZ_TYPE,\n SUBTYPE_ENUM,\n useQuizStore,\n} from './useQuizStore';\nimport ProgressCircle from '../ProgressCircle/ProgressCircle';\nimport { ClockIcon } from '@phosphor-icons/react/dist/csr/Clock';\nimport ProgressBar from '../ProgressBar/ProgressBar';\nimport { cn, getSubjectColorWithOpacity } from '../../utils/utils';\nimport Badge from '../Badge/Badge';\nimport { useTheme } from '../../hooks/useTheme';\nimport Button from '../Button/Button';\nimport { formatExamInfo } from './Quiz.utils';\n\nconst QuizBadge = ({\n subtype,\n}: {\n subtype: SUBTYPE_ENUM | undefined | string;\n}) => {\n switch (subtype) {\n case SUBTYPE_ENUM.PROVA:\n return (\n <Badge variant=\"examsOutlined\" action=\"exam2\" data-testid=\"quiz-badge\">\n Prova\n </Badge>\n );\n case SUBTYPE_ENUM.ENEM_PROVA_1:\n case SUBTYPE_ENUM.ENEM_PROVA_2:\n return (\n <Badge variant=\"examsOutlined\" action=\"exam1\" data-testid=\"quiz-badge\">\n Enem\n </Badge>\n );\n case SUBTYPE_ENUM.VESTIBULAR:\n return (\n <Badge variant=\"examsOutlined\" action=\"exam4\" data-testid=\"quiz-badge\">\n Vestibular\n </Badge>\n );\n case SUBTYPE_ENUM.SIMULADO:\n case SUBTYPE_ENUM.SIMULADAO:\n case undefined:\n return (\n <Badge variant=\"examsOutlined\" action=\"exam3\" data-testid=\"quiz-badge\">\n Simuladão\n </Badge>\n );\n default:\n return (\n <Badge variant=\"solid\" action=\"info\" data-testid=\"quiz-badge\">\n {subtype}\n </Badge>\n );\n }\n};\n\nconst QuizHeaderResult = forwardRef<HTMLDivElement, { className?: string }>(\n ({ className, ...props }, ref) => {\n const {\n getQuestionResultByQuestionId,\n getCurrentQuestion,\n questionsResult,\n } = useQuizStore();\n const [status, setStatus] = useState<ANSWER_STATUS | undefined>(undefined);\n useEffect(() => {\n const cq = getCurrentQuestion();\n if (!cq) {\n setStatus(undefined);\n return;\n }\n const qr = getQuestionResultByQuestionId(cq.id);\n setStatus(qr?.answerStatus);\n }, [\n getCurrentQuestion,\n getQuestionResultByQuestionId,\n getCurrentQuestion()?.id,\n questionsResult,\n ]);\n\n const getClassesByAnswersStatus = () => {\n // Guard para quando status ainda está carregando\n if (status === undefined) {\n return 'bg-gray-100';\n }\n\n switch (status) {\n case ANSWER_STATUS.RESPOSTA_CORRETA:\n return 'bg-success-background';\n case ANSWER_STATUS.RESPOSTA_INCORRETA:\n return 'bg-error-background';\n case ANSWER_STATUS.PENDENTE_AVALIACAO:\n return 'bg-info-background';\n default:\n return 'bg-error-background';\n }\n };\n\n const getLabelByAnswersStatus = () => {\n // Guard para quando status ainda está carregando\n if (status === undefined) {\n return 'Carregando...';\n }\n\n switch (status) {\n case ANSWER_STATUS.RESPOSTA_CORRETA:\n return '🎉 Parabéns!!';\n case ANSWER_STATUS.RESPOSTA_INCORRETA:\n return 'Não foi dessa vez...';\n case ANSWER_STATUS.PENDENTE_AVALIACAO:\n return 'Avaliação pendente';\n case ANSWER_STATUS.NAO_RESPONDIDO:\n return 'Não foi dessa vez...você deixou a resposta em branco';\n default:\n return 'Não foi dessa vez...você deixou a resposta em branco';\n }\n };\n return (\n <div\n ref={ref}\n className={cn(\n 'flex flex-row items-center gap-10 p-3.5 rounded-xl mb-4',\n getClassesByAnswersStatus(),\n className\n )}\n {...props}\n >\n <p className=\"text-text-950 font-bold text-lg\">Resultado</p>\n <p className=\"text-text-700 text-md\">{getLabelByAnswersStatus()}</p>\n </div>\n );\n }\n);\n\nconst getRetryButtonLabel = (type: QUIZ_TYPE | undefined) => {\n switch (type) {\n case QUIZ_TYPE.ATIVIDADE:\n return 'Refazer atividade';\n case QUIZ_TYPE.QUESTIONARIO:\n return 'Repetir questionário';\n case QUIZ_TYPE.SIMULADO:\n return 'Repetir simulado';\n default:\n return 'Refazer';\n }\n};\n\nconst QuizResultHeaderTitle = forwardRef<\n HTMLDivElement,\n {\n className?: string;\n showBadge?: boolean;\n onRepeat?: () => void;\n canRetry?: boolean;\n }\n>(({ className, showBadge = true, onRepeat, canRetry, ...props }, ref) => {\n const { quiz } = useQuizStore();\n return (\n <div\n ref={ref}\n className={cn(\n 'flex flex-row pt-4 justify-between items-center',\n className\n )}\n {...props}\n >\n <p className=\"text-text-950 font-bold text-2xl\">Resultado</p>\n <div className=\"flex flex-row gap-3 items-center\">\n {canRetry && onRepeat && (\n <Button\n variant=\"solid\"\n action=\"primary\"\n size=\"medium\"\n onClick={onRepeat}\n >\n {getRetryButtonLabel(quiz?.type)}\n </Button>\n )}\n\n {showBadge && <QuizBadge subtype={quiz?.subtype || undefined} />}\n </div>\n </div>\n );\n});\n\nconst QuizResultTitle = forwardRef<\n HTMLParagraphElement,\n { className?: string }\n>(({ className, ...props }, ref) => {\n const { getQuizTitle } = useQuizStore();\n const quizTitle = getQuizTitle();\n\n return (\n <p\n className={cn('pt-6 pb-4 text-text-950 font-bold text-lg', className)}\n ref={ref}\n {...props}\n >\n {quizTitle}\n </p>\n );\n});\n\n/**\n * Update statistics counters based on difficulty level\n * @param stats - Statistics object to update\n * @param difficulty - Question difficulty level\n * @param isCorrect - Whether the answer is correct\n */\nconst updateDifficultyStats = (\n stats: {\n correctEasyAnswers: number;\n correctMediumAnswers: number;\n correctDifficultAnswers: number;\n totalEasyQuestions: number;\n totalMediumQuestions: number;\n totalDifficultQuestions: number;\n },\n difficulty: string | undefined,\n isCorrect: boolean\n) => {\n if (difficulty === QUESTION_DIFFICULTY.FACIL) {\n stats.totalEasyQuestions++;\n if (isCorrect) stats.correctEasyAnswers++;\n } else if (difficulty === QUESTION_DIFFICULTY.MEDIO) {\n stats.totalMediumQuestions++;\n if (isCorrect) stats.correctMediumAnswers++;\n } else if (difficulty === QUESTION_DIFFICULTY.DIFICIL) {\n stats.totalDifficultQuestions++;\n if (isCorrect) stats.correctDifficultAnswers++;\n }\n};\n\n/**\n * Calculate answer statistics by difficulty level\n * @param answers - Array of question answers\n * @returns Statistics object with counts by difficulty\n */\nconst calculateAnswerStatistics = (\n answers: Array<{\n answerStatus: string;\n difficultyLevel?: string;\n }>\n) => {\n const stats = {\n correctAnswers: 0,\n correctEasyAnswers: 0,\n correctMediumAnswers: 0,\n correctDifficultAnswers: 0,\n totalEasyQuestions: 0,\n totalMediumQuestions: 0,\n totalDifficultQuestions: 0,\n };\n\n for (const answer of answers) {\n const isCorrect = answer.answerStatus === ANSWER_STATUS.RESPOSTA_CORRETA;\n\n if (isCorrect) {\n stats.correctAnswers++;\n }\n\n updateDifficultyStats(stats, answer.difficultyLevel, isCorrect);\n }\n\n return stats;\n};\n\nconst QuizResultPerformance = forwardRef<\n HTMLDivElement,\n {\n showDetails?: boolean;\n /**\n * Tempo gasto, dentro do anel. Segue `showDetails` por padrão; existe\n * separado porque uma prova feita no papel tem o desempenho por\n * dificuldade, mas não tem cronômetro — qualquer número ali seria\n * inventado.\n */\n showTimeSpent?: boolean;\n }\n>(({ showDetails = true, showTimeSpent = showDetails, ...props }, ref) => {\n const {\n getTotalQuestions,\n formatTime,\n getQuestionResultStatistics,\n getQuestionResult,\n } = useQuizStore();\n\n const totalQuestions = getTotalQuestions();\n const questionResult = getQuestionResult();\n\n const stats = questionResult\n ? calculateAnswerStatistics(questionResult.answers)\n : {\n correctAnswers: 0,\n correctEasyAnswers: 0,\n correctMediumAnswers: 0,\n correctDifficultAnswers: 0,\n totalEasyQuestions: 0,\n totalMediumQuestions: 0,\n totalDifficultQuestions: 0,\n };\n\n const percentage =\n totalQuestions > 0\n ? Math.round((stats.correctAnswers / totalQuestions) * 100)\n : 0;\n\n const classesJustifyBetween = showDetails\n ? 'justify-between'\n : 'justify-center';\n return (\n <div\n className={cn(\n 'flex flex-row gap-6 p-6 rounded-xl bg-background',\n classesJustifyBetween\n )}\n ref={ref}\n {...props}\n >\n <div className=\"relative\">\n <ProgressCircle\n size=\"medium\"\n variant=\"green\"\n value={percentage}\n showPercentage={false}\n label=\"\"\n />\n\n <div className=\"absolute inset-0 flex flex-col items-center justify-center\">\n {showTimeSpent && (\n <div className=\"flex items-center gap-1 mb-1\">\n <ClockIcon size={12} weight=\"regular\" className=\"text-text-800\" />\n <span className=\"text-2xs font-medium text-text-800\">\n {formatTime(\n (getQuestionResultStatistics()?.timeSpent ?? 0) * 60\n )}\n </span>\n </div>\n )}\n\n <div className=\"text-2xl font-medium text-text-800 leading-7\">\n {getQuestionResultStatistics()?.correctAnswers ?? '--'} de{' '}\n {totalQuestions}\n </div>\n\n <div className=\"text-2xs font-medium text-text-600 mt-1\">\n Corretas\n </div>\n </div>\n </div>\n\n {showDetails && (\n <div className=\"flex flex-col gap-4 w-full\">\n <ProgressBar\n className=\"w-full\"\n layout=\"stacked\"\n variant=\"green\"\n value={stats.correctEasyAnswers}\n max={stats.totalEasyQuestions}\n label=\"Fáceis\"\n showHitCount\n labelClassName=\"text-base font-medium text-text-800 leading-none\"\n percentageClassName=\"text-xs font-medium leading-[14px] text-right\"\n />\n\n <ProgressBar\n className=\"w-full\"\n layout=\"stacked\"\n variant=\"green\"\n value={stats.correctMediumAnswers}\n max={stats.totalMediumQuestions}\n label=\"Médias\"\n showHitCount\n labelClassName=\"text-base font-medium text-text-800 leading-none\"\n percentageClassName=\"text-xs font-medium leading-[14px] text-right\"\n />\n\n <ProgressBar\n className=\"w-full\"\n layout=\"stacked\"\n variant=\"green\"\n value={stats.correctDifficultAnswers}\n max={stats.totalDifficultQuestions}\n label=\"Difíceis\"\n showHitCount\n labelClassName=\"text-base font-medium text-text-800 leading-none\"\n percentageClassName=\"text-xs font-medium leading-[14px] text-right\"\n />\n </div>\n )}\n </div>\n );\n});\n\nconst QuizListResult = forwardRef<\n HTMLDivElement,\n {\n className?: string;\n onSubjectClick?: (subject: string) => void;\n }\n>(({ className, onSubjectClick, ...props }, ref) => {\n const { getQuestionsGroupedBySubject } = useQuizStore();\n const { isDark } = useTheme();\n const groupedQuestions = getQuestionsGroupedBySubject();\n const subjectsStats = Object.entries(groupedQuestions).map(\n ([subjectId, questions]) => {\n let correct = 0;\n let incorrect = 0;\n\n for (const question of questions) {\n if (question.answerStatus === ANSWER_STATUS.RESPOSTA_CORRETA) {\n correct++;\n } else {\n incorrect++;\n }\n }\n\n return {\n subject: {\n name:\n questions?.[0]?.knowledgeMatrix?.[0]?.subject?.name ??\n 'Sem componente curricular',\n id: subjectId,\n color: questions?.[0]?.knowledgeMatrix?.[0]?.subject?.color ?? '',\n icon: questions?.[0]?.knowledgeMatrix?.[0]?.subject?.icon ?? '',\n },\n correct,\n incorrect,\n total: questions.length,\n };\n }\n );\n\n return (\n <section ref={ref} className={className} {...props}>\n <p className=\"pt-6 pb-4 text-text-950 font-bold text-lg\">\n Componentes curriculares\n </p>\n\n <ul className=\"flex flex-col gap-2\">\n {subjectsStats.map((subject) => (\n <li key={subject.subject.id}>\n <CardResults\n onClick={() => onSubjectClick?.(subject.subject.id)}\n className=\"max-w-full\"\n header={subject.subject.name}\n correct_answers={subject.correct}\n incorrect_answers={subject.incorrect}\n icon={subject.subject.icon || 'Book'}\n color={\n getSubjectColorWithOpacity(subject.subject.color, isDark) ||\n undefined\n }\n direction=\"row\"\n />\n </li>\n ))}\n </ul>\n </section>\n );\n});\n\nconst QuizListResultByMateria = ({\n subject,\n onQuestionClick,\n subjectName,\n}: {\n subject: string;\n onQuestionClick: (\n question: Question | QuestionResult['answers'][number]\n ) => void;\n subjectName?: string;\n}) => {\n const { getQuestionsGroupedBySubject, getQuestionIndex, quiz } =\n useQuizStore();\n const groupedQuestions = getQuestionsGroupedBySubject();\n\n // Only show exam info (banca/year) for SIMULADO type\n const shouldShowExamInfo = quiz?.type === QUIZ_TYPE.SIMULADO;\n\n const answeredQuestions = groupedQuestions[subject] || [];\n const formattedQuestions =\n subject == 'all'\n ? Object.values(groupedQuestions).flat()\n : answeredQuestions;\n return (\n <div className=\"flex flex-col\">\n <div className=\"flex flex-row pt-4 justify-between\">\n <p className=\"text-text-950 font-bold text-2xl\">\n {subjectName ||\n formattedQuestions?.[0]?.knowledgeMatrix?.[0]?.subject?.name ||\n 'Sem componente curricular'}\n </p>\n </div>\n\n <section className=\"flex flex-col \">\n <p className=\"pt-6 pb-4 text-text-950 font-bold text-lg\">\n Resultado das questões\n </p>\n\n <ul className=\"flex flex-col gap-2 pt-4\">\n {formattedQuestions.map((question) => {\n // questionId exists in QuestionResult answers, id in Question\n const questionId =\n 'questionId' in question ? question.questionId : question.id;\n const questionIndex = getQuestionIndex(questionId);\n\n // examBoard and examYear only exist in Question type - only show for SIMULADO\n const examBoard =\n 'examBoard' in question ? question.examBoard : null;\n const examYear = 'examYear' in question ? question.examYear : null;\n const examInfo = shouldShowExamInfo\n ? formatExamInfo(examBoard, examYear)\n : '';\n const questionTitle = `Questão ${questionIndex.toString().padStart(2, '0')}`;\n const header = examInfo\n ? `${questionTitle} ${examInfo}`\n : questionTitle;\n return (\n <li key={question.id}>\n <CardStatus\n className=\"max-w-full\"\n header={header}\n status={(() => {\n if (\n question.answerStatus === ANSWER_STATUS.RESPOSTA_CORRETA\n )\n return 'correct';\n if (\n question.answerStatus === ANSWER_STATUS.RESPOSTA_INCORRETA\n )\n return 'incorrect';\n if (question.answerStatus === ANSWER_STATUS.NAO_RESPONDIDO)\n return 'unanswered';\n if (\n question.answerStatus === ANSWER_STATUS.PENDENTE_AVALIACAO\n )\n return 'pending';\n return undefined;\n })()}\n onClick={() => onQuestionClick?.(question)}\n />\n </li>\n );\n })}\n </ul>\n </section>\n </div>\n );\n};\n\nexport {\n QuizListResultByMateria,\n QuizListResult,\n QuizResultPerformance,\n QuizResultTitle,\n QuizResultHeaderTitle,\n QuizHeaderResult,\n};\n"]}
@@ -1,21 +0,0 @@
1
- // src/types/enemClassroom.ts
2
- var ENEM_CLASSROOM_LANGUAGE = {
3
- INGLES: "INGLES",
4
- ESPANHOL: "ESPANHOL"
5
- };
6
- var ENEM_CLASSROOM_LANGUAGE_LABELS = {
7
- INGLES: "Ingl\xEAs",
8
- ESPANHOL: "Espanhol"
9
- };
10
- var ENEM_CLASSROOM_PARTICIPATION_STATUS = {
11
- NOT_STARTED: "NOT_STARTED",
12
- IN_PROGRESS: "IN_PROGRESS",
13
- FINISHED: "FINISHED"
14
- };
15
-
16
- export {
17
- ENEM_CLASSROOM_LANGUAGE,
18
- ENEM_CLASSROOM_LANGUAGE_LABELS,
19
- ENEM_CLASSROOM_PARTICIPATION_STATUS
20
- };
21
- //# sourceMappingURL=chunk-ND5M3DZA.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/types/enemClassroom.ts"],"sourcesContent":["/**\n * In-classroom ENEM simulation (\"Simulação do ENEM em sala de aula\").\n *\n * Shapes of the student-facing API (`/enem-classroom/*`), shared by the\n * student web app and the backoffice so both read the same vocabulary.\n */\n\n/**\n * Foreign language the student sits the exam in. Picks which of the two\n * language blocks of the exam the student receives.\n */\nexport const ENEM_CLASSROOM_LANGUAGE = {\n INGLES: 'INGLES',\n ESPANHOL: 'ESPANHOL',\n} as const;\n\nexport type EnemClassroomLanguage =\n (typeof ENEM_CLASSROOM_LANGUAGE)[keyof typeof ENEM_CLASSROOM_LANGUAGE];\n\n/** Human labels for each language, in the order the student sees them. */\nexport const ENEM_CLASSROOM_LANGUAGE_LABELS: Record<\n EnemClassroomLanguage,\n string\n> = {\n INGLES: 'Inglês',\n ESPANHOL: 'Espanhol',\n};\n\n/** Where the student stands in the exam. FINISHED is final. */\nexport const ENEM_CLASSROOM_PARTICIPATION_STATUS = {\n NOT_STARTED: 'NOT_STARTED',\n IN_PROGRESS: 'IN_PROGRESS',\n FINISHED: 'FINISHED',\n} as const;\n\nexport type EnemClassroomParticipationStatus =\n (typeof ENEM_CLASSROOM_PARTICIPATION_STATUS)[keyof typeof ENEM_CLASSROOM_PARTICIPATION_STATUS];\n\n/**\n * One socio-economic question asked before the exam starts. Free text with a\n * \"skip\" option — every field is written by the backoffice.\n */\nexport interface EnemClassroomSurveyQuestion {\n id: string;\n position: number;\n /** Short name of the step in the stepper (\"Curso\"). */\n stepLabel: string;\n /** The question itself (\"Você já tem o curso que quer fazer em mente?\"). */\n prompt: string;\n /** Label of the option that opens the text field (\"Se sim, escreva o seu curso\"). */\n inputLabel: string;\n /** Placeholder of the text field (\"Escreva o curso\"). */\n inputPlaceholder: string;\n /** Label of the option that skips the question (\"Não, ainda estou pensando\"). */\n skipLabel: string;\n}\n\n/** The exam as the student sees it before starting. */\nexport interface EnemClassroomExam {\n id: string;\n title: string;\n /** Introduction video shown on the first step; null when there is none. */\n videoUrl: string | null;\n /** How long the student has once they start. */\n durationMinutes: number;\n /**\n * Whether the student picks English or Spanish before starting (ENEM's\n * day 1). Off, the exam has no foreign-language block and the choice step\n * is not shown (day 2).\n */\n languageChoice: boolean;\n /** What the panel card says while the exam waits to be started; written by the backoffice. */\n bannerText: string;\n surveyQuestions: EnemClassroomSurveyQuestion[];\n}\n\n/** A survey answer; `null` means the student skipped the question. */\nexport interface EnemClassroomSurveyAnswer {\n questionId: string;\n answer: string | null;\n}\n\n/** The student's own record of the exam. */\nexport interface EnemClassroomParticipation {\n status: EnemClassroomParticipationStatus;\n language: EnemClassroomLanguage | null;\n /** ISO 8601 */\n startedAt: string | null;\n /** ISO 8601. `startedAt + durationMinutes`; the exam is submitted at this point. */\n deadlineAt: string | null;\n /** The shared activity behind the exam — what drafts and answers address. */\n activityId: string;\n surveyAnswers: EnemClassroomSurveyAnswer[];\n}\n\n/** `GET /enem-classroom/current` */\nexport interface EnemClassroomCurrentResponse {\n message: string;\n data: {\n /** Null when the institution has no active exam. */\n exam: EnemClassroomExam | null;\n /** Null until the student starts. */\n participation: EnemClassroomParticipation | null;\n };\n}\n\n/** `POST /enem-classroom/exams/:id/start` body */\nexport interface EnemClassroomStartPayload {\n /** Null when the exam offers no language choice. */\n language: EnemClassroomLanguage | null;\n surveyAnswers: EnemClassroomSurveyAnswer[];\n}\n\n/** `POST /enem-classroom/exams/:id/start` response */\nexport interface EnemClassroomStartResponse {\n message: string;\n data: {\n activityId: string;\n startedAt: string;\n deadlineAt: string;\n };\n}\n"],"mappings":";AAWO,IAAM,0BAA0B;AAAA,EACrC,QAAQ;AAAA,EACR,UAAU;AACZ;AAMO,IAAM,iCAGT;AAAA,EACF,QAAQ;AAAA,EACR,UAAU;AACZ;AAGO,IAAM,sCAAsC;AAAA,EACjD,aAAa;AAAA,EACb,aAAa;AAAA,EACb,UAAU;AACZ;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/Quiz/Quiz.tsx"],"sourcesContent":["import { BookOpenIcon } from '@phosphor-icons/react/dist/csr/BookOpen';\nimport { CaretLeftIcon } from '@phosphor-icons/react/dist/csr/CaretLeft';\nimport { CaretRightIcon } from '@phosphor-icons/react/dist/csr/CaretRight';\nimport { SquaresFourIcon } from '@phosphor-icons/react/dist/csr/SquaresFour';\nimport { HeaderAlternative } from '../Alternative/Alternative';\nimport Button from '../Button/Button';\nimport IconButton from '../IconButton/IconButton';\nimport {\n forwardRef,\n ReactNode,\n useEffect,\n useState,\n ComponentType,\n} from 'react';\nimport {\n useQuizStore,\n QUESTION_TYPE,\n QUIZ_TYPE,\n AI_CORRECTION_STATUS,\n CORRECTION_SOURCE,\n} from './useQuizStore';\nimport CorrectionSourceTag from './CorrectionSourceTag';\nimport { resolveCorrectionText } from './correction.utils';\nimport { QuizVariant } from './Quiz.types';\nimport { AlertDialog } from '../AlertDialog/AlertDialog';\nimport Modal from '../Modal/Modal';\n\nimport Select, {\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '../Select/Select';\nimport { cn } from '../../utils/utils';\nimport {\n QuizAlternative,\n QuizConnectDots,\n QuizDissertative,\n QuizFill,\n QuizImageQuestion,\n QuizMultipleChoice,\n QuizTrueOrFalse,\n} from './QuizContent';\nimport { CardStatus } from '../Card/Card';\nimport Text from '../Text/Text';\nimport HtmlMathRenderer from '../HtmlMathRenderer/HtmlMathRenderer';\nimport { formatExamInfo } from './Quiz.utils';\nimport QuizTimer from '../QuizTimer/QuizTimer';\nimport { useMobile } from '../../hooks/useMobile';\n\n// Função para obter configuração do tipo de quiz\nexport const getQuizTypeConfig = (type: QUIZ_TYPE) => {\n // Configuração centralizada para cada tipo de quiz\n const QUIZ_TYPE_CONFIG = {\n [QUIZ_TYPE.SIMULADO]: {\n label: 'Simulado',\n article: 'o',\n preposition: 'do',\n },\n [QUIZ_TYPE.QUESTIONARIO]: {\n label: 'Questionário',\n article: 'o',\n preposition: 'do',\n },\n [QUIZ_TYPE.ATIVIDADE]: {\n label: 'Atividade',\n article: 'a',\n preposition: 'da',\n },\n [QUIZ_TYPE.AULA_RECOMENDADA]: {\n label: 'Aula recomendada',\n article: 'a',\n preposition: 'da',\n },\n } as const;\n\n const config = QUIZ_TYPE_CONFIG[type];\n return config || QUIZ_TYPE_CONFIG[QUIZ_TYPE.SIMULADO]; // fallback para simulado\n};\n\n// Função para obter o label do tipo\nexport const getTypeLabel = (type: QUIZ_TYPE) => {\n return getQuizTypeConfig(type).label;\n};\n\n// Função para obter o artigo (o/a)\nexport const getQuizArticle = (type: QUIZ_TYPE) => {\n return getQuizTypeConfig(type).article;\n};\n\n// Função para obter a preposição (do/da)\nexport const getQuizPreposition = (type: QUIZ_TYPE) => {\n return getQuizTypeConfig(type).preposition;\n};\n\n// Função para gerar título de conclusão\nexport const getCompletionTitle = (type: QUIZ_TYPE) => {\n const config = getQuizTypeConfig(type);\n return `Você concluiu ${config.article} ${config.label.toLowerCase()}!`;\n};\n\n// Função para gerar o rótulo do botão de retorno no modal de conclusão\nexport const getGoBackButtonLabel = (type: QUIZ_TYPE): string => {\n if (type === QUIZ_TYPE.SIMULADO) return 'Ir para simulados';\n if (type === QUIZ_TYPE.QUESTIONARIO) return 'Ir para aulas';\n if (type === QUIZ_TYPE.ATIVIDADE) return 'Ir para atividades';\n if (type === QUIZ_TYPE.AULA_RECOMENDADA) return 'Ir para aulas recomendadas';\n return 'Ir para simulados';\n};\n\n// Função para gerar texto de confirmação de saída\nexport const getExitConfirmationText = (type: QUIZ_TYPE) => {\n const config = getQuizTypeConfig(type);\n // QUESTIONARIO não tem rascunho: ao sair, as respostas são perdidas.\n // Demais tipos (SIMULADO, ATIVIDADE, AULA_RECOMENDADA e fallback) salvam o\n // progresso, então o aluno pode continuar depois de onde parou.\n if (type === QUIZ_TYPE.QUESTIONARIO) {\n return `Se você sair ${config.preposition} ${config.label.toLowerCase()} agora, todas as respostas serão perdidas.`;\n }\n return `Se você sair ${config.preposition} ${config.label.toLowerCase()} agora, poderá continuar de onde parou depois.`;\n};\n\n// Função para gerar texto de confirmação de finalização\nexport const getFinishConfirmationText = (type: QUIZ_TYPE) => {\n const config = getQuizTypeConfig(type);\n return `Tem certeza que deseja finalizar ${config.article} ${config.label.toLowerCase()}?`;\n};\n\nconst Quiz = forwardRef<\n HTMLDivElement,\n { children: ReactNode; className?: string; variant?: 'result' | 'default' }\n>(({ children, className, variant = QuizVariant.DEFAULT, ...props }, ref) => {\n const { setVariant } = useQuizStore();\n\n useEffect(() => {\n setVariant(variant as QuizVariant);\n }, [variant, setVariant]);\n\n return (\n <div ref={ref} className={cn('flex flex-col', className)} {...props}>\n {children}\n </div>\n );\n});\n\nconst QuizTitle = forwardRef<\n HTMLDivElement,\n { className?: string; onBack?: () => void; showTimer?: boolean }\n>(({ className, onBack, showTimer = false, ...props }, ref) => {\n const {\n quiz,\n currentQuestionIndex,\n getTotalQuestions,\n getQuizTitle,\n isStarted,\n } = useQuizStore();\n\n const [showExitConfirmation, setShowExitConfirmation] = useState(false);\n\n const totalQuestions = getTotalQuestions();\n const quizTitle = getQuizTitle();\n\n const handleBackClick = () => {\n if (isStarted) {\n setShowExitConfirmation(true);\n } else {\n actionOnBack();\n }\n };\n\n const handleConfirmExit = () => {\n setShowExitConfirmation(false);\n actionOnBack();\n };\n\n const actionOnBack = () => {\n if (onBack) {\n onBack();\n } else {\n globalThis.history.back();\n }\n };\n\n const handleCancelExit = () => {\n setShowExitConfirmation(false);\n };\n\n return (\n <>\n <div\n ref={ref}\n /*\n * Três colunas em vez de `justify-between`: as laterais são `1fr`\n * iguais, então o título fica centralizado na tela mesmo com o voltar\n * e o cronômetro tendo larguras diferentes. Com flex ele era empurrado\n * para a direita junto do cronômetro.\n */\n className={cn(\n 'grid grid-cols-[1fr_auto_1fr] items-center gap-2 relative p-2',\n className\n )}\n {...props}\n >\n <IconButton\n icon={<CaretLeftIcon size={24} />}\n size=\"md\"\n aria-label=\"Voltar\"\n onClick={handleBackClick}\n className=\"justify-self-start\"\n />\n <span className=\"flex flex-col gap-2 text-center\">\n <Text size=\"md\" weight=\"bold\" color=\"text-text-950\">\n {quizTitle}\n </Text>\n <Text size=\"xs\" color=\"text-text-600\">\n {totalQuestions > 0\n ? `${currentQuestionIndex + 1} de ${totalQuestions}`\n : '0 de 0'}\n </Text>\n </span>\n <div className=\"justify-self-end\">{showTimer && <QuizTimer />}</div>\n </div>\n\n <AlertDialog\n isOpen={showExitConfirmation}\n onChangeOpen={setShowExitConfirmation}\n title=\"Deseja sair?\"\n description={getExitConfirmationText(quiz?.type || QUIZ_TYPE.SIMULADO)}\n cancelButtonLabel=\"Voltar e revisar\"\n submitButtonLabel=\"Sair Mesmo Assim\"\n onSubmit={handleConfirmExit}\n onCancel={handleCancelExit}\n />\n </>\n );\n});\n\nconst QuizHeader = () => {\n const { getCurrentQuestion, getQuestionIndex, quiz } = useQuizStore();\n const currentQuestion = getCurrentQuestion();\n let currentId =\n currentQuestion && 'questionId' in currentQuestion\n ? (currentQuestion.questionId as string)\n : currentQuestion?.id;\n const questionIndex = getQuestionIndex(currentId!);\n\n const questionNumber = currentQuestion\n ? `Questão ${questionIndex.toString().padStart(2, '0')}`\n : 'Questão';\n\n // Only show exam info (banca/year) for SIMULADO type\n const shouldShowExamInfo = quiz?.type === QUIZ_TYPE.SIMULADO;\n const examInfo = shouldShowExamInfo\n ? formatExamInfo(currentQuestion?.examBoard, currentQuestion?.examYear)\n : '';\n\n const title = examInfo ? `${questionNumber} ${examInfo}` : questionNumber;\n\n return (\n <HeaderAlternative\n title={title}\n subTitle={currentQuestion?.knowledgeMatrix?.[0]?.topic?.name ?? ''}\n content={currentQuestion?.statement ?? ''}\n />\n );\n};\n\nconst QuizContent = ({ paddingBottom }: { paddingBottom?: string }) => {\n const { getCurrentQuestion } = useQuizStore();\n const { isMobile } = useMobile();\n const currentQuestion = getCurrentQuestion();\n\n // `QuizFooter` is `position: fixed`, so it sits on top of the content instead\n // of taking space in the flow — without room reserved here, the last\n // alternative ends up underneath it and unreadable. The bar is taller on a\n // phone, where its controls stack into two rows.\n const contentPaddingBottom = paddingBottom ?? (isMobile ? 'pb-32' : 'pb-24');\n const questionComponents: Record<\n string,\n ComponentType<QuizVariantInterface>\n > = {\n [QUESTION_TYPE.ALTERNATIVA]: QuizAlternative,\n [QUESTION_TYPE.MULTIPLA_ESCOLHA]: QuizMultipleChoice,\n [QUESTION_TYPE.DISSERTATIVA]: QuizDissertative,\n [QUESTION_TYPE.VERDADEIRO_FALSO]: QuizTrueOrFalse,\n [QUESTION_TYPE.RELACIONAR]: QuizConnectDots,\n [QUESTION_TYPE.PREENCHER_LACUNAS]: QuizFill,\n [QUESTION_TYPE.IMAGEM]: QuizImageQuestion,\n };\n\n const QuestionComponent = currentQuestion\n ? questionComponents[currentQuestion.questionType]\n : null;\n\n if (!QuestionComponent) {\n return (\n <Text size=\"md\" weight=\"medium\" className=\"text-text-950 text-md\">\n Tipo de questão não suportado\n </Text>\n );\n }\n\n // The teacher's comment is no longer echoed here: in the result variant it\n // lives behind the \"Ver comentário\" button in the footer, so it is not shown\n // twice on the same screen.\n return <QuestionComponent paddingBottom={contentPaddingBottom} />;\n};\n\ninterface QuizVariantInterface {\n paddingBottom?: string;\n}\n\nconst QuizQuestionList = ({\n filterType = 'all',\n onQuestionClick,\n}: {\n filterType?: string;\n onQuestionClick?: () => void;\n} = {}) => {\n const {\n getQuestionsGroupedBySubject,\n goToQuestion,\n getQuestionStatusFromUserAnswers,\n getQuestionIndex,\n quiz,\n } = useQuizStore();\n\n // Only show exam info (banca/year) for SIMULADO type\n const shouldShowExamInfo = quiz?.type === QUIZ_TYPE.SIMULADO;\n\n const groupedQuestions = getQuestionsGroupedBySubject();\n const getQuestionStatus = (questionId: string) => {\n return getQuestionStatusFromUserAnswers(questionId);\n };\n const filteredGroupedQuestions = Object.entries(groupedQuestions).reduce(\n (acc, [subjectId, questions]) => {\n const filteredQuestions = questions.filter((question) => {\n const status = getQuestionStatus(question.id);\n switch (filterType) {\n case 'answered':\n return status === 'answered';\n case 'unanswered':\n return status === 'unanswered' || status === 'skipped';\n default:\n return true;\n }\n });\n\n if (filteredQuestions.length > 0) {\n acc[subjectId] = filteredQuestions;\n }\n\n return acc;\n },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n {} as { [key: string]: any[] }\n );\n\n const getStatusLabel = (status: string) => {\n switch (status) {\n case 'answered':\n return 'Respondida';\n case 'skipped':\n return 'Em branco';\n default:\n return 'Em branco';\n }\n };\n return (\n <div className=\"space-y-6 px-4 h-full\">\n {Object.entries(filteredGroupedQuestions).length == 0 && (\n <div className=\"flex items-center justify-center text-gray-500 py-8 h-full\">\n <p className=\"text-lg\">Nenhum resultado</p>\n </div>\n )}\n {Object.entries(filteredGroupedQuestions).map(\n ([subjectId, questions]) => (\n <section key={subjectId} className=\"flex flex-col gap-2\">\n <span className=\"pt-6 pb-4 flex flex-row gap-2\">\n <div className=\"bg-primary-500 p-1 rounded-sm flex items-center justify-center\">\n <BookOpenIcon size={17} className=\"text-white\" />\n </div>\n <p className=\"text-text-800 font-bold text-lg\">\n {questions?.[0]?.knowledgeMatrix?.[0]?.subject?.name ??\n 'Sem componente curricular'}\n </p>\n </span>\n\n <ul className=\"flex flex-col gap-2\">\n {questions.map((question) => {\n const status = getQuestionStatus(question.id);\n const questionNumber = getQuestionIndex(question.id);\n const examInfo = shouldShowExamInfo\n ? formatExamInfo(question.examBoard, question.examYear)\n : '';\n const questionTitle = `Questão ${questionNumber.toString().padStart(2, '0')}`;\n const header = examInfo\n ? `${questionTitle} ${examInfo}`\n : questionTitle;\n return (\n <CardStatus\n key={question.id}\n header={header}\n label={getStatusLabel(status)}\n onClick={() => {\n goToQuestion(questionNumber - 1);\n onQuestionClick?.();\n }}\n />\n );\n })}\n </ul>\n </section>\n )\n )}\n </div>\n );\n};\n\n/**\n * Shared layout for the quiz result modals (generic result, all-correct and\n * all-incorrect questionnaire variants): a centered image, a title and a\n * footer with action buttons.\n */\nconst QuizResultModal = ({\n isOpen,\n onClose,\n image,\n showImagePlaceholder = true,\n title,\n description,\n footer,\n}: {\n isOpen: boolean;\n onClose: () => void;\n image?: ReactNode;\n showImagePlaceholder?: boolean;\n title: ReactNode;\n description: ReactNode;\n footer: ReactNode;\n}) => (\n <Modal\n isOpen={isOpen}\n onClose={onClose}\n title=\"\"\n closeOnEscape={false}\n hideCloseButton\n size={'md'}\n >\n <div className=\"flex flex-col w-full h-full items-center justify-center gap-4\">\n {image ? (\n <div className=\"w-[282px] h-auto\">{image}</div>\n ) : (\n showImagePlaceholder && (\n <div className=\"w-[282px] h-[200px] bg-gray-100 rounded-md flex items-center justify-center\">\n <Text as=\"span\" size=\"sm\" color=\"text-gray-500\">\n Imagem de resultado\n </Text>\n </div>\n )\n )}\n <div className=\"flex flex-col gap-2 text-center\">\n <Text as=\"h2\" size=\"lg\" weight=\"bold\">\n {title}\n </Text>\n {description}\n </div>\n {footer}\n </div>\n </Modal>\n);\n\n/**\n * Correction of the question currently on screen, resolved once.\n *\n * A dissertativa may have been graded by the AI. The teacher's text wins when it\n * exists, the AI's stands otherwise; the two are never merged — the backend\n * keeps them in separate columns precisely so a review does not destroy the\n * original verdict — and `correctionSource` says which one is on screen.\n *\n * It lives here, and not inline in `QuizFooter`, because both the footer (for\n * the modal body and title) and `QuizReviewActions` (for the buttons) need the\n * same four values, and deriving them twice would be two chances to disagree.\n *\n * @returns The effective comment plus the fields the tag and the title read\n */\nconst useCurrentCorrection = () => {\n const { getCurrentQuestion, getQuestionResultByQuestionId } = useQuizStore();\n\n const currentQuestion = getCurrentQuestion();\n const result = currentQuestion\n ? getQuestionResultByQuestionId(currentQuestion.id)\n : null;\n\n return {\n comment: resolveCorrectionText({ ...result }),\n correctionSource: result?.correctionSource,\n aiCorrectionStatus: result?.aiCorrectionStatus,\n };\n};\n\n/**\n * Title for the per-question feedback modal, phrased for whoever wrote it.\n *\n * Calling an AI correction \"Comentário do professor\" would be a lie the tag\n * inside the modal immediately contradicts, so both are derived from the same\n * `correctionSource`.\n *\n * @param correctionSource - Who produced the correction on display\n * @returns The modal title\n */\nconst getCorrectionModalTitle = (\n correctionSource?: CORRECTION_SOURCE | null\n): string => {\n if (correctionSource === CORRECTION_SOURCE.IA) {\n return 'Correção por IA';\n }\n\n if (correctionSource === CORRECTION_SOURCE.IA_PROFESSOR) {\n return 'Correção revisada pelo professor';\n }\n\n return 'Comentário do professor';\n};\n\n/**\n * The review bar's question-scoped actions: see the resolution, see the correction.\n *\n * Split out of `QuizFooter` because the two bars do different jobs — the\n * `default` one navigates between questions, this one reads a question already\n * graded — and because the four conditions the correction needs pushed the\n * footer past the cognitive-complexity limit while sitting in the middle of\n * unrelated navigation markup.\n *\n * @param props - Callbacks that open the footer's modals\n * @returns JSX element\n */\nconst QuizReviewActions = ({\n onOpenResolution,\n onOpenComment,\n className,\n}: {\n onOpenResolution: () => void;\n onOpenComment: () => void;\n readonly className?: string;\n}) => {\n const { getCurrentQuestion } = useQuizStore();\n const { comment, correctionSource, aiCorrectionStatus } =\n useCurrentCorrection();\n\n const currentQuestion = getCurrentQuestion();\n const hasResolution = Boolean(currentQuestion?.solutionExplanation);\n const isAiCorrecting = aiCorrectionStatus === AI_CORRECTION_STATUS.PENDING;\n const commentLabel =\n correctionSource === CORRECTION_SOURCE.IA\n ? 'Ver correção da IA'\n : 'Ver comentário';\n\n return (\n <div className={className}>\n {hasResolution && (\n <Button\n variant=\"solid\"\n action=\"primary\"\n size=\"large\"\n onClick={onOpenResolution}\n >\n Ver resolução\n </Button>\n )}\n {comment && (\n <Button\n variant=\"outline\"\n action=\"primary\"\n size=\"large\"\n onClick={onOpenComment}\n >\n {commentLabel}\n </Button>\n )}\n {/* Sem comentário ainda, mas a IA está corrigindo: o aluno acaba de\n entregar e chegou aqui antes do feedback existir. Dizer que está a\n caminho é melhor do que não mostrar nada. */}\n {!comment && isAiCorrecting && (\n <CorrectionSourceTag\n aiCorrectionStatus={aiCorrectionStatus}\n className=\"self-center\"\n />\n )}\n </div>\n );\n};\n\n/**\n * What the completion modal shows instead of the score.\n *\n * Some exams are not corrected on the spot — the in-classroom ENEM simulation\n * is graded later — so telling the student how many they got right would be\n * wrong. With this set, finishing opens a modal with only this content and\n * one button.\n */\nexport interface QuizCompletionOverride {\n title: ReactNode;\n description: ReactNode;\n buttonLabel: string;\n onConfirm: () => void;\n}\n\nconst QuizFooter = forwardRef<\n HTMLDivElement,\n {\n className?: string;\n onGoToSimulated?: () => void;\n onDetailResult?: () => void;\n handleFinishSimulated?: () => void;\n onGoToNextModule?: () => void;\n onRepeat?: () => void;\n onTryLater?: () => void;\n resultImageComponent?: ReactNode;\n resultIncorrectImageComponent?: ReactNode;\n /** Replaces the score modal; see `QuizCompletionOverride`. */\n completionOverride?: QuizCompletionOverride;\n }\n>(\n (\n {\n className,\n onGoToSimulated,\n onDetailResult,\n handleFinishSimulated,\n onGoToNextModule,\n onRepeat,\n onTryLater,\n resultImageComponent,\n resultIncorrectImageComponent,\n completionOverride,\n ...props\n },\n ref\n ) => {\n const {\n quiz,\n currentQuestionIndex,\n getTotalQuestions,\n goToNextQuestion,\n goToPreviousQuestion,\n getUnansweredQuestionsFromUserAnswers,\n getCurrentAnswer,\n skipQuestion,\n skipCurrentQuestionIfUnanswered,\n getCurrentQuestion,\n getQuestionStatusFromUserAnswers,\n variant,\n getQuestionResultStatistics,\n } = useQuizStore();\n\n // The review bar carries four controls. Below ~500px they no longer fit on\n // one line, so the actions and the pagination stack into two centred rows.\n const { isMobile } = useMobile();\n\n const totalQuestions = getTotalQuestions();\n const isFirstQuestion = currentQuestionIndex === 0;\n const isLastQuestion = currentQuestionIndex === totalQuestions - 1;\n const currentAnswer = getCurrentAnswer();\n const currentQuestion = getCurrentQuestion();\n const {\n comment: teacherComment,\n correctionSource,\n aiCorrectionStatus,\n } = useCurrentCorrection();\n const isCurrentQuestionSkipped = currentQuestion\n ? getQuestionStatusFromUserAnswers(currentQuestion.id) === 'skipped'\n : false;\n // Sistema unificado de controle de modais\n const [activeModal, setActiveModal] = useState<string | null>(null);\n const [filterType, setFilterType] = useState<string>('all');\n\n // Funções para controlar modais\n const openModal = (modalName: string) => setActiveModal(modalName);\n const closeModal = () => setActiveModal(null);\n const isModalOpen = (modalName: string) => activeModal === modalName;\n const unansweredQuestions = getUnansweredQuestionsFromUserAnswers();\n const allQuestions = getTotalQuestions();\n const stats = getQuestionResultStatistics();\n const correctAnswers = stats?.correctAnswers;\n const quizType = quiz?.type || QUIZ_TYPE.SIMULADO;\n const quizTypeLabel = getTypeLabel(quizType);\n // Real subtopic name, used to label the questionnaire completion modals.\n // The backend always populates the question knowledge matrix, so this is\n // available as soon as the quiz is loaded.\n const moduleName =\n quiz?.questions?.[0]?.knowledgeMatrix?.[0]?.subtopic?.name;\n\n // Submits the answers and opens the correct result modal. Statistics must\n // be read AFTER handleFinishSimulated, which is what populates\n // questionsResult in the store (the render-time values are still empty).\n const submitAndOpenResultModal = async () => {\n if (handleFinishSimulated) {\n await Promise.resolve(handleFinishSimulated());\n }\n\n if (completionOverride) {\n openModal('modalCompletionOverride');\n return;\n }\n\n const latestStats = getQuestionResultStatistics();\n const latestCorrect = latestStats?.correctAnswers;\n const latestTotal = latestStats?.totalAnswered;\n\n if (\n quizType === QUIZ_TYPE.QUESTIONARIO &&\n typeof latestCorrect === 'number' &&\n typeof latestTotal === 'number' &&\n latestCorrect === latestTotal\n ) {\n openModal('modalQuestionnaireAllCorrect');\n return;\n }\n\n if (\n quizType === QUIZ_TYPE.QUESTIONARIO &&\n typeof latestCorrect === 'number' &&\n latestCorrect === 0\n ) {\n openModal('modalQuestionnaireAllIncorrect');\n return;\n }\n\n openModal('modalResult');\n };\n\n const handleFinishQuiz = async () => {\n // Marca a questão atual como pulada se não foi respondida\n skipCurrentQuestionIfUnanswered();\n\n if (unansweredQuestions.length > 0) {\n openModal('alertDialog');\n return;\n }\n\n try {\n await submitAndOpenResultModal();\n } catch (err) {\n console.error('handleFinishSimulated failed:', err);\n }\n };\n\n const handleAlertSubmit = async () => {\n try {\n await submitAndOpenResultModal();\n } catch (err) {\n console.error('handleFinishSimulated failed:', err);\n closeModal();\n }\n };\n\n return (\n <>\n <footer\n ref={ref}\n className={cn(\n 'w-full px-2 bg-background lg:max-w-[1000px] not-lg:max-w-[calc(100vw-32px)] border-t border-border-50 fixed bottom-0 min-h-[80px] flex flex-row justify-between items-center',\n className\n )}\n {...props}\n >\n {variant === 'default' ? (\n <>\n <div className=\"flex flex-row items-center gap-1\">\n <IconButton\n icon={<SquaresFourIcon size={24} className=\"text-text-950\" />}\n size=\"md\"\n onClick={() => openModal('modalNavigate')}\n />\n\n {isFirstQuestion ? (\n <Button\n variant=\"outline\"\n size=\"small\"\n onClick={() => {\n skipQuestion();\n goToNextQuestion();\n }}\n >\n Pular\n </Button>\n ) : (\n <Button\n size=\"medium\"\n variant=\"link\"\n action=\"primary\"\n iconLeft={<CaretLeftIcon size={18} />}\n onClick={() => {\n goToPreviousQuestion();\n }}\n >\n Voltar\n </Button>\n )}\n </div>\n\n {!isFirstQuestion && !isLastQuestion && (\n <Button\n size=\"small\"\n variant=\"outline\"\n action=\"primary\"\n onClick={() => {\n skipQuestion();\n goToNextQuestion();\n }}\n >\n Pular\n </Button>\n )}\n\n {isLastQuestion ? (\n <Button\n size=\"medium\"\n variant=\"solid\"\n action=\"primary\"\n onClick={handleFinishQuiz}\n >\n Finalizar\n </Button>\n ) : (\n <Button\n size=\"medium\"\n variant=\"link\"\n action=\"primary\"\n iconRight={<CaretRightIcon size={18} />}\n disabled={!currentAnswer && !isCurrentQuestionSkipped}\n onClick={() => {\n goToNextQuestion();\n }}\n >\n Avançar\n </Button>\n )}\n </>\n ) : (\n <div\n className={cn(\n 'flex w-full items-center gap-2',\n isMobile ? 'flex-col py-2' : 'flex-row'\n )}\n >\n <QuizReviewActions\n className={cn(\n 'flex flex-row items-center gap-2',\n isMobile && 'justify-center'\n )}\n onOpenResolution={() => openModal('modalResolution')}\n onOpenComment={() => openModal('modalTeacherComment')}\n />\n {/* On a wide bar the pagination sits at the far end, away from the\n actions that act on the question being read; stacked, it is\n centred under them. */}\n <div\n className={cn(\n 'flex flex-row items-center gap-2',\n isMobile ? 'justify-center' : 'flex-1 justify-end'\n )}\n >\n <Button\n variant=\"outline\"\n action=\"primary\"\n size=\"medium\"\n aria-label=\"Questão anterior\"\n disabled={isFirstQuestion}\n onClick={goToPreviousQuestion}\n >\n <CaretLeftIcon size={18} />\n </Button>\n <Button\n variant=\"outline\"\n action=\"primary\"\n size=\"medium\"\n aria-label=\"Próxima questão\"\n disabled={isLastQuestion}\n onClick={goToNextQuestion}\n >\n <CaretRightIcon size={18} />\n </Button>\n </div>\n </div>\n )}\n </footer>\n\n <AlertDialog\n isOpen={isModalOpen('alertDialog')}\n onChangeOpen={(open) =>\n open ? openModal('alertDialog') : closeModal()\n }\n title={`Finalizar ${quizTypeLabel.toLowerCase()}?`}\n description={\n unansweredQuestions.length > 0\n ? `Você deixou as questões ${unansweredQuestions.join(', ')} sem resposta. Finalizar agora pode impactar seu desempenho.`\n : getFinishConfirmationText(quizType)\n }\n cancelButtonLabel=\"Voltar e revisar\"\n submitButtonLabel=\"Finalizar Mesmo Assim\"\n onSubmit={handleAlertSubmit}\n />\n\n <QuizResultModal\n isOpen={isModalOpen('modalResult')}\n onClose={closeModal}\n image={resultImageComponent}\n title={getCompletionTitle(quizType)}\n description={\n <Text as=\"p\" size=\"sm\" color=\"text-text-500\">\n Você acertou {correctAnswers ?? '--'} de {allQuestions} questões.\n </Text>\n }\n footer={\n <div className=\"px-6 flex flex-row items-center gap-2 w-full\">\n <Button\n variant=\"outline\"\n className=\"w-full\"\n size=\"small\"\n onClick={onGoToSimulated}\n >\n {getGoBackButtonLabel(quizType)}\n </Button>\n\n <Button className=\"w-full\" onClick={onDetailResult}>\n Detalhar resultado\n </Button>\n </div>\n }\n />\n\n {completionOverride && (\n <QuizResultModal\n isOpen={isModalOpen('modalCompletionOverride')}\n onClose={closeModal}\n image={resultImageComponent}\n title={completionOverride.title}\n description={\n <Text as=\"p\" size=\"sm\" color=\"text-text-500\">\n {completionOverride.description}\n </Text>\n }\n footer={\n <div className=\"px-6 flex flex-row items-center w-full\">\n <Button\n className=\"w-full\"\n onClick={completionOverride.onConfirm}\n data-testid=\"quiz-completion-override-confirm\"\n >\n {completionOverride.buttonLabel}\n </Button>\n </div>\n }\n />\n )}\n\n <Modal\n isOpen={isModalOpen('modalNavigate')}\n onClose={closeModal}\n title=\"Questões\"\n size={'lg'}\n >\n <div className=\"flex flex-col w-full not-lg:h-[calc(100vh-200px)] lg:max-h-[687px] lg:h-[687px]\">\n <div className=\"flex flex-row justify-between items-center py-6 pt-6 pb-4 border-b border-border-200 flex-shrink-0\">\n <p className=\"text-text-950 font-bold text-lg\">Filtrar por</p>\n <span className=\"max-w-[266px]\">\n <Select value={filterType} onValueChange={setFilterType}>\n <SelectTrigger\n variant=\"rounded\"\n className=\"max-w-[266px] min-w-[160px]\"\n >\n <SelectValue placeholder=\"Selecione uma opção\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">Todas</SelectItem>\n <SelectItem value=\"unanswered\">Em branco</SelectItem>\n <SelectItem value=\"answered\">Respondidas</SelectItem>\n </SelectContent>\n </Select>\n </span>\n </div>\n\n <div className=\"flex flex-col gap-2 flex-1 min-h-0 overflow-y-auto\">\n <QuizQuestionList\n filterType={filterType}\n onQuestionClick={closeModal}\n />\n </div>\n </div>\n </Modal>\n\n <Modal\n isOpen={isModalOpen('modalResolution')}\n onClose={closeModal}\n title=\"Resolução\"\n size={'lg'}\n >\n <HtmlMathRenderer\n content={currentQuestion?.solutionExplanation || ''}\n className=\"text-text-950 text-base\"\n />\n </Modal>\n\n <Modal\n isOpen={isModalOpen('modalTeacherComment')}\n onClose={closeModal}\n title={getCorrectionModalTitle(correctionSource)}\n size={'lg'}\n >\n {/* A tag fica dentro do modal, junto do texto: é ela que diz se o que\n está sendo lido saiu da IA, do professor, ou da IA revisada por\n ele. Sem isso o título sozinho teria que carregar essa informação\n em toda variação. */}\n <CorrectionSourceTag\n correctionSource={correctionSource}\n aiCorrectionStatus={aiCorrectionStatus}\n className=\"mb-3\"\n />\n {/* Plain text on purpose: the teacher writes this in a bare textarea,\n so running it through the HTML/LaTeX renderer would change what\n they typed. `whitespace-pre-wrap` keeps their line breaks. The AI\n feedback is plain text for the same reason. */}\n <Text\n size=\"md\"\n className=\"text-text-950 whitespace-pre-wrap break-words\"\n >\n {teacherComment}\n </Text>\n </Modal>\n\n <QuizResultModal\n isOpen={isModalOpen('modalQuestionnaireAllCorrect')}\n onClose={closeModal}\n image={resultImageComponent}\n title=\"🎉 Parabéns!\"\n description={\n <Text as=\"p\" size=\"sm\" color=\"text-text-500\">\n {moduleName\n ? `Você concluiu o módulo ${moduleName}.`\n : 'Você concluiu o questionário!'}\n </Text>\n }\n footer={\n <div className=\"px-6 flex flex-row items-center gap-2 w-full\">\n <Button className=\"w-full\" onClick={onGoToNextModule}>\n {getGoBackButtonLabel(quizType)}\n </Button>\n </div>\n }\n />\n\n <QuizResultModal\n isOpen={isModalOpen('modalQuestionnaireAllIncorrect')}\n onClose={closeModal}\n image={resultIncorrectImageComponent}\n showImagePlaceholder={false}\n title=\"😕 Não foi dessa vez...\"\n description={\n <>\n <Text as=\"p\" size=\"sm\" color=\"text-text-500\">\n Você tirou 0 no questionário, mas não se preocupe! Isso é apenas\n uma oportunidade de aprendizado.\n </Text>\n\n <Text as=\"p\" size=\"sm\" color=\"text-text-500\">\n Que tal tentar novamente para melhorar sua nota? Estamos aqui\n para te ajudar a entender o conteúdo e evoluir.\n </Text>\n\n {quiz?.canRetry && (\n <Text as=\"p\" size=\"sm\" color=\"text-text-500\">\n Clique em Repetir Questionário e mostre do que você é capaz!\n 💪\n </Text>\n )}\n </>\n }\n footer={\n <div className=\"flex flex-row justify-center items-center gap-2 w-full\">\n {quiz?.canRetry && (\n <Button\n type=\"button\"\n variant=\"link\"\n size=\"small\"\n className=\"w-auto\"\n onClick={() => {\n closeModal();\n openModal('alertDialogTryLater');\n }}\n >\n Tentar depois\n </Button>\n )}\n\n <Button\n variant=\"outline\"\n size=\"small\"\n className=\"w-auto\"\n onClick={onDetailResult}\n >\n Detalhar resultado\n </Button>\n\n {quiz?.canRetry ? (\n <Button className=\"w-auto\" size=\"small\" onClick={onRepeat}>\n Repetir questionário\n </Button>\n ) : (\n <Button\n className=\"w-auto\"\n size=\"small\"\n onClick={onGoToSimulated}\n >\n {getGoBackButtonLabel(quizType)}\n </Button>\n )}\n </div>\n }\n />\n\n <AlertDialog\n isOpen={isModalOpen('alertDialogTryLater')}\n onChangeOpen={(open) =>\n open ? openModal('alertDialogTryLater') : closeModal()\n }\n title=\"Tentar depois?\"\n description={\n 'Você optou por refazer o questionário mais tarde.\\n\\nLembre-se: enquanto não refazer o questionário, sua nota permanecerá 0 no sistema.'\n }\n cancelButtonLabel=\"Repetir questionário\"\n submitButtonLabel=\"Tentar depois\"\n onSubmit={() => {\n onTryLater?.();\n closeModal();\n }}\n onCancel={() => {\n onRepeat?.();\n closeModal();\n }}\n />\n </>\n );\n }\n);\n\nexport {\n QuizTitle,\n Quiz,\n QuizHeader,\n QuizContent,\n QuizFooter,\n QuizQuestionList,\n};\n"],"mappings":"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","names":[]}
@@ -1,21 +0,0 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/types/enemClassroom.ts
2
- var ENEM_CLASSROOM_LANGUAGE = {
3
- INGLES: "INGLES",
4
- ESPANHOL: "ESPANHOL"
5
- };
6
- var ENEM_CLASSROOM_LANGUAGE_LABELS = {
7
- INGLES: "Ingl\xEAs",
8
- ESPANHOL: "Espanhol"
9
- };
10
- var ENEM_CLASSROOM_PARTICIPATION_STATUS = {
11
- NOT_STARTED: "NOT_STARTED",
12
- IN_PROGRESS: "IN_PROGRESS",
13
- FINISHED: "FINISHED"
14
- };
15
-
16
-
17
-
18
-
19
-
20
- exports.ENEM_CLASSROOM_LANGUAGE = ENEM_CLASSROOM_LANGUAGE; exports.ENEM_CLASSROOM_LANGUAGE_LABELS = ENEM_CLASSROOM_LANGUAGE_LABELS; exports.ENEM_CLASSROOM_PARTICIPATION_STATUS = ENEM_CLASSROOM_PARTICIPATION_STATUS;
21
- //# sourceMappingURL=chunk-NYKBCQUO.js.map