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.
- package/dist/AccessReportModal/index.js +3 -3
- package/dist/AccessReportModal/index.mjs +2 -2
- package/dist/ActivitiesHistory/index.js +49 -49
- package/dist/ActivitiesHistory/index.mjs +48 -48
- package/dist/ActivityCardQuestionBanks/index.js +49 -49
- package/dist/ActivityCardQuestionBanks/index.mjs +48 -48
- package/dist/ActivityCardQuestionPreview/index.js +49 -49
- package/dist/ActivityCardQuestionPreview/index.mjs +48 -48
- package/dist/ActivityCreate/ActivityCreateContent/index.js +49 -49
- package/dist/ActivityCreate/ActivityCreateContent/index.mjs +48 -48
- package/dist/ActivityCreate/index.js +49 -49
- package/dist/ActivityCreate/index.mjs +48 -48
- package/dist/ActivityDetails/index.js +49 -49
- package/dist/ActivityDetails/index.mjs +48 -48
- package/dist/ActivityFilters/index.js +49 -49
- package/dist/ActivityFilters/index.mjs +48 -48
- package/dist/ActivityPageLayout/index.js +49 -49
- package/dist/ActivityPageLayout/index.mjs +48 -48
- package/dist/ActivityPreview/index.js +49 -49
- package/dist/ActivityPreview/index.mjs +48 -48
- package/dist/AlertManager/index.js +49 -49
- package/dist/AlertManager/index.mjs +48 -48
- package/dist/AlertManagerView/index.js +3 -3
- package/dist/AlertManagerView/index.mjs +2 -2
- package/dist/AnnouncementModal/index.js +3 -3
- package/dist/AnnouncementModal/index.mjs +2 -2
- package/dist/AnnouncementsGate/index.js +4 -4
- package/dist/AnnouncementsGate/index.mjs +3 -3
- package/dist/AnswerKeyModal/index.js +3 -3
- package/dist/AnswerKeyModal/index.mjs +2 -2
- package/dist/AppHeader/index.js +6 -6
- package/dist/AppHeader/index.mjs +5 -5
- package/dist/CalendarCard/index.js +4 -4
- package/dist/CalendarCard/index.mjs +3 -3
- package/dist/Chat/index.js +3 -3
- package/dist/Chat/index.mjs +2 -2
- package/dist/CheckBox/index.d.ts.map +1 -1
- package/dist/CheckBox/index.js +2 -2
- package/dist/CheckBox/index.mjs +1 -1
- package/dist/CheckBoxGroup/index.js +49 -49
- package/dist/CheckBoxGroup/index.mjs +48 -48
- package/dist/ComparatorChart/ComparatorView/index.js +3 -3
- package/dist/ComparatorChart/ComparatorView/index.mjs +2 -2
- package/dist/CorrectActivityModal/index.js +7 -7
- package/dist/CorrectActivityModal/index.mjs +6 -6
- package/dist/DownloadButton/index.js +4 -4
- package/dist/DownloadButton/index.mjs +3 -3
- package/dist/DownloadModal/index.js +3 -3
- package/dist/DownloadModal/index.mjs +2 -2
- package/dist/DropdownMenu/index.js +3 -3
- package/dist/DropdownMenu/index.mjs +2 -2
- package/dist/EnemClassroomStartModal/index.d.ts.map +1 -1
- package/dist/EnemClassroomStartModal/index.js +7 -7
- package/dist/EnemClassroomStartModal/index.mjs +6 -6
- package/dist/EnemMoment/index.js +57 -57
- package/dist/EnemMoment/index.mjs +51 -51
- package/dist/EnemMomentStudentModal/index.js +50 -50
- package/dist/EnemMomentStudentModal/index.mjs +48 -48
- package/dist/ExamDetailsLayout/ExamDetailsPage/index.js +49 -49
- package/dist/ExamDetailsLayout/ExamDetailsPage/index.mjs +48 -48
- package/dist/ExamPageLayout/index.js +49 -49
- package/dist/ExamPageLayout/index.mjs +48 -48
- package/dist/Forum/index.js +5 -5
- package/dist/Forum/index.mjs +4 -4
- package/dist/KnowledgePerformanceCard/index.js +51 -51
- package/dist/KnowledgePerformanceCard/index.mjs +50 -50
- package/dist/LessonCardPreview/index.js +49 -49
- package/dist/LessonCardPreview/index.mjs +48 -48
- package/dist/LessonMediaSections/index.js +49 -49
- package/dist/LessonMediaSections/index.mjs +48 -48
- package/dist/LessonsCatalog/index.js +49 -49
- package/dist/LessonsCatalog/index.mjs +48 -48
- package/dist/Modal/index.d.ts.map +1 -1
- package/dist/Modal/index.js +2 -2
- package/dist/Modal/index.mjs +1 -1
- package/dist/MultiCheckSelect/index.js +5 -5
- package/dist/MultiCheckSelect/index.mjs +4 -4
- package/dist/MultiSearchSelect/index.js +3 -3
- package/dist/MultiSearchSelect/index.mjs +2 -2
- package/dist/MultipleChoice/index.js +3 -3
- package/dist/MultipleChoice/index.mjs +2 -2
- package/dist/NotificationCard/index.js +4 -4
- package/dist/NotificationCard/index.mjs +3 -3
- package/dist/PerformanceReportModal/index.js +3 -3
- package/dist/PerformanceReportModal/index.mjs +2 -2
- package/dist/PrintableUsersTable/index.js +49 -49
- package/dist/PrintableUsersTable/index.mjs +48 -48
- package/dist/ProgressModal/index.js +3 -3
- package/dist/ProgressModal/index.mjs +2 -2
- package/dist/QuestionsPerformanceCard/index.js +50 -50
- package/dist/QuestionsPerformanceCard/index.mjs +49 -49
- package/dist/Quiz/index.js +6 -6
- package/dist/Quiz/index.mjs +5 -5
- package/dist/RecommendedLessonCreate/index.js +49 -49
- package/dist/RecommendedLessonCreate/index.mjs +48 -48
- package/dist/RecommendedLessonDetails/index.js +7 -7
- package/dist/RecommendedLessonDetails/index.mjs +6 -6
- package/dist/RecommendedLessonsHistory/index.js +49 -49
- package/dist/RecommendedLessonsHistory/index.mjs +48 -48
- package/dist/ReportDetailModal/index.js +4 -4
- package/dist/ReportDetailModal/index.mjs +3 -3
- package/dist/RichEditor/index.js +5 -5
- package/dist/RichEditor/index.mjs +4 -4
- package/dist/{RichEditorCore-6MTYSSKS.mjs → RichEditorCore-2S5YUAOI.mjs} +5 -5
- package/dist/{RichEditorCore-KDARBEK4.js → RichEditorCore-N7A2445B.js} +16 -16
- package/dist/{RichEditorCore-KDARBEK4.js.map → RichEditorCore-N7A2445B.js.map} +1 -1
- package/dist/Search/index.js +4 -4
- package/dist/Search/index.mjs +3 -3
- package/dist/SendActivityModal/SendActivityModal.js +49 -49
- package/dist/SendActivityModal/SendActivityModal.mjs +48 -48
- package/dist/SendActivityModal/index.js +49 -49
- package/dist/SendActivityModal/index.mjs +48 -48
- package/dist/SendLessonModal/index.js +49 -49
- package/dist/SendLessonModal/index.mjs +48 -48
- package/dist/SimulatedPerformance/SimulatedPerformanceView/index.js +49 -49
- package/dist/SimulatedPerformance/SimulatedPerformanceView/index.mjs +48 -48
- package/dist/SimulatedPerformance/useSimulatedPerformance/index.js +5 -5
- package/dist/SimulatedPerformance/useSimulatedPerformance/index.mjs +4 -4
- package/dist/SimulatedStudentSimulationsModal/index.js +6 -6
- package/dist/SimulatedStudentSimulationsModal/index.mjs +5 -5
- package/dist/SimulationsPage/index.js +49 -49
- package/dist/SimulationsPage/index.mjs +48 -48
- package/dist/StudentLessonProgressModal/index.js +3 -3
- package/dist/StudentLessonProgressModal/index.mjs +2 -2
- package/dist/StudentPerformanceDetailsModal/index.js +5 -5
- package/dist/StudentPerformanceDetailsModal/index.mjs +4 -4
- package/dist/Support/TicketModal/index.js +3 -3
- package/dist/Support/TicketModal/index.mjs +2 -2
- package/dist/Support/index.js +4 -4
- package/dist/Support/index.mjs +3 -3
- package/dist/SupportChatComposer/index.js +3 -3
- package/dist/SupportChatComposer/index.mjs +2 -2
- package/dist/SupportChatEvent/index.js +3 -3
- package/dist/SupportChatEvent/index.mjs +2 -2
- package/dist/SupportChatMessage/index.js +3 -3
- package/dist/SupportChatMessage/index.mjs +2 -2
- package/dist/SupportChatWidget/index.js +3 -3
- package/dist/SupportChatWidget/index.mjs +2 -2
- package/dist/SupportConcludeModal/index.js +4 -4
- package/dist/SupportConcludeModal/index.mjs +3 -3
- package/dist/SupportConversationHeader/index.js +4 -4
- package/dist/SupportConversationHeader/index.mjs +3 -3
- package/dist/SupportConversationMessages/index.js +5 -5
- package/dist/SupportConversationMessages/index.mjs +4 -4
- package/dist/SupportTicketConversation/index.js +12 -12
- package/dist/SupportTicketConversation/index.mjs +11 -11
- package/dist/TableProvider/index.js +49 -49
- package/dist/TableProvider/index.mjs +48 -48
- package/dist/UnifiedDraftModelPage/index.js +49 -49
- package/dist/UnifiedDraftModelPage/index.mjs +48 -48
- package/dist/UnifiedHistoryPage/index.js +49 -49
- package/dist/UnifiedHistoryPage/index.mjs +48 -48
- package/dist/VideoPlayer/index.js +5 -5
- package/dist/VideoPlayer/index.mjs +4 -4
- package/dist/Whiteboard/index.js +3 -3
- package/dist/Whiteboard/index.mjs +2 -2
- package/dist/{chunk-B6QOBHZM.mjs → chunk-24BEZK43.mjs} +2 -2
- package/dist/{chunk-CYSODZGX.js → chunk-27Y6V3GM.js} +169 -66
- package/dist/chunk-27Y6V3GM.js.map +1 -0
- package/dist/{chunk-OQTXTDSK.mjs → chunk-2OJ3QSLU.mjs} +3 -3
- package/dist/{chunk-VDUO65VK.mjs → chunk-3EGJJDIM.mjs} +2 -2
- package/dist/{chunk-VDUO65VK.mjs.map → chunk-3EGJJDIM.mjs.map} +1 -1
- package/dist/{chunk-4OUBPEVS.mjs → chunk-3HKLGNUE.mjs} +3 -3
- package/dist/{chunk-YA7XLH7D.js → chunk-3MFACEZ2.js} +3 -3
- package/dist/{chunk-YA7XLH7D.js.map → chunk-3MFACEZ2.js.map} +1 -1
- package/dist/{chunk-IHBWJM4C.mjs → chunk-3Q7RJKUP.mjs} +2 -2
- package/dist/{chunk-PY6WD6SB.mjs → chunk-3WRB4WCD.mjs} +4 -4
- package/dist/{chunk-4RHCBMMP.js → chunk-46VHAL4S.js} +3 -3
- package/dist/{chunk-4RHCBMMP.js.map → chunk-46VHAL4S.js.map} +1 -1
- package/dist/{chunk-POT3ALY3.js → chunk-5DINXU6W.js} +1 -1
- package/dist/{chunk-POT3ALY3.js.map → chunk-5DINXU6W.js.map} +1 -1
- package/dist/{chunk-L52NFNFK.mjs → chunk-5VC4BK65.mjs} +3 -3
- package/dist/{chunk-B67RLIUM.js → chunk-72D7G6YQ.js} +3 -3
- package/dist/{chunk-B67RLIUM.js.map → chunk-72D7G6YQ.js.map} +1 -1
- package/dist/{chunk-C65DG2RI.mjs → chunk-7FSBWUOM.mjs} +2 -2
- package/dist/{chunk-QWMFWYII.js → chunk-7IZNLARX.js} +3 -3
- package/dist/{chunk-QWMFWYII.js.map → chunk-7IZNLARX.js.map} +1 -1
- package/dist/{chunk-ZCBT2BUZ.js → chunk-7RFHXFFV.js} +13 -13
- package/dist/{chunk-ZCBT2BUZ.js.map → chunk-7RFHXFFV.js.map} +1 -1
- package/dist/{chunk-EMWX6IKP.js → chunk-7VJP5D26.js} +13 -13
- package/dist/{chunk-EMWX6IKP.js.map → chunk-7VJP5D26.js.map} +1 -1
- package/dist/{chunk-HCQJR5CE.mjs → chunk-7ZWEBNFB.mjs} +2 -2
- package/dist/{chunk-3RHNJUXU.mjs → chunk-ACSEJOW6.mjs} +2 -2
- package/dist/{chunk-WQZHUW7C.mjs → chunk-ANFHLSDB.mjs} +3 -3
- package/dist/{chunk-H6NQOLQY.mjs → chunk-ANFLWCVD.mjs} +2 -2
- package/dist/{chunk-BKBDQXZX.js → chunk-AOYPUZRO.js} +3 -3
- package/dist/{chunk-BKBDQXZX.js.map → chunk-AOYPUZRO.js.map} +1 -1
- package/dist/{chunk-5WS6IENQ.mjs → chunk-AU2HLQDJ.mjs} +2 -2
- package/dist/{chunk-P6FX3NT6.mjs → chunk-AZGDHAP5.mjs} +2 -2
- package/dist/{chunk-NCGO7FPB.js → chunk-AZKNYREH.js} +8 -8
- package/dist/{chunk-NCGO7FPB.js.map → chunk-AZKNYREH.js.map} +1 -1
- package/dist/{chunk-R6MTPYYW.js → chunk-AZTBNERQ.js} +3 -3
- package/dist/{chunk-R6MTPYYW.js.map → chunk-AZTBNERQ.js.map} +1 -1
- package/dist/{chunk-NPB2JTYC.mjs → chunk-BO3QVQ37.mjs} +4 -4
- package/dist/{chunk-2WI4Q2I2.mjs → chunk-BPMWRFSI.mjs} +4 -4
- package/dist/{chunk-TEW33GLR.mjs → chunk-BXN3VO6I.mjs} +2 -2
- package/dist/{chunk-7ZB3YHF2.mjs → chunk-C6LC5LD5.mjs} +1 -1
- package/dist/{chunk-7ZB3YHF2.mjs.map → chunk-C6LC5LD5.mjs.map} +1 -1
- package/dist/{chunk-5HONWYQA.js → chunk-C7ILTLT5.js} +3 -3
- package/dist/{chunk-5HONWYQA.js.map → chunk-C7ILTLT5.js.map} +1 -1
- package/dist/{chunk-OES54VU6.mjs → chunk-CFV2OZ3P.mjs} +116 -13
- package/dist/chunk-CFV2OZ3P.mjs.map +1 -0
- package/dist/{chunk-4OVIHZ3I.js → chunk-CGXWWPEA.js} +6 -6
- package/dist/{chunk-4OVIHZ3I.js.map → chunk-CGXWWPEA.js.map} +1 -1
- package/dist/{chunk-MNU45FM3.js → chunk-COT4KW3H.js} +2 -2
- package/dist/{chunk-MNU45FM3.js.map → chunk-COT4KW3H.js.map} +1 -1
- package/dist/{chunk-JDQUXG75.js → chunk-CVDNCU6L.js} +3 -3
- package/dist/{chunk-JDQUXG75.js.map → chunk-CVDNCU6L.js.map} +1 -1
- package/dist/{chunk-HBZHWSMZ.mjs → chunk-D46PJSQ7.mjs} +13 -13
- package/dist/{chunk-ARYIJ4RU.js → chunk-DDORKDQO.js} +3 -3
- package/dist/{chunk-ARYIJ4RU.js.map → chunk-DDORKDQO.js.map} +1 -1
- package/dist/{chunk-7YQTDJFA.js → chunk-DKXSR2V3.js} +3 -3
- package/dist/{chunk-7YQTDJFA.js.map → chunk-DKXSR2V3.js.map} +1 -1
- package/dist/{chunk-I6EAPPBL.mjs → chunk-DZMYIOKZ.mjs} +5 -5
- package/dist/{chunk-SKM7NFPY.js → chunk-EPXAFJVW.js} +6 -6
- package/dist/{chunk-SKM7NFPY.js.map → chunk-EPXAFJVW.js.map} +1 -1
- package/dist/{chunk-AYYMS23L.js → chunk-ESIQ2GB4.js} +7 -7
- package/dist/{chunk-AYYMS23L.js.map → chunk-ESIQ2GB4.js.map} +1 -1
- package/dist/{chunk-NU2WNYOD.js → chunk-EW7HGUFV.js} +87 -87
- package/dist/{chunk-NU2WNYOD.js.map → chunk-EW7HGUFV.js.map} +1 -1
- package/dist/{chunk-I4QGQMXI.mjs → chunk-EXYXZFNK.mjs} +2 -2
- package/dist/{chunk-RBJAO57A.js → chunk-FAAR4XC5.js} +3 -3
- package/dist/{chunk-RBJAO57A.js.map → chunk-FAAR4XC5.js.map} +1 -1
- package/dist/{chunk-N2VNE3ON.js → chunk-FDTDJDZI.js} +13 -13
- package/dist/{chunk-N2VNE3ON.js.map → chunk-FDTDJDZI.js.map} +1 -1
- package/dist/{chunk-SU5Q64TW.mjs → chunk-FVCTKS33.mjs} +6 -5
- package/dist/chunk-FVCTKS33.mjs.map +1 -0
- package/dist/{chunk-AVHZHWI3.js → chunk-GBIFSFWJ.js} +15 -15
- package/dist/{chunk-AVHZHWI3.js.map → chunk-GBIFSFWJ.js.map} +1 -1
- package/dist/{chunk-KSUPPAKH.js → chunk-GIQSHTB5.js} +9 -9
- package/dist/{chunk-KSUPPAKH.js.map → chunk-GIQSHTB5.js.map} +1 -1
- package/dist/{chunk-4QBKD4JN.js → chunk-GUUJYGXF.js} +3 -3
- package/dist/{chunk-4QBKD4JN.js.map → chunk-GUUJYGXF.js.map} +1 -1
- package/dist/{chunk-M4O46VDY.mjs → chunk-GX2PKLN2.mjs} +2 -2
- package/dist/{chunk-5BUTINIM.mjs → chunk-HLVLSWKD.mjs} +3 -3
- package/dist/{chunk-FU23WOTY.js → chunk-HSV5VZ4Z.js} +6 -6
- package/dist/{chunk-FU23WOTY.js.map → chunk-HSV5VZ4Z.js.map} +1 -1
- package/dist/{chunk-MMS2ELDK.mjs → chunk-IIQCS3A2.mjs} +2 -2
- package/dist/{chunk-NKWLCZUZ.mjs → chunk-JGGUMHM6.mjs} +2 -2
- package/dist/{chunk-HT2GREFH.js → chunk-JLD46DL7.js} +11 -11
- package/dist/{chunk-HT2GREFH.js.map → chunk-JLD46DL7.js.map} +1 -1
- package/dist/{chunk-NVL5TKWD.mjs → chunk-JYFLOQYT.mjs} +2 -2
- package/dist/{chunk-DWGDEUEW.mjs → chunk-KG563P7F.mjs} +5 -5
- package/dist/{chunk-TCIC5556.mjs → chunk-KH4TEDGD.mjs} +2 -2
- package/dist/{chunk-23PAYKWB.js → chunk-KM27ZDHZ.js} +2 -2
- package/dist/{chunk-23PAYKWB.js.map → chunk-KM27ZDHZ.js.map} +1 -1
- package/dist/{chunk-XZUMD3CB.mjs → chunk-LODDYDTP.mjs} +2 -2
- package/dist/{chunk-XZUMD3CB.mjs.map → chunk-LODDYDTP.mjs.map} +1 -1
- package/dist/{chunk-E6CGJBID.mjs → chunk-LUHKMY56.mjs} +2 -2
- package/dist/{chunk-TVLEUNKE.mjs → chunk-LZP5VZCO.mjs} +2 -2
- package/dist/{chunk-EHNEBXS7.mjs → chunk-M6DXZ2FM.mjs} +2 -2
- package/dist/{chunk-B4C5DWAP.mjs → chunk-MMMJDO75.mjs} +2 -2
- package/dist/{chunk-AFCWMJQO.js → chunk-MOUPNP53.js} +3 -3
- package/dist/{chunk-AFCWMJQO.js.map → chunk-MOUPNP53.js.map} +1 -1
- package/dist/{chunk-36KFIZ43.js → chunk-MYPUZ6EG.js} +3 -3
- package/dist/{chunk-36KFIZ43.js.map → chunk-MYPUZ6EG.js.map} +1 -1
- package/dist/{chunk-6JHIKIPA.js → chunk-NUGLTWEA.js} +23 -23
- package/dist/{chunk-6JHIKIPA.js.map → chunk-NUGLTWEA.js.map} +1 -1
- package/dist/{chunk-KWXOYHYK.mjs → chunk-P7MORXSE.mjs} +2 -2
- package/dist/{chunk-YG4IZ5Q3.mjs → chunk-Q2OSEROT.mjs} +2 -2
- package/dist/{chunk-L5SXG6T6.mjs → chunk-QQKOHKO2.mjs} +3 -3
- package/dist/{chunk-SADSJ2MV.js → chunk-QVGUYPXO.js} +3 -3
- package/dist/{chunk-SADSJ2MV.js.map → chunk-QVGUYPXO.js.map} +1 -1
- package/dist/{chunk-K45PTE7F.mjs → chunk-RBKQXT73.mjs} +4 -4
- package/dist/{chunk-JZFISWTP.js → chunk-RIN2IN7E.js} +2 -2
- package/dist/{chunk-JZFISWTP.js.map → chunk-RIN2IN7E.js.map} +1 -1
- package/dist/{chunk-BXLAOYAG.mjs → chunk-RIUVPTG7.mjs} +2 -2
- package/dist/{chunk-QVB54LBS.mjs → chunk-RNZGX6MX.mjs} +3 -3
- package/dist/{chunk-VSVLIRO2.js → chunk-RXEU77VN.js} +15 -15
- package/dist/{chunk-VSVLIRO2.js.map → chunk-RXEU77VN.js.map} +1 -1
- package/dist/{chunk-ZRIYCU2V.js → chunk-S2BZPPAI.js} +5 -5
- package/dist/{chunk-ZRIYCU2V.js.map → chunk-S2BZPPAI.js.map} +1 -1
- package/dist/{chunk-MES2BP4T.mjs → chunk-SGL5IUCV.mjs} +2 -2
- package/dist/{chunk-7LS5UQCQ.mjs → chunk-STKUPDHG.mjs} +2 -2
- package/dist/{chunk-PPYCCT2K.js → chunk-SWDVSCQJ.js} +9 -8
- package/dist/chunk-SWDVSCQJ.js.map +1 -0
- package/dist/{chunk-JCA76TCX.mjs → chunk-SZKLJOTN.mjs} +2 -2
- package/dist/{chunk-F5WR6XZZ.js → chunk-T73HPYF2.js} +3 -3
- package/dist/{chunk-F5WR6XZZ.js.map → chunk-T73HPYF2.js.map} +1 -1
- package/dist/{chunk-ZB6HDDE4.js → chunk-TQO37PVW.js} +14 -14
- package/dist/{chunk-ZB6HDDE4.js.map → chunk-TQO37PVW.js.map} +1 -1
- package/dist/{chunk-VKQ5AJDT.mjs → chunk-UENZQF2Y.mjs} +2 -2
- package/dist/{chunk-DCG7EUBC.js → chunk-UWLW5YVB.js} +6 -6
- package/dist/{chunk-DCG7EUBC.js.map → chunk-UWLW5YVB.js.map} +1 -1
- package/dist/{chunk-37AJ2GVO.mjs → chunk-UXJIZDXQ.mjs} +2 -2
- package/dist/{chunk-PLLPFCN3.js → chunk-UXMDPRAI.js} +14 -14
- package/dist/{chunk-PLLPFCN3.js.map → chunk-UXMDPRAI.js.map} +1 -1
- package/dist/{chunk-7BOTKRY6.mjs → chunk-V55DG5B4.mjs} +2 -2
- package/dist/{chunk-YRTIDZTN.js → chunk-VHEDMUAW.js} +4 -4
- package/dist/{chunk-YRTIDZTN.js.map → chunk-VHEDMUAW.js.map} +1 -1
- package/dist/{chunk-4RD55E4R.js → chunk-VWLWSO4J.js} +3 -3
- package/dist/{chunk-4RD55E4R.js.map → chunk-VWLWSO4J.js.map} +1 -1
- package/dist/{chunk-VJQIKFMG.mjs → chunk-W3CWEZDB.mjs} +3 -3
- package/dist/{chunk-JM6SLU7D.js → chunk-W7NNH4VY.js} +6 -6
- package/dist/{chunk-JM6SLU7D.js.map → chunk-W7NNH4VY.js.map} +1 -1
- package/dist/{chunk-VQ7MSYIH.js → chunk-WUN5NHZE.js} +4 -4
- package/dist/{chunk-VQ7MSYIH.js.map → chunk-WUN5NHZE.js.map} +1 -1
- package/dist/{chunk-AAU7ABJN.js → chunk-WWTRSQ3X.js} +3 -3
- package/dist/{chunk-AAU7ABJN.js.map → chunk-WWTRSQ3X.js.map} +1 -1
- package/dist/{chunk-BR6D2TGF.js → chunk-WZOA2PVJ.js} +3 -3
- package/dist/{chunk-BR6D2TGF.js.map → chunk-WZOA2PVJ.js.map} +1 -1
- package/dist/{chunk-TZKR5Z4J.mjs → chunk-XJF2F36N.mjs} +2 -2
- package/dist/{chunk-P6ACVNQK.mjs → chunk-YD2XBEKO.mjs} +2 -2
- package/dist/{chunk-LMXWIPGR.js → chunk-YWPLHFAK.js} +3 -3
- package/dist/{chunk-LMXWIPGR.js.map → chunk-YWPLHFAK.js.map} +1 -1
- package/dist/{chunk-DCEWWHV5.mjs → chunk-Z3HGYPH7.mjs} +2 -2
- package/dist/{chunk-Q3PKW6TH.js → chunk-ZCV3HWI2.js} +6 -6
- package/dist/{chunk-Q3PKW6TH.js.map → chunk-ZCV3HWI2.js.map} +1 -1
- package/dist/{chunk-OSA3YVDZ.mjs → chunk-ZF46DCAC.mjs} +2 -2
- package/dist/{chunk-5T6IDXSB.js → chunk-ZO2GA23I.js} +3 -3
- package/dist/{chunk-5T6IDXSB.js.map → chunk-ZO2GA23I.js.map} +1 -1
- package/dist/{chunk-ZN3763VZ.js → chunk-ZQLW4EJB.js} +9 -9
- package/dist/{chunk-ZN3763VZ.js.map → chunk-ZQLW4EJB.js.map} +1 -1
- package/dist/{chunk-CM5R4SPF.js → chunk-ZQQJTO6T.js} +3 -3
- package/dist/{chunk-CM5R4SPF.js.map → chunk-ZQQJTO6T.js.map} +1 -1
- package/dist/{chunk-SEL4QDCO.js → chunk-ZSXSAE3D.js} +3 -3
- package/dist/{chunk-SEL4QDCO.js.map → chunk-ZSXSAE3D.js.map} +1 -1
- package/dist/components/SupportChatWidget/guestSupportChatAdapter.d.ts +6 -1
- package/dist/components/SupportChatWidget/guestSupportChatAdapter.d.ts.map +1 -1
- package/dist/hooks/useAppContent/index.js +49 -49
- package/dist/hooks/useAppContent/index.mjs +48 -48
- package/dist/hooks/useSupportChat.d.ts +2 -0
- package/dist/hooks/useSupportChat.d.ts.map +1 -1
- package/dist/index.js +49 -49
- package/dist/index.mjs +48 -48
- package/dist/types/supportChat/index.d.ts +14 -0
- package/dist/types/supportChat/index.d.ts.map +1 -1
- package/dist/types/supportChat/index.js +2 -2
- package/dist/types/supportChat/index.mjs +1 -1
- package/dist/types/supportChat.d.ts +14 -0
- package/dist/types/supportChat.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-CYSODZGX.js.map +0 -1
- package/dist/chunk-OES54VU6.mjs.map +0 -1
- package/dist/chunk-PPYCCT2K.js.map +0 -1
- package/dist/chunk-SU5Q64TW.mjs.map +0 -1
- /package/dist/{RichEditorCore-6MTYSSKS.mjs.map → RichEditorCore-2S5YUAOI.mjs.map} +0 -0
- /package/dist/{chunk-B6QOBHZM.mjs.map → chunk-24BEZK43.mjs.map} +0 -0
- /package/dist/{chunk-OQTXTDSK.mjs.map → chunk-2OJ3QSLU.mjs.map} +0 -0
- /package/dist/{chunk-4OUBPEVS.mjs.map → chunk-3HKLGNUE.mjs.map} +0 -0
- /package/dist/{chunk-IHBWJM4C.mjs.map → chunk-3Q7RJKUP.mjs.map} +0 -0
- /package/dist/{chunk-PY6WD6SB.mjs.map → chunk-3WRB4WCD.mjs.map} +0 -0
- /package/dist/{chunk-L52NFNFK.mjs.map → chunk-5VC4BK65.mjs.map} +0 -0
- /package/dist/{chunk-C65DG2RI.mjs.map → chunk-7FSBWUOM.mjs.map} +0 -0
- /package/dist/{chunk-HCQJR5CE.mjs.map → chunk-7ZWEBNFB.mjs.map} +0 -0
- /package/dist/{chunk-3RHNJUXU.mjs.map → chunk-ACSEJOW6.mjs.map} +0 -0
- /package/dist/{chunk-WQZHUW7C.mjs.map → chunk-ANFHLSDB.mjs.map} +0 -0
- /package/dist/{chunk-H6NQOLQY.mjs.map → chunk-ANFLWCVD.mjs.map} +0 -0
- /package/dist/{chunk-5WS6IENQ.mjs.map → chunk-AU2HLQDJ.mjs.map} +0 -0
- /package/dist/{chunk-P6FX3NT6.mjs.map → chunk-AZGDHAP5.mjs.map} +0 -0
- /package/dist/{chunk-NPB2JTYC.mjs.map → chunk-BO3QVQ37.mjs.map} +0 -0
- /package/dist/{chunk-2WI4Q2I2.mjs.map → chunk-BPMWRFSI.mjs.map} +0 -0
- /package/dist/{chunk-TEW33GLR.mjs.map → chunk-BXN3VO6I.mjs.map} +0 -0
- /package/dist/{chunk-HBZHWSMZ.mjs.map → chunk-D46PJSQ7.mjs.map} +0 -0
- /package/dist/{chunk-I6EAPPBL.mjs.map → chunk-DZMYIOKZ.mjs.map} +0 -0
- /package/dist/{chunk-I4QGQMXI.mjs.map → chunk-EXYXZFNK.mjs.map} +0 -0
- /package/dist/{chunk-M4O46VDY.mjs.map → chunk-GX2PKLN2.mjs.map} +0 -0
- /package/dist/{chunk-5BUTINIM.mjs.map → chunk-HLVLSWKD.mjs.map} +0 -0
- /package/dist/{chunk-MMS2ELDK.mjs.map → chunk-IIQCS3A2.mjs.map} +0 -0
- /package/dist/{chunk-NKWLCZUZ.mjs.map → chunk-JGGUMHM6.mjs.map} +0 -0
- /package/dist/{chunk-NVL5TKWD.mjs.map → chunk-JYFLOQYT.mjs.map} +0 -0
- /package/dist/{chunk-DWGDEUEW.mjs.map → chunk-KG563P7F.mjs.map} +0 -0
- /package/dist/{chunk-TCIC5556.mjs.map → chunk-KH4TEDGD.mjs.map} +0 -0
- /package/dist/{chunk-E6CGJBID.mjs.map → chunk-LUHKMY56.mjs.map} +0 -0
- /package/dist/{chunk-TVLEUNKE.mjs.map → chunk-LZP5VZCO.mjs.map} +0 -0
- /package/dist/{chunk-EHNEBXS7.mjs.map → chunk-M6DXZ2FM.mjs.map} +0 -0
- /package/dist/{chunk-B4C5DWAP.mjs.map → chunk-MMMJDO75.mjs.map} +0 -0
- /package/dist/{chunk-KWXOYHYK.mjs.map → chunk-P7MORXSE.mjs.map} +0 -0
- /package/dist/{chunk-YG4IZ5Q3.mjs.map → chunk-Q2OSEROT.mjs.map} +0 -0
- /package/dist/{chunk-L5SXG6T6.mjs.map → chunk-QQKOHKO2.mjs.map} +0 -0
- /package/dist/{chunk-K45PTE7F.mjs.map → chunk-RBKQXT73.mjs.map} +0 -0
- /package/dist/{chunk-BXLAOYAG.mjs.map → chunk-RIUVPTG7.mjs.map} +0 -0
- /package/dist/{chunk-QVB54LBS.mjs.map → chunk-RNZGX6MX.mjs.map} +0 -0
- /package/dist/{chunk-MES2BP4T.mjs.map → chunk-SGL5IUCV.mjs.map} +0 -0
- /package/dist/{chunk-7LS5UQCQ.mjs.map → chunk-STKUPDHG.mjs.map} +0 -0
- /package/dist/{chunk-JCA76TCX.mjs.map → chunk-SZKLJOTN.mjs.map} +0 -0
- /package/dist/{chunk-VKQ5AJDT.mjs.map → chunk-UENZQF2Y.mjs.map} +0 -0
- /package/dist/{chunk-37AJ2GVO.mjs.map → chunk-UXJIZDXQ.mjs.map} +0 -0
- /package/dist/{chunk-7BOTKRY6.mjs.map → chunk-V55DG5B4.mjs.map} +0 -0
- /package/dist/{chunk-VJQIKFMG.mjs.map → chunk-W3CWEZDB.mjs.map} +0 -0
- /package/dist/{chunk-TZKR5Z4J.mjs.map → chunk-XJF2F36N.mjs.map} +0 -0
- /package/dist/{chunk-P6ACVNQK.mjs.map → chunk-YD2XBEKO.mjs.map} +0 -0
- /package/dist/{chunk-DCEWWHV5.mjs.map → chunk-Z3HGYPH7.mjs.map} +0 -0
- /package/dist/{chunk-OSA3YVDZ.mjs.map → chunk-ZF46DCAC.mjs.map} +0 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
var _chunkJZZ5DD3Rjs = require('./chunk-JZZ5DD3R.js');
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
var
|
|
6
|
+
var _chunkKM27ZDHZjs = require('./chunk-KM27ZDHZ.js');
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
@@ -53,7 +53,7 @@ var AnnouncementModal = ({
|
|
|
53
53
|
const embeddableVideoId = videoUrl && _chunkQFG6ZOOTjs.isYouTubeUrl.call(void 0, videoUrl) ? _chunkQFG6ZOOTjs.getYouTubeVideoId.call(void 0, videoUrl) : null;
|
|
54
54
|
const hasMoreAnnouncements = remainingCount > 0;
|
|
55
55
|
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
56
|
-
|
|
56
|
+
_chunkKM27ZDHZjs.Modal_default,
|
|
57
57
|
{
|
|
58
58
|
isOpen,
|
|
59
59
|
onClose,
|
|
@@ -105,4 +105,4 @@ var AnnouncementModal_default = AnnouncementModal;
|
|
|
105
105
|
|
|
106
106
|
|
|
107
107
|
exports.AnnouncementMessage = AnnouncementMessage; exports.AnnouncementModal_default = AnnouncementModal_default;
|
|
108
|
-
//# sourceMappingURL=chunk-
|
|
108
|
+
//# sourceMappingURL=chunk-AZTBNERQ.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-AZTBNERQ.js","../src/components/AnnouncementModal/AnnouncementModal.tsx"],"names":[],"mappings":"AAAA;AACE;AACF,sDAA4B;AAC5B;AACE;AACF,sDAA4B;AAC5B;AACE;AACA;AACA;AACF,sDAA4B;AAC5B;AACE;AACF,sDAA4B;AAC5B;AACE;AACF,sDAA4B;AAC5B;AACA;AC0BU,+CAAA;AA9BV,IAAM,mBAAA,EAAqB,YAAA;AAoBpB,IAAM,oBAAA,EAAsB,CAAC,EAAE,KAAK,CAAA,EAAA,GAAgC;AACzE,EAAA,MAAM,MAAA,EAAQ,iDAAA,IAAuB,CAAA;AAErC,EAAA,uBACE,6BAAA;AAAA,IAAC,6BAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,IAAA;AAAA,MACL,SAAA,EAAU,yDAAA;AAAA,MAET,QAAA,EAAA,KAAA,CAAM,GAAA;AAAA,QAAI,CAAC,IAAA,EAAM,KAAA,EAAA,GAChB,IAAA,CAAK,OAAA,kBACH,6BAAA;AAAA,UAAC,GAAA;AAAA,UAAA;AAAA,YAIC,IAAA,EAAM,IAAA,CAAK,IAAA;AAAA,YACX,MAAA,EAAO,QAAA;AAAA,YACP,GAAA,EAAI,qBAAA;AAAA,YACJ,SAAA,EAAU,6DAAA;AAAA,YAET,QAAA,EAAA,IAAA,CAAK;AAAA,UAAA,CAAA;AAAA,UAND,CAAA,EAAA;AAOP,QAAA;AAIJ,MAAA;AAAA,IAAA;AACF,EAAA;AAEJ;AAqCM;AACJ,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AAC4B;AACvB,EAAA;AAEG,EAAA;AAEF,EAAA;AAGA,EAAA;AAGJ,EAAA;AAAC,IAAA;AAAA,IAAA;AACC,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AAEK,QAAA;AAOD,wBAAA;AAGF,MAAA;AAGF,MAAA;AACG,QAAA;AACE,UAAA;AAAA,UAAA;AAAA,YAAA;AAC0C,YAAA;AAC/B,YAAA;AACK,YAAA;AACT,YAAA;AACgB,UAAA;AACxB,QAAA;AAID,QAAA;AACE,UAAA;AAAA,UAAA;AAAA,YAAA;AACO,YAAA;AACC,YAAA;AACH,YAAA;AACM,YAAA;AACX,UAAA;AAED,QAAA;AAGD,QAAA;AAEA,QAAA;AACE,UAAA;AAAA,UAAA;AAAA,YAAA;AACO,YAAA;AACC,YAAA;AACH,YAAA;AACM,YAAA;AAEI,UAAA;AAChB,QAAA;AAEJ,MAAA;AAAA,IAAA;AACF,EAAA;AAEJ;AAEO;ADxEI;AACA;AACA;AACA;AACA","file":"/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-AZTBNERQ.js","sourcesContent":[null,"import Modal from '../Modal/Modal';\nimport Button from '../Button/Button';\nimport Text from '../Text/Text';\nimport {\n getYouTubeEmbedUrl,\n getYouTubeVideoId,\n isYouTubeUrl,\n} from '../Modal/utils/videoUtils';\nimport { splitTextWithLinks } from '../../utils/announcements';\nimport type { Announcement } from '../../types/announcements';\n\n/**\n * Default label for the call-to-action button when the backoffice left it blank.\n */\nconst DEFAULT_LINK_LABEL = 'Saiba mais';\n\n/**\n * Props for {@link AnnouncementMessage}\n */\ntype AnnouncementMessageProps = {\n /** Raw message text, possibly containing bare URLs */\n text: string;\n};\n\n/**\n * Renders an announcement message with any bare URL turned into a link.\n *\n * Links open in a new tab with `noopener noreferrer`, so the announcement can\n * never reach back into the app through `window.opener`. Rendering React nodes\n * (rather than injecting HTML) keeps backoffice-authored text inert.\n *\n * @param text - Raw message text\n * @returns The message, with clickable links\n */\nexport const AnnouncementMessage = ({ text }: AnnouncementMessageProps) => {\n const parts = splitTextWithLinks(text);\n\n return (\n <Text\n size=\"sm\"\n className=\"text-text-700 whitespace-pre-line break-words leading-6\"\n >\n {parts.map((part, index) =>\n part.isLink ? (\n <a\n // Segments have no stable id of their own; the index is the position\n // in an immutable split of the same string.\n key={`${part.text}-${index}`}\n href={part.text}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-primary-700 underline break-all hover:text-primary-800\"\n >\n {part.text}\n </a>\n ) : (\n <span key={`${part.text}-${index}`}>{part.text}</span>\n )\n )}\n </Text>\n );\n};\n\n/**\n * Props for {@link AnnouncementModal}\n */\nexport type AnnouncementModalProps = {\n /** Announcement to display */\n announcement: Announcement;\n /** Whether the modal is open */\n isOpen: boolean;\n /** Called when the user dismisses this announcement */\n onClose: () => void;\n /**\n * How many announcements are still queued behind this one. Drives the button\n * label (\"Próxima\" vs \"Entendi\") and the \"1 de 3\" counter.\n */\n remainingCount?: number;\n};\n\n/**\n * Modal that shows one global announcement right after login.\n *\n * Handles the three content combinations the backoffice can produce: a YouTube\n * video alone, a message alone, or both — plus an optional call-to-action link.\n * The video is embedded through the same `videoUtils` the rest of the lib uses,\n * so an unembeddable URL degrades to a link instead of a blank iframe.\n *\n * @example\n * ```tsx\n * <AnnouncementModal\n * announcement={announcement}\n * isOpen\n * onClose={dismissCurrent}\n * remainingCount={2}\n * />\n * ```\n */\nconst AnnouncementModal = ({\n announcement,\n isOpen,\n onClose,\n remainingCount = 0,\n}: AnnouncementModalProps) => {\n if (!isOpen) return null;\n\n const { title, message, videoUrl, linkUrl, linkLabel } = announcement;\n\n const embeddableVideoId =\n videoUrl && isYouTubeUrl(videoUrl) ? getYouTubeVideoId(videoUrl) : null;\n\n const hasMoreAnnouncements = remainingCount > 0;\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={onClose}\n title={title}\n size=\"lg\"\n footer={\n <div className=\"flex w-full items-center justify-between gap-3\">\n {hasMoreAnnouncements ? (\n <Text size=\"xs\" className=\"text-text-500\">\n {`Restam ${remainingCount}`}\n </Text>\n ) : (\n <span />\n )}\n <Button variant=\"solid\" action=\"primary\" onClick={onClose}>\n {hasMoreAnnouncements ? 'Próxima' : 'Entendi'}\n </Button>\n </div>\n }\n >\n <div className=\"flex flex-col gap-4\">\n {embeddableVideoId && (\n <iframe\n src={getYouTubeEmbedUrl(embeddableVideoId)}\n className=\"w-full aspect-video rounded-lg\"\n allowFullScreen\n allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\"\n title={`Vídeo: ${title}`}\n />\n )}\n\n {/* A video URL the embed cannot handle still has to be reachable */}\n {videoUrl && !embeddableVideoId && (\n <a\n href={videoUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-primary-700 underline break-all hover:text-primary-800\"\n >\n Assistir ao vídeo\n </a>\n )}\n\n {message && <AnnouncementMessage text={message} />}\n\n {linkUrl && (\n <a\n href={linkUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"self-start rounded-md border border-primary-950 bg-primary-950 px-4 py-2 text-sm font-medium text-text hover:bg-primary-800 hover:border-primary-800\"\n >\n {linkLabel || DEFAULT_LINK_LABEL}\n </a>\n )}\n </div>\n </Modal>\n );\n};\n\nexport default AnnouncementModal;\n"]}
|
|
@@ -10,10 +10,10 @@ import {
|
|
|
10
10
|
} from "./chunk-GRLCPYN5.mjs";
|
|
11
11
|
import {
|
|
12
12
|
VideoPlayer_default
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-AU2HLQDJ.mjs";
|
|
14
14
|
import {
|
|
15
15
|
Whiteboard_default
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-SGL5IUCV.mjs";
|
|
17
17
|
import {
|
|
18
18
|
QuestionCommentField
|
|
19
19
|
} from "./chunk-KUB46JZT.mjs";
|
|
@@ -77,7 +77,7 @@ import {
|
|
|
77
77
|
} from "./chunk-N26PFH64.mjs";
|
|
78
78
|
import {
|
|
79
79
|
Modal_default
|
|
80
|
-
} from "./chunk-
|
|
80
|
+
} from "./chunk-LODDYDTP.mjs";
|
|
81
81
|
import {
|
|
82
82
|
useTheme
|
|
83
83
|
} from "./chunk-2HURJL6I.mjs";
|
|
@@ -1954,4 +1954,4 @@ export {
|
|
|
1954
1954
|
StudentPerformanceModal,
|
|
1955
1955
|
RecommendedLessonDetails_default
|
|
1956
1956
|
};
|
|
1957
|
-
//# sourceMappingURL=chunk-
|
|
1957
|
+
//# sourceMappingURL=chunk-BO3QVQ37.mjs.map
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-FZYK5HMK.mjs";
|
|
4
4
|
import {
|
|
5
5
|
RichEditor
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-RIUVPTG7.mjs";
|
|
7
7
|
import {
|
|
8
8
|
ImageUpload
|
|
9
9
|
} from "./chunk-LXP6LRHO.mjs";
|
|
@@ -29,10 +29,10 @@ import {
|
|
|
29
29
|
DropdownMenuItem,
|
|
30
30
|
DropdownMenuTrigger,
|
|
31
31
|
DropdownMenu_default
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-7ZWEBNFB.mjs";
|
|
33
33
|
import {
|
|
34
34
|
Modal_default
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-LODDYDTP.mjs";
|
|
36
36
|
import {
|
|
37
37
|
Button_default
|
|
38
38
|
} from "./chunk-ZQZBOTZJ.mjs";
|
|
@@ -932,4 +932,4 @@ export {
|
|
|
932
932
|
Forum,
|
|
933
933
|
Forum_default
|
|
934
934
|
};
|
|
935
|
-
//# sourceMappingURL=chunk-
|
|
935
|
+
//# sourceMappingURL=chunk-BPMWRFSI.mjs.map
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from "./chunk-RV6HA5CB.mjs";
|
|
7
7
|
import {
|
|
8
8
|
ReportDetailModal_default
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-RNZGX6MX.mjs";
|
|
10
10
|
import {
|
|
11
11
|
SelectContent,
|
|
12
12
|
SelectItem,
|
|
@@ -2010,4 +2010,4 @@ export {
|
|
|
2010
2010
|
SimulatedViewTab,
|
|
2011
2011
|
useSimulatedPerformance
|
|
2012
2012
|
};
|
|
2013
|
-
//# sourceMappingURL=chunk-
|
|
2013
|
+
//# sourceMappingURL=chunk-BXN3VO6I.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types/supportChat.ts"],"sourcesContent":["import type { SupportType } from './support';\n\n/**\n * Support (SAC) chat types\n */\n\n/**\n * Who authored a support chat message. `USER`, `GUEST`, `AI` and `AGENT`\n * match the backend `senderRole`; `GUEST` (logged-out visitor) renders like `USER`.\n * `INTERNAL_NOTE` is only visible in the backoffice.\n */\nexport const SUPPORT_CHAT_MESSAGE_TYPE = {\n USER: 'USER',\n GUEST: 'GUEST',\n AI: 'AI',\n AGENT: 'AGENT',\n INTERNAL_NOTE: 'INTERNAL_NOTE',\n} as const;\n\nexport type SupportChatMessageType =\n (typeof SUPPORT_CHAT_MESSAGE_TYPE)[keyof typeof SUPPORT_CHAT_MESSAGE_TYPE];\n\n/**\n * Delivery status of a message sent by the current user/agent\n */\nexport const SUPPORT_CHAT_SEND_STATUS = {\n SENT: 'SENT',\n SENDING: 'SENDING',\n FAILED: 'FAILED',\n} as const;\n\nexport type SupportChatSendStatus =\n (typeof SUPPORT_CHAT_SEND_STATUS)[keyof typeof SUPPORT_CHAT_SEND_STATUS];\n\n/**\n * File attached to a support chat message (same shape as the backend attachment)\n */\nexport interface SupportChatAttachment {\n id: string;\n fileName: string;\n url: string;\n /** MIME type; `image/*` renders a thumbnail */\n mimeType?: string;\n /** File size in bytes */\n size?: number;\n}\n\n/**\n * Where an agent reply goes: to the requester (`USER`) or only to the team\n * (`INTERNAL_NOTE`, same value as the message type shown in the backoffice)\n */\nexport const SUPPORT_CHAT_REPLY_MODE = {\n USER: 'USER',\n INTERNAL_NOTE: 'INTERNAL_NOTE',\n} as const;\n\nexport type SupportChatReplyMode =\n (typeof SUPPORT_CHAT_REPLY_MODE)[keyof typeof SUPPORT_CHAT_REPLY_MODE];\n\n/**\n * Kind of event shown between chat messages\n */\nexport const SUPPORT_CHAT_EVENT_TYPE = {\n NEUTRAL: 'NEUTRAL',\n TRANSFER: 'TRANSFER',\n AI: 'AI',\n SUCCESS: 'SUCCESS',\n DATE: 'DATE',\n} as const;\n\nexport type SupportChatEventType =\n (typeof SUPPORT_CHAT_EVENT_TYPE)[keyof typeof SUPPORT_CHAT_EVENT_TYPE];\n\n/**\n * Author displayed next to a support chat message\n */\nexport interface SupportChatAuthor {\n name: string;\n /** Overrides the initials computed from `name` */\n initials?: string;\n /** Tailwind classes overriding the avatar background color */\n avatarClassName?: string;\n}\n\n/**\n * FAQ entry the AI answer was based on\n */\nexport interface SupportChatFaqReference {\n title: string;\n onClick?: () => void;\n}\n\n/*\n * Support chat widget (floating chat on top of a SupportChatAdapter)\n */\n\n/**\n * Ticket status, as sent by the backend (sup_support.status)\n */\nexport const SUPPORT_CHAT_STATUS = {\n ABERTO: 'ABERTO',\n PENDENTE: 'PENDENTE',\n EM_ANDAMENTO: 'EM_ANDAMENTO',\n FECHADO: 'FECHADO',\n} as const;\n\nexport type SupportChatStatus =\n (typeof SUPPORT_CHAT_STATUS)[keyof typeof SUPPORT_CHAT_STATUS];\n\n/**\n * Who is handling the ticket\n */\nexport const SUPPORT_CHAT_HANDLER = {\n IA: 'IA',\n HUMANO: 'HUMANO',\n} as const;\n\nexport type SupportChatHandler =\n (typeof SUPPORT_CHAT_HANDLER)[keyof typeof SUPPORT_CHAT_HANDLER];\n\n/**\n * Author of a message (sent by the backend as senderRole)\n */\nexport const SUPPORT_CHAT_AUTHOR = {\n USER: 'USER',\n GUEST: 'GUEST',\n AGENT: 'AGENT',\n AI: 'AI',\n} as const;\n\nexport type SupportChatAuthorRole =\n (typeof SUPPORT_CHAT_AUTHOR)[keyof typeof SUPPORT_CHAT_AUTHOR];\n\n/** senderId of the messages written by a visitor (not logged in) */\nexport const SUPPORT_CHAT_GUEST_SENDER_ID = 'guest';\n\n/** Images accepted by the backend */\nexport const SUPPORT_CHAT_IMAGE_TYPES = [\n 'image/jpeg',\n 'image/png',\n 'image/gif',\n 'image/webp',\n];\n\n/** Largest image the backend accepts (5 MB) */\nexport const SUPPORT_CHAT_MAX_IMAGE_BYTES = 5 * 1024 * 1024;\n\n/** Most attachments in one message */\nexport const SUPPORT_CHAT_MAX_ATTACHMENTS = 5;\n\nconst MB = 1024 * 1024;\n\n/**\n * Files the backend accepts in the support chat (mime type → largest size).\n * Mirrors SUPPORT_ATTACHMENT_RULES of the API: images, PDF and short videos.\n */\nexport const SUPPORT_CHAT_ATTACHMENT_RULES: Record<string, number> = {\n 'image/jpeg': 5 * MB,\n 'image/png': 5 * MB,\n 'image/gif': 5 * MB,\n 'image/webp': 5 * MB,\n 'application/pdf': 10 * MB,\n 'video/mp4': 50 * MB,\n 'video/webm': 50 * MB,\n 'video/quicktime': 50 * MB,\n};\n\n/**\n * FAQ article opened inside the chat (GET /help-center/:institutionId/articles/:id)\n */\nexport interface SupportChatArticle {\n id: string;\n title: string;\n /** Article HTML as saved by the help-center editor */\n body: string;\n /** ISO date of the last update, when known */\n updatedAt: string | null;\n}\n\n/**\n * Chat message (same shape as the platform chat, plus attachments)\n */\nexport interface SupportChatMessage {\n id: string;\n senderId: string;\n senderName: string;\n senderPhoto: string | null;\n senderRole: SupportChatAuthorRole;\n content: string;\n messageType: string;\n createdAt: string;\n attachments: SupportChatAttachment[];\n /** FAQ article an AI message is based on */\n faq?: { id: string; title: string } | null;\n /**\n * Contact fields an AI message asks for: the chat shows a form for them\n * under the message\n */\n contactRequest?: SupportChatContactField[] | null;\n /** Local only: shown before the server confirms it (optimistic) */\n pending?: boolean;\n}\n\n/**\n * Ticket the conversation belongs to\n */\nexport interface SupportChatTicket {\n id: string;\n status: SupportChatStatus;\n handlerType: SupportChatHandler | null;\n problemType: string | null;\n}\n\n/**\n * Realtime events pushed to the conversation (WebSocket in the real adapter)\n */\nexport type SupportChatEvent =\n | { type: 'new_message'; payload: { message: SupportChatMessage } }\n | {\n type: 'message_updated';\n payload: { messageId: string; content: string; read: boolean };\n }\n | {\n type: 'ticket_updated';\n payload: { ticketId: string } & Omit<SupportChatTicket, 'id'>;\n }\n | { type: 'error'; payload: { message: string } };\n\n/**\n * Data needed to open a conversation (first message creates the ticket)\n */\nexport interface StartSupportChatInput {\n message: string;\n channel: string;\n institutionId?: string;\n requesterName?: string;\n email?: string;\n /** Files sent with the first message */\n files?: File[];\n}\n\n/**\n * Data layer of the widget. The mock adapter implements it in memory; the\n * real one will use the support REST API and the chat WebSocket.\n */\nexport interface SupportChatAdapter {\n /**\n * Create the ticket with its first message. With files the API may store\n * them as a second message, hence the list.\n */\n startConversation(input: StartSupportChatInput): Promise<{\n ticket: SupportChatTicket;\n messages: SupportChatMessage[];\n }>;\n /** Send a message (text and/or files) on an existing ticket */\n sendMessage(\n ticketId: string,\n content: string,\n files?: File[]\n ): Promise<SupportChatMessage>;\n /** Messages of the ticket, oldest first */\n listMessages(ticketId: string): Promise<SupportChatMessage[]>;\n /** Listen to realtime events of the ticket; returns the unsubscribe */\n subscribe(\n ticketId: string,\n listener: (event: SupportChatEvent) => void\n ): () => void;\n /**\n * Save the name and/or e-mail the visitor typed in the contact form.\n * Without it the chat does not show the form (the AI request stays a text).\n */\n updateContact?(ticketId: string, contact: SupportChatContact): Promise<void>;\n /**\n * Load a FAQ article of the institution. With it, the article an AI answer\n * is based on opens inside the chat instead of a new tab.\n */\n getArticle?(\n institutionId: string,\n articleId: string\n ): Promise<SupportChatArticle>;\n}\n\n/** Contact field the AI asks for */\nexport type SupportChatContactField = 'name' | 'email';\n\n/** Contact sent by the chat form */\nexport interface SupportChatContact {\n requesterName?: string;\n email?: string;\n}\n\n/**\n * Feature flags of the widget\n */\nexport interface SupportChatFlags {\n /** Widget available at all (default true) */\n enabled?: boolean;\n /** Chat with the support (default true) */\n chat?: boolean;\n /** FAQ (reserved, not rendered yet) */\n faq?: boolean;\n /** AI first answer (reserved, not rendered yet) */\n ai?: boolean;\n /** ZENDESK hides the widget (the Zendesk messenger is used instead) */\n supportType?: SupportType;\n}\n\n/**\n * Visual customization of the widget\n */\nexport interface SupportChatTheme {\n /** Background of the button and the header (any CSS color) */\n primaryColor?: string;\n /** Corner of the screen (default bottom-right) */\n position?: 'bottom-right' | 'bottom-left';\n /** Header title (default \"Suporte\") */\n title?: string;\n}\n\n/**\n * Logged user (optional; a visitor has none)\n */\nexport interface SupportChatUser {\n name?: string;\n email?: string;\n}\n\n/**\n * HTTP client the API adapter needs (axios instances fit as they are)\n */\nexport interface SupportChatHttpClient {\n get: <T>(\n url: string,\n config?: { headers?: Record<string, string> }\n ) => Promise<{ data: T }>;\n post: <T>(\n url: string,\n data?: unknown,\n config?: { headers?: Record<string, string> }\n ) => Promise<{ data: T }>;\n /** Used to save the visitor contact (PUT /support/guest/:id) */\n put?: <T>(\n url: string,\n data?: unknown,\n config?: { headers?: Record<string, string> }\n ) => Promise<{ data: T }>;\n}\n\n/**\n * Message as returned by the support REST routes\n */\nexport interface SupportChatAnswerApi {\n id: string;\n authorType: SupportChatAuthorRole;\n answer: string;\n createdAt: string;\n attachments?: SupportChatAttachment[];\n /** FAQ article an AI message is based on */\n faqArticleId?: string | null;\n faqArticleTitle?: string | null;\n /** Contact fields an AI message asks for */\n contactRequest?: SupportChatContactField[] | null;\n}\n"],"mappings":";AAWO,IAAM,4BAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,eAAe;AACjB;AAQO,IAAM,2BAA2B;AAAA,EACtC,MAAM;AAAA,EACN,SAAS;AAAA,EACT,QAAQ;AACV;AAsBO,IAAM,0BAA0B;AAAA,EACrC,MAAM;AAAA,EACN,eAAe;AACjB;AAQO,IAAM,0BAA0B;AAAA,EACrC,SAAS;AAAA,EACT,UAAU;AAAA,EACV,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,MAAM;AACR;AA+BO,IAAM,sBAAsB;AAAA,EACjC,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,cAAc;AAAA,EACd,SAAS;AACX;AAQO,IAAM,uBAAuB;AAAA,EAClC,IAAI;AAAA,EACJ,QAAQ;AACV;AAQO,IAAM,sBAAsB;AAAA,EACjC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,OAAO;AAAA,EACP,IAAI;AACN;AAMO,IAAM,+BAA+B;AAGrC,IAAM,2BAA2B;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,IAAM,+BAA+B,IAAI,OAAO;AAGhD,IAAM,+BAA+B;AAE5C,IAAM,KAAK,OAAO;AAMX,IAAM,gCAAwD;AAAA,EACnE,cAAc,IAAI;AAAA,EAClB,aAAa,IAAI;AAAA,EACjB,aAAa,IAAI;AAAA,EACjB,cAAc,IAAI;AAAA,EAClB,mBAAmB,KAAK;AAAA,EACxB,aAAa,KAAK;AAAA,EAClB,cAAc,KAAK;AAAA,EACnB,mBAAmB,KAAK;AAC1B;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/types/supportChat.ts"],"sourcesContent":["import type { SupportType } from './support';\n\n/**\n * Support (SAC) chat types\n */\n\n/**\n * Who authored a support chat message. `USER`, `GUEST`, `AI` and `AGENT`\n * match the backend `senderRole`; `GUEST` (logged-out visitor) renders like `USER`.\n * `INTERNAL_NOTE` is only visible in the backoffice.\n */\nexport const SUPPORT_CHAT_MESSAGE_TYPE = {\n USER: 'USER',\n GUEST: 'GUEST',\n AI: 'AI',\n AGENT: 'AGENT',\n INTERNAL_NOTE: 'INTERNAL_NOTE',\n} as const;\n\nexport type SupportChatMessageType =\n (typeof SUPPORT_CHAT_MESSAGE_TYPE)[keyof typeof SUPPORT_CHAT_MESSAGE_TYPE];\n\n/**\n * Delivery status of a message sent by the current user/agent\n */\nexport const SUPPORT_CHAT_SEND_STATUS = {\n SENT: 'SENT',\n SENDING: 'SENDING',\n FAILED: 'FAILED',\n} as const;\n\nexport type SupportChatSendStatus =\n (typeof SUPPORT_CHAT_SEND_STATUS)[keyof typeof SUPPORT_CHAT_SEND_STATUS];\n\n/**\n * File attached to a support chat message (same shape as the backend attachment)\n */\nexport interface SupportChatAttachment {\n id: string;\n fileName: string;\n url: string;\n /** MIME type; `image/*` renders a thumbnail */\n mimeType?: string;\n /** File size in bytes */\n size?: number;\n}\n\n/**\n * Where an agent reply goes: to the requester (`USER`) or only to the team\n * (`INTERNAL_NOTE`, same value as the message type shown in the backoffice)\n */\nexport const SUPPORT_CHAT_REPLY_MODE = {\n USER: 'USER',\n INTERNAL_NOTE: 'INTERNAL_NOTE',\n} as const;\n\nexport type SupportChatReplyMode =\n (typeof SUPPORT_CHAT_REPLY_MODE)[keyof typeof SUPPORT_CHAT_REPLY_MODE];\n\n/**\n * Kind of event shown between chat messages\n */\nexport const SUPPORT_CHAT_EVENT_TYPE = {\n NEUTRAL: 'NEUTRAL',\n TRANSFER: 'TRANSFER',\n AI: 'AI',\n SUCCESS: 'SUCCESS',\n DATE: 'DATE',\n} as const;\n\nexport type SupportChatEventType =\n (typeof SUPPORT_CHAT_EVENT_TYPE)[keyof typeof SUPPORT_CHAT_EVENT_TYPE];\n\n/**\n * Author displayed next to a support chat message\n */\nexport interface SupportChatAuthor {\n name: string;\n /** Overrides the initials computed from `name` */\n initials?: string;\n /** Tailwind classes overriding the avatar background color */\n avatarClassName?: string;\n}\n\n/**\n * FAQ entry the AI answer was based on\n */\nexport interface SupportChatFaqReference {\n title: string;\n onClick?: () => void;\n}\n\n/*\n * Support chat widget (floating chat on top of a SupportChatAdapter)\n */\n\n/**\n * Ticket status, as sent by the backend (sup_support.status)\n */\nexport const SUPPORT_CHAT_STATUS = {\n ABERTO: 'ABERTO',\n PENDENTE: 'PENDENTE',\n EM_ANDAMENTO: 'EM_ANDAMENTO',\n FECHADO: 'FECHADO',\n} as const;\n\nexport type SupportChatStatus =\n (typeof SUPPORT_CHAT_STATUS)[keyof typeof SUPPORT_CHAT_STATUS];\n\n/**\n * Who is handling the ticket\n */\nexport const SUPPORT_CHAT_HANDLER = {\n IA: 'IA',\n HUMANO: 'HUMANO',\n} as const;\n\nexport type SupportChatHandler =\n (typeof SUPPORT_CHAT_HANDLER)[keyof typeof SUPPORT_CHAT_HANDLER];\n\n/**\n * Author of a message (sent by the backend as senderRole)\n */\nexport const SUPPORT_CHAT_AUTHOR = {\n USER: 'USER',\n GUEST: 'GUEST',\n AGENT: 'AGENT',\n AI: 'AI',\n} as const;\n\nexport type SupportChatAuthorRole =\n (typeof SUPPORT_CHAT_AUTHOR)[keyof typeof SUPPORT_CHAT_AUTHOR];\n\n/** senderId of the messages written by a visitor (not logged in) */\nexport const SUPPORT_CHAT_GUEST_SENDER_ID = 'guest';\n\n/** Images accepted by the backend */\nexport const SUPPORT_CHAT_IMAGE_TYPES = [\n 'image/jpeg',\n 'image/png',\n 'image/gif',\n 'image/webp',\n];\n\n/** Largest image the backend accepts (5 MB) */\nexport const SUPPORT_CHAT_MAX_IMAGE_BYTES = 5 * 1024 * 1024;\n\n/** Most attachments in one message */\nexport const SUPPORT_CHAT_MAX_ATTACHMENTS = 5;\n\nconst MB = 1024 * 1024;\n\n/**\n * Files the backend accepts in the support chat (mime type → largest size).\n * Mirrors SUPPORT_ATTACHMENT_RULES of the API: images, PDF and short videos.\n */\nexport const SUPPORT_CHAT_ATTACHMENT_RULES: Record<string, number> = {\n 'image/jpeg': 5 * MB,\n 'image/png': 5 * MB,\n 'image/gif': 5 * MB,\n 'image/webp': 5 * MB,\n 'application/pdf': 10 * MB,\n 'video/mp4': 50 * MB,\n 'video/webm': 50 * MB,\n 'video/quicktime': 50 * MB,\n};\n\n/**\n * FAQ article opened inside the chat (GET /help-center/:institutionId/articles/:id)\n */\nexport interface SupportChatArticle {\n id: string;\n title: string;\n /** Article HTML as saved by the help-center editor */\n body: string;\n /** ISO date of the last update, when known */\n updatedAt: string | null;\n}\n\n/**\n * Chat message (same shape as the platform chat, plus attachments)\n */\nexport interface SupportChatMessage {\n id: string;\n senderId: string;\n senderName: string;\n senderPhoto: string | null;\n senderRole: SupportChatAuthorRole;\n content: string;\n messageType: string;\n createdAt: string;\n attachments: SupportChatAttachment[];\n /** FAQ article an AI message is based on */\n faq?: { id: string; title: string } | null;\n /**\n * Contact fields an AI message asks for: the chat shows a form for them\n * under the message\n */\n contactRequest?: SupportChatContactField[] | null;\n /** Local only: shown before the server confirms it (optimistic) */\n pending?: boolean;\n}\n\n/**\n * Ticket the conversation belongs to\n */\nexport interface SupportChatTicket {\n id: string;\n status: SupportChatStatus;\n handlerType: SupportChatHandler | null;\n problemType: string | null;\n}\n\n/**\n * Realtime events pushed to the conversation (WebSocket in the real adapter)\n */\nexport type SupportChatEvent =\n | { type: 'new_message'; payload: { message: SupportChatMessage } }\n | {\n type: 'message_updated';\n payload: { messageId: string; content: string; read: boolean };\n }\n | {\n type: 'ticket_updated';\n payload: { ticketId: string } & Omit<SupportChatTicket, 'id'>;\n }\n | { type: 'error'; payload: { message: string } };\n\n/**\n * Data needed to open a conversation (first message creates the ticket)\n */\nexport interface StartSupportChatInput {\n message: string;\n channel: string;\n institutionId?: string;\n requesterName?: string;\n email?: string;\n /** Files sent with the first message */\n files?: File[];\n}\n\n/**\n * Data layer of the widget. The mock adapter implements it in memory; the\n * real one will use the support REST API and the chat WebSocket.\n */\nexport interface SupportChatAdapter {\n /**\n * Create the ticket with its first message. With files the API may store\n * them as a second message, hence the list.\n */\n startConversation(input: StartSupportChatInput): Promise<{\n ticket: SupportChatTicket;\n messages: SupportChatMessage[];\n }>;\n /** Send a message (text and/or files) on an existing ticket */\n sendMessage(\n ticketId: string,\n content: string,\n files?: File[]\n ): Promise<SupportChatMessage>;\n /** Messages of the ticket, oldest first */\n listMessages(ticketId: string): Promise<SupportChatMessage[]>;\n /** Listen to realtime events of the ticket; returns the unsubscribe */\n subscribe(\n ticketId: string,\n listener: (event: SupportChatEvent) => void\n ): () => void;\n /**\n * Save the name and/or e-mail the visitor typed in the contact form.\n * Without it the chat does not show the form (the AI request stays a text).\n */\n updateContact?(ticketId: string, contact: SupportChatContact): Promise<void>;\n /**\n * Conversation kept from an earlier page load that is still unresolved, so\n * a reload does not drop it. Null when there is none, when it was resolved\n * or when it belongs to another user (`email` of the logged user; omit for\n * a visitor).\n */\n restoreConversation?(input: { email?: string }): Promise<{\n ticket: SupportChatTicket;\n messages: SupportChatMessage[];\n } | null>;\n /** Stop keeping the conversation (resolved, or the chat started over) */\n forgetConversation?(): void;\n /**\n * Load a FAQ article of the institution. With it, the article an AI answer\n * is based on opens inside the chat instead of a new tab.\n */\n getArticle?(\n institutionId: string,\n articleId: string\n ): Promise<SupportChatArticle>;\n}\n\n/** Contact field the AI asks for */\nexport type SupportChatContactField = 'name' | 'email';\n\n/** Contact sent by the chat form */\nexport interface SupportChatContact {\n requesterName?: string;\n email?: string;\n}\n\n/**\n * Feature flags of the widget\n */\nexport interface SupportChatFlags {\n /** Widget available at all (default true) */\n enabled?: boolean;\n /** Chat with the support (default true) */\n chat?: boolean;\n /** FAQ (reserved, not rendered yet) */\n faq?: boolean;\n /** AI first answer (reserved, not rendered yet) */\n ai?: boolean;\n /** ZENDESK hides the widget (the Zendesk messenger is used instead) */\n supportType?: SupportType;\n}\n\n/**\n * Visual customization of the widget\n */\nexport interface SupportChatTheme {\n /** Background of the button and the header (any CSS color) */\n primaryColor?: string;\n /** Corner of the screen (default bottom-right) */\n position?: 'bottom-right' | 'bottom-left';\n /** Header title (default \"Suporte\") */\n title?: string;\n}\n\n/**\n * Logged user (optional; a visitor has none)\n */\nexport interface SupportChatUser {\n name?: string;\n email?: string;\n}\n\n/**\n * HTTP client the API adapter needs (axios instances fit as they are)\n */\nexport interface SupportChatHttpClient {\n get: <T>(\n url: string,\n config?: { headers?: Record<string, string> }\n ) => Promise<{ data: T }>;\n post: <T>(\n url: string,\n data?: unknown,\n config?: { headers?: Record<string, string> }\n ) => Promise<{ data: T }>;\n /** Used to save the visitor contact (PUT /support/guest/:id) */\n put?: <T>(\n url: string,\n data?: unknown,\n config?: { headers?: Record<string, string> }\n ) => Promise<{ data: T }>;\n}\n\n/**\n * Message as returned by the support REST routes\n */\nexport interface SupportChatAnswerApi {\n id: string;\n authorType: SupportChatAuthorRole;\n answer: string;\n createdAt: string;\n attachments?: SupportChatAttachment[];\n /** FAQ article an AI message is based on */\n faqArticleId?: string | null;\n faqArticleTitle?: string | null;\n /** Contact fields an AI message asks for */\n contactRequest?: SupportChatContactField[] | null;\n}\n"],"mappings":";AAWO,IAAM,4BAA4B;AAAA,EACvC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,eAAe;AACjB;AAQO,IAAM,2BAA2B;AAAA,EACtC,MAAM;AAAA,EACN,SAAS;AAAA,EACT,QAAQ;AACV;AAsBO,IAAM,0BAA0B;AAAA,EACrC,MAAM;AAAA,EACN,eAAe;AACjB;AAQO,IAAM,0BAA0B;AAAA,EACrC,SAAS;AAAA,EACT,UAAU;AAAA,EACV,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,MAAM;AACR;AA+BO,IAAM,sBAAsB;AAAA,EACjC,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,cAAc;AAAA,EACd,SAAS;AACX;AAQO,IAAM,uBAAuB;AAAA,EAClC,IAAI;AAAA,EACJ,QAAQ;AACV;AAQO,IAAM,sBAAsB;AAAA,EACjC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,OAAO;AAAA,EACP,IAAI;AACN;AAMO,IAAM,+BAA+B;AAGrC,IAAM,2BAA2B;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,IAAM,+BAA+B,IAAI,OAAO;AAGhD,IAAM,+BAA+B;AAE5C,IAAM,KAAK,OAAO;AAMX,IAAM,gCAAwD;AAAA,EACnE,cAAc,IAAI;AAAA,EAClB,aAAa,IAAI;AAAA,EACjB,aAAa,IAAI;AAAA,EACjB,cAAc,IAAI;AAAA,EAClB,mBAAmB,KAAK;AAAA,EACxB,aAAa,KAAK;AAAA,EAClB,cAAc,KAAK;AAAA,EACnB,mBAAmB,KAAK;AAC1B;","names":[]}
|
|
@@ -14,7 +14,7 @@ var _chunkGCWS5HG5js = require('./chunk-GCWS5HG5.js');
|
|
|
14
14
|
var _chunk3D27ONG2js = require('./chunk-3D27ONG2.js');
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
var
|
|
17
|
+
var _chunkKM27ZDHZjs = require('./chunk-KM27ZDHZ.js');
|
|
18
18
|
|
|
19
19
|
// src/components/AccessReportModal/AccessReportModal.tsx
|
|
20
20
|
var _jsxruntime = require('react/jsx-runtime');
|
|
@@ -248,7 +248,7 @@ var AccessReportModal = ({
|
|
|
248
248
|
content = /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGCWS5HG5js.ErrorContent, { message: "Variante de relat\xF3rio inv\xE1lida." });
|
|
249
249
|
}
|
|
250
250
|
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
251
|
-
|
|
251
|
+
_chunkKM27ZDHZjs.Modal_default,
|
|
252
252
|
{
|
|
253
253
|
isOpen,
|
|
254
254
|
onClose,
|
|
@@ -265,4 +265,4 @@ var AccessReportModal_default = AccessReportModal;
|
|
|
265
265
|
|
|
266
266
|
|
|
267
267
|
exports.AccessReportModal = AccessReportModal; exports.AccessReportModal_default = AccessReportModal_default;
|
|
268
|
-
//# sourceMappingURL=chunk-
|
|
268
|
+
//# sourceMappingURL=chunk-C7ILTLT5.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-5HONWYQA.js","../src/components/AccessReportModal/AccessReportModal.tsx"],"names":[],"mappings":"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","file":"/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-5HONWYQA.js","sourcesContent":[null,"import { type ReactNode } from 'react';\nimport Modal from '../Modal/Modal';\nimport { MetricBox } from '../shared/MetricBox';\nimport { LegendPieCard, type PieSlice } from '../shared/ChartComponents';\nimport {\n SectionTitle,\n UserHeader,\n ErrorContent,\n} from '../shared/ModalComponents';\nimport { REPORT_MODAL_VARIANT } from '../../types/common';\nimport { SimpleBarChart } from '../SimpleBarChart/SimpleBarChart';\n\n// ─── API Types ────────────────────────────────────────────────\n\n/**\n * Time + percentage pair returned by the backend for platform/hours breakdowns.\n */\nexport interface AccessReportTimePercentage {\n time: string;\n percentage: number;\n}\n\n/**\n * User context returned by the backend inside every access report response.\n */\nexport interface AccessReportUser {\n id: string;\n name: string;\n profileType: string;\n school: string;\n group: string | null;\n class: string | null;\n year: number;\n}\n\n/**\n * Platform access breakdown — web vs mobile.\n */\nexport interface AccessReportByPlatform {\n web: AccessReportTimePercentage;\n mobile: AccessReportTimePercentage;\n}\n\n/**\n * Full 200 response for STUDENT access report.\n * Mirrors backend shape from GET /access-report/access/user/:userId (student variant).\n */\nexport interface AccessReportStudentData {\n user: AccessReportUser;\n accessData: {\n totalTime: string;\n activitiesTime: string;\n contentTime: string;\n recommendedLessonsTime: string;\n simulationsTime: string;\n questionnairesTime: string;\n accessCount: number;\n lastAccess: string | null;\n };\n accessByPlatform: AccessReportByPlatform;\n hoursByItem: {\n activities: AccessReportTimePercentage;\n content: AccessReportTimePercentage;\n simulations: AccessReportTimePercentage;\n questionnaires: AccessReportTimePercentage;\n recommendedLessons: AccessReportTimePercentage;\n };\n}\n\n/**\n * Full 200 response for TEACHER / UNIT_MANAGER / REGIONAL_MANAGER access report.\n * Mirrors backend shape from GET /access-report/access/user/:userId (professional variant).\n */\nexport interface AccessReportProfessionalData {\n user: AccessReportUser;\n accessData: {\n totalTime: string;\n activitiesTime: string;\n recommendedLessonsTime: string;\n accessCount: number;\n lastAccess: string | null;\n };\n accessByPlatform: AccessReportByPlatform;\n hoursByItem: {\n activities: AccessReportTimePercentage;\n recommendedLessons: AccessReportTimePercentage;\n };\n}\n\n/** @deprecated Use {@link REPORT_MODAL_VARIANT} instead. Re-exported for backwards compatibility. */\nexport { REPORT_MODAL_VARIANT as AccessReportModalVariant } from '../../types/common';\n\n/**\n * Access count by period item for bar chart\n */\nexport interface AccessCountByPeriodItem {\n label: string;\n count: number;\n}\n\ninterface AccessReportModalBaseProps {\n isOpen: boolean;\n onClose: () => void;\n /** Modal title (default: \"Relatório de acesso\") */\n title?: string;\n loading?: boolean;\n error?: string | null;\n /** Optional access count by period data for rendering the access count chart */\n accessCountByPeriod?: AccessCountByPeriodItem[];\n}\n\ntype AccessReportModalStudentProps = {\n variant: REPORT_MODAL_VARIANT.STUDENT;\n data: AccessReportStudentData | null;\n};\n\ntype AccessReportModalProfessionalProps = {\n variant: REPORT_MODAL_VARIANT.PROFESSIONAL;\n data: AccessReportProfessionalData | null;\n};\n\nexport type AccessReportModalProps = AccessReportModalBaseProps &\n (AccessReportModalStudentProps | AccessReportModalProfessionalProps);\n\n// ─── Pie slice builders ───────────────────────────────────────\n\nfunction buildPlatformSlices(platform: AccessReportByPlatform): PieSlice[] {\n // The pie is sized by the percentage; the legend reads the time next to each\n // platform (as in the design), not the percentage.\n return [\n {\n label: 'Web',\n value: platform.web.percentage,\n displayValue: platform.web.time,\n colorClass: 'bg-success-700',\n color: 'var(--Success-success700, #206F3E)',\n },\n {\n label: 'Celular',\n value: platform.mobile.percentage,\n displayValue: platform.mobile.time,\n colorClass: 'bg-success-300',\n color: 'var(--Success-success300, #66B584)',\n },\n ];\n}\n\nfunction buildStudentHoursSlices(\n hoursByItem: AccessReportStudentData['hoursByItem']\n): PieSlice[] {\n // Order, labels and colors mirror STUDENT_CATEGORIES from the reports page\n // TimeChart so the modal breakdown matches the page chart 1:1.\n return [\n {\n label: 'Atividades',\n value: hoursByItem.activities.percentage,\n colorClass: 'bg-success-700',\n },\n {\n label: 'Simulados',\n value: hoursByItem.simulations.percentage,\n colorClass: 'bg-warning-300',\n },\n {\n label: 'Questionários',\n value: hoursByItem.questionnaires.percentage,\n colorClass: 'bg-indicator-info',\n },\n {\n label: 'Videoaulas',\n value: hoursByItem.content.percentage,\n colorClass: 'bg-success-300',\n },\n {\n label: 'Aulas recomendadas',\n value: hoursByItem.recommendedLessons.percentage,\n colorClass: 'bg-indicator-positive',\n },\n ];\n}\n\n// ─── Modal content ────────────────────────────────────────────\n\nconst ReportContentLayout = ({\n user,\n metricBoxes,\n platformSlices,\n hoursSlices,\n accessCountByPeriod,\n}: {\n user: AccessReportUser;\n metricBoxes: ReactNode;\n platformSlices: PieSlice[];\n hoursSlices: PieSlice[];\n accessCountByPeriod?: AccessCountByPeriodItem[];\n}) => (\n <div className=\"flex flex-col gap-6\">\n <UserHeader\n name={user.name}\n school={user.school}\n className={user.class ?? ''}\n year={user.year}\n />\n\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-3\">{metricBoxes}</div>\n\n {accessCountByPeriod && accessCountByPeriod.length > 0 && (\n <SimpleBarChart\n data={accessCountByPeriod.map((item) => ({\n label: item.label,\n value: item.count,\n }))}\n title=\"Quantidade de acessos por período\"\n barColor=\"bg-info-500\"\n chartHeight={150}\n />\n )}\n\n <div className=\"flex flex-col gap-3\">\n <SectionTitle>Dados de acesso por plataforma</SectionTitle>\n <LegendPieCard slices={platformSlices} />\n </div>\n\n <div className=\"flex flex-col gap-3\">\n <SectionTitle>Dados de horas por item</SectionTitle>\n <LegendPieCard slices={hoursSlices} />\n </div>\n </div>\n);\n\nconst StudentModalContent = ({\n data,\n accessCountByPeriod,\n}: {\n data: AccessReportStudentData;\n accessCountByPeriod?: AccessCountByPeriodItem[];\n}) => (\n <ReportContentLayout\n user={data.user}\n platformSlices={buildPlatformSlices(data.accessByPlatform)}\n hoursSlices={buildStudentHoursSlices(data.hoursByItem)}\n accessCountByPeriod={accessCountByPeriod}\n metricBoxes={\n <>\n <MetricBox label=\"Tempo total\" value={data.accessData.totalTime} />\n <MetricBox label=\"Videoaulas\" value={data.accessData.contentTime} />\n <MetricBox\n label=\"Aulas recomendadas\"\n value={data.accessData.recommendedLessonsTime}\n />\n <MetricBox label=\"Simulados\" value={data.accessData.simulationsTime} />\n <MetricBox\n label=\"Quantidade de acessos\"\n value={data.accessData.accessCount}\n />\n <MetricBox\n label=\"Último acesso\"\n value={data.accessData.lastAccess ?? '—'}\n />\n </>\n }\n />\n);\n\nconst ProfessionalModalContent = ({\n data,\n accessCountByPeriod,\n}: {\n data: AccessReportProfessionalData;\n accessCountByPeriod?: AccessCountByPeriodItem[];\n}) => (\n <div className=\"flex flex-col gap-6\">\n <UserHeader\n name={data.user.name}\n school={data.user.school}\n className={data.user.class ?? ''}\n year={data.user.year}\n />\n\n <div className=\"flex flex-col gap-3\">\n <SectionTitle>Dados de acesso</SectionTitle>\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-3\">\n <MetricBox label=\"Tempo total\" value={data.accessData.totalTime} />\n <MetricBox label=\"Acessos\" value={data.accessData.accessCount} />\n <MetricBox\n label=\"Último acesso\"\n value={data.accessData.lastAccess ?? '—'}\n />\n </div>\n </div>\n\n {accessCountByPeriod && accessCountByPeriod.length > 0 && (\n <SimpleBarChart\n data={accessCountByPeriod.map((item) => ({\n label: item.label,\n value: item.count,\n }))}\n title=\"Quantidade de acessos por período\"\n barColor=\"bg-info-500\"\n chartHeight={150}\n />\n )}\n\n <div className=\"flex flex-col gap-3\">\n <SectionTitle>Dados de acesso por plataforma</SectionTitle>\n <LegendPieCard slices={buildPlatformSlices(data.accessByPlatform)} />\n </div>\n </div>\n);\n\nconst LoadingSkeleton = ({\n metricCount,\n showSecondaryChart = true,\n}: {\n metricCount: number;\n showSecondaryChart?: boolean;\n}) => (\n <div className=\"flex flex-col gap-4 animate-pulse\">\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-3\">\n {Array.from({ length: metricCount }, (_, i) => (\n <div\n key={`skeleton-${String(i)}`}\n className=\"h-16 bg-background-200 rounded-xl\"\n />\n ))}\n </div>\n <div className=\"h-5 bg-background-200 rounded w-40 mt-2\" />\n <div className=\"h-32 bg-background-200 rounded-xl\" />\n {showSecondaryChart && (\n <>\n <div className=\"h-5 bg-background-200 rounded w-32\" />\n <div className=\"h-32 bg-background-200 rounded-xl\" />\n </>\n )}\n </div>\n);\n\n// ─── Main component ───────────────────────────────────────────\n\n/**\n * AccessReportModal component\n *\n * Displays a modal with access data for a user.\n *\n * Two variants driven by the profile type:\n * - `STUDENT` — 6 metric boxes (totalTime, contentTime, recommendedLessonsTime,\n * simulationsTime, accessCount, lastAccess) + platform pie chart + hours-by-item pie chart\n * - `PROFESSIONAL` — 3 metric boxes (totalTime, accessCount, lastAccess) +\n * platform pie chart only (no hours-by-item breakdown for professionals)\n *\n * @example\n * ```tsx\n * <AccessReportModal\n * isOpen={isOpen}\n * onClose={() => setIsOpen(false)}\n * variant={REPORT_MODAL_VARIANT.STUDENT}\n * data={apiResponse.data}\n * />\n * ```\n */\nexport const AccessReportModal = ({\n isOpen,\n onClose,\n title = 'Relatório de acesso',\n loading = false,\n error = null,\n accessCountByPeriod,\n ...variantProps\n}: AccessReportModalProps) => {\n let content: ReactNode;\n\n const isStudent = variantProps.variant === REPORT_MODAL_VARIANT.STUDENT;\n // Student: 6 metrics + 2 charts; Professional: 3 metrics + 1 chart\n const metricCount = isStudent ? 6 : 3;\n const showSecondaryChart = isStudent;\n\n if (loading) {\n content = (\n <LoadingSkeleton\n metricCount={metricCount}\n showSecondaryChart={showSecondaryChart}\n />\n );\n } else if (error) {\n content = <ErrorContent message={error} />;\n } else if (variantProps.data === null) {\n content = <ErrorContent message=\"Nenhum dado disponível.\" />;\n } else if (variantProps.variant === REPORT_MODAL_VARIANT.STUDENT) {\n content = (\n <StudentModalContent\n data={variantProps.data}\n accessCountByPeriod={accessCountByPeriod}\n />\n );\n } else if (variantProps.variant === REPORT_MODAL_VARIANT.PROFESSIONAL) {\n content = (\n <ProfessionalModalContent\n data={variantProps.data}\n accessCountByPeriod={accessCountByPeriod}\n />\n );\n } else {\n content = <ErrorContent message=\"Variante de relatório inválida.\" />;\n }\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={onClose}\n title={title}\n size=\"lg\"\n contentClassName=\"max-h-[80vh] overflow-y-auto\"\n >\n {content}\n </Modal>\n );\n};\n\nexport default AccessReportModal;\n"]}
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-C7ILTLT5.js","../src/components/AccessReportModal/AccessReportModal.tsx"],"names":[],"mappings":"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","file":"/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-C7ILTLT5.js","sourcesContent":[null,"import { type ReactNode } from 'react';\nimport Modal from '../Modal/Modal';\nimport { MetricBox } from '../shared/MetricBox';\nimport { LegendPieCard, type PieSlice } from '../shared/ChartComponents';\nimport {\n SectionTitle,\n UserHeader,\n ErrorContent,\n} from '../shared/ModalComponents';\nimport { REPORT_MODAL_VARIANT } from '../../types/common';\nimport { SimpleBarChart } from '../SimpleBarChart/SimpleBarChart';\n\n// ─── API Types ────────────────────────────────────────────────\n\n/**\n * Time + percentage pair returned by the backend for platform/hours breakdowns.\n */\nexport interface AccessReportTimePercentage {\n time: string;\n percentage: number;\n}\n\n/**\n * User context returned by the backend inside every access report response.\n */\nexport interface AccessReportUser {\n id: string;\n name: string;\n profileType: string;\n school: string;\n group: string | null;\n class: string | null;\n year: number;\n}\n\n/**\n * Platform access breakdown — web vs mobile.\n */\nexport interface AccessReportByPlatform {\n web: AccessReportTimePercentage;\n mobile: AccessReportTimePercentage;\n}\n\n/**\n * Full 200 response for STUDENT access report.\n * Mirrors backend shape from GET /access-report/access/user/:userId (student variant).\n */\nexport interface AccessReportStudentData {\n user: AccessReportUser;\n accessData: {\n totalTime: string;\n activitiesTime: string;\n contentTime: string;\n recommendedLessonsTime: string;\n simulationsTime: string;\n questionnairesTime: string;\n accessCount: number;\n lastAccess: string | null;\n };\n accessByPlatform: AccessReportByPlatform;\n hoursByItem: {\n activities: AccessReportTimePercentage;\n content: AccessReportTimePercentage;\n simulations: AccessReportTimePercentage;\n questionnaires: AccessReportTimePercentage;\n recommendedLessons: AccessReportTimePercentage;\n };\n}\n\n/**\n * Full 200 response for TEACHER / UNIT_MANAGER / REGIONAL_MANAGER access report.\n * Mirrors backend shape from GET /access-report/access/user/:userId (professional variant).\n */\nexport interface AccessReportProfessionalData {\n user: AccessReportUser;\n accessData: {\n totalTime: string;\n activitiesTime: string;\n recommendedLessonsTime: string;\n accessCount: number;\n lastAccess: string | null;\n };\n accessByPlatform: AccessReportByPlatform;\n hoursByItem: {\n activities: AccessReportTimePercentage;\n recommendedLessons: AccessReportTimePercentage;\n };\n}\n\n/** @deprecated Use {@link REPORT_MODAL_VARIANT} instead. Re-exported for backwards compatibility. */\nexport { REPORT_MODAL_VARIANT as AccessReportModalVariant } from '../../types/common';\n\n/**\n * Access count by period item for bar chart\n */\nexport interface AccessCountByPeriodItem {\n label: string;\n count: number;\n}\n\ninterface AccessReportModalBaseProps {\n isOpen: boolean;\n onClose: () => void;\n /** Modal title (default: \"Relatório de acesso\") */\n title?: string;\n loading?: boolean;\n error?: string | null;\n /** Optional access count by period data for rendering the access count chart */\n accessCountByPeriod?: AccessCountByPeriodItem[];\n}\n\ntype AccessReportModalStudentProps = {\n variant: REPORT_MODAL_VARIANT.STUDENT;\n data: AccessReportStudentData | null;\n};\n\ntype AccessReportModalProfessionalProps = {\n variant: REPORT_MODAL_VARIANT.PROFESSIONAL;\n data: AccessReportProfessionalData | null;\n};\n\nexport type AccessReportModalProps = AccessReportModalBaseProps &\n (AccessReportModalStudentProps | AccessReportModalProfessionalProps);\n\n// ─── Pie slice builders ───────────────────────────────────────\n\nfunction buildPlatformSlices(platform: AccessReportByPlatform): PieSlice[] {\n // The pie is sized by the percentage; the legend reads the time next to each\n // platform (as in the design), not the percentage.\n return [\n {\n label: 'Web',\n value: platform.web.percentage,\n displayValue: platform.web.time,\n colorClass: 'bg-success-700',\n color: 'var(--Success-success700, #206F3E)',\n },\n {\n label: 'Celular',\n value: platform.mobile.percentage,\n displayValue: platform.mobile.time,\n colorClass: 'bg-success-300',\n color: 'var(--Success-success300, #66B584)',\n },\n ];\n}\n\nfunction buildStudentHoursSlices(\n hoursByItem: AccessReportStudentData['hoursByItem']\n): PieSlice[] {\n // Order, labels and colors mirror STUDENT_CATEGORIES from the reports page\n // TimeChart so the modal breakdown matches the page chart 1:1.\n return [\n {\n label: 'Atividades',\n value: hoursByItem.activities.percentage,\n colorClass: 'bg-success-700',\n },\n {\n label: 'Simulados',\n value: hoursByItem.simulations.percentage,\n colorClass: 'bg-warning-300',\n },\n {\n label: 'Questionários',\n value: hoursByItem.questionnaires.percentage,\n colorClass: 'bg-indicator-info',\n },\n {\n label: 'Videoaulas',\n value: hoursByItem.content.percentage,\n colorClass: 'bg-success-300',\n },\n {\n label: 'Aulas recomendadas',\n value: hoursByItem.recommendedLessons.percentage,\n colorClass: 'bg-indicator-positive',\n },\n ];\n}\n\n// ─── Modal content ────────────────────────────────────────────\n\nconst ReportContentLayout = ({\n user,\n metricBoxes,\n platformSlices,\n hoursSlices,\n accessCountByPeriod,\n}: {\n user: AccessReportUser;\n metricBoxes: ReactNode;\n platformSlices: PieSlice[];\n hoursSlices: PieSlice[];\n accessCountByPeriod?: AccessCountByPeriodItem[];\n}) => (\n <div className=\"flex flex-col gap-6\">\n <UserHeader\n name={user.name}\n school={user.school}\n className={user.class ?? ''}\n year={user.year}\n />\n\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-3\">{metricBoxes}</div>\n\n {accessCountByPeriod && accessCountByPeriod.length > 0 && (\n <SimpleBarChart\n data={accessCountByPeriod.map((item) => ({\n label: item.label,\n value: item.count,\n }))}\n title=\"Quantidade de acessos por período\"\n barColor=\"bg-info-500\"\n chartHeight={150}\n />\n )}\n\n <div className=\"flex flex-col gap-3\">\n <SectionTitle>Dados de acesso por plataforma</SectionTitle>\n <LegendPieCard slices={platformSlices} />\n </div>\n\n <div className=\"flex flex-col gap-3\">\n <SectionTitle>Dados de horas por item</SectionTitle>\n <LegendPieCard slices={hoursSlices} />\n </div>\n </div>\n);\n\nconst StudentModalContent = ({\n data,\n accessCountByPeriod,\n}: {\n data: AccessReportStudentData;\n accessCountByPeriod?: AccessCountByPeriodItem[];\n}) => (\n <ReportContentLayout\n user={data.user}\n platformSlices={buildPlatformSlices(data.accessByPlatform)}\n hoursSlices={buildStudentHoursSlices(data.hoursByItem)}\n accessCountByPeriod={accessCountByPeriod}\n metricBoxes={\n <>\n <MetricBox label=\"Tempo total\" value={data.accessData.totalTime} />\n <MetricBox label=\"Videoaulas\" value={data.accessData.contentTime} />\n <MetricBox\n label=\"Aulas recomendadas\"\n value={data.accessData.recommendedLessonsTime}\n />\n <MetricBox label=\"Simulados\" value={data.accessData.simulationsTime} />\n <MetricBox\n label=\"Quantidade de acessos\"\n value={data.accessData.accessCount}\n />\n <MetricBox\n label=\"Último acesso\"\n value={data.accessData.lastAccess ?? '—'}\n />\n </>\n }\n />\n);\n\nconst ProfessionalModalContent = ({\n data,\n accessCountByPeriod,\n}: {\n data: AccessReportProfessionalData;\n accessCountByPeriod?: AccessCountByPeriodItem[];\n}) => (\n <div className=\"flex flex-col gap-6\">\n <UserHeader\n name={data.user.name}\n school={data.user.school}\n className={data.user.class ?? ''}\n year={data.user.year}\n />\n\n <div className=\"flex flex-col gap-3\">\n <SectionTitle>Dados de acesso</SectionTitle>\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-3\">\n <MetricBox label=\"Tempo total\" value={data.accessData.totalTime} />\n <MetricBox label=\"Acessos\" value={data.accessData.accessCount} />\n <MetricBox\n label=\"Último acesso\"\n value={data.accessData.lastAccess ?? '—'}\n />\n </div>\n </div>\n\n {accessCountByPeriod && accessCountByPeriod.length > 0 && (\n <SimpleBarChart\n data={accessCountByPeriod.map((item) => ({\n label: item.label,\n value: item.count,\n }))}\n title=\"Quantidade de acessos por período\"\n barColor=\"bg-info-500\"\n chartHeight={150}\n />\n )}\n\n <div className=\"flex flex-col gap-3\">\n <SectionTitle>Dados de acesso por plataforma</SectionTitle>\n <LegendPieCard slices={buildPlatformSlices(data.accessByPlatform)} />\n </div>\n </div>\n);\n\nconst LoadingSkeleton = ({\n metricCount,\n showSecondaryChart = true,\n}: {\n metricCount: number;\n showSecondaryChart?: boolean;\n}) => (\n <div className=\"flex flex-col gap-4 animate-pulse\">\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-3\">\n {Array.from({ length: metricCount }, (_, i) => (\n <div\n key={`skeleton-${String(i)}`}\n className=\"h-16 bg-background-200 rounded-xl\"\n />\n ))}\n </div>\n <div className=\"h-5 bg-background-200 rounded w-40 mt-2\" />\n <div className=\"h-32 bg-background-200 rounded-xl\" />\n {showSecondaryChart && (\n <>\n <div className=\"h-5 bg-background-200 rounded w-32\" />\n <div className=\"h-32 bg-background-200 rounded-xl\" />\n </>\n )}\n </div>\n);\n\n// ─── Main component ───────────────────────────────────────────\n\n/**\n * AccessReportModal component\n *\n * Displays a modal with access data for a user.\n *\n * Two variants driven by the profile type:\n * - `STUDENT` — 6 metric boxes (totalTime, contentTime, recommendedLessonsTime,\n * simulationsTime, accessCount, lastAccess) + platform pie chart + hours-by-item pie chart\n * - `PROFESSIONAL` — 3 metric boxes (totalTime, accessCount, lastAccess) +\n * platform pie chart only (no hours-by-item breakdown for professionals)\n *\n * @example\n * ```tsx\n * <AccessReportModal\n * isOpen={isOpen}\n * onClose={() => setIsOpen(false)}\n * variant={REPORT_MODAL_VARIANT.STUDENT}\n * data={apiResponse.data}\n * />\n * ```\n */\nexport const AccessReportModal = ({\n isOpen,\n onClose,\n title = 'Relatório de acesso',\n loading = false,\n error = null,\n accessCountByPeriod,\n ...variantProps\n}: AccessReportModalProps) => {\n let content: ReactNode;\n\n const isStudent = variantProps.variant === REPORT_MODAL_VARIANT.STUDENT;\n // Student: 6 metrics + 2 charts; Professional: 3 metrics + 1 chart\n const metricCount = isStudent ? 6 : 3;\n const showSecondaryChart = isStudent;\n\n if (loading) {\n content = (\n <LoadingSkeleton\n metricCount={metricCount}\n showSecondaryChart={showSecondaryChart}\n />\n );\n } else if (error) {\n content = <ErrorContent message={error} />;\n } else if (variantProps.data === null) {\n content = <ErrorContent message=\"Nenhum dado disponível.\" />;\n } else if (variantProps.variant === REPORT_MODAL_VARIANT.STUDENT) {\n content = (\n <StudentModalContent\n data={variantProps.data}\n accessCountByPeriod={accessCountByPeriod}\n />\n );\n } else if (variantProps.variant === REPORT_MODAL_VARIANT.PROFESSIONAL) {\n content = (\n <ProfessionalModalContent\n data={variantProps.data}\n accessCountByPeriod={accessCountByPeriod}\n />\n );\n } else {\n content = <ErrorContent message=\"Variante de relatório inválida.\" />;\n }\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={onClose}\n title={title}\n size=\"lg\"\n contentClassName=\"max-h-[80vh] overflow-y-auto\"\n >\n {content}\n </Modal>\n );\n};\n\nexport default AccessReportModal;\n"]}
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
SUPPORT_CHAT_HANDLER,
|
|
21
21
|
SUPPORT_CHAT_MAX_ATTACHMENTS,
|
|
22
22
|
SUPPORT_CHAT_STATUS
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-C6LC5LD5.mjs";
|
|
24
24
|
import {
|
|
25
25
|
isSupportTicketOrigin
|
|
26
26
|
} from "./chunk-MVT7IVMY.mjs";
|
|
@@ -89,8 +89,31 @@ var useSupportChat = ({
|
|
|
89
89
|
const [messages, setMessages] = useState([]);
|
|
90
90
|
const [sending, setSending] = useState(false);
|
|
91
91
|
const [error, setError] = useState(null);
|
|
92
|
+
const [restored, setRestored] = useState(false);
|
|
92
93
|
const sendingRef = useRef(false);
|
|
93
94
|
const ticketId = ticket?.id;
|
|
95
|
+
const userEmail = user?.email;
|
|
96
|
+
const ticketRef = useRef(ticket);
|
|
97
|
+
ticketRef.current = ticket;
|
|
98
|
+
useEffect(() => {
|
|
99
|
+
if (!adapter.restoreConversation) return;
|
|
100
|
+
let active = true;
|
|
101
|
+
adapter.restoreConversation({ email: userEmail }).then((resumed) => {
|
|
102
|
+
if (!active || !resumed) return;
|
|
103
|
+
if (ticketRef.current || sendingRef.current) return;
|
|
104
|
+
setTicket(resumed.ticket);
|
|
105
|
+
setMessages(resumed.messages);
|
|
106
|
+
setRestored(true);
|
|
107
|
+
}).catch(() => {
|
|
108
|
+
});
|
|
109
|
+
return () => {
|
|
110
|
+
active = false;
|
|
111
|
+
};
|
|
112
|
+
}, [adapter, userEmail]);
|
|
113
|
+
const closed = ticket?.status === SUPPORT_CHAT_STATUS.FECHADO;
|
|
114
|
+
useEffect(() => {
|
|
115
|
+
if (closed) adapter.forgetConversation?.();
|
|
116
|
+
}, [adapter, closed]);
|
|
94
117
|
useEffect(() => {
|
|
95
118
|
if (!ticketId) return;
|
|
96
119
|
const handleEvent = (event) => {
|
|
@@ -180,16 +203,19 @@ var useSupportChat = ({
|
|
|
180
203
|
[adapter, ticketId]
|
|
181
204
|
);
|
|
182
205
|
const reset = useCallback(() => {
|
|
206
|
+
adapter.forgetConversation?.();
|
|
183
207
|
setTicket(null);
|
|
184
208
|
setMessages([]);
|
|
185
209
|
setError(null);
|
|
186
|
-
|
|
210
|
+
setRestored(false);
|
|
211
|
+
}, [adapter]);
|
|
187
212
|
return {
|
|
188
213
|
ticket,
|
|
189
214
|
messages,
|
|
190
215
|
sending,
|
|
191
216
|
error,
|
|
192
|
-
closed
|
|
217
|
+
closed,
|
|
218
|
+
restored,
|
|
193
219
|
send,
|
|
194
220
|
updateContact: adapter.updateContact ? updateContact : void 0,
|
|
195
221
|
reset
|
|
@@ -740,7 +766,16 @@ var SupportChatWidgetContent = ({
|
|
|
740
766
|
const listRef = useRef3(null);
|
|
741
767
|
const fileInputRef = useRef3(null);
|
|
742
768
|
const seenCount = useRef3(0);
|
|
743
|
-
const {
|
|
769
|
+
const {
|
|
770
|
+
messages,
|
|
771
|
+
sending,
|
|
772
|
+
error,
|
|
773
|
+
closed,
|
|
774
|
+
restored,
|
|
775
|
+
send,
|
|
776
|
+
updateContact,
|
|
777
|
+
reset
|
|
778
|
+
} = useSupportChat({
|
|
744
779
|
adapter,
|
|
745
780
|
channel,
|
|
746
781
|
institutionId,
|
|
@@ -776,10 +811,10 @@ var SupportChatWidgetContent = ({
|
|
|
776
811
|
useEffect4(() => {
|
|
777
812
|
const fresh = messages.slice(seenCount.current);
|
|
778
813
|
seenCount.current = messages.length;
|
|
779
|
-
if (isOpen) return;
|
|
814
|
+
if (isOpen || restored && fresh.length === messages.length) return;
|
|
780
815
|
const replies = fresh.filter((message) => !isOwnMessage(message)).length;
|
|
781
816
|
if (replies) setUnread((count) => count + replies);
|
|
782
|
-
}, [messages, isOpen]);
|
|
817
|
+
}, [messages, isOpen, restored]);
|
|
783
818
|
useEffect4(() => {
|
|
784
819
|
if (!isOpen || article) return;
|
|
785
820
|
setUnread(0);
|
|
@@ -1041,6 +1076,30 @@ var SupportChatWidgetContent = ({
|
|
|
1041
1076
|
import { useMemo as useMemo2 } from "react";
|
|
1042
1077
|
|
|
1043
1078
|
// src/components/SupportChatWidget/guestSupportChatAdapter.ts
|
|
1079
|
+
var DEFAULT_STORAGE_KEY = "analytica:support-chat";
|
|
1080
|
+
var readStoredSession = (key) => {
|
|
1081
|
+
try {
|
|
1082
|
+
const raw = globalThis.localStorage?.getItem(key);
|
|
1083
|
+
if (!raw) return null;
|
|
1084
|
+
const session = JSON.parse(raw);
|
|
1085
|
+
return session.ticketId && session.token ? session : null;
|
|
1086
|
+
} catch {
|
|
1087
|
+
return null;
|
|
1088
|
+
}
|
|
1089
|
+
};
|
|
1090
|
+
var writeStoredSession = (key, session) => {
|
|
1091
|
+
try {
|
|
1092
|
+
globalThis.localStorage?.setItem(key, JSON.stringify(session));
|
|
1093
|
+
} catch {
|
|
1094
|
+
}
|
|
1095
|
+
};
|
|
1096
|
+
var clearStoredSession = (key) => {
|
|
1097
|
+
try {
|
|
1098
|
+
globalThis.localStorage?.removeItem(key);
|
|
1099
|
+
} catch {
|
|
1100
|
+
}
|
|
1101
|
+
};
|
|
1102
|
+
var statusOf = (error) => error?.response?.status;
|
|
1044
1103
|
var GUEST_TOKEN_HEADER = "x-support-guest-token";
|
|
1045
1104
|
var senderNameFor = (role, requesterName) => {
|
|
1046
1105
|
if (role === SUPPORT_CHAT_AUTHOR.AGENT) return "Suporte";
|
|
@@ -1063,7 +1122,8 @@ var fromSupportAnswer = (answer, requesterName) => ({
|
|
|
1063
1122
|
var createGuestSupportChatAdapter = ({
|
|
1064
1123
|
apiClient,
|
|
1065
1124
|
wsUrl,
|
|
1066
|
-
pollIntervalMs = 3e3
|
|
1125
|
+
pollIntervalMs = 3e3,
|
|
1126
|
+
storageKey = DEFAULT_STORAGE_KEY
|
|
1067
1127
|
}) => {
|
|
1068
1128
|
const sessions = /* @__PURE__ */ new Map();
|
|
1069
1129
|
const hiddenIds = /* @__PURE__ */ new Set();
|
|
@@ -1131,15 +1191,22 @@ var createGuestSupportChatAdapter = ({
|
|
|
1131
1191
|
...isSupportTicketOrigin(channel) ? { origin: channel } : {}
|
|
1132
1192
|
});
|
|
1133
1193
|
const ticketId = data.data.id;
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
name: requesterName || "Visitante"
|
|
1137
|
-
});
|
|
1194
|
+
const name = requesterName || "Visitante";
|
|
1195
|
+
sessions.set(ticketId, { token: data.data.guestToken, name });
|
|
1138
1196
|
let messages = await listMessages(ticketId);
|
|
1197
|
+
let hiddenId;
|
|
1139
1198
|
if (!message && messages[0]) {
|
|
1140
|
-
|
|
1199
|
+
hiddenId = messages[0].id;
|
|
1200
|
+
hiddenIds.add(hiddenId);
|
|
1141
1201
|
messages = messages.slice(1);
|
|
1142
1202
|
}
|
|
1203
|
+
writeStoredSession(storageKey, {
|
|
1204
|
+
ticketId,
|
|
1205
|
+
token: data.data.guestToken,
|
|
1206
|
+
name,
|
|
1207
|
+
userEmail: email ?? null,
|
|
1208
|
+
hiddenId
|
|
1209
|
+
});
|
|
1143
1210
|
if (files.length) messages.push(await sendMessage(ticketId, "", files));
|
|
1144
1211
|
return {
|
|
1145
1212
|
ticket: {
|
|
@@ -1167,8 +1234,44 @@ var createGuestSupportChatAdapter = ({
|
|
|
1167
1234
|
const session = sessions.get(ticketId);
|
|
1168
1235
|
if (session && contact.requesterName) {
|
|
1169
1236
|
session.name = contact.requesterName;
|
|
1237
|
+
const stored = readStoredSession(storageKey);
|
|
1238
|
+
if (stored?.ticketId === ticketId) {
|
|
1239
|
+
writeStoredSession(storageKey, {
|
|
1240
|
+
...stored,
|
|
1241
|
+
name: contact.requesterName
|
|
1242
|
+
});
|
|
1243
|
+
}
|
|
1170
1244
|
}
|
|
1171
1245
|
},
|
|
1246
|
+
async restoreConversation({ email }) {
|
|
1247
|
+
const stored = readStoredSession(storageKey);
|
|
1248
|
+
if (!stored) return null;
|
|
1249
|
+
if (stored.userEmail !== (email ?? null)) {
|
|
1250
|
+
clearStoredSession(storageKey);
|
|
1251
|
+
return null;
|
|
1252
|
+
}
|
|
1253
|
+
const { ticketId } = stored;
|
|
1254
|
+
sessions.set(ticketId, { token: stored.token, name: stored.name });
|
|
1255
|
+
if (stored.hiddenId) hiddenIds.add(stored.hiddenId);
|
|
1256
|
+
try {
|
|
1257
|
+
const { data } = await apiClient.get(
|
|
1258
|
+
`/support/guest/${ticketId}`,
|
|
1259
|
+
{ headers: headersFor(ticketId) }
|
|
1260
|
+
);
|
|
1261
|
+
if (data.data.status === SUPPORT_CHAT_STATUS.FECHADO) {
|
|
1262
|
+
clearStoredSession(storageKey);
|
|
1263
|
+
return null;
|
|
1264
|
+
}
|
|
1265
|
+
return { ticket: data.data, messages: await listMessages(ticketId) };
|
|
1266
|
+
} catch (error) {
|
|
1267
|
+
if (statusOf(error) === 404) clearStoredSession(storageKey);
|
|
1268
|
+
sessions.delete(ticketId);
|
|
1269
|
+
return null;
|
|
1270
|
+
}
|
|
1271
|
+
},
|
|
1272
|
+
forgetConversation() {
|
|
1273
|
+
clearStoredSession(storageKey);
|
|
1274
|
+
},
|
|
1172
1275
|
listMessages,
|
|
1173
1276
|
subscribe(ticketId, listener) {
|
|
1174
1277
|
const seen = /* @__PURE__ */ new Map();
|
|
@@ -1433,4 +1536,4 @@ export {
|
|
|
1433
1536
|
NativeSupportChat,
|
|
1434
1537
|
createMockSupportChatAdapter
|
|
1435
1538
|
};
|
|
1436
|
-
//# sourceMappingURL=chunk-
|
|
1539
|
+
//# sourceMappingURL=chunk-CFV2OZ3P.mjs.map
|