analytica-frontend-lib 1.6.76 → 1.6.78

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 (473) hide show
  1. package/dist/AccessReportModal/index.js +4 -5
  2. package/dist/AccessReportModal/index.js.map +1 -1
  3. package/dist/AccessReportModal/index.mjs +3 -4
  4. package/dist/AccessibilityWidget/index.js +4 -5
  5. package/dist/AccessibilityWidget/index.js.map +1 -1
  6. package/dist/AccessibilityWidget/index.mjs +3 -4
  7. package/dist/Accordation/index.js +4 -4
  8. package/dist/Accordation/index.mjs +3 -3
  9. package/dist/ActivitiesHistory/index.js +48 -49
  10. package/dist/ActivitiesHistory/index.js.map +1 -1
  11. package/dist/ActivitiesHistory/index.mjs +47 -48
  12. package/dist/ActivityCardQuestionBanks/index.d.ts.map +1 -1
  13. package/dist/ActivityCardQuestionBanks/index.js +48 -49
  14. package/dist/ActivityCardQuestionBanks/index.js.map +1 -1
  15. package/dist/ActivityCardQuestionBanks/index.mjs +47 -48
  16. package/dist/ActivityCardQuestionPreview/index.js +48 -49
  17. package/dist/ActivityCardQuestionPreview/index.js.map +1 -1
  18. package/dist/ActivityCardQuestionPreview/index.mjs +47 -48
  19. package/dist/ActivityCreate/ActivityCreateContent/index.js +48 -49
  20. package/dist/ActivityCreate/ActivityCreateContent/index.js.map +1 -1
  21. package/dist/ActivityCreate/ActivityCreateContent/index.mjs +47 -48
  22. package/dist/ActivityCreate/index.js +48 -49
  23. package/dist/ActivityCreate/index.js.map +1 -1
  24. package/dist/ActivityCreate/index.mjs +47 -48
  25. package/dist/ActivityDetails/index.js +48 -49
  26. package/dist/ActivityDetails/index.js.map +1 -1
  27. package/dist/ActivityDetails/index.mjs +47 -48
  28. package/dist/ActivityFilters/index.js +48 -49
  29. package/dist/ActivityFilters/index.js.map +1 -1
  30. package/dist/ActivityFilters/index.mjs +47 -48
  31. package/dist/ActivityPageLayout/index.js +48 -49
  32. package/dist/ActivityPageLayout/index.js.map +1 -1
  33. package/dist/ActivityPageLayout/index.mjs +47 -48
  34. package/dist/ActivityPreview/index.js +48 -49
  35. package/dist/ActivityPreview/index.js.map +1 -1
  36. package/dist/ActivityPreview/index.mjs +47 -48
  37. package/dist/AlertDialog/index.d.ts.map +1 -1
  38. package/dist/AlertDialog/index.js +3 -3
  39. package/dist/AlertDialog/index.mjs +2 -2
  40. package/dist/AlertManager/index.js +48 -49
  41. package/dist/AlertManager/index.js.map +1 -1
  42. package/dist/AlertManager/index.mjs +47 -48
  43. package/dist/AlertManagerView/index.js +4 -5
  44. package/dist/AlertManagerView/index.js.map +1 -1
  45. package/dist/AlertManagerView/index.mjs +3 -4
  46. package/dist/AnnouncementModal/index.js +4 -5
  47. package/dist/AnnouncementModal/index.js.map +1 -1
  48. package/dist/AnnouncementModal/index.mjs +3 -4
  49. package/dist/AnnouncementsGate/index.js +5 -6
  50. package/dist/AnnouncementsGate/index.js.map +1 -1
  51. package/dist/AnnouncementsGate/index.mjs +4 -5
  52. package/dist/AnswerKeyModal/index.js +4 -5
  53. package/dist/AnswerKeyModal/index.js.map +1 -1
  54. package/dist/AnswerKeyModal/index.mjs +3 -4
  55. package/dist/AppHeader/index.js +8 -9
  56. package/dist/AppHeader/index.js.map +1 -1
  57. package/dist/AppHeader/index.mjs +7 -8
  58. package/dist/CalendarCard/index.js +6 -7
  59. package/dist/CalendarCard/index.js.map +1 -1
  60. package/dist/CalendarCard/index.mjs +5 -6
  61. package/dist/Card/index.d.ts.map +1 -1
  62. package/dist/Card/index.js +3 -3
  63. package/dist/Card/index.mjs +2 -2
  64. package/dist/Chat/index.js +4 -5
  65. package/dist/Chat/index.js.map +1 -1
  66. package/dist/Chat/index.mjs +3 -4
  67. package/dist/Chatbot/index.js +4 -5
  68. package/dist/Chatbot/index.js.map +1 -1
  69. package/dist/Chatbot/index.mjs +3 -4
  70. package/dist/CheckBoxGroup/index.js +48 -49
  71. package/dist/CheckBoxGroup/index.js.map +1 -1
  72. package/dist/CheckBoxGroup/index.mjs +47 -48
  73. package/dist/ComparatorChart/ComparatorView/index.js +4 -5
  74. package/dist/ComparatorChart/ComparatorView/index.js.map +1 -1
  75. package/dist/ComparatorChart/ComparatorView/index.mjs +3 -4
  76. package/dist/CorrectActivityModal/index.js +9 -10
  77. package/dist/CorrectActivityModal/index.js.map +1 -1
  78. package/dist/CorrectActivityModal/index.mjs +8 -9
  79. package/dist/DownloadButton/index.js +6 -7
  80. package/dist/DownloadButton/index.js.map +1 -1
  81. package/dist/DownloadButton/index.mjs +5 -6
  82. package/dist/DownloadModal/index.js +4 -5
  83. package/dist/DownloadModal/index.js.map +1 -1
  84. package/dist/DownloadModal/index.mjs +3 -4
  85. package/dist/DropdownMenu/index.js +4 -5
  86. package/dist/DropdownMenu/index.js.map +1 -1
  87. package/dist/DropdownMenu/index.mjs +3 -4
  88. package/dist/EnemClassroomStartModal/index.js +8 -9
  89. package/dist/EnemClassroomStartModal/index.js.map +1 -1
  90. package/dist/EnemClassroomStartModal/index.mjs +7 -8
  91. package/dist/EnemMoment/index.js +110 -94
  92. package/dist/EnemMoment/index.js.map +1 -1
  93. package/dist/EnemMoment/index.mjs +74 -58
  94. package/dist/EnemMoment/index.mjs.map +1 -1
  95. package/dist/EnemMomentStudentModal/index.js +62 -63
  96. package/dist/EnemMomentStudentModal/index.js.map +1 -1
  97. package/dist/EnemMomentStudentModal/index.mjs +48 -49
  98. package/dist/EnemMomentStudentModal/index.mjs.map +1 -1
  99. package/dist/EssayThemePicker/index.js +3 -3
  100. package/dist/EssayThemePicker/index.mjs +2 -2
  101. package/dist/ExamDetailsLayout/ExamDetailsPage/index.js +48 -49
  102. package/dist/ExamDetailsLayout/ExamDetailsPage/index.js.map +1 -1
  103. package/dist/ExamDetailsLayout/ExamDetailsPage/index.mjs +47 -48
  104. package/dist/ExamPageLayout/index.js +48 -49
  105. package/dist/ExamPageLayout/index.js.map +1 -1
  106. package/dist/ExamPageLayout/index.mjs +47 -48
  107. package/dist/Forum/index.js +6 -7
  108. package/dist/Forum/index.js.map +1 -1
  109. package/dist/Forum/index.mjs +5 -6
  110. package/dist/IconButton/index.js +2 -2
  111. package/dist/IconButton/index.mjs +1 -1
  112. package/dist/LessonCardPreview/index.js +48 -49
  113. package/dist/LessonCardPreview/index.js.map +1 -1
  114. package/dist/LessonCardPreview/index.mjs +47 -48
  115. package/dist/LessonMediaSections/index.js +48 -49
  116. package/dist/LessonMediaSections/index.js.map +1 -1
  117. package/dist/LessonMediaSections/index.mjs +47 -48
  118. package/dist/LessonsCatalog/index.js +48 -49
  119. package/dist/LessonsCatalog/index.js.map +1 -1
  120. package/dist/LessonsCatalog/index.mjs +47 -48
  121. package/dist/Modal/index.d.ts +11 -1
  122. package/dist/Modal/index.d.ts.map +1 -1
  123. package/dist/Modal/index.js +3 -4
  124. package/dist/Modal/index.js.map +1 -1
  125. package/dist/Modal/index.mjs +2 -3
  126. package/dist/MultiCheckSelect/index.js +5 -6
  127. package/dist/MultiCheckSelect/index.js.map +1 -1
  128. package/dist/MultiCheckSelect/index.mjs +4 -5
  129. package/dist/NotificationCard/index.js +6 -7
  130. package/dist/NotificationCard/index.js.map +1 -1
  131. package/dist/NotificationCard/index.mjs +5 -6
  132. package/dist/PerformanceReportModal/index.js +4 -5
  133. package/dist/PerformanceReportModal/index.js.map +1 -1
  134. package/dist/PerformanceReportModal/index.mjs +3 -4
  135. package/dist/PrintableUsersTable/index.js +48 -49
  136. package/dist/PrintableUsersTable/index.js.map +1 -1
  137. package/dist/PrintableUsersTable/index.mjs +47 -48
  138. package/dist/ProgressModal/index.js +4 -5
  139. package/dist/ProgressModal/index.js.map +1 -1
  140. package/dist/ProgressModal/index.mjs +3 -4
  141. package/dist/QuestionsPerformanceCard/index.js +49 -50
  142. package/dist/QuestionsPerformanceCard/index.js.map +1 -1
  143. package/dist/QuestionsPerformanceCard/index.mjs +48 -49
  144. package/dist/Quiz/QuizResult/index.js +4 -4
  145. package/dist/Quiz/QuizResult/index.mjs +3 -3
  146. package/dist/Quiz/index.d.ts.map +1 -1
  147. package/dist/Quiz/index.js +8 -9
  148. package/dist/Quiz/index.js.map +1 -1
  149. package/dist/Quiz/index.mjs +7 -8
  150. package/dist/QuizTimer/index.d.ts +12 -0
  151. package/dist/QuizTimer/index.d.ts.map +1 -1
  152. package/dist/QuizTimer/index.js +4 -2
  153. package/dist/QuizTimer/index.js.map +1 -1
  154. package/dist/QuizTimer/index.mjs +4 -2
  155. package/dist/RecommendedLessonCreate/index.js +48 -49
  156. package/dist/RecommendedLessonCreate/index.js.map +1 -1
  157. package/dist/RecommendedLessonCreate/index.mjs +47 -48
  158. package/dist/RecommendedLessonDetails/index.js +11 -12
  159. package/dist/RecommendedLessonDetails/index.js.map +1 -1
  160. package/dist/RecommendedLessonDetails/index.mjs +10 -11
  161. package/dist/RecommendedLessonsHistory/index.js +48 -49
  162. package/dist/RecommendedLessonsHistory/index.js.map +1 -1
  163. package/dist/RecommendedLessonsHistory/index.mjs +47 -48
  164. package/dist/ReportDetailModal/index.js +5 -6
  165. package/dist/ReportDetailModal/index.js.map +1 -1
  166. package/dist/ReportDetailModal/index.mjs +4 -5
  167. package/dist/RichEditor/index.js +6 -7
  168. package/dist/RichEditor/index.js.map +1 -1
  169. package/dist/RichEditor/index.mjs +5 -6
  170. package/dist/{RichEditorCore-62NIM7PC.js → RichEditorCore-6OT3VNJR.js} +15 -16
  171. package/dist/RichEditorCore-6OT3VNJR.js.map +1 -0
  172. package/dist/{RichEditorCore-CCO3SSSU.mjs → RichEditorCore-IF6JQHEO.mjs} +6 -7
  173. package/dist/{RichEditorCore-CCO3SSSU.mjs.map → RichEditorCore-IF6JQHEO.mjs.map} +1 -1
  174. package/dist/Search/index.js +5 -6
  175. package/dist/Search/index.js.map +1 -1
  176. package/dist/Search/index.mjs +4 -5
  177. package/dist/SendActivityModal/SendActivityModal.js +48 -49
  178. package/dist/SendActivityModal/SendActivityModal.js.map +1 -1
  179. package/dist/SendActivityModal/SendActivityModal.mjs +47 -48
  180. package/dist/SendActivityModal/index.js +48 -49
  181. package/dist/SendActivityModal/index.js.map +1 -1
  182. package/dist/SendActivityModal/index.mjs +47 -48
  183. package/dist/SendLessonModal/index.js +48 -49
  184. package/dist/SendLessonModal/index.js.map +1 -1
  185. package/dist/SendLessonModal/index.mjs +47 -48
  186. package/dist/SimulatedPerformance/SimulatedPerformanceView/index.js +48 -49
  187. package/dist/SimulatedPerformance/SimulatedPerformanceView/index.js.map +1 -1
  188. package/dist/SimulatedPerformance/SimulatedPerformanceView/index.mjs +47 -48
  189. package/dist/SimulatedPerformance/useSimulatedPerformance/index.js +6 -7
  190. package/dist/SimulatedPerformance/useSimulatedPerformance/index.js.map +1 -1
  191. package/dist/SimulatedPerformance/useSimulatedPerformance/index.mjs +5 -6
  192. package/dist/SimulatedStudentSimulationsModal/index.js +8 -9
  193. package/dist/SimulatedStudentSimulationsModal/index.js.map +1 -1
  194. package/dist/SimulatedStudentSimulationsModal/index.mjs +7 -8
  195. package/dist/SimulationSummaryCards/index.js +5 -5
  196. package/dist/SimulationSummaryCards/index.mjs +4 -4
  197. package/dist/SimulationsPage/index.js +48 -49
  198. package/dist/SimulationsPage/index.js.map +1 -1
  199. package/dist/SimulationsPage/index.mjs +47 -48
  200. package/dist/StudentLessonProgressModal/index.js +6 -7
  201. package/dist/StudentLessonProgressModal/index.js.map +1 -1
  202. package/dist/StudentLessonProgressModal/index.mjs +5 -6
  203. package/dist/StudentPerformanceDetailsModal/index.js +9 -10
  204. package/dist/StudentPerformanceDetailsModal/index.js.map +1 -1
  205. package/dist/StudentPerformanceDetailsModal/index.mjs +8 -9
  206. package/dist/Support/TicketModal/index.js +4 -5
  207. package/dist/Support/TicketModal/index.js.map +1 -1
  208. package/dist/Support/TicketModal/index.mjs +3 -4
  209. package/dist/Support/index.js +5 -6
  210. package/dist/Support/index.js.map +1 -1
  211. package/dist/Support/index.mjs +4 -5
  212. package/dist/TableProvider/index.js +48 -49
  213. package/dist/TableProvider/index.js.map +1 -1
  214. package/dist/TableProvider/index.mjs +47 -48
  215. package/dist/UnifiedDraftModelPage/index.js +48 -49
  216. package/dist/UnifiedDraftModelPage/index.js.map +1 -1
  217. package/dist/UnifiedDraftModelPage/index.mjs +47 -48
  218. package/dist/UnifiedHistoryPage/index.js +48 -49
  219. package/dist/UnifiedHistoryPage/index.js.map +1 -1
  220. package/dist/UnifiedHistoryPage/index.mjs +47 -48
  221. package/dist/VideoPlayer/index.js +7 -8
  222. package/dist/VideoPlayer/index.js.map +1 -1
  223. package/dist/VideoPlayer/index.mjs +6 -7
  224. package/dist/Whiteboard/index.js +4 -5
  225. package/dist/Whiteboard/index.js.map +1 -1
  226. package/dist/Whiteboard/index.mjs +3 -4
  227. package/dist/{chunk-EVBQNVQW.mjs → chunk-233FSBU7.mjs} +5 -5
  228. package/dist/{chunk-JU63EMZM.js → chunk-24DQFREC.js} +3 -3
  229. package/dist/{chunk-JU63EMZM.js.map → chunk-24DQFREC.js.map} +1 -1
  230. package/dist/{chunk-QFXSQKW3.mjs → chunk-254EBPMW.mjs} +22 -22
  231. package/dist/{chunk-QFXSQKW3.mjs.map → chunk-254EBPMW.mjs.map} +1 -1
  232. package/dist/{chunk-SFQVZ4KQ.js → chunk-2ETPIOCD.js} +3 -3
  233. package/dist/{chunk-SFQVZ4KQ.js.map → chunk-2ETPIOCD.js.map} +1 -1
  234. package/dist/{chunk-RCNIBRZY.js → chunk-2VTJ2PKF.js} +10 -10
  235. package/dist/{chunk-RCNIBRZY.js.map → chunk-2VTJ2PKF.js.map} +1 -1
  236. package/dist/{chunk-B35D5S4G.js → chunk-2ZMGNCMI.js} +6 -6
  237. package/dist/{chunk-B35D5S4G.js.map → chunk-2ZMGNCMI.js.map} +1 -1
  238. package/dist/{chunk-QEPKR6ZF.js → chunk-3KSRDIS2.js} +20 -20
  239. package/dist/{chunk-QEPKR6ZF.js.map → chunk-3KSRDIS2.js.map} +1 -1
  240. package/dist/{chunk-MUCV5ZWZ.mjs → chunk-3YF7H577.mjs} +15 -9
  241. package/dist/chunk-3YF7H577.mjs.map +1 -0
  242. package/dist/{chunk-MADPP2PW.mjs → chunk-3ZSI2KI5.mjs} +2 -2
  243. package/dist/{chunk-2W7PTFXS.mjs → chunk-42XKJV56.mjs} +2 -2
  244. package/dist/{chunk-M6TC6XRQ.mjs → chunk-55ESXRRM.mjs} +2 -2
  245. package/dist/{chunk-4MURAKPC.mjs → chunk-5DJVOLVX.mjs} +3 -3
  246. package/dist/{chunk-YVT7CT3G.mjs → chunk-5P6CBDZ6.mjs} +2 -2
  247. package/dist/{chunk-BHKTJCFD.js → chunk-5QUP5HKB.js} +3 -3
  248. package/dist/{chunk-BHKTJCFD.js.map → chunk-5QUP5HKB.js.map} +1 -1
  249. package/dist/{chunk-SFEU7BMY.mjs → chunk-5SFNRXZB.mjs} +2 -2
  250. package/dist/{chunk-6ALEXGAN.js → chunk-6U4AI5SE.js} +6 -6
  251. package/dist/{chunk-6ALEXGAN.js.map → chunk-6U4AI5SE.js.map} +1 -1
  252. package/dist/{chunk-KYY4U5SN.mjs → chunk-6Z5W5J44.mjs} +3 -3
  253. package/dist/{chunk-XOKBMLW3.js → chunk-7IGUYLSF.js} +3 -3
  254. package/dist/{chunk-XOKBMLW3.js.map → chunk-7IGUYLSF.js.map} +1 -1
  255. package/dist/{chunk-GVYGPJH3.mjs → chunk-AU5M2766.mjs} +2 -2
  256. package/dist/{chunk-2VODGC76.js → chunk-AVEMHDN2.js} +66 -44
  257. package/dist/chunk-AVEMHDN2.js.map +1 -0
  258. package/dist/{chunk-HIIOADV4.js → chunk-AZSRKBYS.js} +63 -71
  259. package/dist/chunk-AZSRKBYS.js.map +1 -0
  260. package/dist/{chunk-CY2VKNCB.js → chunk-BQIBVC6X.js} +5 -5
  261. package/dist/{chunk-CY2VKNCB.js.map → chunk-BQIBVC6X.js.map} +1 -1
  262. package/dist/{chunk-M77TQ5JJ.mjs → chunk-BU32E6BR.mjs} +4 -6
  263. package/dist/{chunk-M77TQ5JJ.mjs.map → chunk-BU32E6BR.mjs.map} +1 -1
  264. package/dist/{chunk-5CQVDUDO.js → chunk-BUNF5POU.js} +5 -5
  265. package/dist/{chunk-5CQVDUDO.js.map → chunk-BUNF5POU.js.map} +1 -1
  266. package/dist/{chunk-Z6UN4ZPW.mjs → chunk-BVHVYC7Q.mjs} +4 -4
  267. package/dist/{chunk-WJENEFDG.js → chunk-CAFVLHDV.js} +3 -3
  268. package/dist/{chunk-WJENEFDG.js.map → chunk-CAFVLHDV.js.map} +1 -1
  269. package/dist/{chunk-BVUPM6EY.js → chunk-CAQ2Q3ON.js} +2 -2
  270. package/dist/chunk-CAQ2Q3ON.js.map +1 -0
  271. package/dist/{chunk-QMPOGLAR.js → chunk-CIASXVWX.js} +3 -3
  272. package/dist/{chunk-QMPOGLAR.js.map → chunk-CIASXVWX.js.map} +1 -1
  273. package/dist/{chunk-APKEYUJ3.js → chunk-CIQLC2ZZ.js} +3 -3
  274. package/dist/{chunk-APKEYUJ3.js.map → chunk-CIQLC2ZZ.js.map} +1 -1
  275. package/dist/{chunk-36XPNLGQ.js → chunk-CW3FCWR4.js} +16 -16
  276. package/dist/{chunk-36XPNLGQ.js.map → chunk-CW3FCWR4.js.map} +1 -1
  277. package/dist/{chunk-J5VEAJN5.mjs → chunk-CWVUGZNK.mjs} +2 -2
  278. package/dist/{chunk-BCMDP6GK.mjs → chunk-DV3N2K3Y.mjs} +4 -4
  279. package/dist/{chunk-PP7SEERV.mjs → chunk-DXYSEBK3.mjs} +9 -3
  280. package/dist/chunk-DXYSEBK3.mjs.map +1 -0
  281. package/dist/{chunk-754M6HQ5.js → chunk-EJN4OP3D.js} +5 -5
  282. package/dist/{chunk-754M6HQ5.js.map → chunk-EJN4OP3D.js.map} +1 -1
  283. package/dist/{chunk-3IM2SBPO.js → chunk-F5K3HMKT.js} +4 -4
  284. package/dist/{chunk-3IM2SBPO.js.map → chunk-F5K3HMKT.js.map} +1 -1
  285. package/dist/{chunk-WMDSGVZ7.mjs → chunk-GCGSAS2Z.mjs} +48 -63
  286. package/dist/chunk-GCGSAS2Z.mjs.map +1 -0
  287. package/dist/{chunk-EXHGEJ4P.mjs → chunk-GKARHTZ2.mjs} +2 -2
  288. package/dist/{chunk-2VDCEEXB.js → chunk-GNKFBVW4.js} +3 -3
  289. package/dist/{chunk-2VDCEEXB.js.map → chunk-GNKFBVW4.js.map} +1 -1
  290. package/dist/{chunk-CDLOMECB.js → chunk-GTBPMNTJ.js} +3 -3
  291. package/dist/{chunk-CDLOMECB.js.map → chunk-GTBPMNTJ.js.map} +1 -1
  292. package/dist/{chunk-YQKAASWM.js → chunk-GXXDSBN2.js} +10 -4
  293. package/dist/chunk-GXXDSBN2.js.map +1 -0
  294. package/dist/{chunk-FASVPU6N.js → chunk-H3F4OCXC.js} +10 -10
  295. package/dist/{chunk-FASVPU6N.js.map → chunk-H3F4OCXC.js.map} +1 -1
  296. package/dist/{chunk-JCFN6KRS.mjs → chunk-HGWDB73S.mjs} +2 -2
  297. package/dist/{chunk-JXXMO7PY.mjs → chunk-HN5RW4C3.mjs} +3 -3
  298. package/dist/{chunk-I2A4EQPH.mjs → chunk-HQ2GXFK5.mjs} +6 -6
  299. package/dist/{chunk-BIPC6F6D.js → chunk-IDJ37MOU.js} +115 -115
  300. package/dist/{chunk-BIPC6F6D.js.map → chunk-IDJ37MOU.js.map} +1 -1
  301. package/dist/{chunk-TBJLNIOY.mjs → chunk-JBLYYTHN.mjs} +2 -2
  302. package/dist/{chunk-G4NK66PM.js → chunk-JTWXQ267.js} +24 -18
  303. package/dist/chunk-JTWXQ267.js.map +1 -0
  304. package/dist/{chunk-V6IC74KH.js → chunk-JXGLDRDC.js} +34 -34
  305. package/dist/{chunk-V6IC74KH.js.map → chunk-JXGLDRDC.js.map} +1 -1
  306. package/dist/{chunk-DDFIRQI5.mjs → chunk-K3E5VEBF.mjs} +56 -34
  307. package/dist/chunk-K3E5VEBF.mjs.map +1 -0
  308. package/dist/{chunk-MSBEWG26.js → chunk-K5O2IOI4.js} +8 -8
  309. package/dist/{chunk-MSBEWG26.js.map → chunk-K5O2IOI4.js.map} +1 -1
  310. package/dist/{chunk-SB5YGKXR.js → chunk-KBMLGQ5J.js} +49 -64
  311. package/dist/chunk-KBMLGQ5J.js.map +1 -0
  312. package/dist/chunk-KCZEKV7M.mjs +81 -0
  313. package/dist/chunk-KCZEKV7M.mjs.map +1 -0
  314. package/dist/{chunk-GRSN76BV.mjs → chunk-KH2R4STU.mjs} +3 -3
  315. package/dist/{chunk-7DQM34JT.js → chunk-KHYSXYPO.js} +23 -23
  316. package/dist/{chunk-7DQM34JT.js.map → chunk-KHYSXYPO.js.map} +1 -1
  317. package/dist/{chunk-V2YHMPRR.js → chunk-KJHBQQYJ.js} +5 -5
  318. package/dist/{chunk-V2YHMPRR.js.map → chunk-KJHBQQYJ.js.map} +1 -1
  319. package/dist/{chunk-ZF5NMQJZ.mjs → chunk-KUKLN3CK.mjs} +4 -4
  320. package/dist/{chunk-6AYB7CZH.js → chunk-KZQVGSR2.js} +2 -2
  321. package/dist/{chunk-6AYB7CZH.js.map → chunk-KZQVGSR2.js.map} +1 -1
  322. package/dist/{chunk-UAKRBNW2.mjs → chunk-L4T76OKM.mjs} +2 -2
  323. package/dist/{chunk-AUCXJ7LG.js → chunk-M3LQH7Y7.js} +3 -3
  324. package/dist/{chunk-AUCXJ7LG.js.map → chunk-M3LQH7Y7.js.map} +1 -1
  325. package/dist/{chunk-FQNJJH7F.js → chunk-MCXRKD56.js} +13 -13
  326. package/dist/{chunk-FQNJJH7F.js.map → chunk-MCXRKD56.js.map} +1 -1
  327. package/dist/{chunk-PY5WCBKN.mjs → chunk-MERKXOSI.mjs} +4 -4
  328. package/dist/{chunk-D3YDZF2G.js → chunk-N472HQPZ.js} +3 -3
  329. package/dist/{chunk-D3YDZF2G.js.map → chunk-N472HQPZ.js.map} +1 -1
  330. package/dist/{chunk-UPMYCGXR.js → chunk-N4K4X34Z.js} +4 -4
  331. package/dist/{chunk-UPMYCGXR.js.map → chunk-N4K4X34Z.js.map} +1 -1
  332. package/dist/{chunk-RU43UMEH.js → chunk-NFCNAFUK.js} +3 -3
  333. package/dist/{chunk-RU43UMEH.js.map → chunk-NFCNAFUK.js.map} +1 -1
  334. package/dist/{chunk-APCB5HWT.mjs → chunk-NLSDZJRR.mjs} +3 -3
  335. package/dist/{chunk-EWYIXCNF.mjs → chunk-NLUTNCLH.mjs} +5 -5
  336. package/dist/{chunk-OP4Q2KDS.mjs → chunk-NMKKMY5P.mjs} +2 -2
  337. package/dist/{chunk-WDPFO4II.mjs → chunk-NMPK336K.mjs} +2 -2
  338. package/dist/{chunk-X6BZ5IEV.mjs → chunk-NU7O6YKR.mjs} +2 -2
  339. package/dist/{chunk-ZABDSRX3.js → chunk-NUZ5K3CB.js} +4 -4
  340. package/dist/{chunk-ZABDSRX3.js.map → chunk-NUZ5K3CB.js.map} +1 -1
  341. package/dist/{chunk-N5ZGFYLA.js → chunk-NZX3BA62.js} +3 -3
  342. package/dist/{chunk-N5ZGFYLA.js.map → chunk-NZX3BA62.js.map} +1 -1
  343. package/dist/{chunk-2TLSEAL2.js → chunk-O4TRDWXJ.js} +3 -3
  344. package/dist/{chunk-2TLSEAL2.js.map → chunk-O4TRDWXJ.js.map} +1 -1
  345. package/dist/{chunk-CBI5F4ME.mjs → chunk-OMSSA4NO.mjs} +2 -2
  346. package/dist/{chunk-YGEEWLGJ.js → chunk-PKKXCX5B.js} +3 -3
  347. package/dist/{chunk-YGEEWLGJ.js.map → chunk-PKKXCX5B.js.map} +1 -1
  348. package/dist/{chunk-GYHD6QEA.mjs → chunk-PQGQ3EH5.mjs} +2 -2
  349. package/dist/{chunk-3LN5GQAC.js → chunk-Q6UIUYNF.js} +6 -8
  350. package/dist/chunk-Q6UIUYNF.js.map +1 -0
  351. package/dist/chunk-QLWBGM7H.js +81 -0
  352. package/dist/chunk-QLWBGM7H.js.map +1 -0
  353. package/dist/{chunk-IF5GW6ID.js → chunk-QZ5DCDZ2.js} +6 -6
  354. package/dist/{chunk-IF5GW6ID.js.map → chunk-QZ5DCDZ2.js.map} +1 -1
  355. package/dist/{chunk-LSUCENYD.mjs → chunk-RBKGHUSR.mjs} +2 -2
  356. package/dist/{chunk-PIZTI5SJ.js → chunk-RMCZ7C2C.js} +3 -3
  357. package/dist/{chunk-PIZTI5SJ.js.map → chunk-RMCZ7C2C.js.map} +1 -1
  358. package/dist/{chunk-LGQNMQOT.mjs → chunk-ROS5XGTQ.mjs} +2 -2
  359. package/dist/chunk-ROS5XGTQ.mjs.map +1 -0
  360. package/dist/{chunk-TEUERRDG.mjs → chunk-RV45XVXE.mjs} +2 -2
  361. package/dist/{chunk-FW6ZI2MC.mjs → chunk-UAFSWXN5.mjs} +2 -2
  362. package/dist/{chunk-QUGKQYAJ.mjs → chunk-ULVFVLFE.mjs} +4 -6
  363. package/dist/{chunk-QUGKQYAJ.mjs.map → chunk-ULVFVLFE.mjs.map} +1 -1
  364. package/dist/{chunk-ANLL2EIX.mjs → chunk-UWCGTH3U.mjs} +2 -2
  365. package/dist/{chunk-6R2LEEEP.mjs → chunk-UZF2D2GG.mjs} +2 -2
  366. package/dist/{chunk-62L3PMYE.mjs → chunk-V3OVMHZD.mjs} +2 -2
  367. package/dist/{chunk-UDITT3N3.mjs → chunk-V6ELDZ2B.mjs} +2 -2
  368. package/dist/{chunk-G7NUCBD3.js → chunk-VDPV24JJ.js} +3 -3
  369. package/dist/{chunk-G7NUCBD3.js.map → chunk-VDPV24JJ.js.map} +1 -1
  370. package/dist/{chunk-IJQOTS5O.mjs → chunk-VJUS3GC4.mjs} +2 -2
  371. package/dist/{chunk-ZUPP7R2K.js → chunk-W7BBVDBI.js} +17 -3
  372. package/dist/chunk-W7BBVDBI.js.map +1 -0
  373. package/dist/{chunk-EHQDQ5RV.js → chunk-XARMPXRN.js} +10 -12
  374. package/dist/chunk-XARMPXRN.js.map +1 -0
  375. package/dist/{chunk-MQEAEU6G.mjs → chunk-XGMRYNER.mjs} +2 -2
  376. package/dist/{chunk-MMQMVVD6.mjs → chunk-XLTD5J74.mjs} +3 -3
  377. package/dist/{chunk-L3ST5GUJ.js → chunk-XQUK7R7L.js} +17 -17
  378. package/dist/{chunk-L3ST5GUJ.js.map → chunk-XQUK7R7L.js.map} +1 -1
  379. package/dist/{chunk-OMBUOOMD.mjs → chunk-XYT542WD.mjs} +2 -2
  380. package/dist/{chunk-IZNABVXE.js → chunk-Y4IGIWP4.js} +3 -3
  381. package/dist/{chunk-IZNABVXE.js.map → chunk-Y4IGIWP4.js.map} +1 -1
  382. package/dist/{chunk-COWOGT7U.mjs → chunk-YZWFDSTC.mjs} +2 -2
  383. package/dist/{chunk-M2FN7CNS.mjs → chunk-Z4L2DWMX.mjs} +17 -3
  384. package/dist/chunk-Z4L2DWMX.mjs.map +1 -0
  385. package/dist/chunk-Z75J66LL.mjs +149 -0
  386. package/dist/chunk-Z75J66LL.mjs.map +1 -0
  387. package/dist/{chunk-CWIJ7RXR.js → chunk-ZHUFICW3.js} +3 -3
  388. package/dist/{chunk-CWIJ7RXR.js.map → chunk-ZHUFICW3.js.map} +1 -1
  389. package/dist/{chunk-Q5XGBTOY.js → chunk-ZNITTMV5.js} +3 -3
  390. package/dist/{chunk-Q5XGBTOY.js.map → chunk-ZNITTMV5.js.map} +1 -1
  391. package/dist/components/EnemMoment/HeaderFilters.d.ts +12 -1
  392. package/dist/components/EnemMoment/HeaderFilters.d.ts.map +1 -1
  393. package/dist/components/EnemMoment/types.d.ts +10 -1
  394. package/dist/components/EnemMoment/types.d.ts.map +1 -1
  395. package/dist/hooks/useAppContent/index.js +48 -49
  396. package/dist/hooks/useAppContent/index.js.map +1 -1
  397. package/dist/hooks/useAppContent/index.mjs +47 -48
  398. package/dist/hooks/useResizableColumns.d.ts +20 -9
  399. package/dist/hooks/useResizableColumns.d.ts.map +1 -1
  400. package/dist/hooks/useScreen/index.js +2 -2
  401. package/dist/hooks/useScreen/index.mjs +1 -1
  402. package/dist/index.js +48 -49
  403. package/dist/index.js.map +1 -1
  404. package/dist/index.mjs +47 -48
  405. package/dist/store/layoutPreferencesStore.d.ts +12 -24
  406. package/dist/store/layoutPreferencesStore.d.ts.map +1 -1
  407. package/package.json +1 -1
  408. package/dist/RichEditorCore-62NIM7PC.js.map +0 -1
  409. package/dist/chunk-2EDRPEYL.mjs +0 -157
  410. package/dist/chunk-2EDRPEYL.mjs.map +0 -1
  411. package/dist/chunk-2VODGC76.js.map +0 -1
  412. package/dist/chunk-3LN5GQAC.js.map +0 -1
  413. package/dist/chunk-BVUPM6EY.js.map +0 -1
  414. package/dist/chunk-CH6BWMSQ.js +0 -17
  415. package/dist/chunk-CH6BWMSQ.js.map +0 -1
  416. package/dist/chunk-DDFIRQI5.mjs.map +0 -1
  417. package/dist/chunk-EHQDQ5RV.js.map +0 -1
  418. package/dist/chunk-G4NK66PM.js.map +0 -1
  419. package/dist/chunk-HIIOADV4.js.map +0 -1
  420. package/dist/chunk-JSH3BQZ7.mjs +0 -17
  421. package/dist/chunk-JSH3BQZ7.mjs.map +0 -1
  422. package/dist/chunk-LGQNMQOT.mjs.map +0 -1
  423. package/dist/chunk-LMDAF6LA.mjs +0 -51
  424. package/dist/chunk-LMDAF6LA.mjs.map +0 -1
  425. package/dist/chunk-M2FN7CNS.mjs.map +0 -1
  426. package/dist/chunk-MUCV5ZWZ.mjs.map +0 -1
  427. package/dist/chunk-PJOBOBNJ.js +0 -51
  428. package/dist/chunk-PJOBOBNJ.js.map +0 -1
  429. package/dist/chunk-PP7SEERV.mjs.map +0 -1
  430. package/dist/chunk-SB5YGKXR.js.map +0 -1
  431. package/dist/chunk-WMDSGVZ7.mjs.map +0 -1
  432. package/dist/chunk-YQKAASWM.js.map +0 -1
  433. package/dist/chunk-ZUPP7R2K.js.map +0 -1
  434. /package/dist/{chunk-EVBQNVQW.mjs.map → chunk-233FSBU7.mjs.map} +0 -0
  435. /package/dist/{chunk-MADPP2PW.mjs.map → chunk-3ZSI2KI5.mjs.map} +0 -0
  436. /package/dist/{chunk-2W7PTFXS.mjs.map → chunk-42XKJV56.mjs.map} +0 -0
  437. /package/dist/{chunk-M6TC6XRQ.mjs.map → chunk-55ESXRRM.mjs.map} +0 -0
  438. /package/dist/{chunk-4MURAKPC.mjs.map → chunk-5DJVOLVX.mjs.map} +0 -0
  439. /package/dist/{chunk-YVT7CT3G.mjs.map → chunk-5P6CBDZ6.mjs.map} +0 -0
  440. /package/dist/{chunk-SFEU7BMY.mjs.map → chunk-5SFNRXZB.mjs.map} +0 -0
  441. /package/dist/{chunk-KYY4U5SN.mjs.map → chunk-6Z5W5J44.mjs.map} +0 -0
  442. /package/dist/{chunk-GVYGPJH3.mjs.map → chunk-AU5M2766.mjs.map} +0 -0
  443. /package/dist/{chunk-Z6UN4ZPW.mjs.map → chunk-BVHVYC7Q.mjs.map} +0 -0
  444. /package/dist/{chunk-J5VEAJN5.mjs.map → chunk-CWVUGZNK.mjs.map} +0 -0
  445. /package/dist/{chunk-BCMDP6GK.mjs.map → chunk-DV3N2K3Y.mjs.map} +0 -0
  446. /package/dist/{chunk-EXHGEJ4P.mjs.map → chunk-GKARHTZ2.mjs.map} +0 -0
  447. /package/dist/{chunk-JCFN6KRS.mjs.map → chunk-HGWDB73S.mjs.map} +0 -0
  448. /package/dist/{chunk-JXXMO7PY.mjs.map → chunk-HN5RW4C3.mjs.map} +0 -0
  449. /package/dist/{chunk-I2A4EQPH.mjs.map → chunk-HQ2GXFK5.mjs.map} +0 -0
  450. /package/dist/{chunk-TBJLNIOY.mjs.map → chunk-JBLYYTHN.mjs.map} +0 -0
  451. /package/dist/{chunk-GRSN76BV.mjs.map → chunk-KH2R4STU.mjs.map} +0 -0
  452. /package/dist/{chunk-ZF5NMQJZ.mjs.map → chunk-KUKLN3CK.mjs.map} +0 -0
  453. /package/dist/{chunk-UAKRBNW2.mjs.map → chunk-L4T76OKM.mjs.map} +0 -0
  454. /package/dist/{chunk-PY5WCBKN.mjs.map → chunk-MERKXOSI.mjs.map} +0 -0
  455. /package/dist/{chunk-APCB5HWT.mjs.map → chunk-NLSDZJRR.mjs.map} +0 -0
  456. /package/dist/{chunk-EWYIXCNF.mjs.map → chunk-NLUTNCLH.mjs.map} +0 -0
  457. /package/dist/{chunk-OP4Q2KDS.mjs.map → chunk-NMKKMY5P.mjs.map} +0 -0
  458. /package/dist/{chunk-WDPFO4II.mjs.map → chunk-NMPK336K.mjs.map} +0 -0
  459. /package/dist/{chunk-X6BZ5IEV.mjs.map → chunk-NU7O6YKR.mjs.map} +0 -0
  460. /package/dist/{chunk-CBI5F4ME.mjs.map → chunk-OMSSA4NO.mjs.map} +0 -0
  461. /package/dist/{chunk-GYHD6QEA.mjs.map → chunk-PQGQ3EH5.mjs.map} +0 -0
  462. /package/dist/{chunk-LSUCENYD.mjs.map → chunk-RBKGHUSR.mjs.map} +0 -0
  463. /package/dist/{chunk-TEUERRDG.mjs.map → chunk-RV45XVXE.mjs.map} +0 -0
  464. /package/dist/{chunk-FW6ZI2MC.mjs.map → chunk-UAFSWXN5.mjs.map} +0 -0
  465. /package/dist/{chunk-ANLL2EIX.mjs.map → chunk-UWCGTH3U.mjs.map} +0 -0
  466. /package/dist/{chunk-6R2LEEEP.mjs.map → chunk-UZF2D2GG.mjs.map} +0 -0
  467. /package/dist/{chunk-62L3PMYE.mjs.map → chunk-V3OVMHZD.mjs.map} +0 -0
  468. /package/dist/{chunk-UDITT3N3.mjs.map → chunk-V6ELDZ2B.mjs.map} +0 -0
  469. /package/dist/{chunk-IJQOTS5O.mjs.map → chunk-VJUS3GC4.mjs.map} +0 -0
  470. /package/dist/{chunk-MQEAEU6G.mjs.map → chunk-XGMRYNER.mjs.map} +0 -0
  471. /package/dist/{chunk-MMQMVVD6.mjs.map → chunk-XLTD5J74.mjs.map} +0 -0
  472. /package/dist/{chunk-OMBUOOMD.mjs.map → chunk-XYT542WD.mjs.map} +0 -0
  473. /package/dist/{chunk-COWOGT7U.mjs.map → chunk-YZWFDSTC.mjs.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
2
 
3
- var _chunkG4NK66PMjs = require('./chunk-G4NK66PM.js');
3
+ var _chunkJTWXQ267js = require('./chunk-JTWXQ267.js');
4
4
 
5
5
 
6
6
  var _chunkANT66KVKjs = require('./chunk-ANT66KVK.js');
@@ -75,7 +75,7 @@ var AnswerRow = ({
75
75
  )
76
76
  ] });
