analytica-frontend-lib 1.7.21 → 1.7.23

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 (384) hide show
  1. package/dist/AccessReportModal/index.js +3 -3
  2. package/dist/AccessReportModal/index.mjs +2 -2
  3. package/dist/ActivitiesHistory/index.js +49 -49
  4. package/dist/ActivitiesHistory/index.mjs +48 -48
  5. package/dist/ActivityCardQuestionBanks/index.js +49 -49
  6. package/dist/ActivityCardQuestionBanks/index.mjs +48 -48
  7. package/dist/ActivityCardQuestionPreview/index.js +49 -49
  8. package/dist/ActivityCardQuestionPreview/index.mjs +48 -48
  9. package/dist/ActivityCreate/ActivityCreateContent/index.js +49 -49
  10. package/dist/ActivityCreate/ActivityCreateContent/index.mjs +48 -48
  11. package/dist/ActivityCreate/index.js +49 -49
  12. package/dist/ActivityCreate/index.mjs +48 -48
  13. package/dist/ActivityDetails/index.js +49 -49
  14. package/dist/ActivityDetails/index.mjs +48 -48
  15. package/dist/ActivityFilters/index.js +49 -49
  16. package/dist/ActivityFilters/index.mjs +48 -48
  17. package/dist/ActivityPageLayout/index.js +49 -49
  18. package/dist/ActivityPageLayout/index.mjs +48 -48
  19. package/dist/ActivityPreview/index.js +49 -49
  20. package/dist/ActivityPreview/index.mjs +48 -48
  21. package/dist/AlertManager/index.js +49 -49
  22. package/dist/AlertManager/index.mjs +48 -48
  23. package/dist/AlertManagerView/index.js +3 -3
  24. package/dist/AlertManagerView/index.mjs +2 -2
  25. package/dist/AnnouncementModal/index.js +3 -3
  26. package/dist/AnnouncementModal/index.mjs +2 -2
  27. package/dist/AnnouncementsGate/index.js +4 -4
  28. package/dist/AnnouncementsGate/index.mjs +3 -3
  29. package/dist/AnswerKeyModal/index.js +3 -3
  30. package/dist/AnswerKeyModal/index.mjs +2 -2
  31. package/dist/AppHeader/index.js +6 -6
  32. package/dist/AppHeader/index.mjs +5 -5
  33. package/dist/CalendarCard/index.js +4 -4
  34. package/dist/CalendarCard/index.mjs +3 -3
  35. package/dist/Chat/index.js +3 -3
  36. package/dist/Chat/index.mjs +2 -2
  37. package/dist/CheckBox/index.d.ts.map +1 -1
  38. package/dist/CheckBox/index.js +2 -2
  39. package/dist/CheckBox/index.mjs +1 -1
  40. package/dist/CheckBoxGroup/index.js +49 -49
  41. package/dist/CheckBoxGroup/index.mjs +48 -48
  42. package/dist/ComparatorChart/ComparatorView/index.js +3 -3
  43. package/dist/ComparatorChart/ComparatorView/index.mjs +2 -2
  44. package/dist/CorrectActivityModal/index.js +7 -7
  45. package/dist/CorrectActivityModal/index.mjs +6 -6
  46. package/dist/DownloadButton/index.js +4 -4
  47. package/dist/DownloadButton/index.mjs +3 -3
  48. package/dist/DownloadModal/index.js +3 -3
  49. package/dist/DownloadModal/index.mjs +2 -2
  50. package/dist/DropdownMenu/index.js +3 -3
  51. package/dist/DropdownMenu/index.mjs +2 -2
  52. package/dist/EnemClassroomStartModal/index.d.ts.map +1 -1
  53. package/dist/EnemClassroomStartModal/index.js +7 -7
  54. package/dist/EnemClassroomStartModal/index.mjs +6 -6
  55. package/dist/EnemMoment/index.js +57 -57
  56. package/dist/EnemMoment/index.mjs +51 -51
  57. package/dist/EnemMomentStudentModal/index.js +50 -50
  58. package/dist/EnemMomentStudentModal/index.mjs +48 -48
  59. package/dist/ExamDetailsLayout/ExamDetailsPage/index.js +49 -49
  60. package/dist/ExamDetailsLayout/ExamDetailsPage/index.mjs +48 -48
  61. package/dist/ExamPageLayout/index.js +49 -49
  62. package/dist/ExamPageLayout/index.mjs +48 -48
  63. package/dist/Forum/index.js +5 -5
  64. package/dist/Forum/index.mjs +4 -4
  65. package/dist/KnowledgePerformanceCard/index.js +51 -51
  66. package/dist/KnowledgePerformanceCard/index.mjs +50 -50
  67. package/dist/LessonCardPreview/index.js +49 -49
  68. package/dist/LessonCardPreview/index.mjs +48 -48
  69. package/dist/LessonMediaSections/index.js +49 -49
  70. package/dist/LessonMediaSections/index.mjs +48 -48
  71. package/dist/LessonsCatalog/index.js +49 -49
  72. package/dist/LessonsCatalog/index.mjs +48 -48
  73. package/dist/Modal/index.d.ts.map +1 -1
  74. package/dist/Modal/index.js +2 -2
  75. package/dist/Modal/index.mjs +1 -1
  76. package/dist/MultiCheckSelect/index.js +5 -5
  77. package/dist/MultiCheckSelect/index.mjs +4 -4
  78. package/dist/MultiSearchSelect/index.js +3 -3
  79. package/dist/MultiSearchSelect/index.mjs +2 -2
  80. package/dist/MultipleChoice/index.js +3 -3
  81. package/dist/MultipleChoice/index.mjs +2 -2
  82. package/dist/NotificationCard/index.js +4 -4
  83. package/dist/NotificationCard/index.mjs +3 -3
  84. package/dist/PerformanceReportModal/index.js +3 -3
  85. package/dist/PerformanceReportModal/index.mjs +2 -2
  86. package/dist/PrintableUsersTable/index.js +49 -49
  87. package/dist/PrintableUsersTable/index.mjs +48 -48
  88. package/dist/ProgressModal/index.js +3 -3
  89. package/dist/ProgressModal/index.mjs +2 -2
  90. package/dist/QuestionsPerformanceCard/index.js +50 -50
  91. package/dist/QuestionsPerformanceCard/index.mjs +49 -49
  92. package/dist/Quiz/index.js +6 -6
  93. package/dist/Quiz/index.mjs +5 -5
  94. package/dist/RecommendedLessonCreate/index.js +49 -49
  95. package/dist/RecommendedLessonCreate/index.mjs +48 -48
  96. package/dist/RecommendedLessonDetails/index.js +7 -7
  97. package/dist/RecommendedLessonDetails/index.mjs +6 -6
  98. package/dist/RecommendedLessonsHistory/index.js +49 -49
  99. package/dist/RecommendedLessonsHistory/index.mjs +48 -48
  100. package/dist/ReportDetailModal/index.js +4 -4
  101. package/dist/ReportDetailModal/index.mjs +3 -3
  102. package/dist/RichEditor/index.js +5 -5
  103. package/dist/RichEditor/index.mjs +4 -4
  104. package/dist/{RichEditorCore-6MTYSSKS.mjs → RichEditorCore-2S5YUAOI.mjs} +5 -5
  105. package/dist/{RichEditorCore-KDARBEK4.js → RichEditorCore-N7A2445B.js} +16 -16
  106. package/dist/{RichEditorCore-KDARBEK4.js.map → RichEditorCore-N7A2445B.js.map} +1 -1
  107. package/dist/Search/index.js +4 -4
  108. package/dist/Search/index.mjs +3 -3
  109. package/dist/SendActivityModal/SendActivityModal.js +49 -49
  110. package/dist/SendActivityModal/SendActivityModal.mjs +48 -48
  111. package/dist/SendActivityModal/index.js +49 -49
  112. package/dist/SendActivityModal/index.mjs +48 -48
  113. package/dist/SendLessonModal/index.js +49 -49
  114. package/dist/SendLessonModal/index.mjs +48 -48
  115. package/dist/SimulatedPerformance/SimulatedPerformanceView/index.js +49 -49
  116. package/dist/SimulatedPerformance/SimulatedPerformanceView/index.mjs +48 -48
  117. package/dist/SimulatedPerformance/useSimulatedPerformance/index.js +5 -5
  118. package/dist/SimulatedPerformance/useSimulatedPerformance/index.mjs +4 -4
  119. package/dist/SimulatedStudentSimulationsModal/index.js +6 -6
  120. package/dist/SimulatedStudentSimulationsModal/index.mjs +5 -5
  121. package/dist/SimulationsPage/index.js +49 -49
  122. package/dist/SimulationsPage/index.mjs +48 -48
  123. package/dist/StudentLessonProgressModal/index.js +3 -3
  124. package/dist/StudentLessonProgressModal/index.mjs +2 -2
  125. package/dist/StudentPerformanceDetailsModal/index.js +5 -5
  126. package/dist/StudentPerformanceDetailsModal/index.mjs +4 -4
  127. package/dist/Support/TicketModal/index.js +3 -3
  128. package/dist/Support/TicketModal/index.mjs +2 -2
  129. package/dist/Support/index.js +4 -4
  130. package/dist/Support/index.mjs +3 -3
  131. package/dist/SupportChatComposer/index.js +3 -3
  132. package/dist/SupportChatComposer/index.mjs +2 -2
  133. package/dist/SupportChatEvent/index.js +3 -3
  134. package/dist/SupportChatEvent/index.mjs +2 -2
  135. package/dist/SupportChatMessage/index.js +3 -3
  136. package/dist/SupportChatMessage/index.mjs +2 -2
  137. package/dist/SupportChatWidget/index.js +3 -3
  138. package/dist/SupportChatWidget/index.mjs +2 -2
  139. package/dist/SupportConcludeModal/index.js +4 -4
  140. package/dist/SupportConcludeModal/index.mjs +3 -3
  141. package/dist/SupportConversationHeader/index.js +4 -4
  142. package/dist/SupportConversationHeader/index.mjs +3 -3
  143. package/dist/SupportConversationMessages/index.js +5 -5
  144. package/dist/SupportConversationMessages/index.mjs +4 -4
  145. package/dist/SupportTicketConversation/index.js +12 -12
  146. package/dist/SupportTicketConversation/index.mjs +11 -11
  147. package/dist/TableProvider/index.js +49 -49
  148. package/dist/TableProvider/index.mjs +48 -48
  149. package/dist/UnifiedDraftModelPage/index.js +49 -49
  150. package/dist/UnifiedDraftModelPage/index.mjs +48 -48
  151. package/dist/UnifiedHistoryPage/index.js +49 -49
  152. package/dist/UnifiedHistoryPage/index.mjs +48 -48
  153. package/dist/VideoPlayer/index.js +5 -5
  154. package/dist/VideoPlayer/index.mjs +4 -4
  155. package/dist/Whiteboard/index.js +3 -3
  156. package/dist/Whiteboard/index.mjs +2 -2
  157. package/dist/{chunk-B6QOBHZM.mjs → chunk-24BEZK43.mjs} +2 -2
  158. package/dist/{chunk-CYSODZGX.js → chunk-27Y6V3GM.js} +169 -66
  159. package/dist/chunk-27Y6V3GM.js.map +1 -0
  160. package/dist/{chunk-OQTXTDSK.mjs → chunk-2OJ3QSLU.mjs} +3 -3
  161. package/dist/{chunk-VDUO65VK.mjs → chunk-3EGJJDIM.mjs} +2 -2
  162. package/dist/{chunk-VDUO65VK.mjs.map → chunk-3EGJJDIM.mjs.map} +1 -1
  163. package/dist/{chunk-4OUBPEVS.mjs → chunk-3HKLGNUE.mjs} +3 -3
  164. package/dist/{chunk-YA7XLH7D.js → chunk-3MFACEZ2.js} +3 -3
  165. package/dist/{chunk-YA7XLH7D.js.map → chunk-3MFACEZ2.js.map} +1 -1
  166. package/dist/{chunk-IHBWJM4C.mjs → chunk-3Q7RJKUP.mjs} +2 -2
  167. package/dist/{chunk-PY6WD6SB.mjs → chunk-3WRB4WCD.mjs} +4 -4
  168. package/dist/{chunk-4RHCBMMP.js → chunk-46VHAL4S.js} +3 -3
  169. package/dist/{chunk-4RHCBMMP.js.map → chunk-46VHAL4S.js.map} +1 -1
  170. package/dist/{chunk-POT3ALY3.js → chunk-5DINXU6W.js} +1 -1
  171. package/dist/{chunk-POT3ALY3.js.map → chunk-5DINXU6W.js.map} +1 -1
  172. package/dist/{chunk-L52NFNFK.mjs → chunk-5VC4BK65.mjs} +3 -3
  173. package/dist/{chunk-B67RLIUM.js → chunk-72D7G6YQ.js} +3 -3
  174. package/dist/{chunk-B67RLIUM.js.map → chunk-72D7G6YQ.js.map} +1 -1
  175. package/dist/{chunk-C65DG2RI.mjs → chunk-7FSBWUOM.mjs} +2 -2
  176. package/dist/{chunk-QWMFWYII.js → chunk-7IZNLARX.js} +3 -3
  177. package/dist/{chunk-QWMFWYII.js.map → chunk-7IZNLARX.js.map} +1 -1
  178. package/dist/{chunk-ZCBT2BUZ.js → chunk-7RFHXFFV.js} +13 -13
  179. package/dist/{chunk-ZCBT2BUZ.js.map → chunk-7RFHXFFV.js.map} +1 -1
  180. package/dist/{chunk-EMWX6IKP.js → chunk-7VJP5D26.js} +13 -13
  181. package/dist/{chunk-EMWX6IKP.js.map → chunk-7VJP5D26.js.map} +1 -1
  182. package/dist/{chunk-HCQJR5CE.mjs → chunk-7ZWEBNFB.mjs} +2 -2
  183. package/dist/{chunk-3RHNJUXU.mjs → chunk-ACSEJOW6.mjs} +2 -2
  184. package/dist/{chunk-WQZHUW7C.mjs → chunk-ANFHLSDB.mjs} +3 -3
  185. package/dist/{chunk-H6NQOLQY.mjs → chunk-ANFLWCVD.mjs} +2 -2
  186. package/dist/{chunk-BKBDQXZX.js → chunk-AOYPUZRO.js} +3 -3
  187. package/dist/{chunk-BKBDQXZX.js.map → chunk-AOYPUZRO.js.map} +1 -1
  188. package/dist/{chunk-5WS6IENQ.mjs → chunk-AU2HLQDJ.mjs} +2 -2
  189. package/dist/{chunk-P6FX3NT6.mjs → chunk-AZGDHAP5.mjs} +2 -2
  190. package/dist/{chunk-NCGO7FPB.js → chunk-AZKNYREH.js} +8 -8
  191. package/dist/{chunk-NCGO7FPB.js.map → chunk-AZKNYREH.js.map} +1 -1
  192. package/dist/{chunk-R6MTPYYW.js → chunk-AZTBNERQ.js} +3 -3
  193. package/dist/{chunk-R6MTPYYW.js.map → chunk-AZTBNERQ.js.map} +1 -1
  194. package/dist/{chunk-NPB2JTYC.mjs → chunk-BO3QVQ37.mjs} +4 -4
  195. package/dist/{chunk-2WI4Q2I2.mjs → chunk-BPMWRFSI.mjs} +4 -4
  196. package/dist/{chunk-TEW33GLR.mjs → chunk-BXN3VO6I.mjs} +2 -2
  197. package/dist/{chunk-7ZB3YHF2.mjs → chunk-C6LC5LD5.mjs} +1 -1
  198. package/dist/{chunk-7ZB3YHF2.mjs.map → chunk-C6LC5LD5.mjs.map} +1 -1
  199. package/dist/{chunk-5HONWYQA.js → chunk-C7ILTLT5.js} +3 -3
  200. package/dist/{chunk-5HONWYQA.js.map → chunk-C7ILTLT5.js.map} +1 -1
  201. package/dist/{chunk-OES54VU6.mjs → chunk-CFV2OZ3P.mjs} +116 -13
  202. package/dist/chunk-CFV2OZ3P.mjs.map +1 -0
  203. package/dist/{chunk-4OVIHZ3I.js → chunk-CGXWWPEA.js} +6 -6
  204. package/dist/{chunk-4OVIHZ3I.js.map → chunk-CGXWWPEA.js.map} +1 -1
  205. package/dist/{chunk-MNU45FM3.js → chunk-COT4KW3H.js} +2 -2
  206. package/dist/{chunk-MNU45FM3.js.map → chunk-COT4KW3H.js.map} +1 -1
  207. package/dist/{chunk-JDQUXG75.js → chunk-CVDNCU6L.js} +3 -3
  208. package/dist/{chunk-JDQUXG75.js.map → chunk-CVDNCU6L.js.map} +1 -1
  209. package/dist/{chunk-HBZHWSMZ.mjs → chunk-D46PJSQ7.mjs} +13 -13
  210. package/dist/{chunk-ARYIJ4RU.js → chunk-DDORKDQO.js} +3 -3
  211. package/dist/{chunk-ARYIJ4RU.js.map → chunk-DDORKDQO.js.map} +1 -1
  212. package/dist/{chunk-7YQTDJFA.js → chunk-DKXSR2V3.js} +3 -3
  213. package/dist/{chunk-7YQTDJFA.js.map → chunk-DKXSR2V3.js.map} +1 -1
  214. package/dist/{chunk-I6EAPPBL.mjs → chunk-DZMYIOKZ.mjs} +5 -5
  215. package/dist/{chunk-SKM7NFPY.js → chunk-EPXAFJVW.js} +6 -6
  216. package/dist/{chunk-SKM7NFPY.js.map → chunk-EPXAFJVW.js.map} +1 -1
  217. package/dist/{chunk-AYYMS23L.js → chunk-ESIQ2GB4.js} +7 -7
  218. package/dist/{chunk-AYYMS23L.js.map → chunk-ESIQ2GB4.js.map} +1 -1
  219. package/dist/{chunk-NU2WNYOD.js → chunk-EW7HGUFV.js} +87 -87
  220. package/dist/{chunk-NU2WNYOD.js.map → chunk-EW7HGUFV.js.map} +1 -1
  221. package/dist/{chunk-I4QGQMXI.mjs → chunk-EXYXZFNK.mjs} +2 -2
  222. package/dist/{chunk-RBJAO57A.js → chunk-FAAR4XC5.js} +3 -3
  223. package/dist/{chunk-RBJAO57A.js.map → chunk-FAAR4XC5.js.map} +1 -1
  224. package/dist/{chunk-N2VNE3ON.js → chunk-FDTDJDZI.js} +13 -13
  225. package/dist/{chunk-N2VNE3ON.js.map → chunk-FDTDJDZI.js.map} +1 -1
  226. package/dist/{chunk-SU5Q64TW.mjs → chunk-FVCTKS33.mjs} +6 -5
  227. package/dist/chunk-FVCTKS33.mjs.map +1 -0
  228. package/dist/{chunk-AVHZHWI3.js → chunk-GBIFSFWJ.js} +15 -15
  229. package/dist/{chunk-AVHZHWI3.js.map → chunk-GBIFSFWJ.js.map} +1 -1
  230. package/dist/{chunk-KSUPPAKH.js → chunk-GIQSHTB5.js} +9 -9
  231. package/dist/{chunk-KSUPPAKH.js.map → chunk-GIQSHTB5.js.map} +1 -1
  232. package/dist/{chunk-4QBKD4JN.js → chunk-GUUJYGXF.js} +3 -3
  233. package/dist/{chunk-4QBKD4JN.js.map → chunk-GUUJYGXF.js.map} +1 -1
  234. package/dist/{chunk-M4O46VDY.mjs → chunk-GX2PKLN2.mjs} +2 -2
  235. package/dist/{chunk-5BUTINIM.mjs → chunk-HLVLSWKD.mjs} +3 -3
  236. package/dist/{chunk-FU23WOTY.js → chunk-HSV5VZ4Z.js} +6 -6
  237. package/dist/{chunk-FU23WOTY.js.map → chunk-HSV5VZ4Z.js.map} +1 -1
  238. package/dist/{chunk-MMS2ELDK.mjs → chunk-IIQCS3A2.mjs} +2 -2
  239. package/dist/{chunk-NKWLCZUZ.mjs → chunk-JGGUMHM6.mjs} +2 -2
  240. package/dist/{chunk-HT2GREFH.js → chunk-JLD46DL7.js} +11 -11
  241. package/dist/{chunk-HT2GREFH.js.map → chunk-JLD46DL7.js.map} +1 -1
  242. package/dist/{chunk-NVL5TKWD.mjs → chunk-JYFLOQYT.mjs} +2 -2
  243. package/dist/{chunk-DWGDEUEW.mjs → chunk-KG563P7F.mjs} +5 -5
  244. package/dist/{chunk-TCIC5556.mjs → chunk-KH4TEDGD.mjs} +2 -2
  245. package/dist/{chunk-23PAYKWB.js → chunk-KM27ZDHZ.js} +2 -2
  246. package/dist/{chunk-23PAYKWB.js.map → chunk-KM27ZDHZ.js.map} +1 -1
  247. package/dist/{chunk-XZUMD3CB.mjs → chunk-LODDYDTP.mjs} +2 -2
  248. package/dist/{chunk-XZUMD3CB.mjs.map → chunk-LODDYDTP.mjs.map} +1 -1
  249. package/dist/{chunk-E6CGJBID.mjs → chunk-LUHKMY56.mjs} +2 -2
  250. package/dist/{chunk-TVLEUNKE.mjs → chunk-LZP5VZCO.mjs} +2 -2
  251. package/dist/{chunk-EHNEBXS7.mjs → chunk-M6DXZ2FM.mjs} +2 -2
  252. package/dist/{chunk-B4C5DWAP.mjs → chunk-MMMJDO75.mjs} +2 -2
  253. package/dist/{chunk-AFCWMJQO.js → chunk-MOUPNP53.js} +3 -3
  254. package/dist/{chunk-AFCWMJQO.js.map → chunk-MOUPNP53.js.map} +1 -1
  255. package/dist/{chunk-36KFIZ43.js → chunk-MYPUZ6EG.js} +3 -3
  256. package/dist/{chunk-36KFIZ43.js.map → chunk-MYPUZ6EG.js.map} +1 -1
  257. package/dist/{chunk-6JHIKIPA.js → chunk-NUGLTWEA.js} +23 -23
  258. package/dist/{chunk-6JHIKIPA.js.map → chunk-NUGLTWEA.js.map} +1 -1
  259. package/dist/{chunk-KWXOYHYK.mjs → chunk-P7MORXSE.mjs} +2 -2
  260. package/dist/{chunk-YG4IZ5Q3.mjs → chunk-Q2OSEROT.mjs} +2 -2
  261. package/dist/{chunk-L5SXG6T6.mjs → chunk-QQKOHKO2.mjs} +3 -3
  262. package/dist/{chunk-SADSJ2MV.js → chunk-QVGUYPXO.js} +3 -3
  263. package/dist/{chunk-SADSJ2MV.js.map → chunk-QVGUYPXO.js.map} +1 -1
  264. package/dist/{chunk-K45PTE7F.mjs → chunk-RBKQXT73.mjs} +4 -4
  265. package/dist/{chunk-JZFISWTP.js → chunk-RIN2IN7E.js} +2 -2
  266. package/dist/{chunk-JZFISWTP.js.map → chunk-RIN2IN7E.js.map} +1 -1
  267. package/dist/{chunk-BXLAOYAG.mjs → chunk-RIUVPTG7.mjs} +2 -2
  268. package/dist/{chunk-QVB54LBS.mjs → chunk-RNZGX6MX.mjs} +3 -3
  269. package/dist/{chunk-VSVLIRO2.js → chunk-RXEU77VN.js} +15 -15
  270. package/dist/{chunk-VSVLIRO2.js.map → chunk-RXEU77VN.js.map} +1 -1
  271. package/dist/{chunk-ZRIYCU2V.js → chunk-S2BZPPAI.js} +5 -5
  272. package/dist/{chunk-ZRIYCU2V.js.map → chunk-S2BZPPAI.js.map} +1 -1
  273. package/dist/{chunk-MES2BP4T.mjs → chunk-SGL5IUCV.mjs} +2 -2
  274. package/dist/{chunk-7LS5UQCQ.mjs → chunk-STKUPDHG.mjs} +2 -2
  275. package/dist/{chunk-PPYCCT2K.js → chunk-SWDVSCQJ.js} +9 -8
  276. package/dist/chunk-SWDVSCQJ.js.map +1 -0
  277. package/dist/{chunk-JCA76TCX.mjs → chunk-SZKLJOTN.mjs} +2 -2
  278. package/dist/{chunk-F5WR6XZZ.js → chunk-T73HPYF2.js} +3 -3
  279. package/dist/{chunk-F5WR6XZZ.js.map → chunk-T73HPYF2.js.map} +1 -1
  280. package/dist/{chunk-ZB6HDDE4.js → chunk-TQO37PVW.js} +14 -14
  281. package/dist/{chunk-ZB6HDDE4.js.map → chunk-TQO37PVW.js.map} +1 -1
  282. package/dist/{chunk-VKQ5AJDT.mjs → chunk-UENZQF2Y.mjs} +2 -2
  283. package/dist/{chunk-DCG7EUBC.js → chunk-UWLW5YVB.js} +6 -6
  284. package/dist/{chunk-DCG7EUBC.js.map → chunk-UWLW5YVB.js.map} +1 -1
  285. package/dist/{chunk-37AJ2GVO.mjs → chunk-UXJIZDXQ.mjs} +2 -2
  286. package/dist/{chunk-PLLPFCN3.js → chunk-UXMDPRAI.js} +14 -14
  287. package/dist/{chunk-PLLPFCN3.js.map → chunk-UXMDPRAI.js.map} +1 -1
  288. package/dist/{chunk-7BOTKRY6.mjs → chunk-V55DG5B4.mjs} +2 -2
  289. package/dist/{chunk-YRTIDZTN.js → chunk-VHEDMUAW.js} +4 -4
  290. package/dist/{chunk-YRTIDZTN.js.map → chunk-VHEDMUAW.js.map} +1 -1
  291. package/dist/{chunk-4RD55E4R.js → chunk-VWLWSO4J.js} +3 -3
  292. package/dist/{chunk-4RD55E4R.js.map → chunk-VWLWSO4J.js.map} +1 -1
  293. package/dist/{chunk-VJQIKFMG.mjs → chunk-W3CWEZDB.mjs} +3 -3
  294. package/dist/{chunk-JM6SLU7D.js → chunk-W7NNH4VY.js} +6 -6
  295. package/dist/{chunk-JM6SLU7D.js.map → chunk-W7NNH4VY.js.map} +1 -1
  296. package/dist/{chunk-VQ7MSYIH.js → chunk-WUN5NHZE.js} +4 -4
  297. package/dist/{chunk-VQ7MSYIH.js.map → chunk-WUN5NHZE.js.map} +1 -1
  298. package/dist/{chunk-AAU7ABJN.js → chunk-WWTRSQ3X.js} +3 -3
  299. package/dist/{chunk-AAU7ABJN.js.map → chunk-WWTRSQ3X.js.map} +1 -1
  300. package/dist/{chunk-BR6D2TGF.js → chunk-WZOA2PVJ.js} +3 -3
  301. package/dist/{chunk-BR6D2TGF.js.map → chunk-WZOA2PVJ.js.map} +1 -1
  302. package/dist/{chunk-TZKR5Z4J.mjs → chunk-XJF2F36N.mjs} +2 -2
  303. package/dist/{chunk-P6ACVNQK.mjs → chunk-YD2XBEKO.mjs} +2 -2
  304. package/dist/{chunk-LMXWIPGR.js → chunk-YWPLHFAK.js} +3 -3
  305. package/dist/{chunk-LMXWIPGR.js.map → chunk-YWPLHFAK.js.map} +1 -1
  306. package/dist/{chunk-DCEWWHV5.mjs → chunk-Z3HGYPH7.mjs} +2 -2
  307. package/dist/{chunk-Q3PKW6TH.js → chunk-ZCV3HWI2.js} +6 -6
  308. package/dist/{chunk-Q3PKW6TH.js.map → chunk-ZCV3HWI2.js.map} +1 -1
  309. package/dist/{chunk-OSA3YVDZ.mjs → chunk-ZF46DCAC.mjs} +2 -2
  310. package/dist/{chunk-5T6IDXSB.js → chunk-ZO2GA23I.js} +3 -3
  311. package/dist/{chunk-5T6IDXSB.js.map → chunk-ZO2GA23I.js.map} +1 -1
  312. package/dist/{chunk-ZN3763VZ.js → chunk-ZQLW4EJB.js} +9 -9
  313. package/dist/{chunk-ZN3763VZ.js.map → chunk-ZQLW4EJB.js.map} +1 -1
  314. package/dist/{chunk-CM5R4SPF.js → chunk-ZQQJTO6T.js} +3 -3
  315. package/dist/{chunk-CM5R4SPF.js.map → chunk-ZQQJTO6T.js.map} +1 -1
  316. package/dist/{chunk-SEL4QDCO.js → chunk-ZSXSAE3D.js} +3 -3
  317. package/dist/{chunk-SEL4QDCO.js.map → chunk-ZSXSAE3D.js.map} +1 -1
  318. package/dist/components/SupportChatWidget/guestSupportChatAdapter.d.ts +6 -1
  319. package/dist/components/SupportChatWidget/guestSupportChatAdapter.d.ts.map +1 -1
  320. package/dist/hooks/useAppContent/index.js +49 -49
  321. package/dist/hooks/useAppContent/index.mjs +48 -48
  322. package/dist/hooks/useSupportChat.d.ts +2 -0
  323. package/dist/hooks/useSupportChat.d.ts.map +1 -1
  324. package/dist/index.js +49 -49
  325. package/dist/index.mjs +48 -48
  326. package/dist/types/supportChat/index.d.ts +14 -0
  327. package/dist/types/supportChat/index.d.ts.map +1 -1
  328. package/dist/types/supportChat/index.js +2 -2
  329. package/dist/types/supportChat/index.mjs +1 -1
  330. package/dist/types/supportChat.d.ts +14 -0
  331. package/dist/types/supportChat.d.ts.map +1 -1
  332. package/package.json +1 -1
  333. package/dist/chunk-CYSODZGX.js.map +0 -1
  334. package/dist/chunk-OES54VU6.mjs.map +0 -1
  335. package/dist/chunk-PPYCCT2K.js.map +0 -1
  336. package/dist/chunk-SU5Q64TW.mjs.map +0 -1
  337. /package/dist/{RichEditorCore-6MTYSSKS.mjs.map → RichEditorCore-2S5YUAOI.mjs.map} +0 -0
  338. /package/dist/{chunk-B6QOBHZM.mjs.map → chunk-24BEZK43.mjs.map} +0 -0
  339. /package/dist/{chunk-OQTXTDSK.mjs.map → chunk-2OJ3QSLU.mjs.map} +0 -0
  340. /package/dist/{chunk-4OUBPEVS.mjs.map → chunk-3HKLGNUE.mjs.map} +0 -0
  341. /package/dist/{chunk-IHBWJM4C.mjs.map → chunk-3Q7RJKUP.mjs.map} +0 -0
  342. /package/dist/{chunk-PY6WD6SB.mjs.map → chunk-3WRB4WCD.mjs.map} +0 -0
  343. /package/dist/{chunk-L52NFNFK.mjs.map → chunk-5VC4BK65.mjs.map} +0 -0
  344. /package/dist/{chunk-C65DG2RI.mjs.map → chunk-7FSBWUOM.mjs.map} +0 -0
  345. /package/dist/{chunk-HCQJR5CE.mjs.map → chunk-7ZWEBNFB.mjs.map} +0 -0
  346. /package/dist/{chunk-3RHNJUXU.mjs.map → chunk-ACSEJOW6.mjs.map} +0 -0
  347. /package/dist/{chunk-WQZHUW7C.mjs.map → chunk-ANFHLSDB.mjs.map} +0 -0
  348. /package/dist/{chunk-H6NQOLQY.mjs.map → chunk-ANFLWCVD.mjs.map} +0 -0
  349. /package/dist/{chunk-5WS6IENQ.mjs.map → chunk-AU2HLQDJ.mjs.map} +0 -0
  350. /package/dist/{chunk-P6FX3NT6.mjs.map → chunk-AZGDHAP5.mjs.map} +0 -0
  351. /package/dist/{chunk-NPB2JTYC.mjs.map → chunk-BO3QVQ37.mjs.map} +0 -0
  352. /package/dist/{chunk-2WI4Q2I2.mjs.map → chunk-BPMWRFSI.mjs.map} +0 -0
  353. /package/dist/{chunk-TEW33GLR.mjs.map → chunk-BXN3VO6I.mjs.map} +0 -0
  354. /package/dist/{chunk-HBZHWSMZ.mjs.map → chunk-D46PJSQ7.mjs.map} +0 -0
  355. /package/dist/{chunk-I6EAPPBL.mjs.map → chunk-DZMYIOKZ.mjs.map} +0 -0
  356. /package/dist/{chunk-I4QGQMXI.mjs.map → chunk-EXYXZFNK.mjs.map} +0 -0
  357. /package/dist/{chunk-M4O46VDY.mjs.map → chunk-GX2PKLN2.mjs.map} +0 -0
  358. /package/dist/{chunk-5BUTINIM.mjs.map → chunk-HLVLSWKD.mjs.map} +0 -0
  359. /package/dist/{chunk-MMS2ELDK.mjs.map → chunk-IIQCS3A2.mjs.map} +0 -0
  360. /package/dist/{chunk-NKWLCZUZ.mjs.map → chunk-JGGUMHM6.mjs.map} +0 -0
  361. /package/dist/{chunk-NVL5TKWD.mjs.map → chunk-JYFLOQYT.mjs.map} +0 -0
  362. /package/dist/{chunk-DWGDEUEW.mjs.map → chunk-KG563P7F.mjs.map} +0 -0
  363. /package/dist/{chunk-TCIC5556.mjs.map → chunk-KH4TEDGD.mjs.map} +0 -0
  364. /package/dist/{chunk-E6CGJBID.mjs.map → chunk-LUHKMY56.mjs.map} +0 -0
  365. /package/dist/{chunk-TVLEUNKE.mjs.map → chunk-LZP5VZCO.mjs.map} +0 -0
  366. /package/dist/{chunk-EHNEBXS7.mjs.map → chunk-M6DXZ2FM.mjs.map} +0 -0
  367. /package/dist/{chunk-B4C5DWAP.mjs.map → chunk-MMMJDO75.mjs.map} +0 -0
  368. /package/dist/{chunk-KWXOYHYK.mjs.map → chunk-P7MORXSE.mjs.map} +0 -0
  369. /package/dist/{chunk-YG4IZ5Q3.mjs.map → chunk-Q2OSEROT.mjs.map} +0 -0
  370. /package/dist/{chunk-L5SXG6T6.mjs.map → chunk-QQKOHKO2.mjs.map} +0 -0
  371. /package/dist/{chunk-K45PTE7F.mjs.map → chunk-RBKQXT73.mjs.map} +0 -0
  372. /package/dist/{chunk-BXLAOYAG.mjs.map → chunk-RIUVPTG7.mjs.map} +0 -0
  373. /package/dist/{chunk-QVB54LBS.mjs.map → chunk-RNZGX6MX.mjs.map} +0 -0
  374. /package/dist/{chunk-MES2BP4T.mjs.map → chunk-SGL5IUCV.mjs.map} +0 -0
  375. /package/dist/{chunk-7LS5UQCQ.mjs.map → chunk-STKUPDHG.mjs.map} +0 -0
  376. /package/dist/{chunk-JCA76TCX.mjs.map → chunk-SZKLJOTN.mjs.map} +0 -0
  377. /package/dist/{chunk-VKQ5AJDT.mjs.map → chunk-UENZQF2Y.mjs.map} +0 -0
  378. /package/dist/{chunk-37AJ2GVO.mjs.map → chunk-UXJIZDXQ.mjs.map} +0 -0
  379. /package/dist/{chunk-7BOTKRY6.mjs.map → chunk-V55DG5B4.mjs.map} +0 -0
  380. /package/dist/{chunk-VJQIKFMG.mjs.map → chunk-W3CWEZDB.mjs.map} +0 -0
  381. /package/dist/{chunk-TZKR5Z4J.mjs.map → chunk-XJF2F36N.mjs.map} +0 -0
  382. /package/dist/{chunk-P6ACVNQK.mjs.map → chunk-YD2XBEKO.mjs.map} +0 -0
  383. /package/dist/{chunk-DCEWWHV5.mjs.map → chunk-Z3HGYPH7.mjs.map} +0 -0
  384. /package/dist/{chunk-OSA3YVDZ.mjs.map → chunk-ZF46DCAC.mjs.map} +0 -0
@@ -3,7 +3,7 @@
3
3
  var _chunkVRXURXVMjs = require('./chunk-VRXURXVM.js');
4
4
 
5
5
 
6
- var _chunk23PAYKWBjs = require('./chunk-23PAYKWB.js');
6
+ var _chunkKM27ZDHZjs = require('./chunk-KM27ZDHZ.js');
7
7
 
8
8
 
9
9
  var _chunkANT66KVKjs = require('./chunk-ANT66KVK.js');
@@ -24,7 +24,7 @@ var ProgressModal = ({
24
24
  const resolvedAccessibleName = typeof message === "string" ? message : _nullishCoalesce(accessibleName, () => ( "Carregando"));
25
25
  const resolvedAlt = _nullishCoalesce(imageAlt, () => ( resolvedAccessibleName));
26
26
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
27
- _chunk23PAYKWBjs.Modal_default,
27
+ _chunkKM27ZDHZjs.Modal_default,
28
28
  {
29
29
  isOpen,
30
30
  onClose,
@@ -58,4 +58,4 @@ var ProgressModal_default = ProgressModal;
58
58
 
59
59
 
60
60
  exports.ProgressModal_default = ProgressModal_default;
61
- //# sourceMappingURL=chunk-QWMFWYII.js.map
61
+ //# sourceMappingURL=chunk-7IZNLARX.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-QWMFWYII.js","../src/components/ProgressModal/ProgressModal.tsx"],"names":[],"mappings":"AAAA;AACE;AACF,sDAA4B;AAC5B;AACE;AACF,sDAA4B;AAC5B;AACE;AACF,sDAA4B;AAC5B;AACA;ACiEa,+CAAA;AAnBb,IAAM,cAAA,EAAgB,CAAC;AAAA,EACrB,MAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA,EACA,cAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA,EAAO;AACT,CAAA,EAAA,GAA0B;AACxB,EAAA,MAAM,gBAAA,EAAkB,SAAA,IAAa,KAAA,CAAA;AACrC,EAAA,MAAM,uBAAA,EACJ,OAAO,QAAA,IAAY,SAAA,EAAW,QAAA,mBAAW,cAAA,UAAkB,cAAA;AAC7D,EAAA,MAAM,YAAA,mBAAc,QAAA,UAAY,wBAAA;AAEhC,EAAA,uBACE,6BAAA;AAAA,IAAC,8BAAA;AAAA,IAAA;AAAA,MACC,MAAA;AAAA,MACA,OAAA;AAAA,MACA,KAAA,kBAAO,6BAAA,MAAC,EAAA,EAAK,SAAA,EAAU,SAAA,EAAW,QAAA,EAAA,uBAAA,CAAuB,CAAA;AAAA,MACzD,IAAA;AAAA,MAEA,QAAA,kBAAA,8BAAA,KAAC,EAAA,EAAI,SAAA,EAAU,uCAAA,EACZ,QAAA,EAAA;AAAA,QAAA,MAAA,mBACC,6BAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,GAAA,EAAK,KAAA;AAAA,YACL,GAAA,EAAK,WAAA;AAAA,YACL,SAAA,EAAU;AAAA,UAAA;AAAA,QACZ,CAAA;AAAA,wBAGF,6BAAA,6BAAC,EAAA,EAAK,IAAA,EAAK,IAAA,EAAK,SAAA,EAAU,2BAAA,EACvB,QAAA,EAAA,QAAA,CACH,CAAA;AAAA,wBAEA,6BAAA,KAAC,EAAA,EAAI,SAAA,EAAW,gBAAA,EAAkB,uBAAA,EAAyB,QAAA,EACzD,QAAA,kBAAA,6BAAA;AAAA,UAAC,oCAAA;AAAA,UAAA;AAAA,YACC,KAAA,mBAAO,QAAA,UAAY,IAAA;AAAA,YACnB,IAAA,EAAK,QAAA;AAAA,YACL,OAAA,EAAQ,MAAA;AAAA,YACR,cAAA,EAAgB,CAAC;AAAA,UAAA;AAAA,QACnB,EAAA,CACF;AAAA,MAAA,EAAA,CACF;AAAA,IAAA;AAAA,EACF,CAAA;AAEJ,CAAA;AAEA,IAAO,sBAAA,EAAQ,aAAA;ADhDf;AACA;AACE;AACF,sDAAC","file":"/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-QWMFWYII.js","sourcesContent":[null,"import { ReactNode } from 'react';\nimport Modal from '../Modal/Modal';\nimport ProgressBar from '../ProgressBar/ProgressBar';\nimport Text from '../Text/Text';\n\nexport interface ProgressModalProps {\n /** Controla se o modal está aberto */\n isOpen: boolean;\n /** Callback ao fechar */\n onClose: () => void;\n /**\n * Mensagem principal exibida abaixo da imagem. Também é usada como\n * accessible name do dialog (renderizada visualmente escondida no `<h2>`\n * do Modal pra leitores de tela).\n */\n message: ReactNode;\n /** URL ou import de imagem ilustrativa (opcional) */\n image?: string;\n /** Alt text da imagem — se não informado usa a `message` quando for string */\n imageAlt?: string;\n /**\n * Accessible name quando `message` é ReactNode. Se omitido, cai em\n * \"Carregando\". Ignorado quando `message` é string.\n */\n accessibleName?: string;\n /**\n * Valor 0-100. Se omitido, mostra indicador indeterminado (pulse sem %).\n * Use quando o backend não reportar progresso real.\n */\n progress?: number;\n /** Tamanho do Modal. Default: 'sm' */\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n}\n\n/**\n * Modal de progresso com imagem ilustrativa + mensagem + ProgressBar.\n *\n * Pensado para operações assíncronas longas (upload, OCR, correção por IA, etc).\n * Quando `progress` é omitido, a barra é renderizada em modo indeterminado\n * (`animate-pulse` sem percentual visível).\n *\n * Layout: X no topo direito, imagem centralizada, mensagem abaixo da imagem,\n * progress bar ao final. A mensagem também é injetada como título invisível\n * (`sr-only`) no `<h2>` do Modal pra acessibilidade.\n *\n * @example\n * ```tsx\n * <ProgressModal\n * isOpen={isLoading}\n * onClose={() => setIsLoading(false)}\n * image={myImage}\n * message=\"Analisando sua redação...\"\n * // progress opcional — sem valor, usa indicador indeterminado\n * />\n * ```\n */\nconst ProgressModal = ({\n isOpen,\n onClose,\n message,\n image,\n imageAlt,\n accessibleName,\n progress,\n size = 'sm',\n}: ProgressModalProps) => {\n const isIndeterminate = progress === undefined;\n const resolvedAccessibleName =\n typeof message === 'string' ? message : (accessibleName ?? 'Carregando');\n const resolvedAlt = imageAlt ?? resolvedAccessibleName;\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={onClose}\n title={<span className=\"sr-only\">{resolvedAccessibleName}</span>}\n size={size}\n >\n <div className=\"flex flex-col items-center gap-6 py-2\">\n {image && (\n <img\n src={image}\n alt={resolvedAlt}\n className=\"w-60 h-60 object-contain\"\n />\n )}\n\n <Text size=\"md\" className=\"text-text-950 text-center\">\n {message}\n </Text>\n\n <div className={isIndeterminate ? 'w-full animate-pulse' : 'w-full'}>\n <ProgressBar\n value={progress ?? 60}\n size=\"medium\"\n variant=\"blue\"\n showPercentage={!isIndeterminate}\n />\n </div>\n </div>\n </Modal>\n );\n};\n\nexport default ProgressModal;\n"]}
1
+ {"version":3,"sources":["/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-7IZNLARX.js","../src/components/ProgressModal/ProgressModal.tsx"],"names":[],"mappings":"AAAA;AACE;AACF,sDAA4B;AAC5B;AACE;AACF,sDAA4B;AAC5B;AACE;AACF,sDAA4B;AAC5B;AACA;ACiEa,+CAAA;AAnBb,IAAM,cAAA,EAAgB,CAAC;AAAA,EACrB,MAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA,EACA,cAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA,EAAO;AACT,CAAA,EAAA,GAA0B;AACxB,EAAA,MAAM,gBAAA,EAAkB,SAAA,IAAa,KAAA,CAAA;AACrC,EAAA,MAAM,uBAAA,EACJ,OAAO,QAAA,IAAY,SAAA,EAAW,QAAA,mBAAW,cAAA,UAAkB,cAAA;AAC7D,EAAA,MAAM,YAAA,mBAAc,QAAA,UAAY,wBAAA;AAEhC,EAAA,uBACE,6BAAA;AAAA,IAAC,8BAAA;AAAA,IAAA;AAAA,MACC,MAAA;AAAA,MACA,OAAA;AAAA,MACA,KAAA,kBAAO,6BAAA,MAAC,EAAA,EAAK,SAAA,EAAU,SAAA,EAAW,QAAA,EAAA,uBAAA,CAAuB,CAAA;AAAA,MACzD,IAAA;AAAA,MAEA,QAAA,kBAAA,8BAAA,KAAC,EAAA,EAAI,SAAA,EAAU,uCAAA,EACZ,QAAA,EAAA;AAAA,QAAA,MAAA,mBACC,6BAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,GAAA,EAAK,KAAA;AAAA,YACL,GAAA,EAAK,WAAA;AAAA,YACL,SAAA,EAAU;AAAA,UAAA;AAAA,QACZ,CAAA;AAAA,wBAGF,6BAAA,6BAAC,EAAA,EAAK,IAAA,EAAK,IAAA,EAAK,SAAA,EAAU,2BAAA,EACvB,QAAA,EAAA,QAAA,CACH,CAAA;AAAA,wBAEA,6BAAA,KAAC,EAAA,EAAI,SAAA,EAAW,gBAAA,EAAkB,uBAAA,EAAyB,QAAA,EACzD,QAAA,kBAAA,6BAAA;AAAA,UAAC,oCAAA;AAAA,UAAA;AAAA,YACC,KAAA,mBAAO,QAAA,UAAY,IAAA;AAAA,YACnB,IAAA,EAAK,QAAA;AAAA,YACL,OAAA,EAAQ,MAAA;AAAA,YACR,cAAA,EAAgB,CAAC;AAAA,UAAA;AAAA,QACnB,EAAA,CACF;AAAA,MAAA,EAAA,CACF;AAAA,IAAA;AAAA,EACF,CAAA;AAEJ,CAAA;AAEA,IAAO,sBAAA,EAAQ,aAAA;ADhDf;AACA;AACE;AACF,sDAAC","file":"/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-7IZNLARX.js","sourcesContent":[null,"import { ReactNode } from 'react';\nimport Modal from '../Modal/Modal';\nimport ProgressBar from '../ProgressBar/ProgressBar';\nimport Text from '../Text/Text';\n\nexport interface ProgressModalProps {\n /** Controla se o modal está aberto */\n isOpen: boolean;\n /** Callback ao fechar */\n onClose: () => void;\n /**\n * Mensagem principal exibida abaixo da imagem. Também é usada como\n * accessible name do dialog (renderizada visualmente escondida no `<h2>`\n * do Modal pra leitores de tela).\n */\n message: ReactNode;\n /** URL ou import de imagem ilustrativa (opcional) */\n image?: string;\n /** Alt text da imagem — se não informado usa a `message` quando for string */\n imageAlt?: string;\n /**\n * Accessible name quando `message` é ReactNode. Se omitido, cai em\n * \"Carregando\". Ignorado quando `message` é string.\n */\n accessibleName?: string;\n /**\n * Valor 0-100. Se omitido, mostra indicador indeterminado (pulse sem %).\n * Use quando o backend não reportar progresso real.\n */\n progress?: number;\n /** Tamanho do Modal. Default: 'sm' */\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n}\n\n/**\n * Modal de progresso com imagem ilustrativa + mensagem + ProgressBar.\n *\n * Pensado para operações assíncronas longas (upload, OCR, correção por IA, etc).\n * Quando `progress` é omitido, a barra é renderizada em modo indeterminado\n * (`animate-pulse` sem percentual visível).\n *\n * Layout: X no topo direito, imagem centralizada, mensagem abaixo da imagem,\n * progress bar ao final. A mensagem também é injetada como título invisível\n * (`sr-only`) no `<h2>` do Modal pra acessibilidade.\n *\n * @example\n * ```tsx\n * <ProgressModal\n * isOpen={isLoading}\n * onClose={() => setIsLoading(false)}\n * image={myImage}\n * message=\"Analisando sua redação...\"\n * // progress opcional — sem valor, usa indicador indeterminado\n * />\n * ```\n */\nconst ProgressModal = ({\n isOpen,\n onClose,\n message,\n image,\n imageAlt,\n accessibleName,\n progress,\n size = 'sm',\n}: ProgressModalProps) => {\n const isIndeterminate = progress === undefined;\n const resolvedAccessibleName =\n typeof message === 'string' ? message : (accessibleName ?? 'Carregando');\n const resolvedAlt = imageAlt ?? resolvedAccessibleName;\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={onClose}\n title={<span className=\"sr-only\">{resolvedAccessibleName}</span>}\n size={size}\n >\n <div className=\"flex flex-col items-center gap-6 py-2\">\n {image && (\n <img\n src={image}\n alt={resolvedAlt}\n className=\"w-60 h-60 object-contain\"\n />\n )}\n\n <Text size=\"md\" className=\"text-text-950 text-center\">\n {message}\n </Text>\n\n <div className={isIndeterminate ? 'w-full animate-pulse' : 'w-full'}>\n <ProgressBar\n value={progress ?? 60}\n size=\"medium\"\n variant=\"blue\"\n showPercentage={!isIndeterminate}\n />\n </div>\n </div>\n </Modal>\n );\n};\n\nexport default ProgressModal;\n"]}
@@ -18,10 +18,10 @@ var _chunkJVDEOFXDjs = require('./chunk-JVDEOFXD.js');
18
18
 
19
19
 
20
20
 
21
- var _chunkRBJAO57Ajs = require('./chunk-RBJAO57A.js');
21
+ var _chunkFAAR4XC5js = require('./chunk-FAAR4XC5.js');
22
22
 
23
23
 
24
- var _chunk23PAYKWBjs = require('./chunk-23PAYKWB.js');
24
+ var _chunkKM27ZDHZjs = require('./chunk-KM27ZDHZ.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
- _chunk23PAYKWBjs.Modal_default,
101
+ _chunkKM27ZDHZjs.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, _chunkRBJAO57Ajs.DropdownMenu_default, { children: [
156
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkFAAR4XC5js.DropdownMenu_default, { children: [
157
157
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
158
- _chunkRBJAO57Ajs.DropdownMenuTrigger,
158
+ _chunkFAAR4XC5js.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, _chunkRBJAO57Ajs.DropdownMenuContent, { align: "end", className: "min-w-[160px]", children: [
165
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkFAAR4XC5js.DropdownMenuContent, { align: "end", className: "min-w-[160px]", children: [
166
166
  !isRead && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
167
- _chunkRBJAO57Ajs.DropdownMenuItem,
167
+ _chunkFAAR4XC5js.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, _chunkRBJAO57Ajs.DropdownMenuItem, { onClick: handleDelete, className: "text-error-600", children: "Deletar" })
174
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkFAAR4XC5js.DropdownMenuItem, { onClick: handleDelete, className: "text-error-600", children: "Deletar" })
175
175
  ] })
176
176
  ] })
177
177
  ] }),
@@ -386,7 +386,7 @@ var NotificationCenter = ({
386
386
  }
387
387
  ),
388
388
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
389
- _chunk23PAYKWBjs.Modal_default,
389
+ _chunkKM27ZDHZjs.Modal_default,
390
390
  {
391
391
  isOpen: isModalOpen,
392
392
  onClose: () => setIsModalOpen(false),
@@ -449,11 +449,11 @@ 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
- _chunkRBJAO57Ajs.DropdownMenu_default,
452
+ _chunkFAAR4XC5js.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, _chunkRBJAO57Ajs.DropdownMenuTrigger, { className: "text-primary cursor-pointer", asChild: true, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
456
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkFAAR4XC5js.DropdownMenuTrigger, { className: "text-primary cursor-pointer", asChild: true, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
457
457
  _chunkCAQ2Q3ONjs.IconButton_default,
458
458
  {
459
459
  active: isActive,
@@ -471,7 +471,7 @@ var NotificationCenter = ({
471
471
  }
472
472
  ) }),
473
473
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
474
- _chunkRBJAO57Ajs.DropdownMenuContent,
474
+ _chunkFAAR4XC5js.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-ZCBT2BUZ.js.map
654
+ //# sourceMappingURL=chunk-7RFHXFFV.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-ZCBT2BUZ.js","../src/components/NotificationCard/NotificationCard.tsx"],"names":[],"mappings":"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","file":"/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-ZCBT2BUZ.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-7RFHXFFV.js","../src/components/NotificationCard/NotificationCard.tsx"],"names":[],"mappings":"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","file":"/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-7RFHXFFV.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"]}
@@ -4,7 +4,7 @@ var _chunkXQL6H446js = require('./chunk-XQL6H446.js');
4
4
 
5
5
 
6
6
 
7
- var _chunkPOT3ALY3js = require('./chunk-POT3ALY3.js');
7
+ var _chunk5DINXU6Wjs = require('./chunk-5DINXU6W.js');
8
8
 
9
9
 
10
10
  var _chunkXN2HPVVHjs = require('./chunk-XN2HPVVH.js');
@@ -48,11 +48,11 @@ var Sparkle_default = Sparkle;
48
48
  // src/components/SupportChat/SupportChatMessage.tsx
49
49
 
50
50
  var BUBBLE_CLASSES = {
51
- [_chunkPOT3ALY3js.SUPPORT_CHAT_MESSAGE_TYPE.USER]: "bg-background-100",
52
- [_chunkPOT3ALY3js.SUPPORT_CHAT_MESSAGE_TYPE.GUEST]: "bg-background-100",
53
- [_chunkPOT3ALY3js.SUPPORT_CHAT_MESSAGE_TYPE.AI]: "bg-primary-50/60 border border-primary-100",
54
- [_chunkPOT3ALY3js.SUPPORT_CHAT_MESSAGE_TYPE.AGENT]: "bg-primary-950",
55
- [_chunkPOT3ALY3js.SUPPORT_CHAT_MESSAGE_TYPE.INTERNAL_NOTE]: "bg-exam-3 border border-warning-200"
51
+ [_chunk5DINXU6Wjs.SUPPORT_CHAT_MESSAGE_TYPE.USER]: "bg-background-100",
52
+ [_chunk5DINXU6Wjs.SUPPORT_CHAT_MESSAGE_TYPE.GUEST]: "bg-background-100",
53
+ [_chunk5DINXU6Wjs.SUPPORT_CHAT_MESSAGE_TYPE.AI]: "bg-primary-50/60 border border-primary-100",
54
+ [_chunk5DINXU6Wjs.SUPPORT_CHAT_MESSAGE_TYPE.AGENT]: "bg-primary-950",
55
+ [_chunk5DINXU6Wjs.SUPPORT_CHAT_MESSAGE_TYPE.INTERNAL_NOTE]: "bg-exam-3 border border-warning-200"
56
56
  };
57
57
  function AiAvatar() {
58
58
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
@@ -136,16 +136,16 @@ function SupportChatMessage({
136
136
  author,
137
137
  faq,
138
138
  attachments,
139
- status = _chunkPOT3ALY3js.SUPPORT_CHAT_SEND_STATUS.SENT,
139
+ status = _chunk5DINXU6Wjs.SUPPORT_CHAT_SEND_STATUS.SENT,
140
140
  onRetry,
141
141
  className
142
142
  }) {
143
- const isAi = type === _chunkPOT3ALY3js.SUPPORT_CHAT_MESSAGE_TYPE.AI;
144
- const isAgent = type === _chunkPOT3ALY3js.SUPPORT_CHAT_MESSAGE_TYPE.AGENT;
145
- const isNote = type === _chunkPOT3ALY3js.SUPPORT_CHAT_MESSAGE_TYPE.INTERNAL_NOTE;
143
+ const isAi = type === _chunk5DINXU6Wjs.SUPPORT_CHAT_MESSAGE_TYPE.AI;
144
+ const isAgent = type === _chunk5DINXU6Wjs.SUPPORT_CHAT_MESSAGE_TYPE.AGENT;
145
+ const isNote = type === _chunk5DINXU6Wjs.SUPPORT_CHAT_MESSAGE_TYPE.INTERNAL_NOTE;
146
146
  const isRight = isAgent || isNote;
147
- const isSending = status === _chunkPOT3ALY3js.SUPPORT_CHAT_SEND_STATUS.SENDING;
148
- const isFailed = status === _chunkPOT3ALY3js.SUPPORT_CHAT_SEND_STATUS.FAILED;
147
+ const isSending = status === _chunk5DINXU6Wjs.SUPPORT_CHAT_SEND_STATUS.SENDING;
148
+ const isFailed = status === _chunk5DINXU6Wjs.SUPPORT_CHAT_SEND_STATUS.FAILED;
149
149
  const avatar = isAi ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AiAvatar, {}) : author && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, InitialsAvatar, { author });
150
150
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
151
151
  "div",
@@ -270,4 +270,4 @@ function SupportChatMessage({
270
270
 
271
271
 
272
272
  exports.SupportChatMessage = SupportChatMessage;
273
- //# sourceMappingURL=chunk-EMWX6IKP.js.map
273
+ //# sourceMappingURL=chunk-7VJP5D26.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-EMWX6IKP.js","../src/components/SupportChat/SupportChatMessage.tsx","../src/assets/icons/Sparkle.tsx"],"names":["jsx"],"mappings":"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","file":"/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-EMWX6IKP.js","sourcesContent":[null,"import { FileIcon } from '@phosphor-icons/react/dist/csr/File';\nimport { WarningCircleIcon } from '@phosphor-icons/react/dist/csr/WarningCircle';\nimport Text from '../Text/Text';\nimport Button from '../Button/Button';\nimport Sparkle from '../../assets/icons/Sparkle';\nimport { cn } from '../../utils/utils';\nimport { getInitials } from '../../utils/getInitials';\nimport {\n SUPPORT_CHAT_MESSAGE_TYPE,\n SUPPORT_CHAT_SEND_STATUS,\n type SupportChatAttachment,\n type SupportChatAuthor,\n type SupportChatFaqReference,\n type SupportChatMessageType,\n type SupportChatSendStatus,\n} from '../../types/supportChat';\n\n/**\n * Props for a support (SAC) chat message\n */\nexport interface SupportChatMessageProps {\n /** Who authored the message (user, AI assistant, agent or internal note) */\n type: SupportChatMessageType;\n /** Message body; line breaks are preserved */\n text: string;\n /** Already formatted time, e.g. \"13:52\" */\n time: string;\n /** Author shown in the avatar (and as the name for agents/notes) */\n author?: SupportChatAuthor;\n /** FAQ the AI answer was based on (AI messages only) */\n faq?: SupportChatFaqReference;\n /** Files attached to the message */\n attachments?: SupportChatAttachment[];\n /** Delivery status; defaults to SENT */\n status?: SupportChatSendStatus;\n /** Called when the user clicks \"Tentar novamente\" on a failed message */\n onRetry?: () => void;\n /** Extra classes for the root element */\n className?: string;\n}\n\n/** Bubble classes for each message type */\nconst BUBBLE_CLASSES: Record<SupportChatMessageType, string> = {\n [SUPPORT_CHAT_MESSAGE_TYPE.USER]: 'bg-background-100',\n [SUPPORT_CHAT_MESSAGE_TYPE.GUEST]: 'bg-background-100',\n [SUPPORT_CHAT_MESSAGE_TYPE.AI]: 'bg-primary-50/60 border border-primary-100',\n [SUPPORT_CHAT_MESSAGE_TYPE.AGENT]: 'bg-primary-950',\n [SUPPORT_CHAT_MESSAGE_TYPE.INTERNAL_NOTE]:\n 'bg-exam-3 border border-warning-200',\n};\n\n/**\n * Avatar for the virtual assistant (sparkle icon)\n */\nfunction AiAvatar() {\n return (\n <div\n role=\"img\"\n aria-label=\"Assistente virtual\"\n className=\"flex size-6 shrink-0 items-center justify-center rounded-full border border-primary-100 bg-primary-50 text-primary-800\"\n >\n <Sparkle\n width={12}\n height={12}\n aria-hidden=\"true\"\n data-testid=\"support-chat-ai-sparkle\"\n />\n </div>\n );\n}\n\n/**\n * Avatar with the author's initials\n */\nfunction InitialsAvatar({ author }: Readonly<{ author: SupportChatAuthor }>) {\n return (\n <div\n role=\"img\"\n aria-label={author.name}\n className={cn(\n 'flex size-6 shrink-0 items-center justify-center rounded-full bg-primary-800',\n author.avatarClassName\n )}\n >\n <Text size=\"2xs\" weight=\"bold\" color=\"text-white\" aria-hidden=\"true\">\n {author.initials ?? getInitials(author.name)}\n </Text>\n </div>\n );\n}\n\n/**\n * Single attachment: image thumbnail or generic file icon, plus the file name\n */\nfunction AttachmentItem({\n attachment,\n isDark,\n}: Readonly<{ attachment: SupportChatAttachment; isDark: boolean }>) {\n const isImage = attachment.mimeType?.startsWith('image/') ?? false;\n return (\n <a\n href={attachment.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex max-w-full items-center gap-2\"\n >\n {isImage ? (\n <img\n src={attachment.url}\n alt={attachment.fileName}\n className=\"size-16 shrink-0 rounded-lg object-cover\"\n />\n ) : (\n <FileIcon\n size={20}\n aria-hidden=\"true\"\n className={cn('shrink-0', isDark ? 'text-white' : 'text-text-700')}\n />\n )}\n <Text\n as=\"span\"\n size=\"xs\"\n color={isDark ? 'text-white' : 'text-text-700'}\n className=\"truncate underline\"\n >\n {attachment.fileName}\n </Text>\n </a>\n );\n}\n\n/**\n * Support (SAC) chat message bubble.\n *\n * - USER: light gray bubble on the left with an initials avatar\n * - AI: light blue bubble on the left labeled \"ASSISTENTE VIRTUAL\", with an optional FAQ reference\n * - AGENT: dark blue bubble on the right with the agent name and avatar\n * - INTERNAL_NOTE: yellow bubble on the right, visible only in the backoffice\n */\nexport default function SupportChatMessage({\n type,\n text,\n time,\n author,\n faq,\n attachments,\n status = SUPPORT_CHAT_SEND_STATUS.SENT,\n onRetry,\n className,\n}: Readonly<SupportChatMessageProps>) {\n const isAi = type === SUPPORT_CHAT_MESSAGE_TYPE.AI;\n const isAgent = type === SUPPORT_CHAT_MESSAGE_TYPE.AGENT;\n const isNote = type === SUPPORT_CHAT_MESSAGE_TYPE.INTERNAL_NOTE;\n const isRight = isAgent || isNote;\n const isSending = status === SUPPORT_CHAT_SEND_STATUS.SENDING;\n const isFailed = status === SUPPORT_CHAT_SEND_STATUS.FAILED;\n\n const avatar = isAi ? (\n <AiAvatar />\n ) : (\n author && <InitialsAvatar author={author} />\n );\n\n return (\n <div\n className={cn(\n 'flex w-full items-end gap-2',\n isRight ? 'justify-end' : 'justify-start',\n className\n )}\n >\n {!isRight && avatar}\n\n <div\n className={cn(\n 'flex min-w-0 max-w-[85%] flex-col gap-1 sm:max-w-[498px]',\n isRight ? 'items-end' : 'items-start'\n )}\n >\n <div\n data-testid=\"support-chat-message-bubble\"\n className={cn(\n 'flex max-w-full flex-col gap-1.5 rounded-xl px-3.5 py-2.5',\n BUBBLE_CLASSES[type],\n isSending && 'opacity-60'\n )}\n >\n {isAi && (\n <Text\n size=\"2xs\"\n weight=\"bold\"\n color=\"text-primary-800\"\n className=\"uppercase tracking-wider\"\n >\n Assistente virtual\n </Text>\n )}\n\n {isNote && (\n <Text\n size=\"2xs\"\n weight=\"bold\"\n color=\"text-warning-700\"\n className=\"uppercase tracking-wider\"\n >\n {author ? `Nota interna · ${author.name}` : 'Nota interna'}\n </Text>\n )}\n\n {isAgent && author && (\n <Text size=\"2xs\" weight=\"bold\" color=\"text-primary-100\">\n {author.name}\n </Text>\n )}\n\n <Text\n size=\"sm\"\n color={isAgent ? 'text-white' : 'text-text-950'}\n className=\"whitespace-pre-wrap break-words\"\n >\n {text}\n </Text>\n\n {Array.isArray(attachments) && attachments.length > 0 && (\n <div className=\"flex flex-col gap-2\">\n {attachments.map((attachment) => (\n <AttachmentItem\n key={attachment.id}\n attachment={attachment}\n isDark={isAgent}\n />\n ))}\n </div>\n )}\n\n {isAi && faq && (\n <div className=\"self-stretch border-t border-primary-100 pt-1.5\">\n {faq.onClick ? (\n <Button\n variant=\"link\"\n size=\"extra-small\"\n onClick={faq.onClick}\n className=\"p-0 text-left font-normal text-primary-800\"\n >\n Baseado na FAQ: {faq.title}\n </Button>\n ) : (\n <Text size=\"xs\" color=\"text-primary-800\">\n Baseado na FAQ: {faq.title}\n </Text>\n )}\n </div>\n )}\n </div>\n\n <div className=\"flex items-center gap-2\">\n {isFailed && (\n <>\n <WarningCircleIcon\n size={14}\n aria-hidden=\"true\"\n className=\"text-error-600\"\n />\n <Text as=\"span\" size=\"2xs\" color=\"text-error-600\">\n Falha no envio\n </Text>\n {onRetry && (\n <Button\n variant=\"link\"\n action=\"negative\"\n size=\"extra-small\"\n onClick={onRetry}\n className=\"p-0\"\n >\n Tentar novamente\n </Button>\n )}\n </>\n )}\n {isSending && (\n <Text as=\"span\" size=\"2xs\" color=\"text-text-400\">\n Enviando…\n </Text>\n )}\n <Text as=\"span\" size=\"2xs\" color=\"text-text-400\">\n {time}\n </Text>\n </div>\n </div>\n\n {isRight && avatar}\n </div>\n );\n}\n","import { SVGProps } from 'react';\n\n/**\n * Outlined four-point sparkle icon (Figma \"icon/sparkle\").\n * 24x24 grid, 2px stroke; color follows `currentColor`.\n */\nconst Sparkle = (props: SVGProps<SVGSVGElement>) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M12 3C12.6 7.4 15.6 10.1 20 10.75C15.6 11.4 12.6 14.1 12 18.5C11.4 14.1 8.4 11.4 4 10.75C8.4 10.1 11.4 7.4 12 3Z\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n};\n\nexport default Sparkle;\n"]}
1
+ {"version":3,"sources":["/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-7VJP5D26.js","../src/components/SupportChat/SupportChatMessage.tsx","../src/assets/icons/Sparkle.tsx"],"names":["jsx"],"mappings":"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","file":"/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-7VJP5D26.js","sourcesContent":[null,"import { FileIcon } from '@phosphor-icons/react/dist/csr/File';\nimport { WarningCircleIcon } from '@phosphor-icons/react/dist/csr/WarningCircle';\nimport Text from '../Text/Text';\nimport Button from '../Button/Button';\nimport Sparkle from '../../assets/icons/Sparkle';\nimport { cn } from '../../utils/utils';\nimport { getInitials } from '../../utils/getInitials';\nimport {\n SUPPORT_CHAT_MESSAGE_TYPE,\n SUPPORT_CHAT_SEND_STATUS,\n type SupportChatAttachment,\n type SupportChatAuthor,\n type SupportChatFaqReference,\n type SupportChatMessageType,\n type SupportChatSendStatus,\n} from '../../types/supportChat';\n\n/**\n * Props for a support (SAC) chat message\n */\nexport interface SupportChatMessageProps {\n /** Who authored the message (user, AI assistant, agent or internal note) */\n type: SupportChatMessageType;\n /** Message body; line breaks are preserved */\n text: string;\n /** Already formatted time, e.g. \"13:52\" */\n time: string;\n /** Author shown in the avatar (and as the name for agents/notes) */\n author?: SupportChatAuthor;\n /** FAQ the AI answer was based on (AI messages only) */\n faq?: SupportChatFaqReference;\n /** Files attached to the message */\n attachments?: SupportChatAttachment[];\n /** Delivery status; defaults to SENT */\n status?: SupportChatSendStatus;\n /** Called when the user clicks \"Tentar novamente\" on a failed message */\n onRetry?: () => void;\n /** Extra classes for the root element */\n className?: string;\n}\n\n/** Bubble classes for each message type */\nconst BUBBLE_CLASSES: Record<SupportChatMessageType, string> = {\n [SUPPORT_CHAT_MESSAGE_TYPE.USER]: 'bg-background-100',\n [SUPPORT_CHAT_MESSAGE_TYPE.GUEST]: 'bg-background-100',\n [SUPPORT_CHAT_MESSAGE_TYPE.AI]: 'bg-primary-50/60 border border-primary-100',\n [SUPPORT_CHAT_MESSAGE_TYPE.AGENT]: 'bg-primary-950',\n [SUPPORT_CHAT_MESSAGE_TYPE.INTERNAL_NOTE]:\n 'bg-exam-3 border border-warning-200',\n};\n\n/**\n * Avatar for the virtual assistant (sparkle icon)\n */\nfunction AiAvatar() {\n return (\n <div\n role=\"img\"\n aria-label=\"Assistente virtual\"\n className=\"flex size-6 shrink-0 items-center justify-center rounded-full border border-primary-100 bg-primary-50 text-primary-800\"\n >\n <Sparkle\n width={12}\n height={12}\n aria-hidden=\"true\"\n data-testid=\"support-chat-ai-sparkle\"\n />\n </div>\n );\n}\n\n/**\n * Avatar with the author's initials\n */\nfunction InitialsAvatar({ author }: Readonly<{ author: SupportChatAuthor }>) {\n return (\n <div\n role=\"img\"\n aria-label={author.name}\n className={cn(\n 'flex size-6 shrink-0 items-center justify-center rounded-full bg-primary-800',\n author.avatarClassName\n )}\n >\n <Text size=\"2xs\" weight=\"bold\" color=\"text-white\" aria-hidden=\"true\">\n {author.initials ?? getInitials(author.name)}\n </Text>\n </div>\n );\n}\n\n/**\n * Single attachment: image thumbnail or generic file icon, plus the file name\n */\nfunction AttachmentItem({\n attachment,\n isDark,\n}: Readonly<{ attachment: SupportChatAttachment; isDark: boolean }>) {\n const isImage = attachment.mimeType?.startsWith('image/') ?? false;\n return (\n <a\n href={attachment.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex max-w-full items-center gap-2\"\n >\n {isImage ? (\n <img\n src={attachment.url}\n alt={attachment.fileName}\n className=\"size-16 shrink-0 rounded-lg object-cover\"\n />\n ) : (\n <FileIcon\n size={20}\n aria-hidden=\"true\"\n className={cn('shrink-0', isDark ? 'text-white' : 'text-text-700')}\n />\n )}\n <Text\n as=\"span\"\n size=\"xs\"\n color={isDark ? 'text-white' : 'text-text-700'}\n className=\"truncate underline\"\n >\n {attachment.fileName}\n </Text>\n </a>\n );\n}\n\n/**\n * Support (SAC) chat message bubble.\n *\n * - USER: light gray bubble on the left with an initials avatar\n * - AI: light blue bubble on the left labeled \"ASSISTENTE VIRTUAL\", with an optional FAQ reference\n * - AGENT: dark blue bubble on the right with the agent name and avatar\n * - INTERNAL_NOTE: yellow bubble on the right, visible only in the backoffice\n */\nexport default function SupportChatMessage({\n type,\n text,\n time,\n author,\n faq,\n attachments,\n status = SUPPORT_CHAT_SEND_STATUS.SENT,\n onRetry,\n className,\n}: Readonly<SupportChatMessageProps>) {\n const isAi = type === SUPPORT_CHAT_MESSAGE_TYPE.AI;\n const isAgent = type === SUPPORT_CHAT_MESSAGE_TYPE.AGENT;\n const isNote = type === SUPPORT_CHAT_MESSAGE_TYPE.INTERNAL_NOTE;\n const isRight = isAgent || isNote;\n const isSending = status === SUPPORT_CHAT_SEND_STATUS.SENDING;\n const isFailed = status === SUPPORT_CHAT_SEND_STATUS.FAILED;\n\n const avatar = isAi ? (\n <AiAvatar />\n ) : (\n author && <InitialsAvatar author={author} />\n );\n\n return (\n <div\n className={cn(\n 'flex w-full items-end gap-2',\n isRight ? 'justify-end' : 'justify-start',\n className\n )}\n >\n {!isRight && avatar}\n\n <div\n className={cn(\n 'flex min-w-0 max-w-[85%] flex-col gap-1 sm:max-w-[498px]',\n isRight ? 'items-end' : 'items-start'\n )}\n >\n <div\n data-testid=\"support-chat-message-bubble\"\n className={cn(\n 'flex max-w-full flex-col gap-1.5 rounded-xl px-3.5 py-2.5',\n BUBBLE_CLASSES[type],\n isSending && 'opacity-60'\n )}\n >\n {isAi && (\n <Text\n size=\"2xs\"\n weight=\"bold\"\n color=\"text-primary-800\"\n className=\"uppercase tracking-wider\"\n >\n Assistente virtual\n </Text>\n )}\n\n {isNote && (\n <Text\n size=\"2xs\"\n weight=\"bold\"\n color=\"text-warning-700\"\n className=\"uppercase tracking-wider\"\n >\n {author ? `Nota interna · ${author.name}` : 'Nota interna'}\n </Text>\n )}\n\n {isAgent && author && (\n <Text size=\"2xs\" weight=\"bold\" color=\"text-primary-100\">\n {author.name}\n </Text>\n )}\n\n <Text\n size=\"sm\"\n color={isAgent ? 'text-white' : 'text-text-950'}\n className=\"whitespace-pre-wrap break-words\"\n >\n {text}\n </Text>\n\n {Array.isArray(attachments) && attachments.length > 0 && (\n <div className=\"flex flex-col gap-2\">\n {attachments.map((attachment) => (\n <AttachmentItem\n key={attachment.id}\n attachment={attachment}\n isDark={isAgent}\n />\n ))}\n </div>\n )}\n\n {isAi && faq && (\n <div className=\"self-stretch border-t border-primary-100 pt-1.5\">\n {faq.onClick ? (\n <Button\n variant=\"link\"\n size=\"extra-small\"\n onClick={faq.onClick}\n className=\"p-0 text-left font-normal text-primary-800\"\n >\n Baseado na FAQ: {faq.title}\n </Button>\n ) : (\n <Text size=\"xs\" color=\"text-primary-800\">\n Baseado na FAQ: {faq.title}\n </Text>\n )}\n </div>\n )}\n </div>\n\n <div className=\"flex items-center gap-2\">\n {isFailed && (\n <>\n <WarningCircleIcon\n size={14}\n aria-hidden=\"true\"\n className=\"text-error-600\"\n />\n <Text as=\"span\" size=\"2xs\" color=\"text-error-600\">\n Falha no envio\n </Text>\n {onRetry && (\n <Button\n variant=\"link\"\n action=\"negative\"\n size=\"extra-small\"\n onClick={onRetry}\n className=\"p-0\"\n >\n Tentar novamente\n </Button>\n )}\n </>\n )}\n {isSending && (\n <Text as=\"span\" size=\"2xs\" color=\"text-text-400\">\n Enviando…\n </Text>\n )}\n <Text as=\"span\" size=\"2xs\" color=\"text-text-400\">\n {time}\n </Text>\n </div>\n </div>\n\n {isRight && avatar}\n </div>\n );\n}\n","import { SVGProps } from 'react';\n\n/**\n * Outlined four-point sparkle icon (Figma \"icon/sparkle\").\n * 24x24 grid, 2px stroke; color follows `currentColor`.\n */\nconst Sparkle = (props: SVGProps<SVGSVGElement>) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M12 3C12.6 7.4 15.6 10.1 20 10.75C15.6 11.4 12.6 14.1 12 18.5C11.4 14.1 8.4 11.4 4 10.75C8.4 10.1 11.4 7.4 12 3Z\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n};\n\nexport default Sparkle;\n"]}
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-4V2UAEJP.mjs";
7
7
  import {
8
8
  Modal_default
9
- } from "./chunk-XZUMD3CB.mjs";
9
+ } from "./chunk-LODDYDTP.mjs";
10
10
  import {
11
11
  readingFluencyBird_default
12
12
  } from "./chunk-MEUREWL3.mjs";
@@ -949,4 +949,4 @@ export {
949
949
  ProfileMenuReadingFluencyFooter,
950
950
  DropdownMenu_default
951
951
  };
952
- //# sourceMappingURL=chunk-HCQJR5CE.mjs.map
952
+ //# sourceMappingURL=chunk-7ZWEBNFB.mjs.map
@@ -16,7 +16,7 @@ import {
16
16
  DropdownMenuItem,
17
17
  DropdownMenuTrigger,
18
18
  DropdownMenu_default
19
- } from "./chunk-HCQJR5CE.mjs";
19
+ } from "./chunk-7ZWEBNFB.mjs";
20
20
  import {
21
21
  Text_default
22
22
  } from "./chunk-IMCIR6TJ.mjs";
@@ -188,4 +188,4 @@ function SupportConversationHeader({
188
188
  export {
189
189
  SupportConversationHeader
190
190
  };
191
- //# sourceMappingURL=chunk-3RHNJUXU.mjs.map
191
+ //# sourceMappingURL=chunk-ACSEJOW6.mjs.map
@@ -18,10 +18,10 @@ import {
18
18
  DropdownMenuItem,
19
19
  DropdownMenuTrigger,
20
20
  DropdownMenu_default
21
- } from "./chunk-HCQJR5CE.mjs";
21
+ } from "./chunk-7ZWEBNFB.mjs";
22
22
  import {
23
23
  Modal_default
24
- } from "./chunk-XZUMD3CB.mjs";
24
+ } from "./chunk-LODDYDTP.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-WQZHUW7C.mjs.map
654
+ //# sourceMappingURL=chunk-ANFHLSDB.mjs.map
@@ -17,7 +17,7 @@ import {
17
17
  } from "./chunk-N26PFH64.mjs";
18
18
  import {
19
19
  Modal_default
20
- } from "./chunk-XZUMD3CB.mjs";
20
+ } from "./chunk-LODDYDTP.mjs";
21
21
  import {
22
22
  Text_default
23
23
  } from "./chunk-IMCIR6TJ.mjs";
@@ -267,4 +267,4 @@ export {
267
267
  PerformanceReportModal,
268
268
  PerformanceReportModal_default
269
269
  };
270
- //# sourceMappingURL=chunk-H6NQOLQY.mjs.map
270
+ //# sourceMappingURL=chunk-ANFLWCVD.mjs.map
@@ -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 _chunk23PAYKWBjs = require('./chunk-23PAYKWB.js');
3
+ var _chunkKM27ZDHZjs = require('./chunk-KM27ZDHZ.js');
4
4
 
5
5
 
6
6
  var _chunkTN3AYOMVjs = require('./chunk-TN3AYOMV.js');
@@ -147,7 +147,7 @@ var Whiteboard = ({
147
147
  image.id
148
148
  )) }),
149
149
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
150
- _chunk23PAYKWBjs.Modal_default,
150
+ _chunkKM27ZDHZjs.Modal_default,
151
151
  {
152
152
  isOpen: previewImage !== null,
153
153
  onClose: () => setPreviewImageId(null),
@@ -172,4 +172,4 @@ var Whiteboard_default = Whiteboard;
172
172
 
173
173
 
174
174
  exports.Whiteboard_default = Whiteboard_default;
175
- //# sourceMappingURL=chunk-BKBDQXZX.js.map
175
+ //# sourceMappingURL=chunk-AOYPUZRO.js.map