77
77
  };
78
- var AnswerKeyModal = ({ answers, onClose }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkG4NK66PMjs.Modal_default, { isOpen: true, onClose, title: "Gabarito", size: "xl", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-3", children: [
78
+ var AnswerKeyModal = ({ answers, onClose }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkJTWXQ267js.Modal_default, { isOpen: true, onClose, title: "Gabarito", size: "xl", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-3", children: [
79
79
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkANT66KVKjs.Text_default, { size: "sm", weight: "bold", color: "text-text-950", children: "Respostas" }),
80
80
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "ul", { className: "grid gap-3 md:grid-cols-2 lg:grid-cols-3", children: answers.map((answer, index) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
81
81
  AnswerRow,
@@ -91,4 +91,4 @@ var AnswerKeyModal_default = AnswerKeyModal;
91
91
 
92
92
 
93
93
  exports.AnswerKeyModal_default = AnswerKeyModal_default;
94
- //# sourceMappingURL=chunk-QMPOGLAR.js.map
94
+ //# sourceMappingURL=chunk-CIASXVWX.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-QMPOGLAR.js","../src/components/AnswerKeyModal/AnswerKeyModal.tsx"],"names":[],"mappings":"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","file":"/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-QMPOGLAR.js","sourcesContent":[null,"import Modal from '../Modal/Modal';\nimport Text from '../Text/Text';\nimport { ANSWER_STATUS, type QuestionResult } from '../Quiz/useQuizStore';\nimport { CheckCircleIcon } from '@phosphor-icons/react/dist/csr/CheckCircle';\nimport { XCircleIcon } from '@phosphor-icons/react/dist/csr/XCircle';\nimport { MinusCircleIcon } from '@phosphor-icons/react/dist/csr/MinusCircle';\nimport { ClockIcon } from '@phosphor-icons/react/dist/csr/Clock';\n\ntype Answer = QuestionResult['answers'][number];\n\nexport interface AnswerKeyModalProps {\n /** Respostas do aluno, na ordem da prova. */\n answers: Answer[];\n onClose: () => void;\n}\n\n/** Letras das alternativas, na ordem em que as opções foram cadastradas. */\nconst LETTERS = ['A', 'B', 'C', 'D', 'E'];\n\n/**\n * Como cada estado da correção se apresenta na linha.\n *\n * O `Record` sobre o enum é proposital: um estado novo em `ANSWER_STATUS` vira\n * erro de compilação aqui, em vez de cair silenciosamente num \"incorreta\".\n *\n * Em branco tem tratamento próprio, e não vermelho, porque numa prova de papel\n * ele é o sintoma de uma bolha que a leitura óptica não reconheceu — é\n * justamente o que o aluno abre este modal para descobrir.\n */\nconst STATUS_PRESENTATION: Record<\n ANSWER_STATUS,\n {\n label: string;\n Icon: typeof CheckCircleIcon;\n iconClass: string;\n /** Cor da bolha marcada; vazia quando o estado não julga a resposta. */\n bubbleClass: string;\n }\n> = {\n [ANSWER_STATUS.RESPOSTA_CORRETA]: {\n label: 'correta',\n Icon: CheckCircleIcon,\n iconClass: 'text-success-600',\n bubbleClass: 'bg-success-200 border-success-300 text-text-900',\n },\n [ANSWER_STATUS.RESPOSTA_INCORRETA]: {\n label: 'incorreta',\n Icon: XCircleIcon,\n iconClass: 'text-error-600',\n bubbleClass: 'bg-error-200 border-error-300 text-text-900',\n },\n [ANSWER_STATUS.NAO_RESPONDIDO]: {\n label: 'em branco',\n Icon: MinusCircleIcon,\n iconClass: 'text-text-400',\n bubbleClass: 'bg-background-100 border-border-300 text-text-900',\n },\n [ANSWER_STATUS.PENDENTE_AVALIACAO]: {\n label: 'aguardando correção',\n Icon: ClockIcon,\n iconClass: 'text-info-600',\n bubbleClass: 'bg-info-background border-info-300 text-text-900',\n },\n};\n\n/**\n * Posição da alternativa que o aluno marcou.\n *\n * A letra não é gravada: ela é a posição da opção na questão — a mesma regra\n * que a leitura óptica usa para transformar a bolha preenchida em resposta.\n *\n * @param answer - Resposta do aluno a uma questão\n * @returns O índice marcado, ou -1 quando ficou em branco\n */\nconst selectedIndex = (answer: Answer): number => {\n const selected = answer.selectedOptions?.[0]?.optionId;\n if (!selected || !answer.options) return -1;\n return answer.options.findIndex((option) => option.id === selected);\n};\n\n/**\n * Uma linha do gabarito: o número da questão, as cinco bolhas e o veredito.\n *\n * @param answer - Resposta do aluno\n * @param sequence - Número da questão na prova\n * @returns JSX da linha\n */\nconst AnswerRow = ({\n answer,\n sequence,\n}: {\n answer: Answer;\n sequence: number;\n}) => {\n const marked = selectedIndex(answer);\n const presentation =\n STATUS_PRESENTATION[answer.answerStatus] ??\n STATUS_PRESENTATION[ANSWER_STATUS.NAO_RESPONDIDO];\n const { Icon } = presentation;\n\n return (\n <li className=\"flex items-center gap-3 border border-border-100 rounded-lg px-3 py-2\">\n <span className=\"w-6 h-6 shrink-0 rounded-full bg-primary-700 text-white text-xs font-semibold flex items-center justify-center\">\n {sequence}\n </span>\n\n <span className=\"flex items-center gap-1 flex-1\">\n {LETTERS.map((letter, index) => {\n const isMarked = index === marked;\n const tone = isMarked\n ? presentation.bubbleClass\n : 'border-border-200 text-text-600';\n return (\n <span\n key={letter}\n aria-hidden={!isMarked}\n className={`w-6 h-6 rounded-full border text-xs flex items-center justify-center ${tone}`}\n >\n {letter}\n </span>\n );\n })}\n </span>\n\n <Icon\n size={18}\n className={`${presentation.iconClass} shrink-0`}\n aria-label={`Questão ${sequence}: ${presentation.label}`}\n />\n </li>\n );\n};\n\n/**\n * O gabarito como o aluno o preencheu no papel.\n *\n * Mostra a bolha que a leitura óptica reconheceu em cada questão — é assim que\n * ele confere se o que foi lido bate com o que ele marcou, coisa que numa\n * prova impressa não dá para ver de outro jeito.\n *\n * @param answers - Respostas do aluno, na ordem da prova\n * @param onClose - Fecha o modal\n * @returns JSX do modal do gabarito\n */\nconst AnswerKeyModal = ({ answers, onClose }: AnswerKeyModalProps) => (\n <Modal isOpen onClose={onClose} title=\"Gabarito\" size=\"xl\">\n <div className=\"flex flex-col gap-3\">\n <Text size=\"sm\" weight=\"bold\" color=\"text-text-950\">\n Respostas\n </Text>\n <ul className=\"grid gap-3 md:grid-cols-2 lg:grid-cols-3\">\n {answers.map((answer, index) => (\n <AnswerRow\n key={answer.questionId}\n answer={answer}\n sequence={index + 1}\n />\n ))}\n </ul>\n </div>\n </Modal>\n);\n\nexport default AnswerKeyModal;\n"]}
1
+ {"version":3,"sources":["/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-CIASXVWX.js","../src/components/AnswerKeyModal/AnswerKeyModal.tsx"],"names":[],"mappings":"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","file":"/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-CIASXVWX.js","sourcesContent":[null,"import Modal from '../Modal/Modal';\nimport Text from '../Text/Text';\nimport { ANSWER_STATUS, type QuestionResult } from '../Quiz/useQuizStore';\nimport { CheckCircleIcon } from '@phosphor-icons/react/dist/csr/CheckCircle';\nimport { XCircleIcon } from '@phosphor-icons/react/dist/csr/XCircle';\nimport { MinusCircleIcon } from '@phosphor-icons/react/dist/csr/MinusCircle';\nimport { ClockIcon } from '@phosphor-icons/react/dist/csr/Clock';\n\ntype Answer = QuestionResult['answers'][number];\n\nexport interface AnswerKeyModalProps {\n /** Respostas do aluno, na ordem da prova. */\n answers: Answer[];\n onClose: () => void;\n}\n\n/** Letras das alternativas, na ordem em que as opções foram cadastradas. */\nconst LETTERS = ['A', 'B', 'C', 'D', 'E'];\n\n/**\n * Como cada estado da correção se apresenta na linha.\n *\n * O `Record` sobre o enum é proposital: um estado novo em `ANSWER_STATUS` vira\n * erro de compilação aqui, em vez de cair silenciosamente num \"incorreta\".\n *\n * Em branco tem tratamento próprio, e não vermelho, porque numa prova de papel\n * ele é o sintoma de uma bolha que a leitura óptica não reconheceu — é\n * justamente o que o aluno abre este modal para descobrir.\n */\nconst STATUS_PRESENTATION: Record<\n ANSWER_STATUS,\n {\n label: string;\n Icon: typeof CheckCircleIcon;\n iconClass: string;\n /** Cor da bolha marcada; vazia quando o estado não julga a resposta. */\n bubbleClass: string;\n }\n> = {\n [ANSWER_STATUS.RESPOSTA_CORRETA]: {\n label: 'correta',\n Icon: CheckCircleIcon,\n iconClass: 'text-success-600',\n bubbleClass: 'bg-success-200 border-success-300 text-text-900',\n },\n [ANSWER_STATUS.RESPOSTA_INCORRETA]: {\n label: 'incorreta',\n Icon: XCircleIcon,\n iconClass: 'text-error-600',\n bubbleClass: 'bg-error-200 border-error-300 text-text-900',\n },\n [ANSWER_STATUS.NAO_RESPONDIDO]: {\n label: 'em branco',\n Icon: MinusCircleIcon,\n iconClass: 'text-text-400',\n bubbleClass: 'bg-background-100 border-border-300 text-text-900',\n },\n [ANSWER_STATUS.PENDENTE_AVALIACAO]: {\n label: 'aguardando correção',\n Icon: ClockIcon,\n iconClass: 'text-info-600',\n bubbleClass: 'bg-info-background border-info-300 text-text-900',\n },\n};\n\n/**\n * Posição da alternativa que o aluno marcou.\n *\n * A letra não é gravada: ela é a posição da opção na questão — a mesma regra\n * que a leitura óptica usa para transformar a bolha preenchida em resposta.\n *\n * @param answer - Resposta do aluno a uma questão\n * @returns O índice marcado, ou -1 quando ficou em branco\n */\nconst selectedIndex = (answer: Answer): number => {\n const selected = answer.selectedOptions?.[0]?.optionId;\n if (!selected || !answer.options) return -1;\n return answer.options.findIndex((option) => option.id === selected);\n};\n\n/**\n * Uma linha do gabarito: o número da questão, as cinco bolhas e o veredito.\n *\n * @param answer - Resposta do aluno\n * @param sequence - Número da questão na prova\n * @returns JSX da linha\n */\nconst AnswerRow = ({\n answer,\n sequence,\n}: {\n answer: Answer;\n sequence: number;\n}) => {\n const marked = selectedIndex(answer);\n const presentation =\n STATUS_PRESENTATION[answer.answerStatus] ??\n STATUS_PRESENTATION[ANSWER_STATUS.NAO_RESPONDIDO];\n const { Icon } = presentation;\n\n return (\n <li className=\"flex items-center gap-3 border border-border-100 rounded-lg px-3 py-2\">\n <span className=\"w-6 h-6 shrink-0 rounded-full bg-primary-700 text-white text-xs font-semibold flex items-center justify-center\">\n {sequence}\n </span>\n\n <span className=\"flex items-center gap-1 flex-1\">\n {LETTERS.map((letter, index) => {\n const isMarked = index === marked;\n const tone = isMarked\n ? presentation.bubbleClass\n : 'border-border-200 text-text-600';\n return (\n <span\n key={letter}\n aria-hidden={!isMarked}\n className={`w-6 h-6 rounded-full border text-xs flex items-center justify-center ${tone}`}\n >\n {letter}\n </span>\n );\n })}\n </span>\n\n <Icon\n size={18}\n className={`${presentation.iconClass} shrink-0`}\n aria-label={`Questão ${sequence}: ${presentation.label}`}\n />\n </li>\n );\n};\n\n/**\n * O gabarito como o aluno o preencheu no papel.\n *\n * Mostra a bolha que a leitura óptica reconheceu em cada questão — é assim que\n * ele confere se o que foi lido bate com o que ele marcou, coisa que numa\n * prova impressa não dá para ver de outro jeito.\n *\n * @param answers - Respostas do aluno, na ordem da prova\n * @param onClose - Fecha o modal\n * @returns JSX do modal do gabarito\n */\nconst AnswerKeyModal = ({ answers, onClose }: AnswerKeyModalProps) => (\n <Modal isOpen onClose={onClose} title=\"Gabarito\" size=\"xl\">\n <div className=\"flex flex-col gap-3\">\n <Text size=\"sm\" weight=\"bold\" color=\"text-text-950\">\n Respostas\n </Text>\n <ul className=\"grid gap-3 md:grid-cols-2 lg:grid-cols-3\">\n {answers.map((answer, index) => (\n <AnswerRow\n key={answer.questionId}\n answer={answer}\n sequence={index + 1}\n />\n ))}\n </ul>\n </div>\n </Modal>\n);\n\nexport default AnswerKeyModal;\n"]}
@@ -14,7 +14,7 @@ var _chunkGCWS5HG5js = require('./chunk-GCWS5HG5.js');
14
14
  var _chunkE5DU4DIYjs = require('./chunk-E5DU4DIY.js');
15
15
 
16
16
 
17
- var _chunkG4NK66PMjs = require('./chunk-G4NK66PM.js');
17
+ var _chunkJTWXQ267js = require('./chunk-JTWXQ267.js');
18
18
 
19
19
  // src/components/AccessReportModal/AccessReportModal.tsx
20
20
  var _jsxruntime = require('react/jsx-runtime');
@@ -248,7 +248,7 @@ var AccessReportModal = ({
248
248
  content = /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGCWS5HG5js.ErrorContent, { message: "Variante de relat\xF3rio inv\xE1lida." });
249
249
  }
250
250
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
251
- _chunkG4NK66PMjs.Modal_default,
251
+ _chunkJTWXQ267js.Modal_default,
252
252
  {
253
253
  isOpen,
254
254
  onClose,
@@ -265,4 +265,4 @@ var AccessReportModal_default = AccessReportModal;
265
265
 
266
266
 
267
267
  exports.AccessReportModal = AccessReportModal; exports.AccessReportModal_default = AccessReportModal_default;
268
- //# sourceMappingURL=chunk-APKEYUJ3.js.map
268
+ //# sourceMappingURL=chunk-CIQLC2ZZ.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-APKEYUJ3.js","../src/components/AccessReportModal/AccessReportModal.tsx"],"names":[],"mappings":"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","file":"/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-APKEYUJ3.js","sourcesContent":[null,"import { type ReactNode } from 'react';\nimport Modal from '../Modal/Modal';\nimport { MetricBox } from '../shared/MetricBox';\nimport { LegendPieCard, type PieSlice } from '../shared/ChartComponents';\nimport {\n SectionTitle,\n UserHeader,\n ErrorContent,\n} from '../shared/ModalComponents';\nimport { REPORT_MODAL_VARIANT } from '../../types/common';\nimport { SimpleBarChart } from '../SimpleBarChart/SimpleBarChart';\n\n// ─── API Types ────────────────────────────────────────────────\n\n/**\n * Time + percentage pair returned by the backend for platform/hours breakdowns.\n */\nexport interface AccessReportTimePercentage {\n time: string;\n percentage: number;\n}\n\n/**\n * User context returned by the backend inside every access report response.\n */\nexport interface AccessReportUser {\n id: string;\n name: string;\n profileType: string;\n school: string;\n group: string | null;\n class: string | null;\n year: number;\n}\n\n/**\n * Platform access breakdown — web vs mobile.\n */\nexport interface AccessReportByPlatform {\n web: AccessReportTimePercentage;\n mobile: AccessReportTimePercentage;\n}\n\n/**\n * Full 200 response for STUDENT access report.\n * Mirrors backend shape from GET /access-report/access/user/:userId (student variant).\n */\nexport interface AccessReportStudentData {\n user: AccessReportUser;\n accessData: {\n totalTime: string;\n activitiesTime: string;\n contentTime: string;\n recommendedLessonsTime: string;\n simulationsTime: string;\n questionnairesTime: string;\n accessCount: number;\n lastAccess: string | null;\n };\n accessByPlatform: AccessReportByPlatform;\n hoursByItem: {\n activities: AccessReportTimePercentage;\n content: AccessReportTimePercentage;\n simulations: AccessReportTimePercentage;\n questionnaires: AccessReportTimePercentage;\n recommendedLessons: AccessReportTimePercentage;\n };\n}\n\n/**\n * Full 200 response for TEACHER / UNIT_MANAGER / REGIONAL_MANAGER access report.\n * Mirrors backend shape from GET /access-report/access/user/:userId (professional variant).\n */\nexport interface AccessReportProfessionalData {\n user: AccessReportUser;\n accessData: {\n totalTime: string;\n activitiesTime: string;\n recommendedLessonsTime: string;\n accessCount: number;\n lastAccess: string | null;\n };\n accessByPlatform: AccessReportByPlatform;\n hoursByItem: {\n activities: AccessReportTimePercentage;\n recommendedLessons: AccessReportTimePercentage;\n };\n}\n\n/** @deprecated Use {@link REPORT_MODAL_VARIANT} instead. Re-exported for backwards compatibility. */\nexport { REPORT_MODAL_VARIANT as AccessReportModalVariant } from '../../types/common';\n\n/**\n * Access count by period item for bar chart\n */\nexport interface AccessCountByPeriodItem {\n label: string;\n count: number;\n}\n\ninterface AccessReportModalBaseProps {\n isOpen: boolean;\n onClose: () => void;\n /** Modal title (default: \"Relatório de acesso\") */\n title?: string;\n loading?: boolean;\n error?: string | null;\n /** Optional access count by period data for rendering the access count chart */\n accessCountByPeriod?: AccessCountByPeriodItem[];\n}\n\ntype AccessReportModalStudentProps = {\n variant: REPORT_MODAL_VARIANT.STUDENT;\n data: AccessReportStudentData | null;\n};\n\ntype AccessReportModalProfessionalProps = {\n variant: REPORT_MODAL_VARIANT.PROFESSIONAL;\n data: AccessReportProfessionalData | null;\n};\n\nexport type AccessReportModalProps = AccessReportModalBaseProps &\n (AccessReportModalStudentProps | AccessReportModalProfessionalProps);\n\n// ─── Pie slice builders ───────────────────────────────────────\n\nfunction buildPlatformSlices(platform: AccessReportByPlatform): PieSlice[] {\n // The pie is sized by the percentage; the legend reads the time next to each\n // platform (as in the design), not the percentage.\n return [\n {\n label: 'Web',\n value: platform.web.percentage,\n displayValue: platform.web.time,\n colorClass: 'bg-success-700',\n color: 'var(--Success-success700, #206F3E)',\n },\n {\n label: 'Celular',\n value: platform.mobile.percentage,\n displayValue: platform.mobile.time,\n colorClass: 'bg-success-300',\n color: 'var(--Success-success300, #66B584)',\n },\n ];\n}\n\nfunction buildStudentHoursSlices(\n hoursByItem: AccessReportStudentData['hoursByItem']\n): PieSlice[] {\n // Order, labels and colors mirror STUDENT_CATEGORIES from the reports page\n // TimeChart so the modal breakdown matches the page chart 1:1.\n return [\n {\n label: 'Atividades',\n value: hoursByItem.activities.percentage,\n colorClass: 'bg-success-700',\n },\n {\n label: 'Simulados',\n value: hoursByItem.simulations.percentage,\n colorClass: 'bg-warning-300',\n },\n {\n label: 'Questionários',\n value: hoursByItem.questionnaires.percentage,\n colorClass: 'bg-indicator-info',\n },\n {\n label: 'Videoaulas',\n value: hoursByItem.content.percentage,\n colorClass: 'bg-success-300',\n },\n {\n label: 'Aulas recomendadas',\n value: hoursByItem.recommendedLessons.percentage,\n colorClass: 'bg-indicator-positive',\n },\n ];\n}\n\n// ─── Modal content ────────────────────────────────────────────\n\nconst ReportContentLayout = ({\n user,\n metricBoxes,\n platformSlices,\n hoursSlices,\n accessCountByPeriod,\n}: {\n user: AccessReportUser;\n metricBoxes: ReactNode;\n platformSlices: PieSlice[];\n hoursSlices: PieSlice[];\n accessCountByPeriod?: AccessCountByPeriodItem[];\n}) => (\n <div className=\"flex flex-col gap-6\">\n <UserHeader\n name={user.name}\n school={user.school}\n className={user.class ?? ''}\n year={user.year}\n />\n\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-3\">{metricBoxes}</div>\n\n {accessCountByPeriod && accessCountByPeriod.length > 0 && (\n <SimpleBarChart\n data={accessCountByPeriod.map((item) => ({\n label: item.label,\n value: item.count,\n }))}\n title=\"Quantidade de acessos por período\"\n barColor=\"bg-info-500\"\n chartHeight={150}\n />\n )}\n\n <div className=\"flex flex-col gap-3\">\n <SectionTitle>Dados de acesso por plataforma</SectionTitle>\n <LegendPieCard slices={platformSlices} />\n </div>\n\n <div className=\"flex flex-col gap-3\">\n <SectionTitle>Dados de horas por item</SectionTitle>\n <LegendPieCard slices={hoursSlices} />\n </div>\n </div>\n);\n\nconst StudentModalContent = ({\n data,\n accessCountByPeriod,\n}: {\n data: AccessReportStudentData;\n accessCountByPeriod?: AccessCountByPeriodItem[];\n}) => (\n <ReportContentLayout\n user={data.user}\n platformSlices={buildPlatformSlices(data.accessByPlatform)}\n hoursSlices={buildStudentHoursSlices(data.hoursByItem)}\n accessCountByPeriod={accessCountByPeriod}\n metricBoxes={\n <>\n <MetricBox label=\"Tempo total\" value={data.accessData.totalTime} />\n <MetricBox label=\"Videoaulas\" value={data.accessData.contentTime} />\n <MetricBox\n label=\"Aulas recomendadas\"\n value={data.accessData.recommendedLessonsTime}\n />\n <MetricBox label=\"Simulados\" value={data.accessData.simulationsTime} />\n <MetricBox\n label=\"Quantidade de acessos\"\n value={data.accessData.accessCount}\n />\n <MetricBox\n label=\"Último acesso\"\n value={data.accessData.lastAccess ?? '—'}\n />\n </>\n }\n />\n);\n\nconst ProfessionalModalContent = ({\n data,\n accessCountByPeriod,\n}: {\n data: AccessReportProfessionalData;\n accessCountByPeriod?: AccessCountByPeriodItem[];\n}) => (\n <div className=\"flex flex-col gap-6\">\n <UserHeader\n name={data.user.name}\n school={data.user.school}\n className={data.user.class ?? ''}\n year={data.user.year}\n />\n\n <div className=\"flex flex-col gap-3\">\n <SectionTitle>Dados de acesso</SectionTitle>\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-3\">\n <MetricBox label=\"Tempo total\" value={data.accessData.totalTime} />\n <MetricBox label=\"Acessos\" value={data.accessData.accessCount} />\n <MetricBox\n label=\"Último acesso\"\n value={data.accessData.lastAccess ?? '—'}\n />\n </div>\n </div>\n\n {accessCountByPeriod && accessCountByPeriod.length > 0 && (\n <SimpleBarChart\n data={accessCountByPeriod.map((item) => ({\n label: item.label,\n value: item.count,\n }))}\n title=\"Quantidade de acessos por período\"\n barColor=\"bg-info-500\"\n chartHeight={150}\n />\n )}\n\n <div className=\"flex flex-col gap-3\">\n <SectionTitle>Dados de acesso por plataforma</SectionTitle>\n <LegendPieCard slices={buildPlatformSlices(data.accessByPlatform)} />\n </div>\n </div>\n);\n\nconst LoadingSkeleton = ({\n metricCount,\n showSecondaryChart = true,\n}: {\n metricCount: number;\n showSecondaryChart?: boolean;\n}) => (\n <div className=\"flex flex-col gap-4 animate-pulse\">\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-3\">\n {Array.from({ length: metricCount }, (_, i) => (\n <div\n key={`skeleton-${String(i)}`}\n className=\"h-16 bg-background-200 rounded-xl\"\n />\n ))}\n </div>\n <div className=\"h-5 bg-background-200 rounded w-40 mt-2\" />\n <div className=\"h-32 bg-background-200 rounded-xl\" />\n {showSecondaryChart && (\n <>\n <div className=\"h-5 bg-background-200 rounded w-32\" />\n <div className=\"h-32 bg-background-200 rounded-xl\" />\n </>\n )}\n </div>\n);\n\n// ─── Main component ───────────────────────────────────────────\n\n/**\n * AccessReportModal component\n *\n * Displays a modal with access data for a user.\n *\n * Two variants driven by the profile type:\n * - `STUDENT` — 6 metric boxes (totalTime, contentTime, recommendedLessonsTime,\n * simulationsTime, accessCount, lastAccess) + platform pie chart + hours-by-item pie chart\n * - `PROFESSIONAL` — 3 metric boxes (totalTime, accessCount, lastAccess) +\n * platform pie chart only (no hours-by-item breakdown for professionals)\n *\n * @example\n * ```tsx\n * <AccessReportModal\n * isOpen={isOpen}\n * onClose={() => setIsOpen(false)}\n * variant={REPORT_MODAL_VARIANT.STUDENT}\n * data={apiResponse.data}\n * />\n * ```\n */\nexport const AccessReportModal = ({\n isOpen,\n onClose,\n title = 'Relatório de acesso',\n loading = false,\n error = null,\n accessCountByPeriod,\n ...variantProps\n}: AccessReportModalProps) => {\n let content: ReactNode;\n\n const isStudent = variantProps.variant === REPORT_MODAL_VARIANT.STUDENT;\n // Student: 6 metrics + 2 charts; Professional: 3 metrics + 1 chart\n const metricCount = isStudent ? 6 : 3;\n const showSecondaryChart = isStudent;\n\n if (loading) {\n content = (\n <LoadingSkeleton\n metricCount={metricCount}\n showSecondaryChart={showSecondaryChart}\n />\n );\n } else if (error) {\n content = <ErrorContent message={error} />;\n } else if (variantProps.data === null) {\n content = <ErrorContent message=\"Nenhum dado disponível.\" />;\n } else if (variantProps.variant === REPORT_MODAL_VARIANT.STUDENT) {\n content = (\n <StudentModalContent\n data={variantProps.data}\n accessCountByPeriod={accessCountByPeriod}\n />\n );\n } else if (variantProps.variant === REPORT_MODAL_VARIANT.PROFESSIONAL) {\n content = (\n <ProfessionalModalContent\n data={variantProps.data}\n accessCountByPeriod={accessCountByPeriod}\n />\n );\n } else {\n content = <ErrorContent message=\"Variante de relatório inválida.\" />;\n }\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={onClose}\n title={title}\n size=\"lg\"\n contentClassName=\"max-h-[80vh] overflow-y-auto\"\n >\n {content}\n </Modal>\n );\n};\n\nexport default AccessReportModal;\n"]}
1
+ {"version":3,"sources":["/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-CIQLC2ZZ.js","../src/components/AccessReportModal/AccessReportModal.tsx"],"names":[],"mappings":"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","file":"/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-CIQLC2ZZ.js","sourcesContent":[null,"import { type ReactNode } from 'react';\nimport Modal from '../Modal/Modal';\nimport { MetricBox } from '../shared/MetricBox';\nimport { LegendPieCard, type PieSlice } from '../shared/ChartComponents';\nimport {\n SectionTitle,\n UserHeader,\n ErrorContent,\n} from '../shared/ModalComponents';\nimport { REPORT_MODAL_VARIANT } from '../../types/common';\nimport { SimpleBarChart } from '../SimpleBarChart/SimpleBarChart';\n\n// ─── API Types ────────────────────────────────────────────────\n\n/**\n * Time + percentage pair returned by the backend for platform/hours breakdowns.\n */\nexport interface AccessReportTimePercentage {\n time: string;\n percentage: number;\n}\n\n/**\n * User context returned by the backend inside every access report response.\n */\nexport interface AccessReportUser {\n id: string;\n name: string;\n profileType: string;\n school: string;\n group: string | null;\n class: string | null;\n year: number;\n}\n\n/**\n * Platform access breakdown — web vs mobile.\n */\nexport interface AccessReportByPlatform {\n web: AccessReportTimePercentage;\n mobile: AccessReportTimePercentage;\n}\n\n/**\n * Full 200 response for STUDENT access report.\n * Mirrors backend shape from GET /access-report/access/user/:userId (student variant).\n */\nexport interface AccessReportStudentData {\n user: AccessReportUser;\n accessData: {\n totalTime: string;\n activitiesTime: string;\n contentTime: string;\n recommendedLessonsTime: string;\n simulationsTime: string;\n questionnairesTime: string;\n accessCount: number;\n lastAccess: string | null;\n };\n accessByPlatform: AccessReportByPlatform;\n hoursByItem: {\n activities: AccessReportTimePercentage;\n content: AccessReportTimePercentage;\n simulations: AccessReportTimePercentage;\n questionnaires: AccessReportTimePercentage;\n recommendedLessons: AccessReportTimePercentage;\n };\n}\n\n/**\n * Full 200 response for TEACHER / UNIT_MANAGER / REGIONAL_MANAGER access report.\n * Mirrors backend shape from GET /access-report/access/user/:userId (professional variant).\n */\nexport interface AccessReportProfessionalData {\n user: AccessReportUser;\n accessData: {\n totalTime: string;\n activitiesTime: string;\n recommendedLessonsTime: string;\n accessCount: number;\n lastAccess: string | null;\n };\n accessByPlatform: AccessReportByPlatform;\n hoursByItem: {\n activities: AccessReportTimePercentage;\n recommendedLessons: AccessReportTimePercentage;\n };\n}\n\n/** @deprecated Use {@link REPORT_MODAL_VARIANT} instead. Re-exported for backwards compatibility. */\nexport { REPORT_MODAL_VARIANT as AccessReportModalVariant } from '../../types/common';\n\n/**\n * Access count by period item for bar chart\n */\nexport interface AccessCountByPeriodItem {\n label: string;\n count: number;\n}\n\ninterface AccessReportModalBaseProps {\n isOpen: boolean;\n onClose: () => void;\n /** Modal title (default: \"Relatório de acesso\") */\n title?: string;\n loading?: boolean;\n error?: string | null;\n /** Optional access count by period data for rendering the access count chart */\n accessCountByPeriod?: AccessCountByPeriodItem[];\n}\n\ntype AccessReportModalStudentProps = {\n variant: REPORT_MODAL_VARIANT.STUDENT;\n data: AccessReportStudentData | null;\n};\n\ntype AccessReportModalProfessionalProps = {\n variant: REPORT_MODAL_VARIANT.PROFESSIONAL;\n data: AccessReportProfessionalData | null;\n};\n\nexport type AccessReportModalProps = AccessReportModalBaseProps &\n (AccessReportModalStudentProps | AccessReportModalProfessionalProps);\n\n// ─── Pie slice builders ───────────────────────────────────────\n\nfunction buildPlatformSlices(platform: AccessReportByPlatform): PieSlice[] {\n // The pie is sized by the percentage; the legend reads the time next to each\n // platform (as in the design), not the percentage.\n return [\n {\n label: 'Web',\n value: platform.web.percentage,\n displayValue: platform.web.time,\n colorClass: 'bg-success-700',\n color: 'var(--Success-success700, #206F3E)',\n },\n {\n label: 'Celular',\n value: platform.mobile.percentage,\n displayValue: platform.mobile.time,\n colorClass: 'bg-success-300',\n color: 'var(--Success-success300, #66B584)',\n },\n ];\n}\n\nfunction buildStudentHoursSlices(\n hoursByItem: AccessReportStudentData['hoursByItem']\n): PieSlice[] {\n // Order, labels and colors mirror STUDENT_CATEGORIES from the reports page\n // TimeChart so the modal breakdown matches the page chart 1:1.\n return [\n {\n label: 'Atividades',\n value: hoursByItem.activities.percentage,\n colorClass: 'bg-success-700',\n },\n {\n label: 'Simulados',\n value: hoursByItem.simulations.percentage,\n colorClass: 'bg-warning-300',\n },\n {\n label: 'Questionários',\n value: hoursByItem.questionnaires.percentage,\n colorClass: 'bg-indicator-info',\n },\n {\n label: 'Videoaulas',\n value: hoursByItem.content.percentage,\n colorClass: 'bg-success-300',\n },\n {\n label: 'Aulas recomendadas',\n value: hoursByItem.recommendedLessons.percentage,\n colorClass: 'bg-indicator-positive',\n },\n ];\n}\n\n// ─── Modal content ────────────────────────────────────────────\n\nconst ReportContentLayout = ({\n user,\n metricBoxes,\n platformSlices,\n hoursSlices,\n accessCountByPeriod,\n}: {\n user: AccessReportUser;\n metricBoxes: ReactNode;\n platformSlices: PieSlice[];\n hoursSlices: PieSlice[];\n accessCountByPeriod?: AccessCountByPeriodItem[];\n}) => (\n <div className=\"flex flex-col gap-6\">\n <UserHeader\n name={user.name}\n school={user.school}\n className={user.class ?? ''}\n year={user.year}\n />\n\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-3\">{metricBoxes}</div>\n\n {accessCountByPeriod && accessCountByPeriod.length > 0 && (\n <SimpleBarChart\n data={accessCountByPeriod.map((item) => ({\n label: item.label,\n value: item.count,\n }))}\n title=\"Quantidade de acessos por período\"\n barColor=\"bg-info-500\"\n chartHeight={150}\n />\n )}\n\n <div className=\"flex flex-col gap-3\">\n <SectionTitle>Dados de acesso por plataforma</SectionTitle>\n <LegendPieCard slices={platformSlices} />\n </div>\n\n <div className=\"flex flex-col gap-3\">\n <SectionTitle>Dados de horas por item</SectionTitle>\n <LegendPieCard slices={hoursSlices} />\n </div>\n </div>\n);\n\nconst StudentModalContent = ({\n data,\n accessCountByPeriod,\n}: {\n data: AccessReportStudentData;\n accessCountByPeriod?: AccessCountByPeriodItem[];\n}) => (\n <ReportContentLayout\n user={data.user}\n platformSlices={buildPlatformSlices(data.accessByPlatform)}\n hoursSlices={buildStudentHoursSlices(data.hoursByItem)}\n accessCountByPeriod={accessCountByPeriod}\n metricBoxes={\n <>\n <MetricBox label=\"Tempo total\" value={data.accessData.totalTime} />\n <MetricBox label=\"Videoaulas\" value={data.accessData.contentTime} />\n <MetricBox\n label=\"Aulas recomendadas\"\n value={data.accessData.recommendedLessonsTime}\n />\n <MetricBox label=\"Simulados\" value={data.accessData.simulationsTime} />\n <MetricBox\n label=\"Quantidade de acessos\"\n value={data.accessData.accessCount}\n />\n <MetricBox\n label=\"Último acesso\"\n value={data.accessData.lastAccess ?? '—'}\n />\n </>\n }\n />\n);\n\nconst ProfessionalModalContent = ({\n data,\n accessCountByPeriod,\n}: {\n data: AccessReportProfessionalData;\n accessCountByPeriod?: AccessCountByPeriodItem[];\n}) => (\n <div className=\"flex flex-col gap-6\">\n <UserHeader\n name={data.user.name}\n school={data.user.school}\n className={data.user.class ?? ''}\n year={data.user.year}\n />\n\n <div className=\"flex flex-col gap-3\">\n <SectionTitle>Dados de acesso</SectionTitle>\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-3\">\n <MetricBox label=\"Tempo total\" value={data.accessData.totalTime} />\n <MetricBox label=\"Acessos\" value={data.accessData.accessCount} />\n <MetricBox\n label=\"Último acesso\"\n value={data.accessData.lastAccess ?? '—'}\n />\n </div>\n </div>\n\n {accessCountByPeriod && accessCountByPeriod.length > 0 && (\n <SimpleBarChart\n data={accessCountByPeriod.map((item) => ({\n label: item.label,\n value: item.count,\n }))}\n title=\"Quantidade de acessos por período\"\n barColor=\"bg-info-500\"\n chartHeight={150}\n />\n )}\n\n <div className=\"flex flex-col gap-3\">\n <SectionTitle>Dados de acesso por plataforma</SectionTitle>\n <LegendPieCard slices={buildPlatformSlices(data.accessByPlatform)} />\n </div>\n </div>\n);\n\nconst LoadingSkeleton = ({\n metricCount,\n showSecondaryChart = true,\n}: {\n metricCount: number;\n showSecondaryChart?: boolean;\n}) => (\n <div className=\"flex flex-col gap-4 animate-pulse\">\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-3\">\n {Array.from({ length: metricCount }, (_, i) => (\n <div\n key={`skeleton-${String(i)}`}\n className=\"h-16 bg-background-200 rounded-xl\"\n />\n ))}\n </div>\n <div className=\"h-5 bg-background-200 rounded w-40 mt-2\" />\n <div className=\"h-32 bg-background-200 rounded-xl\" />\n {showSecondaryChart && (\n <>\n <div className=\"h-5 bg-background-200 rounded w-32\" />\n <div className=\"h-32 bg-background-200 rounded-xl\" />\n </>\n )}\n </div>\n);\n\n// ─── Main component ───────────────────────────────────────────\n\n/**\n * AccessReportModal component\n *\n * Displays a modal with access data for a user.\n *\n * Two variants driven by the profile type:\n * - `STUDENT` — 6 metric boxes (totalTime, contentTime, recommendedLessonsTime,\n * simulationsTime, accessCount, lastAccess) + platform pie chart + hours-by-item pie chart\n * - `PROFESSIONAL` — 3 metric boxes (totalTime, accessCount, lastAccess) +\n * platform pie chart only (no hours-by-item breakdown for professionals)\n *\n * @example\n * ```tsx\n * <AccessReportModal\n * isOpen={isOpen}\n * onClose={() => setIsOpen(false)}\n * variant={REPORT_MODAL_VARIANT.STUDENT}\n * data={apiResponse.data}\n * />\n * ```\n */\nexport const AccessReportModal = ({\n isOpen,\n onClose,\n title = 'Relatório de acesso',\n loading = false,\n error = null,\n accessCountByPeriod,\n ...variantProps\n}: AccessReportModalProps) => {\n let content: ReactNode;\n\n const isStudent = variantProps.variant === REPORT_MODAL_VARIANT.STUDENT;\n // Student: 6 metrics + 2 charts; Professional: 3 metrics + 1 chart\n const metricCount = isStudent ? 6 : 3;\n const showSecondaryChart = isStudent;\n\n if (loading) {\n content = (\n <LoadingSkeleton\n metricCount={metricCount}\n showSecondaryChart={showSecondaryChart}\n />\n );\n } else if (error) {\n content = <ErrorContent message={error} />;\n } else if (variantProps.data === null) {\n content = <ErrorContent message=\"Nenhum dado disponível.\" />;\n } else if (variantProps.variant === REPORT_MODAL_VARIANT.STUDENT) {\n content = (\n <StudentModalContent\n data={variantProps.data}\n accessCountByPeriod={accessCountByPeriod}\n />\n );\n } else if (variantProps.variant === REPORT_MODAL_VARIANT.PROFESSIONAL) {\n content = (\n <ProfessionalModalContent\n data={variantProps.data}\n accessCountByPeriod={accessCountByPeriod}\n />\n );\n } else {\n content = <ErrorContent message=\"Variante de relatório inválida.\" />;\n }\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={onClose}\n title={title}\n size=\"lg\"\n contentClassName=\"max-h-[80vh] overflow-y-auto\"\n >\n {content}\n </Modal>\n );\n};\n\nexport default AccessReportModal;\n"]}
@@ -9,7 +9,7 @@ var _chunkAN62GXF5js = require('./chunk-AN62GXF5.js');
9
9
  var _chunkNEDUOGWUjs = require('./chunk-NEDUOGWU.js');
10
10
 
11
11
 
12
- var _chunkBVUPM6EYjs = require('./chunk-BVUPM6EY.js');
12
+ var _chunkCAQ2Q3ONjs = require('./chunk-CAQ2Q3ON.js');
13
13
 
14
14
 
15
15
  var _chunkBJMKBBN3js = require('./chunk-BJMKBBN3.js');
@@ -18,10 +18,10 @@ var _chunkBJMKBBN3js = require('./chunk-BJMKBBN3.js');
18
18
 
19
19
 
20
20
 
21
- var _chunk2TLSEAL2js = require('./chunk-2TLSEAL2.js');
21
+ var _chunkO4TRDWXJjs = require('./chunk-O4TRDWXJ.js');
22
22
 
23
23
 
24
- var _chunkG4NK66PMjs = require('./chunk-G4NK66PM.js');
24
+ var _chunkJTWXQ267js = require('./chunk-JTWXQ267.js');
25
25
 
26
26
 
27
27
  var _chunkANT66KVKjs = require('./chunk-ANT66KVK.js');
@@ -98,7 +98,7 @@ var GlobalNotificationModal = ({
98
98
  onMarkAsReadById,
99
99
  emptyStateImage
100
100
  }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
101
- _chunkG4NK66PMjs.Modal_default,
101
+ _chunkJTWXQ267js.Modal_default,
102
102
  {
103
103
  isOpen,
104
104
  onClose,
@@ -153,25 +153,25 @@ var SingleNotificationCard = ({
153
153
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-2 w-full", children: [
154
154
  !isRead && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-[7px] h-[7px] bg-info-300 rounded-full flex-shrink-0" }),
155
155
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "font-bold text-sm leading-4 text-text-950 flex-grow", children: title }),
156
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk2TLSEAL2js.DropdownMenu_default, { children: [
156
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkO4TRDWXJjs.DropdownMenu_default, { children: [
157
157
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
158
- _chunk2TLSEAL2js.DropdownMenuTrigger,
158
+ _chunkO4TRDWXJjs.DropdownMenuTrigger,
159
159
  {
160
160
  className: "flex-shrink-0 inline-flex items-center justify-center font-medium bg-transparent text-text-950 cursor-pointer hover:bg-info-50 w-6 h-6 rounded-lg",
161
161
  "aria-label": "Mais op\xE7\xF5es",
162
162
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _DotsThreeVertical.DotsThreeVerticalIcon, { size: 24 })
163
163
  }
164
164
  ),
165
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk2TLSEAL2js.DropdownMenuContent, { align: "end", className: "min-w-[160px]", children: [
165
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkO4TRDWXJjs.DropdownMenuContent, { align: "end", className: "min-w-[160px]", children: [
166
166
  !isRead && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
167
- _chunk2TLSEAL2js.DropdownMenuItem,
167
+ _chunkO4TRDWXJjs.DropdownMenuItem,
168
168
  {
169
169
  onClick: handleMarkAsRead,
170
170
  className: "text-text-950",
171
171
  children: "Marcar como lida"
172
172
  }
173
173
  ),
174
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk2TLSEAL2js.DropdownMenuItem, { onClick: handleDelete, className: "text-error-600", children: "Deletar" })
174
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkO4TRDWXJjs.DropdownMenuItem, { onClick: handleDelete, className: "text-error-600", children: "Deletar" })
175
175
  ] })
176
176
  ] })
177
177
  ] }),
@@ -368,7 +368,7 @@ var NotificationCenter = ({
368
368
  if (isMobile) {
369
369
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
370
370
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
371
- _chunkBVUPM6EYjs.IconButton_default,
371
+ _chunkCAQ2Q3ONjs.IconButton_default,
372
372
  {
373
373
  active: isModalOpen,
374
374
  onClick: handleMobileClick,
@@ -386,7 +386,7 @@ var NotificationCenter = ({
386
386
  }
387
387
  ),
388
388
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
389
- _chunkG4NK66PMjs.Modal_default,
389
+ _chunkJTWXQ267js.Modal_default,
390
390
  {
391
391
  isOpen: isModalOpen,
392
392
  onClose: () => setIsModalOpen(false),
@@ -449,12 +449,12 @@ var NotificationCenter = ({
449
449
  }
450
450
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
451
451
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
452
- _chunk2TLSEAL2js.DropdownMenu_default,
452
+ _chunkO4TRDWXJjs.DropdownMenu_default,
453
453
  {
454
454
  ...typeof isActive === "boolean" ? { open: isActive, onOpenChange: handleOpenChange } : { onOpenChange: handleOpenChange },
455
455
  children: [
456
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk2TLSEAL2js.DropdownMenuTrigger, { className: "text-primary cursor-pointer", asChild: true, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
457
- _chunkBVUPM6EYjs.IconButton_default,
456
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkO4TRDWXJjs.DropdownMenuTrigger, { className: "text-primary cursor-pointer", asChild: true, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
457
+ _chunkCAQ2Q3ONjs.IconButton_default,
458
458
  {
459
459
  active: isActive,
460
460
  onClick: handleDesktopClick,
@@ -471,7 +471,7 @@ var NotificationCenter = ({
471
471
  }
472
472
  ) }),
473
473
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
474
- _chunk2TLSEAL2js.DropdownMenuContent,
474
+ _chunkO4TRDWXJjs.DropdownMenuContent,
475
475
  {
476
476
  className: "min-w-[320px] max-w-[400px] max-h-[500px] overflow-hidden",
477
477
  side: "bottom",
@@ -651,4 +651,4 @@ var NotificationCard_default = NotificationCard;
651
651
 
652
652
 
653
653
  exports.LegacyNotificationCard = LegacyNotificationCard; exports.NotificationCard_default = NotificationCard_default;
654
- //# sourceMappingURL=chunk-36XPNLGQ.js.map
654
+ //# sourceMappingURL=chunk-CW3FCWR4.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-36XPNLGQ.js","../src/components/NotificationCard/NotificationCard.tsx"],"names":[],"mappings":"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","file":"/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-36XPNLGQ.js","sourcesContent":[null,"import { DotsThreeVerticalIcon } from '@phosphor-icons/react/dist/csr/DotsThreeVertical';\nimport { BellIcon } from '@phosphor-icons/react/dist/csr/Bell';\nimport { MouseEvent, ReactNode, useState, useEffect } from 'react';\nimport { cn } from '../../utils/utils';\nimport DropdownMenu, {\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '../DropdownMenu/DropdownMenu';\nimport { SkeletonCard } from '../Skeleton/Skeleton';\nimport IconButton from '../IconButton/IconButton';\nimport Modal from '../Modal/Modal';\nimport Text from '../Text/Text';\nimport Badge from '../Badge/Badge';\nimport { useMobile } from '../../hooks/useMobile';\nimport type {\n Notification,\n NotificationGroup,\n NotificationEntityType,\n NotificationEntityStatus,\n} from '../../types/notifications';\nimport { formatTimeAgo } from '../../store/notificationStore';\nimport mockContentImage from '../../assets/img/mock-content.png';\n\n/**\n * Default interval (in ms) to auto-refresh the notification center while it is\n * open, so newly received notifications appear without reopening it.\n */\nconst DEFAULT_REFRESH_INTERVAL_MS = 3000;\n\n/**\n * Nome acessível do sino.\n *\n * O botão era só um ícone com um `sr-only` dentro, e esse texto só existia\n * quando havia não lidas: sem notificação nenhuma o botão ficava sem nome, e o\n * leitor de tela anunciava apenas \"botão\". A contagem entra no próprio rótulo\n * para que o estado seja dito junto com o nome, em vez de depender de um texto\n * que aparece e some.\n */\nconst getNotificationsLabel = (unreadCount: number) => {\n if (unreadCount <= 0) {\n return 'Notificações, sem notificações';\n }\n\n const plural = unreadCount === 1 ? 'notificação' : 'notificações';\n return `Notificações, ${unreadCount} ${plural}`;\n};\n\n// Extended notification item for component usage with time string\nexport interface NotificationItem extends Omit<Notification, 'createdAt'> {\n time: string;\n createdAt: string | Date;\n}\n\n// Base props shared across all modes\ninterface BaseNotificationProps {\n /**\n * Additional CSS classes\n */\n className?: string;\n /**\n * Empty state image path\n */\n emptyStateImage?: string;\n /**\n * Empty state title\n */\n emptyStateTitle?: string;\n /**\n * Empty state description\n */\n emptyStateDescription?: string;\n}\n\n// Single notification card mode\ninterface SingleNotificationCardMode extends BaseNotificationProps {\n /**\n * Component mode - single card\n */\n mode: 'single';\n /**\n * The notification title\n */\n title: string;\n /**\n * The notification message content\n */\n message: string;\n /**\n * Time displayed (e.g., \"Há 3h\", \"12 Fev\")\n */\n time: string;\n /**\n * Whether the notification has been read\n */\n isRead: boolean;\n /**\n * Callback when user marks notification as read\n */\n onMarkAsRead: () => void;\n /**\n * Callback when user deletes notification\n */\n onDelete: () => void;\n /**\n * Optional callback for navigation action\n */\n onNavigate?: () => void;\n /**\n * Label for the action button (only shown if onNavigate is provided)\n */\n actionLabel?: string;\n}\n\n// List mode\ninterface NotificationListMode extends BaseNotificationProps {\n /**\n * Component mode - list\n */\n mode: 'list';\n /**\n * Array of notifications for list mode\n */\n notifications?: NotificationItem[];\n /**\n * Array of grouped notifications\n */\n groupedNotifications?: NotificationGroup[];\n /**\n * Loading state for list mode\n */\n loading?: boolean;\n /**\n * Error state for list mode\n */\n error?: string | null;\n /**\n * Callback for retry when error occurs\n */\n onRetry?: () => void;\n /**\n * Callback when user marks a notification as read in list mode\n */\n onMarkAsReadById?: (id: string) => void;\n /**\n * Callback when user deletes a notification in list mode\n */\n onDeleteById?: (id: string) => void;\n /**\n * Callback when user navigates from a notification in list mode\n */\n onNavigateById?: (\n entityType?: NotificationEntityType,\n entityId?: string,\n entityStatus?: NotificationEntityStatus | null,\n questionId?: string | null\n ) => void;\n /**\n * Callback when user clicks on a global notification\n */\n onGlobalNotificationClick?: (notification: Notification) => void;\n /**\n * Function to get action label for a notification\n */\n getActionLabel?: (entityType?: NotificationEntityType) => string | undefined;\n /**\n * Custom empty state component\n */\n renderEmpty?: () => ReactNode;\n}\n\n// NotificationCenter mode\ninterface NotificationCenterMode extends BaseNotificationProps {\n /**\n * Component mode - center\n */\n mode: 'center';\n /**\n * Array of grouped notifications\n */\n groupedNotifications?: NotificationGroup[];\n /**\n * Loading state for center mode\n */\n loading?: boolean;\n /**\n * Error state for center mode\n */\n error?: string | null;\n /**\n * Callback for retry when error occurs\n */\n onRetry?: () => void;\n /**\n * Whether center mode is currently active (controls dropdown/modal visibility)\n */\n isActive?: boolean;\n /**\n * Callback when center mode is toggled\n */\n onToggleActive?: () => void;\n /**\n * Number of unread notifications for badge display\n */\n unreadCount?: number;\n /**\n * Callback when all notifications should be marked as read\n */\n onMarkAllAsRead?: () => void;\n /**\n * Callback to fetch notifications (called when center opens)\n */\n onFetchNotifications?: () => void;\n /**\n * Callback when user marks a notification as read in center mode\n */\n onMarkAsReadById?: (id: string) => void;\n /**\n * Callback when user deletes a notification in center mode\n */\n onDeleteById?: (id: string) => void;\n /**\n * Callback when user navigates from a notification in center mode\n */\n onNavigateById?: (\n entityType?: NotificationEntityType,\n entityId?: string,\n entityStatus?: NotificationEntityStatus | null,\n questionId?: string | null\n ) => void;\n /**\n * Function to get action label for a notification\n */\n getActionLabel?: (entityType?: NotificationEntityType) => string | undefined;\n /**\n * Callback when dropdown open state changes (for synchronization with parent)\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * Interval (in ms) to auto-refresh the list while the center is open, so newly\n * received notifications appear without reopening it. Defaults to 3000 (3s).\n * Set to 0 to disable polling.\n */\n refreshIntervalMs?: number;\n}\n\n// Union type for all modes\nexport type NotificationCardProps =\n | SingleNotificationCardMode\n | NotificationListMode\n | NotificationCenterMode;\n\n// Legacy interface for backward compatibility\nexport interface LegacyNotificationCardProps extends BaseNotificationProps {\n // Single notification mode props\n title?: string;\n message?: string;\n time?: string;\n isRead?: boolean;\n onMarkAsRead?: () => void;\n onDelete?: () => void;\n onNavigate?: () => void;\n actionLabel?: string;\n\n // List mode props\n notifications?: NotificationItem[];\n groupedNotifications?: NotificationGroup[];\n loading?: boolean;\n error?: string | null;\n onRetry?: () => void;\n onMarkAsReadById?: (id: string) => void;\n onDeleteById?: (id: string) => void;\n onNavigateById?: (\n entityType?: NotificationEntityType,\n entityId?: string,\n entityStatus?: NotificationEntityStatus | null,\n questionId?: string | null\n ) => void;\n onGlobalNotificationClick?: (notification: Notification) => void;\n getActionLabel?: (entityType?: NotificationEntityType) => string | undefined;\n renderEmpty?: () => ReactNode;\n\n // NotificationCenter mode props\n variant?: 'card' | 'center';\n isActive?: boolean;\n onToggleActive?: () => void;\n unreadCount?: number;\n onMarkAllAsRead?: () => void;\n onFetchNotifications?: () => void;\n onOpenChange?: (open: boolean) => void;\n}\n\n/**\n * Empty state component for notifications\n */\nconst NotificationEmpty = ({\n emptyStateImage,\n emptyStateTitle = 'Nenhuma notificação no momento',\n emptyStateDescription = 'Você está em dia com todas as novidades. Volte depois para conferir atualizações!',\n}: {\n emptyStateImage?: string;\n emptyStateTitle?: string;\n emptyStateDescription?: string;\n}) => {\n return (\n <div className=\"flex flex-col items-center justify-center gap-4 p-6 w-full\">\n {/* Notification Icon */}\n {emptyStateImage && (\n <div className=\"w-20 h-20 flex items-center justify-center\">\n <img\n src={emptyStateImage}\n alt=\"Sem notificações\"\n width={82}\n height={82}\n className=\"object-contain\"\n />\n </div>\n )}\n\n {/* Title */}\n <h3 className=\"text-xl font-semibold text-text-950 text-center leading-[23px]\">\n {emptyStateTitle}\n </h3>\n\n {/* Description */}\n <p className=\"text-sm font-normal text-text-400 text-center max-w-[316px] leading-[21px]\">\n {emptyStateDescription}\n </p>\n </div>\n );\n};\n\n/**\n * Notification header component\n */\nconst NotificationHeader = ({\n unreadCount,\n variant = 'modal',\n}: {\n unreadCount: number;\n variant?: 'modal' | 'dropdown';\n}) => {\n return (\n <div className=\"flex items-center justify-between gap-2\">\n {variant === 'modal' ? (\n <Text size=\"sm\" weight=\"bold\" className=\"text-text-950\">\n Notificações\n </Text>\n ) : (\n <h3 className=\"text-sm font-semibold text-text-950\">Notificações</h3>\n )}\n {unreadCount > 0 && (\n <Badge\n variant=\"solid\"\n action=\"info\"\n size=\"small\"\n iconLeft={<BellIcon size={12} aria-hidden=\"true\" focusable=\"false\" />}\n className=\"border-0\"\n >\n {unreadCount === 1 ? '1 não lida' : `${unreadCount} não lidas`}\n </Badge>\n )}\n </div>\n );\n};\n\n/**\n * Marks a notification as read, if it is not already.\n *\n * Opening a notification is what \"viewed\" means to the sender, so every entry\n * point funnels through here: the card body and its \"Ver mais\" button, and the\n * action button inside the notification modal — in list mode and in the\n * notification center, mobile and desktop alike.\n *\n * Without this, the only path that ever reached `PATCH /notifications/:id` was\n * the \"Marcar como lida\" item in the kebab menu, so a student could read every\n * notice and still show up as \"Pendente\" on the teacher's screen.\n *\n * Lives at module level because the center renders its own modals rather than\n * delegating to `NotificationList`, and three copies of this guard is exactly\n * the kind of duplication that drifts apart.\n */\nconst markNotificationAsRead = (\n notification: Notification | null | undefined,\n onMarkAsReadById?: (id: string) => void\n) => {\n if (notification && !notification.isRead) {\n onMarkAsReadById?.(notification.id);\n }\n};\n\n/**\n * Modal that shows the full content of a notice (a notification with no entity\n * behind it).\n *\n * Rendered in three places — list mode, and the center's mobile and desktop\n * branches — which used to carry three near-identical copies of the same twenty\n * lines of `<Modal>` wiring. Keeping them apart meant every change to the notice\n * modal had to be made three times, and Sonar counted the block as duplicated.\n *\n * Closing is the caller's business (each owns its own state), so `onClose` stays\n * a prop; everything else is derived from the notification itself.\n */\nconst GlobalNotificationModal = ({\n notification,\n isOpen,\n onClose,\n onMarkAsReadById,\n emptyStateImage,\n}: {\n notification: Notification | null;\n isOpen: boolean;\n onClose: () => void;\n onMarkAsReadById?: (id: string) => void;\n emptyStateImage?: string;\n}) => (\n <Modal\n isOpen={isOpen}\n onClose={onClose}\n title={notification?.title || ''}\n variant=\"activity\"\n description={notification?.message || ''}\n image={notification?.linkImg || emptyStateImage || mockContentImage}\n actionLink={notification?.actionLink || undefined}\n actionLabel=\"Ver mais\"\n onActionClick={() => markNotificationAsRead(notification, onMarkAsReadById)}\n size=\"lg\"\n />\n);\n\n/**\n * Single notification card component\n */\nconst SingleNotificationCard = ({\n title,\n message,\n time,\n isRead,\n onMarkAsRead,\n onDelete,\n onNavigate,\n actionLabel,\n className,\n}: {\n title: string;\n message: string;\n time: string;\n isRead: boolean;\n onMarkAsRead: () => void;\n onDelete: () => void;\n onNavigate?: () => void;\n actionLabel?: string;\n className?: string;\n}) => {\n const handleMarkAsRead = (e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n if (!isRead) {\n onMarkAsRead();\n }\n };\n\n const handleDelete = (e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n onDelete();\n };\n\n const handleNavigate = (e: MouseEvent) => {\n e.stopPropagation();\n if (onNavigate) {\n onNavigate();\n }\n };\n\n return (\n <div\n className={cn(\n 'flex flex-col justify-center items-start p-4 gap-2 w-full bg-background border-b border-border-200',\n 'last:border-b-0',\n className\n )}\n >\n {/* Header with unread indicator and actions menu */}\n <div className=\"flex items-center gap-2 w-full\">\n {/* Unread indicator */}\n {!isRead && (\n <div className=\"w-[7px] h-[7px] bg-info-300 rounded-full flex-shrink-0\" />\n )}\n\n {/* Title */}\n <h3 className=\"font-bold text-sm leading-4 text-text-950 flex-grow\">\n {title}\n </h3>\n\n {/* Actions dropdown */}\n <DropdownMenu>\n <DropdownMenuTrigger\n className=\"flex-shrink-0 inline-flex items-center justify-center font-medium bg-transparent text-text-950 cursor-pointer hover:bg-info-50 w-6 h-6 rounded-lg\"\n aria-label=\"Mais opções\"\n >\n <DotsThreeVerticalIcon size={24} />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"min-w-[160px]\">\n {!isRead && (\n <DropdownMenuItem\n onClick={handleMarkAsRead}\n className=\"text-text-950\"\n >\n Marcar como lida\n </DropdownMenuItem>\n )}\n <DropdownMenuItem onClick={handleDelete} className=\"text-error-600\">\n Deletar\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n\n {/* Message */}\n <p className=\"text-sm leading-[21px] text-text-800 w-full\">{message}</p>\n\n {/* Time and action button */}\n <div className=\"flex items-center justify-between w-full\">\n <span className=\"text-sm font-medium text-text-400\">{time}</span>\n\n {onNavigate && actionLabel && (\n <button\n type=\"button\"\n onClick={handleNavigate}\n className=\"text-sm font-medium text-info-600 hover:text-info-700 cursor-pointer\"\n >\n {actionLabel}\n </button>\n )}\n </div>\n </div>\n );\n};\n\n/**\n * Notification list component for displaying grouped notifications\n */\nconst NotificationList = ({\n groupedNotifications = [],\n loading = false,\n error = null,\n onRetry,\n onMarkAsReadById,\n onDeleteById,\n onNavigateById,\n onGlobalNotificationClick,\n getActionLabel,\n renderEmpty,\n className,\n emptyStateImage,\n}: {\n groupedNotifications?: NotificationGroup[];\n loading?: boolean;\n error?: string | null;\n onRetry?: () => void;\n onMarkAsReadById?: (id: string) => void;\n onDeleteById?: (id: string) => void;\n onNavigateById?: (\n entityType?: NotificationEntityType,\n entityId?: string,\n entityStatus?: NotificationEntityStatus | null,\n questionId?: string | null\n ) => void;\n onGlobalNotificationClick?: (notification: Notification) => void;\n getActionLabel?: (entityType?: NotificationEntityType) => string | undefined;\n renderEmpty?: () => ReactNode;\n className?: string;\n emptyStateImage?: string;\n}) => {\n // State for global notification modal when onGlobalNotificationClick is not provided\n const [globalNotificationModal, setGlobalNotificationModal] = useState<{\n isOpen: boolean;\n notification: Notification | null;\n }>({ isOpen: false, notification: null });\n\n // Default handler for global notifications when onGlobalNotificationClick is not provided\n const handleGlobalNotificationClick = (notification: Notification) => {\n if (onGlobalNotificationClick) {\n onGlobalNotificationClick(notification);\n } else {\n // Open modal as fallback\n setGlobalNotificationModal({\n isOpen: true,\n notification,\n });\n }\n };\n\n const markAsReadThen = (\n notification: Notification,\n open: (notification: Notification) => void\n ) => {\n markNotificationAsRead(notification, onMarkAsReadById);\n open(notification);\n };\n // Error state\n if (error) {\n return (\n <div className=\"flex flex-col items-center gap-4 p-6 w-full\">\n <p className=\"text-sm text-error-600\">{error}</p>\n {onRetry && (\n <button\n type=\"button\"\n onClick={onRetry}\n className=\"text-sm text-info-600 hover:text-info-700\"\n >\n Tentar novamente\n </button>\n )}\n </div>\n );\n }\n\n // Loading state — only show the skeleton on the initial load (empty list).\n // Background refreshes (e.g. while the center polls) keep the list visible.\n if (loading && groupedNotifications.length === 0) {\n return (\n <div className=\"flex flex-col gap-0 w-full\">\n {['skeleton-first', 'skeleton-second', 'skeleton-third'].map(\n (skeletonId) => (\n <SkeletonCard\n key={skeletonId}\n className=\"p-4 border-b border-border-200\"\n />\n )\n )}\n </div>\n );\n }\n\n // Empty state\n if (!groupedNotifications || groupedNotifications.length === 0) {\n return renderEmpty ? (\n <div className=\"w-full\">{renderEmpty()}</div>\n ) : (\n <NotificationEmpty />\n );\n }\n\n return (\n <div className={cn('flex flex-col gap-0 w-full', className)}>\n {groupedNotifications.map((group, idx) => (\n <div key={`${group.label}-${idx}`} className=\"flex flex-col\">\n {/* Group header */}\n <div className=\"flex items-end px-4 py-6 pb-4\">\n <h4 className=\"text-lg font-bold text-text-500 flex-grow\">\n {group.label}\n </h4>\n </div>\n\n {/* Notifications in group */}\n {group.notifications.map((notification) => {\n // Check if this is a global notification\n const isGlobalNotification =\n !notification.entityType &&\n !notification.entityId &&\n !notification.activity &&\n !notification.recommendedClass;\n\n // Determine navigation handler\n let navigationHandler: (() => void) | undefined;\n if (isGlobalNotification) {\n navigationHandler = () =>\n markAsReadThen(notification, handleGlobalNotificationClick);\n } else if (\n notification.entityType &&\n notification.entityId &&\n onNavigateById\n ) {\n navigationHandler = () =>\n markAsReadThen(notification, (opened) =>\n onNavigateById(\n opened.entityType ?? undefined,\n opened.entityId ?? undefined,\n opened.entityStatus,\n opened.questionId\n )\n );\n }\n\n // Determine action label\n let actionLabel: string | undefined;\n if (isGlobalNotification) {\n // For global notifications, call getActionLabel without parameters or with null\n actionLabel = getActionLabel?.(undefined);\n } else {\n // For entity-specific notifications, pass the entityType\n actionLabel = getActionLabel?.(\n notification.entityType ?? undefined\n );\n }\n\n return (\n <SingleNotificationCard\n key={notification.id}\n title={notification.title}\n message={notification.message}\n time={\n (notification as Partial<NotificationItem>).time ??\n formatTimeAgo(new Date(notification.createdAt))\n }\n isRead={notification.isRead}\n onMarkAsRead={() => onMarkAsReadById?.(notification.id)}\n onDelete={() => onDeleteById?.(notification.id)}\n onNavigate={navigationHandler}\n actionLabel={actionLabel}\n />\n );\n })}\n </div>\n ))}\n\n {/* Global notification modal for list mode */}\n <GlobalNotificationModal\n notification={globalNotificationModal.notification}\n isOpen={globalNotificationModal.isOpen}\n onClose={() =>\n setGlobalNotificationModal({ isOpen: false, notification: null })\n }\n onMarkAsReadById={onMarkAsReadById}\n emptyStateImage={emptyStateImage}\n />\n </div>\n );\n};\n\n// Internal props type for NotificationCenter (without mode)\ntype NotificationCenterProps = Omit<NotificationCenterMode, 'mode'>;\n\n/**\n * NotificationCenter component for modal/dropdown mode\n */\nconst NotificationCenter = ({\n isActive,\n onToggleActive,\n unreadCount = 0,\n groupedNotifications = [],\n loading = false,\n error = null,\n onRetry,\n onMarkAsReadById,\n onDeleteById,\n onNavigateById,\n getActionLabel,\n onFetchNotifications,\n onMarkAllAsRead,\n onOpenChange,\n emptyStateImage,\n emptyStateTitle,\n emptyStateDescription,\n className,\n refreshIntervalMs = DEFAULT_REFRESH_INTERVAL_MS,\n}: NotificationCenterProps) => {\n const { isMobile } = useMobile();\n const [isModalOpen, setIsModalOpen] = useState(false);\n const [globalNotificationModal, setGlobalNotificationModal] = useState<{\n isOpen: boolean;\n notification: Notification | null;\n }>({ isOpen: false, notification: null });\n\n // Handle mobile click\n const handleMobileClick = () => {\n setIsModalOpen(true);\n onFetchNotifications?.();\n };\n\n // Handle desktop click\n const handleDesktopClick = () => {\n onToggleActive?.();\n };\n\n // Handle dropdown open change\n const handleOpenChange = (open: boolean) => {\n const controlledByParent =\n typeof isActive === 'boolean' && typeof onToggleActive === 'function';\n\n // Always notify parent if they want the signal.\n onOpenChange?.(open);\n\n // If parent controls via toggle only (no onOpenChange), keep them in sync on close.\n if (controlledByParent && !onOpenChange && !open && isActive) {\n onToggleActive?.();\n }\n };\n\n // Fetch notifications when dropdown opens\n useEffect(() => {\n if (isActive) {\n onFetchNotifications?.();\n }\n }, [isActive, onFetchNotifications]);\n\n // While the center is open, poll periodically so newly received notifications\n // appear without the user having to reopen it. The list is not replaced by a\n // skeleton on these background refreshes (see NotificationList loading gate).\n const isCenterOpen = isMobile ? isModalOpen : Boolean(isActive);\n useEffect(() => {\n if (!isCenterOpen || !onFetchNotifications || refreshIntervalMs <= 0) {\n return;\n }\n const intervalId = setInterval(() => {\n onFetchNotifications();\n }, refreshIntervalMs);\n return () => clearInterval(intervalId);\n }, [isCenterOpen, onFetchNotifications, refreshIntervalMs]);\n\n const renderEmptyState = () => (\n <NotificationEmpty\n emptyStateImage={emptyStateImage}\n emptyStateTitle={emptyStateTitle}\n emptyStateDescription={emptyStateDescription}\n />\n );\n\n if (isMobile) {\n return (\n <>\n <IconButton\n active={isModalOpen}\n onClick={handleMobileClick}\n aria-label={getNotificationsLabel(unreadCount)}\n // No mobile o sino abre um Modal, não um DropdownMenu, então não há\n // trigger para injetar o estado: ele é declarado aqui.\n aria-expanded={isModalOpen}\n icon={\n <Badge\n variant=\"notification\"\n notificationActive={unreadCount > 0}\n className=\"p-0\"\n />\n }\n className={className}\n />\n <Modal\n isOpen={isModalOpen}\n onClose={() => setIsModalOpen(false)}\n title=\"Notificações\"\n size=\"md\"\n hideCloseButton={false}\n closeOnEscape={true}\n >\n <div className=\"flex flex-col h-full max-h-[80vh]\">\n <div className=\"px-0 pb-3 border-b border-border-200\">\n <NotificationHeader unreadCount={unreadCount} variant=\"modal\" />\n {unreadCount > 0 && onMarkAllAsRead && (\n <button\n type=\"button\"\n onClick={onMarkAllAsRead}\n className=\"text-sm font-medium text-info-600 hover:text-info-700 cursor-pointer mt-2\"\n >\n Marcar todas como lidas\n </button>\n )}\n </div>\n <div className=\"flex-1 overflow-y-auto\">\n <NotificationList\n groupedNotifications={groupedNotifications}\n loading={loading}\n error={error}\n onRetry={onRetry}\n onMarkAsReadById={onMarkAsReadById}\n onDeleteById={onDeleteById}\n // Variadic on purpose: written out by hand, this forwarding\n // silently dropped `entityStatus` — and would drop the next\n // argument too.\n onNavigateById={(...args) => {\n setIsModalOpen(false);\n onNavigateById?.(...args);\n }}\n onGlobalNotificationClick={(notification) => {\n setIsModalOpen(false);\n setGlobalNotificationModal({\n isOpen: true,\n notification,\n });\n }}\n getActionLabel={getActionLabel}\n renderEmpty={renderEmptyState}\n emptyStateImage={emptyStateImage}\n />\n </div>\n </div>\n </Modal>\n {/* Global Notification Modal (mobile) */}\n <GlobalNotificationModal\n notification={globalNotificationModal.notification}\n isOpen={globalNotificationModal.isOpen}\n onClose={() =>\n setGlobalNotificationModal({ isOpen: false, notification: null })\n }\n onMarkAsReadById={onMarkAsReadById}\n emptyStateImage={emptyStateImage}\n />\n </>\n );\n }\n\n return (\n <>\n <DropdownMenu\n {...(typeof isActive === 'boolean'\n ? { open: isActive, onOpenChange: handleOpenChange }\n : { onOpenChange: handleOpenChange })}\n >\n <DropdownMenuTrigger className=\"text-primary cursor-pointer\" asChild>\n <IconButton\n active={isActive}\n onClick={handleDesktopClick}\n aria-label={getNotificationsLabel(unreadCount)}\n icon={\n <Badge\n variant=\"notification\"\n notificationActive={unreadCount > 0}\n className={cn('p-0', isActive && 'text-primary-950!')}\n />\n }\n className={className}\n />\n </DropdownMenuTrigger>\n <DropdownMenuContent\n className=\"min-w-[320px] max-w-[400px] max-h-[500px] overflow-hidden\"\n side=\"bottom\"\n align=\"end\"\n >\n <div className=\"flex flex-col\">\n <div className=\"px-4 py-3 border-b border-border-200\">\n <NotificationHeader\n unreadCount={unreadCount}\n variant=\"dropdown\"\n />\n {unreadCount > 0 && onMarkAllAsRead && (\n <button\n type=\"button\"\n onClick={onMarkAllAsRead}\n className=\"text-sm font-medium text-info-600 hover:text-info-700 cursor-pointer mt-2\"\n >\n Marcar todas como lidas\n </button>\n )}\n </div>\n <div className=\"max-h-[350px] overflow-y-auto\">\n <NotificationList\n groupedNotifications={groupedNotifications}\n loading={loading}\n error={error}\n onRetry={onRetry}\n onMarkAsReadById={onMarkAsReadById}\n onDeleteById={onDeleteById}\n onNavigateById={onNavigateById}\n onGlobalNotificationClick={(notification) => {\n setGlobalNotificationModal({\n isOpen: true,\n notification,\n });\n }}\n getActionLabel={getActionLabel}\n renderEmpty={renderEmptyState}\n emptyStateImage={emptyStateImage}\n />\n </div>\n </div>\n </DropdownMenuContent>\n </DropdownMenu>\n\n {/* Global Notification Modal */}\n <GlobalNotificationModal\n notification={globalNotificationModal.notification}\n isOpen={globalNotificationModal.isOpen}\n onClose={() =>\n setGlobalNotificationModal({ isOpen: false, notification: null })\n }\n onMarkAsReadById={onMarkAsReadById}\n emptyStateImage={emptyStateImage}\n />\n </>\n );\n};\n\n/**\n * NotificationCard component - can display single notification, list of notifications, or center mode\n *\n * @param props - The notification card properties\n * @returns JSX element representing the notification card, list, or center\n */\nconst NotificationCard = (props: NotificationCardProps) => {\n // Use mode discriminator to determine which component to render\n switch (props.mode) {\n case 'single':\n return (\n <SingleNotificationCard\n title={props.title}\n message={props.message}\n time={props.time}\n isRead={props.isRead}\n onMarkAsRead={props.onMarkAsRead}\n onDelete={props.onDelete}\n onNavigate={props.onNavigate}\n actionLabel={props.actionLabel}\n className={props.className}\n />\n );\n\n case 'list':\n return (\n <NotificationList\n groupedNotifications={\n props.groupedNotifications ??\n (props.notifications\n ? [\n {\n label: 'Notificações',\n notifications: props.notifications as Notification[],\n },\n ]\n : [])\n }\n loading={props.loading}\n error={props.error}\n onRetry={props.onRetry}\n onMarkAsReadById={props.onMarkAsReadById}\n onDeleteById={props.onDeleteById}\n onNavigateById={props.onNavigateById}\n onGlobalNotificationClick={props.onGlobalNotificationClick}\n getActionLabel={props.getActionLabel}\n renderEmpty={props.renderEmpty}\n className={props.className}\n emptyStateImage={props.emptyStateImage}\n />\n );\n\n case 'center':\n return <NotificationCenter {...props} />;\n\n default:\n // This should never happen with proper typing, but provides a fallback\n return (\n <div className=\"flex flex-col items-center gap-4 p-6 w-full\">\n <p className=\"text-sm text-text-600\">\n Modo de notificação não reconhecido\n </p>\n </div>\n );\n }\n};\n\n/**\n * Legacy NotificationCard component for backward compatibility\n * Automatically detects mode based on provided props\n */\nexport const LegacyNotificationCard = (props: LegacyNotificationCardProps) => {\n // If variant is center, render NotificationCenter\n if (props.variant === 'center') {\n const centerProps: NotificationCenterMode = {\n mode: 'center',\n ...props,\n };\n return <NotificationCenter {...centerProps} />;\n }\n\n // If we have list-related props, render list mode\n if (\n props.groupedNotifications !== undefined ||\n props.notifications !== undefined ||\n props.loading ||\n props.error\n ) {\n return (\n <NotificationList\n groupedNotifications={\n props.groupedNotifications ??\n (props.notifications\n ? [\n {\n label: 'Notificações',\n notifications: props.notifications as Notification[],\n },\n ]\n : [])\n }\n loading={props.loading}\n error={props.error}\n onRetry={props.onRetry}\n onMarkAsReadById={props.onMarkAsReadById}\n onDeleteById={props.onDeleteById}\n onNavigateById={props.onNavigateById}\n onGlobalNotificationClick={props.onGlobalNotificationClick}\n getActionLabel={props.getActionLabel}\n renderEmpty={props.renderEmpty}\n className={props.className}\n emptyStateImage={props.emptyStateImage}\n />\n );\n }\n\n // If we have single notification props, render single card mode\n if (\n props.title !== undefined &&\n props.message !== undefined &&\n props.time !== undefined &&\n props.isRead !== undefined &&\n props.onMarkAsRead &&\n props.onDelete\n ) {\n const singleProps: SingleNotificationCardMode = {\n mode: 'single',\n title: props.title,\n message: props.message,\n time: props.time,\n isRead: props.isRead,\n onMarkAsRead: props.onMarkAsRead,\n onDelete: props.onDelete,\n onNavigate: props.onNavigate,\n actionLabel: props.actionLabel,\n className: props.className,\n emptyStateImage: props.emptyStateImage,\n emptyStateTitle: props.emptyStateTitle,\n emptyStateDescription: props.emptyStateDescription,\n };\n return (\n <SingleNotificationCard\n title={singleProps.title}\n message={singleProps.message}\n time={singleProps.time}\n isRead={singleProps.isRead}\n onMarkAsRead={singleProps.onMarkAsRead}\n onDelete={singleProps.onDelete}\n onNavigate={singleProps.onNavigate}\n actionLabel={singleProps.actionLabel}\n className={singleProps.className}\n />\n );\n }\n\n // Default empty state if no valid props provided\n return (\n <div className=\"flex flex-col items-center gap-4 p-6 w-full\">\n <p className=\"text-sm text-text-600\">Nenhuma notificação configurada</p>\n </div>\n );\n};\n\nexport default NotificationCard;\nexport type { NotificationGroup };\n"]}
1
+ {"version":3,"sources":["/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-CW3FCWR4.js","../src/components/NotificationCard/NotificationCard.tsx"],"names":[],"mappings":"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","file":"/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-CW3FCWR4.js","sourcesContent":[null,"import { DotsThreeVerticalIcon } from '@phosphor-icons/react/dist/csr/DotsThreeVertical';\nimport { BellIcon } from '@phosphor-icons/react/dist/csr/Bell';\nimport { MouseEvent, ReactNode, useState, useEffect } from 'react';\nimport { cn } from '../../utils/utils';\nimport DropdownMenu, {\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '../DropdownMenu/DropdownMenu';\nimport { SkeletonCard } from '../Skeleton/Skeleton';\nimport IconButton from '../IconButton/IconButton';\nimport Modal from '../Modal/Modal';\nimport Text from '../Text/Text';\nimport Badge from '../Badge/Badge';\nimport { useMobile } from '../../hooks/useMobile';\nimport type {\n Notification,\n NotificationGroup,\n NotificationEntityType,\n NotificationEntityStatus,\n} from '../../types/notifications';\nimport { formatTimeAgo } from '../../store/notificationStore';\nimport mockContentImage from '../../assets/img/mock-content.png';\n\n/**\n * Default interval (in ms) to auto-refresh the notification center while it is\n * open, so newly received notifications appear without reopening it.\n */\nconst DEFAULT_REFRESH_INTERVAL_MS = 3000;\n\n/**\n * Nome acessível do sino.\n *\n * O botão era só um ícone com um `sr-only` dentro, e esse texto só existia\n * quando havia não lidas: sem notificação nenhuma o botão ficava sem nome, e o\n * leitor de tela anunciava apenas \"botão\". A contagem entra no próprio rótulo\n * para que o estado seja dito junto com o nome, em vez de depender de um texto\n * que aparece e some.\n */\nconst getNotificationsLabel = (unreadCount: number) => {\n if (unreadCount <= 0) {\n return 'Notificações, sem notificações';\n }\n\n const plural = unreadCount === 1 ? 'notificação' : 'notificações';\n return `Notificações, ${unreadCount} ${plural}`;\n};\n\n// Extended notification item for component usage with time string\nexport interface NotificationItem extends Omit<Notification, 'createdAt'> {\n time: string;\n createdAt: string | Date;\n}\n\n// Base props shared across all modes\ninterface BaseNotificationProps {\n /**\n * Additional CSS classes\n */\n className?: string;\n /**\n * Empty state image path\n */\n emptyStateImage?: string;\n /**\n * Empty state title\n */\n emptyStateTitle?: string;\n /**\n * Empty state description\n */\n emptyStateDescription?: string;\n}\n\n// Single notification card mode\ninterface SingleNotificationCardMode extends BaseNotificationProps {\n /**\n * Component mode - single card\n */\n mode: 'single';\n /**\n * The notification title\n */\n title: string;\n /**\n * The notification message content\n */\n message: string;\n /**\n * Time displayed (e.g., \"Há 3h\", \"12 Fev\")\n */\n time: string;\n /**\n * Whether the notification has been read\n */\n isRead: boolean;\n /**\n * Callback when user marks notification as read\n */\n onMarkAsRead: () => void;\n /**\n * Callback when user deletes notification\n */\n onDelete: () => void;\n /**\n * Optional callback for navigation action\n */\n onNavigate?: () => void;\n /**\n * Label for the action button (only shown if onNavigate is provided)\n */\n actionLabel?: string;\n}\n\n// List mode\ninterface NotificationListMode extends BaseNotificationProps {\n /**\n * Component mode - list\n */\n mode: 'list';\n /**\n * Array of notifications for list mode\n */\n notifications?: NotificationItem[];\n /**\n * Array of grouped notifications\n */\n groupedNotifications?: NotificationGroup[];\n /**\n * Loading state for list mode\n */\n loading?: boolean;\n /**\n * Error state for list mode\n */\n error?: string | null;\n /**\n * Callback for retry when error occurs\n */\n onRetry?: () => void;\n /**\n * Callback when user marks a notification as read in list mode\n */\n onMarkAsReadById?: (id: string) => void;\n /**\n * Callback when user deletes a notification in list mode\n */\n onDeleteById?: (id: string) => void;\n /**\n * Callback when user navigates from a notification in list mode\n */\n onNavigateById?: (\n entityType?: NotificationEntityType,\n entityId?: string,\n entityStatus?: NotificationEntityStatus | null,\n questionId?: string | null\n ) => void;\n /**\n * Callback when user clicks on a global notification\n */\n onGlobalNotificationClick?: (notification: Notification) => void;\n /**\n * Function to get action label for a notification\n */\n getActionLabel?: (entityType?: NotificationEntityType) => string | undefined;\n /**\n * Custom empty state component\n */\n renderEmpty?: () => ReactNode;\n}\n\n// NotificationCenter mode\ninterface NotificationCenterMode extends BaseNotificationProps {\n /**\n * Component mode - center\n */\n mode: 'center';\n /**\n * Array of grouped notifications\n */\n groupedNotifications?: NotificationGroup[];\n /**\n * Loading state for center mode\n */\n loading?: boolean;\n /**\n * Error state for center mode\n */\n error?: string | null;\n /**\n * Callback for retry when error occurs\n */\n onRetry?: () => void;\n /**\n * Whether center mode is currently active (controls dropdown/modal visibility)\n */\n isActive?: boolean;\n /**\n * Callback when center mode is toggled\n */\n onToggleActive?: () => void;\n /**\n * Number of unread notifications for badge display\n */\n unreadCount?: number;\n /**\n * Callback when all notifications should be marked as read\n */\n onMarkAllAsRead?: () => void;\n /**\n * Callback to fetch notifications (called when center opens)\n */\n onFetchNotifications?: () => void;\n /**\n * Callback when user marks a notification as read in center mode\n */\n onMarkAsReadById?: (id: string) => void;\n /**\n * Callback when user deletes a notification in center mode\n */\n onDeleteById?: (id: string) => void;\n /**\n * Callback when user navigates from a notification in center mode\n */\n onNavigateById?: (\n entityType?: NotificationEntityType,\n entityId?: string,\n entityStatus?: NotificationEntityStatus | null,\n questionId?: string | null\n ) => void;\n /**\n * Function to get action label for a notification\n */\n getActionLabel?: (entityType?: NotificationEntityType) => string | undefined;\n /**\n * Callback when dropdown open state changes (for synchronization with parent)\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * Interval (in ms) to auto-refresh the list while the center is open, so newly\n * received notifications appear without reopening it. Defaults to 3000 (3s).\n * Set to 0 to disable polling.\n */\n refreshIntervalMs?: number;\n}\n\n// Union type for all modes\nexport type NotificationCardProps =\n | SingleNotificationCardMode\n | NotificationListMode\n | NotificationCenterMode;\n\n// Legacy interface for backward compatibility\nexport interface LegacyNotificationCardProps extends BaseNotificationProps {\n // Single notification mode props\n title?: string;\n message?: string;\n time?: string;\n isRead?: boolean;\n onMarkAsRead?: () => void;\n onDelete?: () => void;\n onNavigate?: () => void;\n actionLabel?: string;\n\n // List mode props\n notifications?: NotificationItem[];\n groupedNotifications?: NotificationGroup[];\n loading?: boolean;\n error?: string | null;\n onRetry?: () => void;\n onMarkAsReadById?: (id: string) => void;\n onDeleteById?: (id: string) => void;\n onNavigateById?: (\n entityType?: NotificationEntityType,\n entityId?: string,\n entityStatus?: NotificationEntityStatus | null,\n questionId?: string | null\n ) => void;\n onGlobalNotificationClick?: (notification: Notification) => void;\n getActionLabel?: (entityType?: NotificationEntityType) => string | undefined;\n renderEmpty?: () => ReactNode;\n\n // NotificationCenter mode props\n variant?: 'card' | 'center';\n isActive?: boolean;\n onToggleActive?: () => void;\n unreadCount?: number;\n onMarkAllAsRead?: () => void;\n onFetchNotifications?: () => void;\n onOpenChange?: (open: boolean) => void;\n}\n\n/**\n * Empty state component for notifications\n */\nconst NotificationEmpty = ({\n emptyStateImage,\n emptyStateTitle = 'Nenhuma notificação no momento',\n emptyStateDescription = 'Você está em dia com todas as novidades. Volte depois para conferir atualizações!',\n}: {\n emptyStateImage?: string;\n emptyStateTitle?: string;\n emptyStateDescription?: string;\n}) => {\n return (\n <div className=\"flex flex-col items-center justify-center gap-4 p-6 w-full\">\n {/* Notification Icon */}\n {emptyStateImage && (\n <div className=\"w-20 h-20 flex items-center justify-center\">\n <img\n src={emptyStateImage}\n alt=\"Sem notificações\"\n width={82}\n height={82}\n className=\"object-contain\"\n />\n </div>\n )}\n\n {/* Title */}\n <h3 className=\"text-xl font-semibold text-text-950 text-center leading-[23px]\">\n {emptyStateTitle}\n </h3>\n\n {/* Description */}\n <p className=\"text-sm font-normal text-text-400 text-center max-w-[316px] leading-[21px]\">\n {emptyStateDescription}\n </p>\n </div>\n );\n};\n\n/**\n * Notification header component\n */\nconst NotificationHeader = ({\n unreadCount,\n variant = 'modal',\n}: {\n unreadCount: number;\n variant?: 'modal' | 'dropdown';\n}) => {\n return (\n <div className=\"flex items-center justify-between gap-2\">\n {variant === 'modal' ? (\n <Text size=\"sm\" weight=\"bold\" className=\"text-text-950\">\n Notificações\n </Text>\n ) : (\n <h3 className=\"text-sm font-semibold text-text-950\">Notificações</h3>\n )}\n {unreadCount > 0 && (\n <Badge\n variant=\"solid\"\n action=\"info\"\n size=\"small\"\n iconLeft={<BellIcon size={12} aria-hidden=\"true\" focusable=\"false\" />}\n className=\"border-0\"\n >\n {unreadCount === 1 ? '1 não lida' : `${unreadCount} não lidas`}\n </Badge>\n )}\n </div>\n );\n};\n\n/**\n * Marks a notification as read, if it is not already.\n *\n * Opening a notification is what \"viewed\" means to the sender, so every entry\n * point funnels through here: the card body and its \"Ver mais\" button, and the\n * action button inside the notification modal — in list mode and in the\n * notification center, mobile and desktop alike.\n *\n * Without this, the only path that ever reached `PATCH /notifications/:id` was\n * the \"Marcar como lida\" item in the kebab menu, so a student could read every\n * notice and still show up as \"Pendente\" on the teacher's screen.\n *\n * Lives at module level because the center renders its own modals rather than\n * delegating to `NotificationList`, and three copies of this guard is exactly\n * the kind of duplication that drifts apart.\n */\nconst markNotificationAsRead = (\n notification: Notification | null | undefined,\n onMarkAsReadById?: (id: string) => void\n) => {\n if (notification && !notification.isRead) {\n onMarkAsReadById?.(notification.id);\n }\n};\n\n/**\n * Modal that shows the full content of a notice (a notification with no entity\n * behind it).\n *\n * Rendered in three places — list mode, and the center's mobile and desktop\n * branches — which used to carry three near-identical copies of the same twenty\n * lines of `<Modal>` wiring. Keeping them apart meant every change to the notice\n * modal had to be made three times, and Sonar counted the block as duplicated.\n *\n * Closing is the caller's business (each owns its own state), so `onClose` stays\n * a prop; everything else is derived from the notification itself.\n */\nconst GlobalNotificationModal = ({\n notification,\n isOpen,\n onClose,\n onMarkAsReadById,\n emptyStateImage,\n}: {\n notification: Notification | null;\n isOpen: boolean;\n onClose: () => void;\n onMarkAsReadById?: (id: string) => void;\n emptyStateImage?: string;\n}) => (\n <Modal\n isOpen={isOpen}\n onClose={onClose}\n title={notification?.title || ''}\n variant=\"activity\"\n description={notification?.message || ''}\n image={notification?.linkImg || emptyStateImage || mockContentImage}\n actionLink={notification?.actionLink || undefined}\n actionLabel=\"Ver mais\"\n onActionClick={() => markNotificationAsRead(notification, onMarkAsReadById)}\n size=\"lg\"\n />\n);\n\n/**\n * Single notification card component\n */\nconst SingleNotificationCard = ({\n title,\n message,\n time,\n isRead,\n onMarkAsRead,\n onDelete,\n onNavigate,\n actionLabel,\n className,\n}: {\n title: string;\n message: string;\n time: string;\n isRead: boolean;\n onMarkAsRead: () => void;\n onDelete: () => void;\n onNavigate?: () => void;\n actionLabel?: string;\n className?: string;\n}) => {\n const handleMarkAsRead = (e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n if (!isRead) {\n onMarkAsRead();\n }\n };\n\n const handleDelete = (e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n onDelete();\n };\n\n const handleNavigate = (e: MouseEvent) => {\n e.stopPropagation();\n if (onNavigate) {\n onNavigate();\n }\n };\n\n return (\n <div\n className={cn(\n 'flex flex-col justify-center items-start p-4 gap-2 w-full bg-background border-b border-border-200',\n 'last:border-b-0',\n className\n )}\n >\n {/* Header with unread indicator and actions menu */}\n <div className=\"flex items-center gap-2 w-full\">\n {/* Unread indicator */}\n {!isRead && (\n <div className=\"w-[7px] h-[7px] bg-info-300 rounded-full flex-shrink-0\" />\n )}\n\n {/* Title */}\n <h3 className=\"font-bold text-sm leading-4 text-text-950 flex-grow\">\n {title}\n </h3>\n\n {/* Actions dropdown */}\n <DropdownMenu>\n <DropdownMenuTrigger\n className=\"flex-shrink-0 inline-flex items-center justify-center font-medium bg-transparent text-text-950 cursor-pointer hover:bg-info-50 w-6 h-6 rounded-lg\"\n aria-label=\"Mais opções\"\n >\n <DotsThreeVerticalIcon size={24} />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"min-w-[160px]\">\n {!isRead && (\n <DropdownMenuItem\n onClick={handleMarkAsRead}\n className=\"text-text-950\"\n >\n Marcar como lida\n </DropdownMenuItem>\n )}\n <DropdownMenuItem onClick={handleDelete} className=\"text-error-600\">\n Deletar\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n\n {/* Message */}\n <p className=\"text-sm leading-[21px] text-text-800 w-full\">{message}</p>\n\n {/* Time and action button */}\n <div className=\"flex items-center justify-between w-full\">\n <span className=\"text-sm font-medium text-text-400\">{time}</span>\n\n {onNavigate && actionLabel && (\n <button\n type=\"button\"\n onClick={handleNavigate}\n className=\"text-sm font-medium text-info-600 hover:text-info-700 cursor-pointer\"\n >\n {actionLabel}\n </button>\n )}\n </div>\n </div>\n );\n};\n\n/**\n * Notification list component for displaying grouped notifications\n */\nconst NotificationList = ({\n groupedNotifications = [],\n loading = false,\n error = null,\n onRetry,\n onMarkAsReadById,\n onDeleteById,\n onNavigateById,\n onGlobalNotificationClick,\n getActionLabel,\n renderEmpty,\n className,\n emptyStateImage,\n}: {\n groupedNotifications?: NotificationGroup[];\n loading?: boolean;\n error?: string | null;\n onRetry?: () => void;\n onMarkAsReadById?: (id: string) => void;\n onDeleteById?: (id: string) => void;\n onNavigateById?: (\n entityType?: NotificationEntityType,\n entityId?: string,\n entityStatus?: NotificationEntityStatus | null,\n questionId?: string | null\n ) => void;\n onGlobalNotificationClick?: (notification: Notification) => void;\n getActionLabel?: (entityType?: NotificationEntityType) => string | undefined;\n renderEmpty?: () => ReactNode;\n className?: string;\n emptyStateImage?: string;\n}) => {\n // State for global notification modal when onGlobalNotificationClick is not provided\n const [globalNotificationModal, setGlobalNotificationModal] = useState<{\n isOpen: boolean;\n notification: Notification | null;\n }>({ isOpen: false, notification: null });\n\n // Default handler for global notifications when onGlobalNotificationClick is not provided\n const handleGlobalNotificationClick = (notification: Notification) => {\n if (onGlobalNotificationClick) {\n onGlobalNotificationClick(notification);\n } else {\n // Open modal as fallback\n setGlobalNotificationModal({\n isOpen: true,\n notification,\n });\n }\n };\n\n const markAsReadThen = (\n notification: Notification,\n open: (notification: Notification) => void\n ) => {\n markNotificationAsRead(notification, onMarkAsReadById);\n open(notification);\n };\n // Error state\n if (error) {\n return (\n <div className=\"flex flex-col items-center gap-4 p-6 w-full\">\n <p className=\"text-sm text-error-600\">{error}</p>\n {onRetry && (\n <button\n type=\"button\"\n onClick={onRetry}\n className=\"text-sm text-info-600 hover:text-info-700\"\n >\n Tentar novamente\n </button>\n )}\n </div>\n );\n }\n\n // Loading state — only show the skeleton on the initial load (empty list).\n // Background refreshes (e.g. while the center polls) keep the list visible.\n if (loading && groupedNotifications.length === 0) {\n return (\n <div className=\"flex flex-col gap-0 w-full\">\n {['skeleton-first', 'skeleton-second', 'skeleton-third'].map(\n (skeletonId) => (\n <SkeletonCard\n key={skeletonId}\n className=\"p-4 border-b border-border-200\"\n />\n )\n )}\n </div>\n );\n }\n\n // Empty state\n if (!groupedNotifications || groupedNotifications.length === 0) {\n return renderEmpty ? (\n <div className=\"w-full\">{renderEmpty()}</div>\n ) : (\n <NotificationEmpty />\n );\n }\n\n return (\n <div className={cn('flex flex-col gap-0 w-full', className)}>\n {groupedNotifications.map((group, idx) => (\n <div key={`${group.label}-${idx}`} className=\"flex flex-col\">\n {/* Group header */}\n <div className=\"flex items-end px-4 py-6 pb-4\">\n <h4 className=\"text-lg font-bold text-text-500 flex-grow\">\n {group.label}\n </h4>\n </div>\n\n {/* Notifications in group */}\n {group.notifications.map((notification) => {\n // Check if this is a global notification\n const isGlobalNotification =\n !notification.entityType &&\n !notification.entityId &&\n !notification.activity &&\n !notification.recommendedClass;\n\n // Determine navigation handler\n let navigationHandler: (() => void) | undefined;\n if (isGlobalNotification) {\n navigationHandler = () =>\n markAsReadThen(notification, handleGlobalNotificationClick);\n } else if (\n notification.entityType &&\n notification.entityId &&\n onNavigateById\n ) {\n navigationHandler = () =>\n markAsReadThen(notification, (opened) =>\n onNavigateById(\n opened.entityType ?? undefined,\n opened.entityId ?? undefined,\n opened.entityStatus,\n opened.questionId\n )\n );\n }\n\n // Determine action label\n let actionLabel: string | undefined;\n if (isGlobalNotification) {\n // For global notifications, call getActionLabel without parameters or with null\n actionLabel = getActionLabel?.(undefined);\n } else {\n // For entity-specific notifications, pass the entityType\n actionLabel = getActionLabel?.(\n notification.entityType ?? undefined\n );\n }\n\n return (\n <SingleNotificationCard\n key={notification.id}\n title={notification.title}\n message={notification.message}\n time={\n (notification as Partial<NotificationItem>).time ??\n formatTimeAgo(new Date(notification.createdAt))\n }\n isRead={notification.isRead}\n onMarkAsRead={() => onMarkAsReadById?.(notification.id)}\n onDelete={() => onDeleteById?.(notification.id)}\n onNavigate={navigationHandler}\n actionLabel={actionLabel}\n />\n );\n })}\n </div>\n ))}\n\n {/* Global notification modal for list mode */}\n <GlobalNotificationModal\n notification={globalNotificationModal.notification}\n isOpen={globalNotificationModal.isOpen}\n onClose={() =>\n setGlobalNotificationModal({ isOpen: false, notification: null })\n }\n onMarkAsReadById={onMarkAsReadById}\n emptyStateImage={emptyStateImage}\n />\n </div>\n );\n};\n\n// Internal props type for NotificationCenter (without mode)\ntype NotificationCenterProps = Omit<NotificationCenterMode, 'mode'>;\n\n/**\n * NotificationCenter component for modal/dropdown mode\n */\nconst NotificationCenter = ({\n isActive,\n onToggleActive,\n unreadCount = 0,\n groupedNotifications = [],\n loading = false,\n error = null,\n onRetry,\n onMarkAsReadById,\n onDeleteById,\n onNavigateById,\n getActionLabel,\n onFetchNotifications,\n onMarkAllAsRead,\n onOpenChange,\n emptyStateImage,\n emptyStateTitle,\n emptyStateDescription,\n className,\n refreshIntervalMs = DEFAULT_REFRESH_INTERVAL_MS,\n}: NotificationCenterProps) => {\n const { isMobile } = useMobile();\n const [isModalOpen, setIsModalOpen] = useState(false);\n const [globalNotificationModal, setGlobalNotificationModal] = useState<{\n isOpen: boolean;\n notification: Notification | null;\n }>({ isOpen: false, notification: null });\n\n // Handle mobile click\n const handleMobileClick = () => {\n setIsModalOpen(true);\n onFetchNotifications?.();\n };\n\n // Handle desktop click\n const handleDesktopClick = () => {\n onToggleActive?.();\n };\n\n // Handle dropdown open change\n const handleOpenChange = (open: boolean) => {\n const controlledByParent =\n typeof isActive === 'boolean' && typeof onToggleActive === 'function';\n\n // Always notify parent if they want the signal.\n onOpenChange?.(open);\n\n // If parent controls via toggle only (no onOpenChange), keep them in sync on close.\n if (controlledByParent && !onOpenChange && !open && isActive) {\n onToggleActive?.();\n }\n };\n\n // Fetch notifications when dropdown opens\n useEffect(() => {\n if (isActive) {\n onFetchNotifications?.();\n }\n }, [isActive, onFetchNotifications]);\n\n // While the center is open, poll periodically so newly received notifications\n // appear without the user having to reopen it. The list is not replaced by a\n // skeleton on these background refreshes (see NotificationList loading gate).\n const isCenterOpen = isMobile ? isModalOpen : Boolean(isActive);\n useEffect(() => {\n if (!isCenterOpen || !onFetchNotifications || refreshIntervalMs <= 0) {\n return;\n }\n const intervalId = setInterval(() => {\n onFetchNotifications();\n }, refreshIntervalMs);\n return () => clearInterval(intervalId);\n }, [isCenterOpen, onFetchNotifications, refreshIntervalMs]);\n\n const renderEmptyState = () => (\n <NotificationEmpty\n emptyStateImage={emptyStateImage}\n emptyStateTitle={emptyStateTitle}\n emptyStateDescription={emptyStateDescription}\n />\n );\n\n if (isMobile) {\n return (\n <>\n <IconButton\n active={isModalOpen}\n onClick={handleMobileClick}\n aria-label={getNotificationsLabel(unreadCount)}\n // No mobile o sino abre um Modal, não um DropdownMenu, então não há\n // trigger para injetar o estado: ele é declarado aqui.\n aria-expanded={isModalOpen}\n icon={\n <Badge\n variant=\"notification\"\n notificationActive={unreadCount > 0}\n className=\"p-0\"\n />\n }\n className={className}\n />\n <Modal\n isOpen={isModalOpen}\n onClose={() => setIsModalOpen(false)}\n title=\"Notificações\"\n size=\"md\"\n hideCloseButton={false}\n closeOnEscape={true}\n >\n <div className=\"flex flex-col h-full max-h-[80vh]\">\n <div className=\"px-0 pb-3 border-b border-border-200\">\n <NotificationHeader unreadCount={unreadCount} variant=\"modal\" />\n {unreadCount > 0 && onMarkAllAsRead && (\n <button\n type=\"button\"\n onClick={onMarkAllAsRead}\n className=\"text-sm font-medium text-info-600 hover:text-info-700 cursor-pointer mt-2\"\n >\n Marcar todas como lidas\n </button>\n )}\n </div>\n <div className=\"flex-1 overflow-y-auto\">\n <NotificationList\n groupedNotifications={groupedNotifications}\n loading={loading}\n error={error}\n onRetry={onRetry}\n onMarkAsReadById={onMarkAsReadById}\n onDeleteById={onDeleteById}\n // Variadic on purpose: written out by hand, this forwarding\n // silently dropped `entityStatus` — and would drop the next\n // argument too.\n onNavigateById={(...args) => {\n setIsModalOpen(false);\n onNavigateById?.(...args);\n }}\n onGlobalNotificationClick={(notification) => {\n setIsModalOpen(false);\n setGlobalNotificationModal({\n isOpen: true,\n notification,\n });\n }}\n getActionLabel={getActionLabel}\n renderEmpty={renderEmptyState}\n emptyStateImage={emptyStateImage}\n />\n </div>\n </div>\n </Modal>\n {/* Global Notification Modal (mobile) */}\n <GlobalNotificationModal\n notification={globalNotificationModal.notification}\n isOpen={globalNotificationModal.isOpen}\n onClose={() =>\n setGlobalNotificationModal({ isOpen: false, notification: null })\n }\n onMarkAsReadById={onMarkAsReadById}\n emptyStateImage={emptyStateImage}\n />\n </>\n );\n }\n\n return (\n <>\n <DropdownMenu\n {...(typeof isActive === 'boolean'\n ? { open: isActive, onOpenChange: handleOpenChange }\n : { onOpenChange: handleOpenChange })}\n >\n <DropdownMenuTrigger className=\"text-primary cursor-pointer\" asChild>\n <IconButton\n active={isActive}\n onClick={handleDesktopClick}\n aria-label={getNotificationsLabel(unreadCount)}\n icon={\n <Badge\n variant=\"notification\"\n notificationActive={unreadCount > 0}\n className={cn('p-0', isActive && 'text-primary-950!')}\n />\n }\n className={className}\n />\n </DropdownMenuTrigger>\n <DropdownMenuContent\n className=\"min-w-[320px] max-w-[400px] max-h-[500px] overflow-hidden\"\n side=\"bottom\"\n align=\"end\"\n >\n <div className=\"flex flex-col\">\n <div className=\"px-4 py-3 border-b border-border-200\">\n <NotificationHeader\n unreadCount={unreadCount}\n variant=\"dropdown\"\n />\n {unreadCount > 0 && onMarkAllAsRead && (\n <button\n type=\"button\"\n onClick={onMarkAllAsRead}\n className=\"text-sm font-medium text-info-600 hover:text-info-700 cursor-pointer mt-2\"\n >\n Marcar todas como lidas\n </button>\n )}\n </div>\n <div className=\"max-h-[350px] overflow-y-auto\">\n <NotificationList\n groupedNotifications={groupedNotifications}\n loading={loading}\n error={error}\n onRetry={onRetry}\n onMarkAsReadById={onMarkAsReadById}\n onDeleteById={onDeleteById}\n onNavigateById={onNavigateById}\n onGlobalNotificationClick={(notification) => {\n setGlobalNotificationModal({\n isOpen: true,\n notification,\n });\n }}\n getActionLabel={getActionLabel}\n renderEmpty={renderEmptyState}\n emptyStateImage={emptyStateImage}\n />\n </div>\n </div>\n </DropdownMenuContent>\n </DropdownMenu>\n\n {/* Global Notification Modal */}\n <GlobalNotificationModal\n notification={globalNotificationModal.notification}\n isOpen={globalNotificationModal.isOpen}\n onClose={() =>\n setGlobalNotificationModal({ isOpen: false, notification: null })\n }\n onMarkAsReadById={onMarkAsReadById}\n emptyStateImage={emptyStateImage}\n />\n </>\n );\n};\n\n/**\n * NotificationCard component - can display single notification, list of notifications, or center mode\n *\n * @param props - The notification card properties\n * @returns JSX element representing the notification card, list, or center\n */\nconst NotificationCard = (props: NotificationCardProps) => {\n // Use mode discriminator to determine which component to render\n switch (props.mode) {\n case 'single':\n return (\n <SingleNotificationCard\n title={props.title}\n message={props.message}\n time={props.time}\n isRead={props.isRead}\n onMarkAsRead={props.onMarkAsRead}\n onDelete={props.onDelete}\n onNavigate={props.onNavigate}\n actionLabel={props.actionLabel}\n className={props.className}\n />\n );\n\n case 'list':\n return (\n <NotificationList\n groupedNotifications={\n props.groupedNotifications ??\n (props.notifications\n ? [\n {\n label: 'Notificações',\n notifications: props.notifications as Notification[],\n },\n ]\n : [])\n }\n loading={props.loading}\n error={props.error}\n onRetry={props.onRetry}\n onMarkAsReadById={props.onMarkAsReadById}\n onDeleteById={props.onDeleteById}\n onNavigateById={props.onNavigateById}\n onGlobalNotificationClick={props.onGlobalNotificationClick}\n getActionLabel={props.getActionLabel}\n renderEmpty={props.renderEmpty}\n className={props.className}\n emptyStateImage={props.emptyStateImage}\n />\n );\n\n case 'center':\n return <NotificationCenter {...props} />;\n\n default:\n // This should never happen with proper typing, but provides a fallback\n return (\n <div className=\"flex flex-col items-center gap-4 p-6 w-full\">\n <p className=\"text-sm text-text-600\">\n Modo de notificação não reconhecido\n </p>\n </div>\n );\n }\n};\n\n/**\n * Legacy NotificationCard component for backward compatibility\n * Automatically detects mode based on provided props\n */\nexport const LegacyNotificationCard = (props: LegacyNotificationCardProps) => {\n // If variant is center, render NotificationCenter\n if (props.variant === 'center') {\n const centerProps: NotificationCenterMode = {\n mode: 'center',\n ...props,\n };\n return <NotificationCenter {...centerProps} />;\n }\n\n // If we have list-related props, render list mode\n if (\n props.groupedNotifications !== undefined ||\n props.notifications !== undefined ||\n props.loading ||\n props.error\n ) {\n return (\n <NotificationList\n groupedNotifications={\n props.groupedNotifications ??\n (props.notifications\n ? [\n {\n label: 'Notificações',\n notifications: props.notifications as Notification[],\n },\n ]\n : [])\n }\n loading={props.loading}\n error={props.error}\n onRetry={props.onRetry}\n onMarkAsReadById={props.onMarkAsReadById}\n onDeleteById={props.onDeleteById}\n onNavigateById={props.onNavigateById}\n onGlobalNotificationClick={props.onGlobalNotificationClick}\n getActionLabel={props.getActionLabel}\n renderEmpty={props.renderEmpty}\n className={props.className}\n emptyStateImage={props.emptyStateImage}\n />\n );\n }\n\n // If we have single notification props, render single card mode\n if (\n props.title !== undefined &&\n props.message !== undefined &&\n props.time !== undefined &&\n props.isRead !== undefined &&\n props.onMarkAsRead &&\n props.onDelete\n ) {\n const singleProps: SingleNotificationCardMode = {\n mode: 'single',\n title: props.title,\n message: props.message,\n time: props.time,\n isRead: props.isRead,\n onMarkAsRead: props.onMarkAsRead,\n onDelete: props.onDelete,\n onNavigate: props.onNavigate,\n actionLabel: props.actionLabel,\n className: props.className,\n emptyStateImage: props.emptyStateImage,\n emptyStateTitle: props.emptyStateTitle,\n emptyStateDescription: props.emptyStateDescription,\n };\n return (\n <SingleNotificationCard\n title={singleProps.title}\n message={singleProps.message}\n time={singleProps.time}\n isRead={singleProps.isRead}\n onMarkAsRead={singleProps.onMarkAsRead}\n onDelete={singleProps.onDelete}\n onNavigate={singleProps.onNavigate}\n actionLabel={singleProps.actionLabel}\n className={singleProps.className}\n />\n );\n }\n\n // Default empty state if no valid props provided\n return (\n <div className=\"flex flex-col items-center gap-4 p-6 w-full\">\n <p className=\"text-sm text-text-600\">Nenhuma notificação configurada</p>\n </div>\n );\n};\n\nexport default NotificationCard;\nexport type { NotificationGroup };\n"]}
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-RU26377I.mjs";
4
4
  import {
5
5
  Modal_default
6
- } from "./chunk-MUCV5ZWZ.mjs";
6
+ } from "./chunk-3YF7H577.mjs";
7
7
  import {
8
8
  Text_default
9
9
  } from "./chunk-IMCIR6TJ.mjs";
@@ -58,4 +58,4 @@ var ProgressModal_default = ProgressModal;
58
58
  export {
59
59
  ProgressModal_default
60
60
  };
61
- //# sourceMappingURL=chunk-J5VEAJN5.mjs.map
61
+ //# sourceMappingURL=chunk-CWVUGZNK.mjs.map
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-NKVUUWCA.mjs";
10
10
  import {
11
11
  IconButton_default
12
- } from "./chunk-LGQNMQOT.mjs";
12
+ } from "./chunk-ROS5XGTQ.mjs";
13
13
  import {
14
14
  Badge_default
15
15
  } from "./chunk-OEW3ST4F.mjs";
@@ -18,10 +18,10 @@ import {
18
18
  DropdownMenuItem,
19
19
  DropdownMenuTrigger,
20
20
  DropdownMenu_default
21
- } from "./chunk-WDPFO4II.mjs";
21
+ } from "./chunk-NMPK336K.mjs";
22
22
  import {
23
23
  Modal_default
24
- } from "./chunk-MUCV5ZWZ.mjs";
24
+ } from "./chunk-3YF7H577.mjs";
25
25
  import {
26
26
  Text_default
27
27
  } from "./chunk-IMCIR6TJ.mjs";
@@ -651,4 +651,4 @@ export {
651
651
  LegacyNotificationCard,
652
652
  NotificationCard_default
653
653
  };
654
- //# sourceMappingURL=chunk-BCMDP6GK.mjs.map
654
+ //# sourceMappingURL=chunk-DV3N2K3Y.mjs.map
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-RU26377I.mjs";
7
7
  import {
8
8
  IconButton_default
9
- } from "./chunk-LGQNMQOT.mjs";
9
+ } from "./chunk-ROS5XGTQ.mjs";
10
10
  import {
11
11
  IconRender_default
12
12
  } from "./chunk-QEZJZHJG.mjs";
@@ -665,7 +665,13 @@ var CardStatus = forwardRef(
665
665
  ),
666
666
  label && /* @__PURE__ */ jsx("p", { className: "text-sm text-text-800", children: label })
667
667
  ] }),
668
- /* @__PURE__ */ jsx(CaretRightIcon, { className: "min-w-6 min-h-6 text-text-800 cursor-pointer flex-shrink-0 ml-2" })
668
+ /* @__PURE__ */ jsx(
669
+ CaretRightIcon,
670
+ {
671
+ "aria-hidden": "true",
672
+ className: "min-w-6 min-h-6 text-text-800 cursor-pointer flex-shrink-0 ml-2"
673
+ }
674
+ )
669
675
  ] })
670
676
  }
671
677
  );
@@ -1807,4 +1813,4 @@ export {
1807
1813
  CardEssayHistory,
1808
1814
  CardReadingFluency
1809
1815
  };
1810
- //# sourceMappingURL=chunk-PP7SEERV.mjs.map
1816
+ //# sourceMappingURL=chunk-DXYSEBK3.mjs.map