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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-YRTIDZTN.js","../src/components/Support/Support.tsx","../src/components/Support/schema/index.ts","../src/components/Support/components/SidebarMenuItem.tsx","../src/components/Support/components/TicketListItem.tsx","../src/components/Support/utils/formatTicketTime.ts","../src/components/Support/components/TicketList.tsx","../src/components/Support/hooks/useInfiniteScrollSentinel.ts"],"names":["totalPages"],"mappings":"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","file":"/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-YRTIDZTN.js","sourcesContent":[null,"import { useState, useEffect } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport {\n KeyIcon,\n InfoIcon,\n BugIcon,\n CaretRightIcon,\n} from '@phosphor-icons/react';\nimport dayjs from 'dayjs';\nimport Text from '../Text/Text';\nimport SelectionButton from '../SelectionButton/SelectionButton';\nimport Input from '../Input/Input';\nimport TextArea from '../TextArea/TextArea';\nimport Button from '../Button/Button';\nimport Select, {\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '../Select/Select';\nimport Badge from '../Badge/Badge';\nimport { SkeletonText, SkeletonRounded } from '../Skeleton/Skeleton';\nimport Toast from '../Toast/Toast';\nimport Menu, { MenuContent, MenuItem } from '../Menu/Menu';\nimport { supportSchema, SupportFormData } from './schema';\nimport { TicketModal } from './components/TicketModal';\nimport {\n SupportTicket,\n SupportStatus,\n SupportCategory,\n TabType,\n ProblemType,\n getStatusBadgeAction,\n getStatusText,\n getCategoryText,\n CreateSupportTicketRequest,\n CreateSupportTicketResponse,\n SupportTicketAPI,\n GetSupportTicketsResponse,\n mapApiStatusToInternal,\n mapInternalStatusToApi,\n SupportApiClient,\n SupportTicketOrigin,\n} from '../../types/support';\nimport { getCategoryIcon } from './utils/supportUtils';\nimport SupportImage from '../../assets/img/suporthistory.png';\n\n// Individual ticket component to reduce nesting\nconst TicketCard = ({\n ticket,\n onTicketClick,\n}: {\n ticket: SupportTicket;\n onTicketClick: (ticket: SupportTicket) => void;\n}) => (\n <button\n key={ticket.id}\n type=\"button\"\n className=\"flex items-center justify-between p-4 bg-background rounded-xl cursor-pointer w-full text-left hover:bg-background-50 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2\"\n onClick={() => onTicketClick(ticket)}\n >\n <div className=\"flex flex-col\">\n <Text size=\"xs\" weight=\"bold\" className=\"text-text-900\">\n {ticket.title}\n </Text>\n </div>\n\n <div className=\"flex items-center gap-3\">\n <Badge\n variant=\"solid\"\n className=\"flex items-center gap-1\"\n action={getStatusBadgeAction(ticket.status)}\n >\n {getStatusText(ticket.status)}\n </Badge>\n <Badge variant=\"solid\" className=\"flex items-center gap-1\" action=\"muted\">\n {getCategoryIcon(ticket.category, 18)}\n {getCategoryText(ticket.category)}\n </Badge>\n <CaretRightIcon size={24} className=\"text-text-800\" />\n </div>\n </button>\n);\n\n// Ticket group component to reduce nesting\nconst TicketGroup = ({\n date,\n tickets,\n onTicketClick,\n}: {\n date: string;\n tickets: SupportTicket[];\n onTicketClick: (ticket: SupportTicket) => void;\n}) => (\n <div key={date} className=\"space-y-4\">\n <Text size=\"md\" weight=\"bold\" className=\"text-text-900\">\n {dayjs(date).format('DD MMM YYYY')}\n </Text>\n <div className=\"space-y-3\">\n {tickets.map((ticket) => (\n <TicketCard\n key={ticket.id}\n ticket={ticket}\n onTicketClick={onTicketClick}\n />\n ))}\n </div>\n </div>\n);\n\n// Empty state component\nconst EmptyState = ({ imageSrc }: { imageSrc?: string }) => (\n <div className=\"flex flex-row justify-center items-center mt-48\">\n {imageSrc && <img src={imageSrc} alt=\"Imagem de suporte\" />}\n <Text size=\"3xl\" weight=\"semibold\">\n Nenhum pedido encontrado.\n </Text>\n </div>\n);\n\n// Skeleton component for ticket loading\nconst TicketSkeleton = () => (\n <div className=\"space-y-6\">\n {[0, 1].map((groupIndex) => (\n <div key={groupIndex} className=\"space-y-4\">\n {/* Date skeleton */}\n <SkeletonText width=\"150px\" height={20} />\n\n {/* Tickets skeleton */}\n <div className=\"space-y-3\">\n {[0, 1].map((ticketIndex) => (\n <SkeletonRounded\n key={ticketIndex}\n width=\"100%\"\n height={72}\n className=\"p-4\"\n />\n ))}\n </div>\n </div>\n ))}\n </div>\n);\n\nexport interface SupportProps {\n /** API client instance for making requests */\n apiClient: SupportApiClient;\n /** Current user ID */\n userId?: string;\n /** Custom empty state image source (optional, uses default if not provided) */\n emptyStateImage?: string;\n /** Title displayed in the header */\n title?: string;\n /** Callback when a ticket is successfully created */\n onTicketCreated?: () => void;\n /** Callback when a ticket is successfully closed */\n onTicketClosed?: () => void;\n /** App the page runs in, saved on the tickets it opens (e.g. \"aluno\") */\n origin?: SupportTicketOrigin;\n}\n\nconst Support = ({\n apiClient,\n userId,\n emptyStateImage,\n title = 'Suporte',\n onTicketCreated,\n onTicketClosed,\n origin,\n}: SupportProps) => {\n const [activeTab, setActiveTab] = useState<TabType>('criar-pedido');\n const [selectedProblem, setSelectedProblem] = useState<ProblemType>(null);\n\n // Filtros do histórico\n const [statusFilter, setStatusFilter] = useState<string>('todos');\n const [categoryFilter, setCategoryFilter] = useState<string>('todos');\n\n // Estado do modal\n const [selectedTicket, setSelectedTicket] = useState<SupportTicket | null>(\n null\n );\n const [isModalOpen, setIsModalOpen] = useState(false);\n\n // Estados para feedback\n const [submitError, setSubmitError] = useState<string | null>(null);\n const [showSuccessToast, setShowSuccessToast] = useState(false);\n const [showCloseSuccessToast, setShowCloseSuccessToast] = useState(false);\n const [showCloseErrorToast, setShowCloseErrorToast] = useState(false);\n\n // Estados para histórico\n const [allTickets, setAllTickets] = useState<SupportTicketAPI[]>([]);\n const [loadingTickets, setLoadingTickets] = useState(false);\n const [currentPage, setCurrentPage] = useState(1);\n const ITEMS_PER_PAGE = 10;\n\n // Pagination handlers\n const handlePrevPage = () => {\n if (currentPage > 1) {\n setCurrentPage(currentPage - 1);\n }\n };\n\n const handleNextPage = () => {\n const totalPages = Math.ceil(filteredTickets.length / ITEMS_PER_PAGE);\n if (currentPage < totalPages) {\n setCurrentPage(currentPage + 1);\n }\n };\n\n // useEffect para buscar tickets quando mudar aba ou filtros\n useEffect(() => {\n if (activeTab === 'historico') {\n fetchTickets(statusFilter);\n setCurrentPage(1); // Reset to first page when filters change\n }\n }, [activeTab, statusFilter]);\n\n // Reset page when category filter changes\n useEffect(() => {\n setCurrentPage(1);\n }, [categoryFilter]);\n\n // Funções auxiliares\n\n // Converter dados da API para formato do componente\n const convertApiTicketToComponent = (\n apiTicket: SupportTicketAPI\n ): SupportTicket => {\n return {\n id: apiTicket.id,\n title: apiTicket.subject,\n status: mapApiStatusToInternal(apiTicket.status),\n createdAt: apiTicket.createdAt,\n category: apiTicket.type as SupportCategory,\n description: apiTicket.description,\n };\n };\n\n // Filtrar tickets por categoria e ordenar do mais novo para o mais antigo\n const filteredTickets = allTickets\n .map(convertApiTicketToComponent)\n .filter((ticket) => {\n const categoryMatch =\n categoryFilter === 'todos' || ticket.category === categoryFilter;\n return categoryMatch;\n })\n .sort(\n (a, b) =>\n new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()\n );\n\n // Calcular paginação no frontend\n const totalPages = Math.ceil(filteredTickets.length / ITEMS_PER_PAGE);\n const startIndex = (currentPage - 1) * ITEMS_PER_PAGE;\n const endIndex = startIndex + ITEMS_PER_PAGE;\n const paginatedTickets = filteredTickets.slice(startIndex, endIndex);\n\n const groupedTickets = paginatedTickets.reduce(\n (groups, ticket) => {\n const date = dayjs(ticket.createdAt).format('YYYY-MM-DD');\n if (!groups[date]) {\n groups[date] = [];\n }\n groups[date].push(ticket);\n return groups;\n },\n {} as Record<string, SupportTicket[]>\n );\n\n // React Hook Form setup\n const {\n register,\n handleSubmit,\n setValue,\n reset,\n formState: { errors, isSubmitting },\n } = useForm<SupportFormData>({\n resolver: zodResolver(supportSchema),\n defaultValues: {\n problemType: undefined,\n title: '',\n description: '',\n },\n });\n\n // Fetch tickets from API - buscar todos de uma vez com limit=100\n const fetchTickets = async (status?: string) => {\n setLoadingTickets(true);\n try {\n const params = new URLSearchParams({\n page: '1',\n limit: '100', // Buscar o máximo permitido pela API\n });\n\n if (status && status !== 'todos') {\n // Convert internal status to API status\n const apiStatus = mapInternalStatusToApi(status as SupportStatus);\n params.append('status', apiStatus);\n }\n\n const response = await apiClient.get<GetSupportTicketsResponse>(\n `/support?${params.toString()}`\n );\n\n setAllTickets(response.data.data.support);\n } catch (error) {\n console.error('Erro ao buscar tickets:', error);\n setAllTickets([]);\n } finally {\n setLoadingTickets(false);\n }\n };\n\n // Handle problem type selection\n const handleProblemSelection = (type: ProblemType) => {\n setSelectedProblem(type);\n if (type) {\n setValue('problemType', type, { shouldValidate: true });\n }\n };\n\n // Handle form submission\n const onSubmit = async (data: SupportFormData) => {\n setSubmitError(null);\n\n try {\n const requestData: CreateSupportTicketRequest = {\n subject: data.title,\n description: data.description,\n type: data.problemType,\n ...(origin ? { origin } : {}),\n };\n\n await apiClient.post<CreateSupportTicketResponse>(\n '/support',\n requestData\n );\n\n // Show success toast\n setShowSuccessToast(true);\n setTimeout(() => setShowSuccessToast(false), 4000);\n\n // Reset form after successful submission\n setSelectedProblem(null);\n reset();\n\n // Switch to history tab and refresh tickets list\n setActiveTab('historico');\n fetchTickets(statusFilter);\n\n // Call callback if provided\n onTicketCreated?.();\n } catch (error) {\n console.error('Erro ao criar ticket de suporte:', error);\n setSubmitError('Erro ao criar ticket. Tente novamente.');\n }\n };\n\n // Handle ticket click\n const handleTicketClick = (ticket: SupportTicket) => {\n setSelectedTicket(ticket);\n setIsModalOpen(true);\n };\n\n // Handle modal close\n const handleModalClose = () => {\n setIsModalOpen(false);\n setSelectedTicket(null);\n };\n\n // Handle ticket close\n const handleTicketClose = async (ticketId: string) => {\n try {\n await apiClient.patch(`/support/${ticketId}`, {\n status: mapInternalStatusToApi(SupportStatus.ENCERRADO),\n });\n\n // Show success toast\n setShowCloseSuccessToast(true);\n setTimeout(() => setShowCloseSuccessToast(false), 4000);\n\n // Refresh tickets list\n if (activeTab === 'historico') {\n fetchTickets(statusFilter);\n }\n\n // Call callback if provided\n onTicketClosed?.();\n } catch (error) {\n console.error('Erro ao encerrar ticket:', error);\n // Show error toast\n setShowCloseErrorToast(true);\n setTimeout(() => setShowCloseErrorToast(false), 4000);\n }\n };\n\n const problemTypes = [\n {\n id: SupportCategory.TECNICO,\n title: 'Técnico',\n icon: <BugIcon size={24} />,\n },\n {\n id: SupportCategory.ACESSO,\n title: 'Acesso',\n icon: <KeyIcon size={24} />,\n },\n {\n id: SupportCategory.OUTROS,\n title: 'Outros',\n icon: <InfoIcon size={24} />,\n },\n ];\n\n // Determine which image to use for empty state\n const emptyImage = emptyStateImage || SupportImage;\n\n return (\n <div className=\"flex flex-col w-full h-full overflow-y-auto\">\n <div className=\"flex flex-col w-full h-full\">\n {/* Header */}\n <div className=\"space-y-4\">\n <div className=\"flex w-full mb-4 flex-row items-center justify-between not-lg:gap-4 lg:gap-6\">\n <h1 className=\"font-bold leading-[28px] tracking-[0.2px] text-text-950 text-xl mt-4 sm:text-2xl sm:flex-1 sm:self-end sm:mt-0\">\n {title}\n </h1>\n <div className=\"sm:flex-shrink-0 sm:self-end\">\n <Menu\n value={activeTab}\n defaultValue=\"criar-pedido\"\n variant=\"menu2\"\n onValueChange={(value) => setActiveTab(value as TabType)}\n className=\"bg-transparent shadow-none px-0\"\n >\n <MenuContent variant=\"menu2\">\n <MenuItem\n variant=\"menu2\"\n value=\"criar-pedido\"\n className=\"whitespace-nowrap px-17 not-sm:px-5\"\n >\n Criar Pedido\n </MenuItem>\n <MenuItem\n variant=\"menu2\"\n value=\"historico\"\n className=\"whitespace-nowrap px-17 not-sm:px-5\"\n >\n Histórico\n </MenuItem>\n </MenuContent>\n </Menu>\n </div>\n </div>\n\n {/* Content for Criar Pedido tab */}\n {activeTab === 'criar-pedido' && (\n <div className=\"space-y-2\">\n <Text as=\"h2\" size=\"md\" weight=\"bold\" className=\"text-text-900\">\n Selecione o tipo de problema\n </Text>\n\n <div className=\"flex flex-col sm:flex-row gap-2 sm:gap-4\">\n {problemTypes.map((type) => (\n <SelectionButton\n key={type.id}\n icon={type.icon}\n label={type.title}\n selected={selectedProblem === type.id}\n onClick={() => handleProblemSelection(type.id)}\n className=\"w-full p-4\"\n />\n ))}\n </div>\n {errors.problemType && (\n <Text size=\"sm\" className=\"text-red-500 mt-1\">\n {errors.problemType.message}\n </Text>\n )}\n </div>\n )}\n\n {selectedProblem && activeTab === 'criar-pedido' && (\n <form onSubmit={handleSubmit(onSubmit)} className=\"space-y-4\">\n <div className=\"space-y-1\">\n <Input\n size=\"large\"\n variant=\"rounded\"\n label=\"Título\"\n placeholder=\"Digite o título\"\n {...register('title')}\n errorMessage={errors.title?.message}\n />\n </div>\n <div className=\"space-y-1\">\n <TextArea\n size=\"large\"\n label=\"Descrição\"\n placeholder=\"Descreva o problema aqui\"\n {...register('description')}\n errorMessage={errors.description?.message}\n />\n </div>\n <Button\n size=\"large\"\n className=\"float-end mt-10\"\n type=\"submit\"\n disabled={isSubmitting}\n >\n {isSubmitting ? 'Enviando...' : 'Enviar Pedido'}\n </Button>\n\n {/* Error message */}\n {submitError && (\n <div className=\"mt-4 p-4 bg-red-100 border border-red-400 text-red-700 rounded\">\n <Text size=\"sm\" className=\"text-red-700\">\n {submitError}\n </Text>\n </div>\n )}\n </form>\n )}\n\n {/* Content for Historico tab */}\n {activeTab === 'historico' && (\n <div className=\"space-y-6\">\n {/* Filtros */}\n <div className=\"flex gap-4\">\n <div className=\"flex flex-col flex-1/2 space-y-1\">\n <Select\n label=\"Status\"\n size=\"large\"\n value={statusFilter}\n onValueChange={setStatusFilter}\n >\n <SelectTrigger variant=\"rounded\" className=\"\">\n <SelectValue placeholder=\"Todos\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"todos\">Todos</SelectItem>\n <SelectItem value={SupportStatus.ABERTO}>\n Aberto\n </SelectItem>\n <SelectItem value={SupportStatus.RESPONDIDO}>\n Respondido\n </SelectItem>\n <SelectItem value={SupportStatus.ENCERRADO}>\n Encerrado\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"flex flex-col flex-1/2 space-y-1\">\n <Select\n label=\"Tipo\"\n size=\"large\"\n value={categoryFilter}\n onValueChange={setCategoryFilter}\n >\n <SelectTrigger variant=\"rounded\" className=\"\">\n <SelectValue placeholder=\"Todos\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"todos\">Todos</SelectItem>\n <SelectItem value={SupportCategory.TECNICO}>\n <BugIcon size={16} /> Técnico\n </SelectItem>\n <SelectItem value={SupportCategory.ACESSO}>\n <KeyIcon size={16} /> Acesso\n </SelectItem>\n <SelectItem value={SupportCategory.OUTROS}>\n <InfoIcon size={16} /> Outros\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n </div>\n\n {/* Lista de tickets */}\n {(() => {\n if (loadingTickets) {\n return <TicketSkeleton />;\n }\n\n if (Object.keys(groupedTickets).length === 0) {\n return <EmptyState imageSrc={emptyImage} />;\n }\n\n return (\n <div className=\"space-y-6\">\n {Object.entries(groupedTickets)\n .sort(\n ([a], [b]) =>\n new Date(b).getTime() - new Date(a).getTime()\n )\n .map(([date, tickets]) => (\n <TicketGroup\n key={date}\n date={date}\n tickets={tickets}\n onTicketClick={handleTicketClick}\n />\n ))}\n </div>\n );\n })()}\n\n {/* Paginação */}\n {!loadingTickets && totalPages > 1 && (\n <div className=\"flex justify-center items-center gap-4 mt-6\">\n <Button\n variant=\"outline\"\n size=\"small\"\n onClick={handlePrevPage}\n disabled={currentPage === 1}\n >\n Anterior\n </Button>\n <Text size=\"sm\" className=\"text-text-600\">\n Página {currentPage} de {totalPages}\n </Text>\n <Button\n variant=\"outline\"\n size=\"small\"\n onClick={handleNextPage}\n disabled={currentPage === totalPages}\n >\n Próxima\n </Button>\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n\n {/* Modal do ticket */}\n {selectedTicket && (\n <TicketModal\n ticket={selectedTicket}\n isOpen={isModalOpen}\n onClose={handleModalClose}\n onTicketClose={handleTicketClose}\n apiClient={apiClient}\n userId={userId}\n />\n )}\n\n {/* Success Toast */}\n {showSuccessToast && (\n <div className=\"fixed top-4 left-1/2 transform -translate-x-1/2 z-50\">\n <Toast\n title=\"Pedido enviado!\"\n description=\"Agora você pode acompanhar o andamento do seu pedido.\"\n variant=\"solid\"\n onClose={() => setShowSuccessToast(false)}\n />\n </div>\n )}\n\n {/* Close Success Toast */}\n {showCloseSuccessToast && (\n <div className=\"fixed top-4 left-1/2 transform -translate-x-1/2 z-50\">\n <Toast\n title=\"Pedido encerrado!\"\n description=\"\"\n variant=\"solid\"\n onClose={() => setShowCloseSuccessToast(false)}\n />\n </div>\n )}\n\n {/* Close Error Toast */}\n {showCloseErrorToast && (\n <div className=\"fixed top-4 left-1/2 transform -translate-x-1/2 z-50\">\n <Toast\n title=\"Erro ao encerrar pedido\"\n description=\"Não foi possível encerrar o pedido. Tente novamente.\"\n variant=\"solid\"\n action=\"warning\"\n onClose={() => setShowCloseErrorToast(false)}\n />\n </div>\n )}\n </div>\n );\n};\n\nexport default Support;\n","import { z } from 'zod';\n\n// Schema de validação para o formulário de suporte\nexport const supportSchema = z.object({\n // Tipo de problema selecionado\n problemType: z.enum(['tecnico', 'acesso', 'outros'], {\n error: () =>\n 'Campo obrigatório! Por favor, preencha este campo para continuar.',\n }),\n\n // Título do problema\n title: z\n .string()\n .min(1, 'Campo obrigatório! Por favor, preencha este campo para continuar.')\n .min(5, 'Título deve ter pelo menos 5 caracteres')\n .max(100, 'Título deve ter no máximo 100 caracteres')\n .trim(),\n\n // Descrição do problema\n description: z\n .string()\n .min(1, 'Campo obrigatório! Por favor, preencha este campo para continuar.')\n .min(10, 'Descrição deve ter pelo menos 10 caracteres')\n .max(1000, 'Descrição deve ter no máximo 1000 caracteres')\n .trim(),\n});\n\n// Type inferido do schema\nexport type SupportFormData = z.infer<typeof supportSchema>;\n","import { ButtonHTMLAttributes, ReactNode, forwardRef } from 'react';\nimport { cn } from '../../../utils/utils';\nimport Badge from '../../Badge/Badge';\nimport Button from '../../Button/Button';\nimport Text from '../../Text/Text';\n\n/** Nível do item na árvore do menu lateral. */\nexport type SidebarMenuItemVariant = 'main' | 'sub';\n\n/**\n * Paleta do estado ativo.\n *\n * - `theme` (padrão): segue `primary-*`, ou seja, se adapta à whitelabel /\n * instituição — verde no analytica, azul no parana, vermelho no paraiba.\n * - `info`: segue a rampa `info-*` do tema. Atenção: nem todo tema usa azul\n * aqui (no analytica a rampa `info` é roxa).\n * - `blue`: o azul literal do Figma do SAC, idêntico em qualquer tema. Use\n * quando a tela precisa bater com o Figma e não com a marca do cliente.\n */\nexport type SidebarMenuItemActiveTone = 'theme' | 'info' | 'blue';\n\nconst ACTIVE_CLASSES: Record<SidebarMenuItemActiveTone, string> = {\n theme: 'bg-primary-50 text-primary-700',\n info: 'bg-info-background text-info-800',\n blue: 'bg-[#EBF2FE] text-[#1A56DB]',\n};\n\n/**\n * Tonalidade da contagem do item `main`. O `sub` ignora: ali a contagem é\n * texto puro que herda a cor do item, como no Figma.\n */\nexport type SidebarMenuItemCountTone = 'warning' | 'theme' | 'muted';\n\nconst COUNT_CLASSES: Record<SidebarMenuItemCountTone, string> = {\n warning: 'bg-warning-100 text-warning-700',\n theme: 'bg-primary-100 text-primary-800',\n muted: 'bg-background-muted text-background-800',\n};\n\nconst IDLE_CLASSES: Record<SidebarMenuItemVariant, string> = {\n main: 'text-text-950 hover:bg-background-50',\n sub: 'text-text-600 hover:bg-background-50',\n};\n\n/**\n * Peso do rótulo, no vocabulário do `Text`. Fica no rótulo e não no botão\n * porque o `Text` escreve o próprio `font-*`: um peso herdado do botão seria\n * sobrescrito pelo default (`normal`) do componente.\n */\nconst LABEL_WEIGHT: Record<SidebarMenuItemVariant, 'medium' | 'normal'> = {\n main: 'medium',\n sub: 'normal',\n};\n\n/** Escala do item. `md` é o tamanho do Figma. */\nexport type SidebarMenuItemSize = 'sm' | 'md';\n\n/**\n * Espaçamento, tipografia e ícone andam juntos porque o recuo do sub é\n * derivado deles: o sub precisa alinhar com o *rótulo* do main, ou seja\n * `padding` + ícone + `gap`. Separar isso em props soltas deixaria o consumidor\n * desalinhar os dois níveis sem perceber.\n *\n * - `md`: px-3 (12) + ícone 20 + gap-3 (12) = 44px = `pl-11`\n * - `sm`: px-2 (8) + ícone 16 + gap-2 (8) = 32px = `pl-8`\n *\n * O `[&>svg]:size-*` força o ícone do consumidor a caber na caixa: as props\n * `width`/`height` que o Phosphor escreve no `<svg>` são atributos de\n * apresentação, então qualquer regra CSS ganha delas. Assim um\n * `<Icon size={20} />` passado num item `sm` encolhe em vez de vazar.\n *\n * `label` é o mesmo tamanho do `item`, escrito no vocabulário do `Text`. A\n * classe continua no botão porque a contagem do `sub` é texto puro e herda dali.\n */\nconst SIZE_CLASSES: Record<\n SidebarMenuItemSize,\n {\n item: string;\n subIndent: string;\n icon: string;\n label: 'xs' | 'sm';\n badge: 'small' | 'medium';\n }\n> = {\n sm: {\n item: 'gap-2 px-2 py-1.5 text-xs',\n subIndent: 'pl-8',\n icon: 'size-4 [&>svg]:size-4',\n label: 'xs',\n badge: 'small',\n },\n md: {\n item: 'gap-3 px-3 py-2.5 text-sm',\n subIndent: 'pl-11',\n icon: 'size-5 [&>svg]:size-5',\n label: 'sm',\n badge: 'medium',\n },\n};\n\nexport type SidebarMenuItemProps = {\n /** Texto do item. */\n label: string;\n /** Ícone à esquerda. Renderizado apenas em `variant=\"main\"`. */\n icon?: ReactNode;\n /** Contagem exibida à direita. `0` é exibido; omitir esconde. */\n count?: number;\n /** Marca o item como o destino atual da navegação. */\n active?: boolean;\n /** Nível do item: `main` (com ícone) ou `sub` (recuado). */\n variant?: SidebarMenuItemVariant;\n /** Escala do item. `md` (padrão) é o tamanho do Figma; `sm` é compacto. */\n size?: SidebarMenuItemSize;\n /** Paleta do estado ativo. Ignorada quando o item não está ativo. */\n activeTone?: SidebarMenuItemActiveTone;\n /** Tonalidade da pílula de contagem do `main`. Ignorada pelo `sub`. */\n countTone?: SidebarMenuItemCountTone;\n /** Classes CSS adicionais. */\n className?: string;\n} & ButtonHTMLAttributes<HTMLButtonElement>;\n\nconst BASE_CLASSES =\n 'w-full flex items-center rounded-lg text-left cursor-pointer transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indicator-info disabled:opacity-50 disabled:cursor-not-allowed disabled:pointer-events-none';\n\n/**\n * Item do menu lateral do SAC.\n *\n * Combina os dois eixos do Figma (\"Componentes – Suporte\" → Menu lateral /\n * Item): tipo (`main` | `sub`) e estado (`active`). O main leva ícone e mostra\n * a contagem numa pílula laranja; o sub é recuado, sem ícone, e mostra a\n * contagem como texto que herda a cor do item.\n *\n * Renderiza o `Button` da lib na variante `raw` (`type=\"button\"`, sem estilo\n * próprio) com `onClick` — a navegação fica a cargo do consumidor, sem acoplar a\n * lib a um router.\n *\n * @example\n * ```tsx\n * <SidebarMenuItem\n * icon={<SquaresFourIcon size={20} />}\n * label=\"Dashboard\"\n * count={4}\n * active={pathname === '/dashboard'}\n * onClick={() => navigate('/dashboard')}\n * />\n * <SidebarMenuItem label=\"Meus chamados\" variant=\"sub\" count={4} />\n * ```\n */\nexport const SidebarMenuItem = forwardRef<\n HTMLButtonElement,\n SidebarMenuItemProps\n>(\n (\n {\n label,\n icon,\n count,\n active = false,\n variant = 'main',\n size = 'md',\n activeTone = 'theme',\n countTone = 'warning',\n className,\n ...props\n },\n ref\n ) => {\n const scale = SIZE_CLASSES[size];\n const stateClasses = active ? ACTIVE_CLASSES[activeTone] : undefined;\n const showIcon = variant === 'main' && Boolean(icon);\n\n return (\n <Button\n ref={ref}\n variant=\"raw\"\n aria-current={active ? 'page' : undefined}\n className={cn(\n BASE_CLASSES,\n scale.item,\n variant === 'sub' && scale.subIndent,\n stateClasses ?? IDLE_CLASSES[variant],\n className\n )}\n {...props}\n >\n {showIcon && (\n <span\n data-testid=\"sidebar-menu-item-icon\"\n aria-hidden=\"true\"\n className={cn(\n 'flex items-center justify-center shrink-0',\n scale.icon\n )}\n >\n {icon}\n </span>\n )}\n <Text\n as=\"span\"\n size={scale.label}\n weight={LABEL_WEIGHT[variant]}\n color=\"text-inherit\"\n className=\"flex-1 truncate\"\n >\n {label}\n </Text>\n {count !== undefined && (\n <SidebarMenuItemCount\n count={count}\n variant={variant}\n badgeSize={scale.badge}\n tone={countTone}\n />\n )}\n </Button>\n );\n }\n);\n\nSidebarMenuItem.displayName = 'SidebarMenuItem';\n\n/**\n * A contagem do main é uma pílula laranja; a do sub é texto que herda a cor do\n * item — o `Badge` entra pelo layout/espaçamento e a tonalidade vem do Figma\n * (`warning-100`/`warning-700`, mais saturada que o `warning` padrão do Badge).\n */\nconst SidebarMenuItemCount = ({\n count,\n variant,\n badgeSize,\n tone,\n}: {\n count: number;\n variant: SidebarMenuItemVariant;\n badgeSize: 'small' | 'medium';\n tone: SidebarMenuItemCountTone;\n}) => {\n // Sem classe de tipografia: o número herda tamanho e cor do próprio item.\n if (variant === 'sub') {\n return (\n <span\n data-testid=\"sidebar-menu-item-count\"\n className=\"shrink-0 tabular-nums\"\n >\n {count}\n </span>\n );\n }\n\n return (\n <Badge\n data-testid=\"sidebar-menu-item-count\"\n action=\"warning\"\n size={badgeSize}\n className={cn(\n 'shrink-0 rounded-full font-medium tabular-nums min-w-6',\n COUNT_CLASSES[tone]\n )}\n >\n {count}\n </Badge>\n );\n};\n\nexport default SidebarMenuItem;\n","import { ButtonHTMLAttributes, ReactNode, forwardRef } from 'react';\nimport { cn } from '../../../utils/utils';\nimport { Avatar } from '../../Avatar/Avatar';\nimport Badge from '../../Badge/Badge';\nimport Button from '../../Button/Button';\nimport Text from '../../Text/Text';\nimport { formatTicketTime } from '../utils/formatTicketTime';\n\n/**\n * Fundo da linha. É um eixo puramente visual: a lib não amarra significado a\n * cada cor, quem consome decide o que `danger` quer dizer (SLA, prioridade,\n * ticket reaberto). O hover sobrepõe qualquer tone.\n *\n * As cores vêm dos tokens do tema (`primary-50` é o azul claro do Figma no\n * light e um azul escuro no dark), para a linha seguir o modo escuro. Só a\n * barra e o avatar ficam no azul literal do Figma. Escritas por extenso porque\n * o Tailwind varre o código-fonte e não resolve classe interpolada.\n */\nexport type TicketListItemTone = 'default' | 'info' | 'danger';\n\nconst TONE_CLASSES: Record<TicketListItemTone, string> = {\n default: 'bg-transparent',\n info: 'bg-primary-50',\n danger: 'bg-error-background',\n};\n\n/** Tonalidade das badges. Mapeia para as rampas do tema, como o `Badge`. */\nexport type TicketListItemBadgeTone =\n | 'muted'\n | 'warning'\n | 'info'\n | 'success'\n | 'error';\n\nconst BADGE_TONE_CLASSES: Record<TicketListItemBadgeTone, string> = {\n muted: 'bg-transparent text-text-700 border border-border-300',\n warning: 'bg-warning-100 text-warning-700',\n info: 'bg-info text-info-800',\n success: 'bg-success text-success-800',\n error: 'bg-error-background text-error-700',\n};\n\nconst BADGE_CLASSES = 'shrink-0 rounded-md font-medium uppercase';\n\n/** Escala do item. `md` é o tamanho do Figma. */\nexport type TicketListItemSize = 'sm' | 'md' | 'lg';\n\n/** Tamanhos aceitos pelo `Text`, para os campos tipográficos da escala. */\ntype TicketListItemTextSize = '2xs' | 'xs' | 'sm' | 'md' | 'lg';\n\n/**\n * Espaçamento, avatar, tipografia e ícone andam juntos numa tabela só porque a\n * linha só lê bem quando escalam na mesma proporção: um avatar de 48 ao lado de\n * um nome `text-sm` desalinha a coluna de texto. Separar isso em props soltas\n * deixaria o consumidor quebrar o alinhamento sem perceber.\n *\n * `name`, `time`, `meta` e `message` são tamanhos do `Text`, não classes: quem\n * renderiza esses textos é o componente da lib, que escreve o próprio `text-*`.\n *\n * O `[&>svg]:size-*` força o ícone de canal do consumidor a caber na caixa: as\n * props `width`/`height` que o Phosphor escreve no `<svg>` são atributos de\n * apresentação, então qualquer regra CSS ganha delas.\n */\nconst SIZE_CLASSES: Record<\n TicketListItemSize,\n {\n item: string;\n rows: string;\n avatar: number;\n name: TicketListItemTextSize;\n time: TicketListItemTextSize;\n meta: TicketListItemTextSize;\n message: TicketListItemTextSize;\n badge: 'small' | 'medium';\n icon: string;\n bar: string;\n dot: string;\n }\n> = {\n sm: {\n item: 'gap-2 p-3',\n rows: 'gap-0.5',\n avatar: 32,\n name: 'sm',\n time: '2xs',\n meta: 'xs',\n message: 'xs',\n badge: 'small',\n icon: '[&>svg]:size-3.5',\n bar: 'w-0.5',\n dot: 'size-1.5',\n },\n md: {\n item: 'gap-3 p-4',\n rows: 'gap-1',\n avatar: 40,\n name: 'md',\n time: 'xs',\n meta: 'sm',\n message: 'sm',\n badge: 'small',\n icon: '[&>svg]:size-4',\n bar: 'w-1',\n dot: 'size-2',\n },\n lg: {\n item: 'gap-4 p-5',\n rows: 'gap-1.5',\n avatar: 48,\n name: 'lg',\n time: 'sm',\n meta: 'md',\n message: 'md',\n badge: 'medium',\n icon: '[&>svg]:size-5',\n bar: 'w-1.5',\n dot: 'size-2.5',\n },\n};\n\nconst BASE_CLASSES =\n 'group relative flex w-full items-start text-left cursor-pointer transition-colors hover:bg-primary-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indicator-info disabled:opacity-50 disabled:cursor-not-allowed disabled:pointer-events-none';\n\nexport type TicketListItemProps = {\n /** Nome de quem abriu o ticket. */\n name: string;\n /** Momento da última mensagem. A lib formata o texto relativo. */\n lastMessageAt: Date | string;\n /** Acende o ponto azul antes do tempo e anuncia \"Não lido\". */\n unread?: boolean;\n /**\n * Quantas mensagens ainda não foram lidas. Acima de zero, troca o ponto por\n * uma pílula com o número (`99+` a partir de 100) e já marca a linha como não\n * lida, sem precisar de `unread`.\n */\n unreadCount?: number;\n /** Foto. Sem foto, o avatar mostra as iniciais de `name`. */\n avatarSrc?: string;\n /** Badge do perfil. Texto livre: o vocabulário do SAC ainda não está fechado. */\n profileLabel?: string;\n /** Tonalidade da badge de perfil. Default `muted` (contornada). */\n profileTone?: TicketListItemBadgeTone;\n /** Instituição de origem. */\n organization?: string;\n /** Prévia da última mensagem, truncada em uma linha. */\n message?: string;\n /** Badge do atendimento. Texto livre. */\n attendanceLabel?: string;\n /** Tonalidade da badge de atendimento. Default `warning`, o pêssego do Figma. */\n attendanceTone?: TicketListItemBadgeTone;\n /** Ícone do canal de origem. */\n channelIcon?: ReactNode;\n /** Código do ticket, como vier do app (ex.: `#4826`). */\n ticketCode?: string;\n /** Fundo da linha. */\n tone?: TicketListItemTone;\n /** Escala do item. `md` (padrão) é o tamanho do Figma. */\n size?: TicketListItemSize;\n /** Classes CSS adicionais. */\n className?: string;\n} & ButtonHTMLAttributes<HTMLButtonElement>;\n\n/** Acima disso a pílula de não lidas mostra `99+`. */\nconst MAX_UNREAD_SHOWN = 99;\n\n/** Rótulo lido por leitor de tela na pílula de não lidas. */\nconst formatUnreadLabel = (count: number): string =>\n count === 1 ? '1 mensagem não lida' : `${count} mensagens não lidas`;\n\n/**\n * Linha da lista de tickets do SAC.\n *\n * Reproduz o frame \"Lista de tickets – item\" do Figma (\"Componentes –\n * Suporte\"): avatar, nome, tempo da última mensagem, badge de perfil,\n * instituição, prévia da conversa, badge de atendimento, canal e código.\n *\n * Só `name` e `lastMessageAt` são obrigatórios; cada bloco desaparece quando a\n * prop não vem, então uma lista sem instituição ou sem canal continua alinhada.\n *\n * Renderiza o `Button` da lib na variante `raw` (`type=\"button\"`, sem estilo\n * próprio) com `onClick` — a navegação fica a cargo do consumidor, sem acoplar a\n * lib a um router.\n *\n * @example\n * ```tsx\n * <TicketListItem\n * name=\"Ana Clara Mendes\"\n * lastMessageAt={ticket.updatedAt}\n * profileLabel=\"ESTUDANTE\"\n * organization=\"CE Santos Dumont\"\n * message=\"IA: Entendi. Vou transferir você para um atendente.\"\n * attendanceLabel=\"HUMANO\"\n * channelIcon={<DeviceMobileIcon size={16} />}\n * ticketCode=\"#4826\"\n * tone={ticket.id === selectedId ? 'info' : 'default'}\n * onClick={() => select(ticket.id)}\n * />\n * ```\n */\nexport const TicketListItem = forwardRef<\n HTMLButtonElement,\n TicketListItemProps\n>(\n (\n {\n name,\n lastMessageAt,\n unread = false,\n unreadCount = 0,\n avatarSrc,\n profileLabel,\n profileTone = 'muted',\n organization,\n message,\n attendanceLabel,\n attendanceTone = 'warning',\n channelIcon,\n ticketCode,\n tone = 'default',\n size = 'md',\n className,\n ...props\n },\n ref\n ) => {\n const scale = SIZE_CLASSES[size];\n\n return (\n <Button\n ref={ref}\n variant=\"raw\"\n className={cn(BASE_CLASSES, scale.item, TONE_CLASSES[tone], className)}\n {...props}\n >\n <span\n data-testid=\"ticket-list-item-bar\"\n aria-hidden=\"true\"\n className={cn(\n 'absolute inset-y-0 left-0 bg-[#1C61B2] transition-opacity',\n scale.bar,\n tone === 'info'\n ? 'opacity-100'\n : 'opacity-0 group-hover:opacity-100'\n )}\n />\n\n <Avatar\n src={avatarSrc}\n name={name}\n fallback=\"initials\"\n size={scale.avatar}\n className=\"bg-[#1C61B2] text-white\"\n />\n\n <span className={cn('flex min-w-0 flex-1 flex-col', scale.rows)}>\n <span className=\"flex items-center gap-2\">\n <Text\n as=\"span\"\n size={scale.name}\n weight=\"bold\"\n className=\"min-w-0 flex-1 truncate\"\n >\n {name}\n </Text>\n {unreadCount > 0 && (\n <Text\n as=\"span\"\n size=\"xs\"\n weight=\"bold\"\n color=\"text-white\"\n data-testid=\"ticket-list-item-unread-count\"\n aria-label={formatUnreadLabel(unreadCount)}\n className=\"shrink-0 min-w-5 h-5 px-1.5 rounded-full bg-[#1C61B2] flex items-center justify-center\"\n >\n {unreadCount > MAX_UNREAD_SHOWN\n ? `${MAX_UNREAD_SHOWN}+`\n : unreadCount}\n </Text>\n )}\n {unread && unreadCount <= 0 && (\n <>\n <span\n data-testid=\"ticket-list-item-unread\"\n aria-hidden=\"true\"\n className={cn(\n 'shrink-0 rounded-full bg-[#1C61B2]',\n scale.dot\n )}\n />\n <span className=\"sr-only\">Não lido</span>\n </>\n )}\n <Text\n as=\"span\"\n size={scale.time}\n color=\"text-text-600\"\n className=\"shrink-0\"\n >\n {formatTicketTime(lastMessageAt)}\n </Text>\n </span>\n\n {(profileLabel || organization) && (\n <span className=\"flex min-w-0 items-center gap-2\">\n {profileLabel && (\n <Badge\n data-testid=\"ticket-list-item-profile\"\n size={scale.badge}\n className={cn(BADGE_CLASSES, BADGE_TONE_CLASSES[profileTone])}\n >\n {profileLabel}\n </Badge>\n )}\n {organization && (\n <Text\n as=\"span\"\n size={scale.meta}\n color=\"text-text-600\"\n className=\"min-w-0 truncate\"\n >\n {organization}\n </Text>\n )}\n </span>\n )}\n\n {message && (\n <Text\n as=\"span\"\n size={scale.message}\n color=\"text-text-700\"\n className=\"truncate\"\n >\n {message}\n </Text>\n )}\n\n {(attendanceLabel || channelIcon || ticketCode) && (\n <span className=\"flex items-center gap-2\">\n {attendanceLabel && (\n <Badge\n data-testid=\"ticket-list-item-attendance\"\n size={scale.badge}\n className={cn(\n BADGE_CLASSES,\n BADGE_TONE_CLASSES[attendanceTone]\n )}\n >\n {attendanceLabel}\n </Badge>\n )}\n {channelIcon && (\n <span\n data-testid=\"ticket-list-item-channel\"\n aria-hidden=\"true\"\n className={cn(\n 'flex shrink-0 items-center text-text-600',\n scale.icon\n )}\n >\n {channelIcon}\n </span>\n )}\n {ticketCode && (\n <Text\n as=\"span\"\n size={scale.meta}\n color=\"text-text-600\"\n className=\"shrink-0 tabular-nums\"\n >\n {ticketCode}\n </Text>\n )}\n </span>\n )}\n </span>\n </Button>\n );\n }\n);\n\nTicketListItem.displayName = 'TicketListItem';\n\nexport default TicketListItem;\n","const MINUTE_MS = 60_000;\nconst HOUR_MS = 60 * MINUTE_MS;\nconst DAY_MS = 24 * HOUR_MS;\nconst WEEK_MS = 7 * DAY_MS;\n\n/**\n * Tempo decorrido desde a última mensagem, no formato curto do Figma do SAC.\n *\n * Os limiares são: menos de um minuto vira `agora`; abaixo de uma hora, minutos\n * (`6 min`); abaixo de um dia, horas (`2 h`); abaixo de uma semana, dias\n * (`3 d`); daí em diante a data curta (`12/09/2026`), porque \"há 43 d\" não\n * ajuda ninguém a localizar o atendimento.\n *\n * Recebe `now` por parâmetro para o teste fixar o relógio sem `fakeTimers`, e\n * cai no relógio real quando omitido.\n *\n * Data inválida devolve string vazia: o item prefere não mostrar nada a mostrar\n * `NaN min`.\n *\n * @example\n * ```ts\n * formatTicketTime(ticket.lastMessageAt); // \"6 min\"\n * ```\n */\nexport const formatTicketTime = (\n value: Date | string,\n now: Date = new Date()\n): string => {\n const date = value instanceof Date ? value : new Date(value);\n\n if (Number.isNaN(date.getTime())) {\n return '';\n }\n\n const elapsed = now.getTime() - date.getTime();\n\n if (elapsed < MINUTE_MS) {\n return 'agora';\n }\n\n if (elapsed < HOUR_MS) {\n return `${Math.floor(elapsed / MINUTE_MS)} min`;\n }\n\n if (elapsed < DAY_MS) {\n return `${Math.floor(elapsed / HOUR_MS)} h`;\n }\n\n if (elapsed < WEEK_MS) {\n return `${Math.floor(elapsed / DAY_MS)} d`;\n }\n\n return date.toLocaleDateString('pt-BR');\n};\n","import { ReactNode, useRef } from 'react';\nimport { cn } from '../../../utils/utils';\nimport EmptyState from '../../EmptyState/EmptyState';\nimport { Skeleton, SkeletonCircle } from '../../Skeleton/Skeleton';\nimport { useInfiniteScrollSentinel } from '../hooks/useInfiniteScrollSentinel';\nimport {\n TicketListItem,\n TicketListItemProps,\n TicketListItemSize,\n} from './TicketListItem';\n\n/** Um ticket da lista: as props do item mais o `id` que identifica a seleção. */\nexport type TicketListItemData = Omit<TicketListItemProps, 'onClick'> & {\n id: string;\n};\n\n/** Quantos skeletons o rodapé mostra enquanto a próxima página carrega. */\nconst LOADING_MORE_SKELETONS = 2;\n\nexport type TicketListProps = {\n /** Tickets já carregados, na ordem em que devem aparecer. */\n tickets: TicketListItemData[];\n /** `id` do ticket aberto no painel. */\n selectedId?: string;\n /** Chamado com o `id` do ticket clicado. */\n onSelect?: (id: string) => void;\n /** Primeira carga: substitui a lista por skeletons. */\n loading?: boolean;\n /** Paginação em curso: skeletons no rodapé, sem esconder o que já carregou. */\n loadingMore?: boolean;\n /** Ainda há páginas a buscar. */\n hasMore?: boolean;\n /** Chamado quando a sentinela do fim da lista entra na viewport. */\n onLoadMore?: () => void;\n /** Quantos skeletons exibir na primeira carga. Default 5. */\n skeletonCount?: number;\n /** Substitui o estado vazio padrão. */\n emptyState?: ReactNode;\n /** Escala repassada a todos os itens. `md` (padrão) é o tamanho do Figma. */\n size?: TicketListItemSize;\n /** Classes CSS adicionais. */\n className?: string;\n};\n\n/**\n * Espaçamento e avatar do esqueleto, espelhando o `SIZE_CLASSES` do item para\n * que a lista não mude de altura quando os dados chegam.\n */\nconst SKELETON_SIZE: Record<\n TicketListItemSize,\n { item: string; avatar: number }\n> = {\n sm: { item: 'gap-2 p-3', avatar: 32 },\n md: { item: 'gap-3 p-4', avatar: 40 },\n lg: { item: 'gap-4 p-5', avatar: 48 },\n};\n\n/**\n * Esqueleto no formato da linha: círculo do avatar mais três faixas de texto.\n * Extraído do componente porque o JSX dele já decide entre três caminhos de\n * render, e aninhar o `Array.from` ali dentro vira issue de manutenibilidade.\n */\nconst TicketListSkeletons = ({\n count,\n size,\n}: {\n count: number;\n size: TicketListItemSize;\n}) => (\n <>\n {Array.from({ length: count }, (_, index) => (\n <div\n key={index}\n data-testid=\"ticket-list-skeleton\"\n className={cn('flex items-start', SKELETON_SIZE[size].item)}\n >\n <SkeletonCircle\n width={SKELETON_SIZE[size].avatar}\n height={SKELETON_SIZE[size].avatar}\n />\n <div className=\"flex flex-1 flex-col gap-2\">\n <Skeleton width=\"60%\" />\n <Skeleton width=\"40%\" />\n <Skeleton width=\"80%\" />\n </div>\n </div>\n ))}\n </>\n);\n\n/**\n * Lista de tickets do SAC.\n *\n * Empilha `TicketListItem`, separa com divisores, marca o selecionado e pagina\n * por scroll infinito. A seleção é controlada: o app diz *qual* ticket está\n * aberto e a lista decide *como* isso aparece (o tone `info` do Figma),\n * sobrepondo o `tone` que o próprio ticket tenha pedido.\n *\n * O divisor vive aqui, e não no item, porque o item reaproveitado fora da lista\n * — no topo de uma conversa aberta, por exemplo — não deve carregar borda.\n *\n * @example\n * ```tsx\n * <TicketList\n * tickets={tickets}\n * selectedId={selectedId}\n * onSelect={setSelectedId}\n * loading={isLoading}\n * loadingMore={isFetchingNextPage}\n * hasMore={hasNextPage}\n * onLoadMore={fetchNextPage}\n * />\n * ```\n */\nexport const TicketList = ({\n tickets,\n selectedId,\n onSelect,\n loading = false,\n loadingMore = false,\n hasMore = false,\n onLoadMore,\n skeletonCount = 5,\n emptyState,\n size = 'md',\n className,\n}: TicketListProps) => {\n const sentinelRef = useRef<HTMLDivElement>(null);\n\n useInfiniteScrollSentinel({\n ref: sentinelRef,\n enabled: hasMore && !loading && !loadingMore,\n onIntersect: onLoadMore,\n });\n\n if (loading) {\n return (\n <div className={cn('flex flex-col', className)}>\n <TicketListSkeletons count={skeletonCount} size={size} />\n </div>\n );\n }\n\n if (tickets.length === 0) {\n return (\n <div className={cn('flex flex-col', className)}>\n {emptyState ?? (\n <EmptyState\n size=\"compact\"\n title=\"Nenhum ticket encontrado\"\n description=\"Não há atendimentos para exibir no momento.\"\n />\n )}\n </div>\n );\n }\n\n return (\n <div role=\"list\" className={cn('flex flex-col', className)}>\n {tickets.map(({ id, tone, ...ticket }, index) => {\n const selected = id === selectedId;\n\n return (\n <div\n key={id}\n role=\"listitem\"\n className={cn(\n index < tickets.length - 1 && 'border-b border-border-100'\n )}\n >\n <TicketListItem\n {...ticket}\n size={size}\n tone={selected ? 'info' : tone}\n aria-current={selected ? 'true' : undefined}\n onClick={() => onSelect?.(id)}\n />\n </div>\n );\n })}\n\n {loadingMore && (\n <TicketListSkeletons count={LOADING_MORE_SKELETONS} size={size} />\n )}\n\n <div ref={sentinelRef} aria-hidden=\"true\" className=\"h-px shrink-0\" />\n </div>\n );\n};\n\nexport default TicketList;\n","import { RefObject, useEffect, useRef } from 'react';\n\nexport type UseInfiniteScrollSentinelOptions = {\n /** Elemento sentinela, normalmente um `<div>` de 1px após o último item. */\n ref: RefObject<HTMLElement | null>;\n /** Observa enquanto `true`. Desligue durante carregamento e no fim da lista. */\n enabled?: boolean;\n /** Chamado quando a sentinela entra na viewport. */\n onIntersect?: () => void;\n /** Fração visível que dispara. Default `0.1`, como no `useLessonBank`. */\n threshold?: number;\n};\n\n/**\n * Dispara `onIntersect` quando a sentinela entra na viewport — o scroll\n * infinito, sem conhecer lista nem paginação.\n *\n * O callback é guardado numa ref de propósito. Consumidores costumam passar uma\n * arrow nova a cada render; se ela entrasse nas dependências do efeito, o\n * observer seria destruído e recriado a cada render e voltaria a disparar\n * imediatamente enquanto a sentinela estivesse visível — um laço de\n * `onLoadMore`. Assim o observer só é recriado quando o alvo, o `enabled` ou o\n * `threshold` mudam, e ainda chama sempre a versão mais recente do callback.\n *\n * @example\n * ```tsx\n * const sentinelRef = useRef<HTMLDivElement>(null);\n * useInfiniteScrollSentinel({\n * ref: sentinelRef,\n * enabled: hasMore && !loading,\n * onIntersect: onLoadMore,\n * });\n * ```\n */\nexport const useInfiniteScrollSentinel = ({\n ref,\n enabled = true,\n onIntersect,\n threshold = 0.1,\n}: UseInfiniteScrollSentinelOptions): void => {\n const callbackRef = useRef(onIntersect);\n\n useEffect(() => {\n callbackRef.current = onIntersect;\n }, [onIntersect]);\n\n const hasCallback = Boolean(onIntersect);\n\n useEffect(() => {\n const target = ref.current;\n\n if (!target || !enabled || !hasCallback) {\n return;\n }\n\n const observer = new IntersectionObserver(\n (entries) => {\n if (entries[0]?.isIntersecting) {\n callbackRef.current?.();\n }\n },\n { threshold }\n );\n\n observer.observe(target);\n\n return () => observer.disconnect();\n }, [ref, enabled, hasCallback, threshold]);\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-VHEDMUAW.js","../src/components/Support/Support.tsx","../src/components/Support/schema/index.ts","../src/components/Support/components/SidebarMenuItem.tsx","../src/components/Support/components/TicketListItem.tsx","../src/components/Support/utils/formatTicketTime.ts","../src/components/Support/components/TicketList.tsx","../src/components/Support/hooks/useInfiniteScrollSentinel.ts"],"names":["totalPages"],"mappings":"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","file":"/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-VHEDMUAW.js","sourcesContent":[null,"import { useState, useEffect } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport {\n KeyIcon,\n InfoIcon,\n BugIcon,\n CaretRightIcon,\n} from '@phosphor-icons/react';\nimport dayjs from 'dayjs';\nimport Text from '../Text/Text';\nimport SelectionButton from '../SelectionButton/SelectionButton';\nimport Input from '../Input/Input';\nimport TextArea from '../TextArea/TextArea';\nimport Button from '../Button/Button';\nimport Select, {\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '../Select/Select';\nimport Badge from '../Badge/Badge';\nimport { SkeletonText, SkeletonRounded } from '../Skeleton/Skeleton';\nimport Toast from '../Toast/Toast';\nimport Menu, { MenuContent, MenuItem } from '../Menu/Menu';\nimport { supportSchema, SupportFormData } from './schema';\nimport { TicketModal } from './components/TicketModal';\nimport {\n SupportTicket,\n SupportStatus,\n SupportCategory,\n TabType,\n ProblemType,\n getStatusBadgeAction,\n getStatusText,\n getCategoryText,\n CreateSupportTicketRequest,\n CreateSupportTicketResponse,\n SupportTicketAPI,\n GetSupportTicketsResponse,\n mapApiStatusToInternal,\n mapInternalStatusToApi,\n SupportApiClient,\n SupportTicketOrigin,\n} from '../../types/support';\nimport { getCategoryIcon } from './utils/supportUtils';\nimport SupportImage from '../../assets/img/suporthistory.png';\n\n// Individual ticket component to reduce nesting\nconst TicketCard = ({\n ticket,\n onTicketClick,\n}: {\n ticket: SupportTicket;\n onTicketClick: (ticket: SupportTicket) => void;\n}) => (\n <button\n key={ticket.id}\n type=\"button\"\n className=\"flex items-center justify-between p-4 bg-background rounded-xl cursor-pointer w-full text-left hover:bg-background-50 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2\"\n onClick={() => onTicketClick(ticket)}\n >\n <div className=\"flex flex-col\">\n <Text size=\"xs\" weight=\"bold\" className=\"text-text-900\">\n {ticket.title}\n </Text>\n </div>\n\n <div className=\"flex items-center gap-3\">\n <Badge\n variant=\"solid\"\n className=\"flex items-center gap-1\"\n action={getStatusBadgeAction(ticket.status)}\n >\n {getStatusText(ticket.status)}\n </Badge>\n <Badge variant=\"solid\" className=\"flex items-center gap-1\" action=\"muted\">\n {getCategoryIcon(ticket.category, 18)}\n {getCategoryText(ticket.category)}\n </Badge>\n <CaretRightIcon size={24} className=\"text-text-800\" />\n </div>\n </button>\n);\n\n// Ticket group component to reduce nesting\nconst TicketGroup = ({\n date,\n tickets,\n onTicketClick,\n}: {\n date: string;\n tickets: SupportTicket[];\n onTicketClick: (ticket: SupportTicket) => void;\n}) => (\n <div key={date} className=\"space-y-4\">\n <Text size=\"md\" weight=\"bold\" className=\"text-text-900\">\n {dayjs(date).format('DD MMM YYYY')}\n </Text>\n <div className=\"space-y-3\">\n {tickets.map((ticket) => (\n <TicketCard\n key={ticket.id}\n ticket={ticket}\n onTicketClick={onTicketClick}\n />\n ))}\n </div>\n </div>\n);\n\n// Empty state component\nconst EmptyState = ({ imageSrc }: { imageSrc?: string }) => (\n <div className=\"flex flex-row justify-center items-center mt-48\">\n {imageSrc && <img src={imageSrc} alt=\"Imagem de suporte\" />}\n <Text size=\"3xl\" weight=\"semibold\">\n Nenhum pedido encontrado.\n </Text>\n </div>\n);\n\n// Skeleton component for ticket loading\nconst TicketSkeleton = () => (\n <div className=\"space-y-6\">\n {[0, 1].map((groupIndex) => (\n <div key={groupIndex} className=\"space-y-4\">\n {/* Date skeleton */}\n <SkeletonText width=\"150px\" height={20} />\n\n {/* Tickets skeleton */}\n <div className=\"space-y-3\">\n {[0, 1].map((ticketIndex) => (\n <SkeletonRounded\n key={ticketIndex}\n width=\"100%\"\n height={72}\n className=\"p-4\"\n />\n ))}\n </div>\n </div>\n ))}\n </div>\n);\n\nexport interface SupportProps {\n /** API client instance for making requests */\n apiClient: SupportApiClient;\n /** Current user ID */\n userId?: string;\n /** Custom empty state image source (optional, uses default if not provided) */\n emptyStateImage?: string;\n /** Title displayed in the header */\n title?: string;\n /** Callback when a ticket is successfully created */\n onTicketCreated?: () => void;\n /** Callback when a ticket is successfully closed */\n onTicketClosed?: () => void;\n /** App the page runs in, saved on the tickets it opens (e.g. \"aluno\") */\n origin?: SupportTicketOrigin;\n}\n\nconst Support = ({\n apiClient,\n userId,\n emptyStateImage,\n title = 'Suporte',\n onTicketCreated,\n onTicketClosed,\n origin,\n}: SupportProps) => {\n const [activeTab, setActiveTab] = useState<TabType>('criar-pedido');\n const [selectedProblem, setSelectedProblem] = useState<ProblemType>(null);\n\n // Filtros do histórico\n const [statusFilter, setStatusFilter] = useState<string>('todos');\n const [categoryFilter, setCategoryFilter] = useState<string>('todos');\n\n // Estado do modal\n const [selectedTicket, setSelectedTicket] = useState<SupportTicket | null>(\n null\n );\n const [isModalOpen, setIsModalOpen] = useState(false);\n\n // Estados para feedback\n const [submitError, setSubmitError] = useState<string | null>(null);\n const [showSuccessToast, setShowSuccessToast] = useState(false);\n const [showCloseSuccessToast, setShowCloseSuccessToast] = useState(false);\n const [showCloseErrorToast, setShowCloseErrorToast] = useState(false);\n\n // Estados para histórico\n const [allTickets, setAllTickets] = useState<SupportTicketAPI[]>([]);\n const [loadingTickets, setLoadingTickets] = useState(false);\n const [currentPage, setCurrentPage] = useState(1);\n const ITEMS_PER_PAGE = 10;\n\n // Pagination handlers\n const handlePrevPage = () => {\n if (currentPage > 1) {\n setCurrentPage(currentPage - 1);\n }\n };\n\n const handleNextPage = () => {\n const totalPages = Math.ceil(filteredTickets.length / ITEMS_PER_PAGE);\n if (currentPage < totalPages) {\n setCurrentPage(currentPage + 1);\n }\n };\n\n // useEffect para buscar tickets quando mudar aba ou filtros\n useEffect(() => {\n if (activeTab === 'historico') {\n fetchTickets(statusFilter);\n setCurrentPage(1); // Reset to first page when filters change\n }\n }, [activeTab, statusFilter]);\n\n // Reset page when category filter changes\n useEffect(() => {\n setCurrentPage(1);\n }, [categoryFilter]);\n\n // Funções auxiliares\n\n // Converter dados da API para formato do componente\n const convertApiTicketToComponent = (\n apiTicket: SupportTicketAPI\n ): SupportTicket => {\n return {\n id: apiTicket.id,\n title: apiTicket.subject,\n status: mapApiStatusToInternal(apiTicket.status),\n createdAt: apiTicket.createdAt,\n category: apiTicket.type as SupportCategory,\n description: apiTicket.description,\n };\n };\n\n // Filtrar tickets por categoria e ordenar do mais novo para o mais antigo\n const filteredTickets = allTickets\n .map(convertApiTicketToComponent)\n .filter((ticket) => {\n const categoryMatch =\n categoryFilter === 'todos' || ticket.category === categoryFilter;\n return categoryMatch;\n })\n .sort(\n (a, b) =>\n new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()\n );\n\n // Calcular paginação no frontend\n const totalPages = Math.ceil(filteredTickets.length / ITEMS_PER_PAGE);\n const startIndex = (currentPage - 1) * ITEMS_PER_PAGE;\n const endIndex = startIndex + ITEMS_PER_PAGE;\n const paginatedTickets = filteredTickets.slice(startIndex, endIndex);\n\n const groupedTickets = paginatedTickets.reduce(\n (groups, ticket) => {\n const date = dayjs(ticket.createdAt).format('YYYY-MM-DD');\n if (!groups[date]) {\n groups[date] = [];\n }\n groups[date].push(ticket);\n return groups;\n },\n {} as Record<string, SupportTicket[]>\n );\n\n // React Hook Form setup\n const {\n register,\n handleSubmit,\n setValue,\n reset,\n formState: { errors, isSubmitting },\n } = useForm<SupportFormData>({\n resolver: zodResolver(supportSchema),\n defaultValues: {\n problemType: undefined,\n title: '',\n description: '',\n },\n });\n\n // Fetch tickets from API - buscar todos de uma vez com limit=100\n const fetchTickets = async (status?: string) => {\n setLoadingTickets(true);\n try {\n const params = new URLSearchParams({\n page: '1',\n limit: '100', // Buscar o máximo permitido pela API\n });\n\n if (status && status !== 'todos') {\n // Convert internal status to API status\n const apiStatus = mapInternalStatusToApi(status as SupportStatus);\n params.append('status', apiStatus);\n }\n\n const response = await apiClient.get<GetSupportTicketsResponse>(\n `/support?${params.toString()}`\n );\n\n setAllTickets(response.data.data.support);\n } catch (error) {\n console.error('Erro ao buscar tickets:', error);\n setAllTickets([]);\n } finally {\n setLoadingTickets(false);\n }\n };\n\n // Handle problem type selection\n const handleProblemSelection = (type: ProblemType) => {\n setSelectedProblem(type);\n if (type) {\n setValue('problemType', type, { shouldValidate: true });\n }\n };\n\n // Handle form submission\n const onSubmit = async (data: SupportFormData) => {\n setSubmitError(null);\n\n try {\n const requestData: CreateSupportTicketRequest = {\n subject: data.title,\n description: data.description,\n type: data.problemType,\n ...(origin ? { origin } : {}),\n };\n\n await apiClient.post<CreateSupportTicketResponse>(\n '/support',\n requestData\n );\n\n // Show success toast\n setShowSuccessToast(true);\n setTimeout(() => setShowSuccessToast(false), 4000);\n\n // Reset form after successful submission\n setSelectedProblem(null);\n reset();\n\n // Switch to history tab and refresh tickets list\n setActiveTab('historico');\n fetchTickets(statusFilter);\n\n // Call callback if provided\n onTicketCreated?.();\n } catch (error) {\n console.error('Erro ao criar ticket de suporte:', error);\n setSubmitError('Erro ao criar ticket. Tente novamente.');\n }\n };\n\n // Handle ticket click\n const handleTicketClick = (ticket: SupportTicket) => {\n setSelectedTicket(ticket);\n setIsModalOpen(true);\n };\n\n // Handle modal close\n const handleModalClose = () => {\n setIsModalOpen(false);\n setSelectedTicket(null);\n };\n\n // Handle ticket close\n const handleTicketClose = async (ticketId: string) => {\n try {\n await apiClient.patch(`/support/${ticketId}`, {\n status: mapInternalStatusToApi(SupportStatus.ENCERRADO),\n });\n\n // Show success toast\n setShowCloseSuccessToast(true);\n setTimeout(() => setShowCloseSuccessToast(false), 4000);\n\n // Refresh tickets list\n if (activeTab === 'historico') {\n fetchTickets(statusFilter);\n }\n\n // Call callback if provided\n onTicketClosed?.();\n } catch (error) {\n console.error('Erro ao encerrar ticket:', error);\n // Show error toast\n setShowCloseErrorToast(true);\n setTimeout(() => setShowCloseErrorToast(false), 4000);\n }\n };\n\n const problemTypes = [\n {\n id: SupportCategory.TECNICO,\n title: 'Técnico',\n icon: <BugIcon size={24} />,\n },\n {\n id: SupportCategory.ACESSO,\n title: 'Acesso',\n icon: <KeyIcon size={24} />,\n },\n {\n id: SupportCategory.OUTROS,\n title: 'Outros',\n icon: <InfoIcon size={24} />,\n },\n ];\n\n // Determine which image to use for empty state\n const emptyImage = emptyStateImage || SupportImage;\n\n return (\n <div className=\"flex flex-col w-full h-full overflow-y-auto\">\n <div className=\"flex flex-col w-full h-full\">\n {/* Header */}\n <div className=\"space-y-4\">\n <div className=\"flex w-full mb-4 flex-row items-center justify-between not-lg:gap-4 lg:gap-6\">\n <h1 className=\"font-bold leading-[28px] tracking-[0.2px] text-text-950 text-xl mt-4 sm:text-2xl sm:flex-1 sm:self-end sm:mt-0\">\n {title}\n </h1>\n <div className=\"sm:flex-shrink-0 sm:self-end\">\n <Menu\n value={activeTab}\n defaultValue=\"criar-pedido\"\n variant=\"menu2\"\n onValueChange={(value) => setActiveTab(value as TabType)}\n className=\"bg-transparent shadow-none px-0\"\n >\n <MenuContent variant=\"menu2\">\n <MenuItem\n variant=\"menu2\"\n value=\"criar-pedido\"\n className=\"whitespace-nowrap px-17 not-sm:px-5\"\n >\n Criar Pedido\n </MenuItem>\n <MenuItem\n variant=\"menu2\"\n value=\"historico\"\n className=\"whitespace-nowrap px-17 not-sm:px-5\"\n >\n Histórico\n </MenuItem>\n </MenuContent>\n </Menu>\n </div>\n </div>\n\n {/* Content for Criar Pedido tab */}\n {activeTab === 'criar-pedido' && (\n <div className=\"space-y-2\">\n <Text as=\"h2\" size=\"md\" weight=\"bold\" className=\"text-text-900\">\n Selecione o tipo de problema\n </Text>\n\n <div className=\"flex flex-col sm:flex-row gap-2 sm:gap-4\">\n {problemTypes.map((type) => (\n <SelectionButton\n key={type.id}\n icon={type.icon}\n label={type.title}\n selected={selectedProblem === type.id}\n onClick={() => handleProblemSelection(type.id)}\n className=\"w-full p-4\"\n />\n ))}\n </div>\n {errors.problemType && (\n <Text size=\"sm\" className=\"text-red-500 mt-1\">\n {errors.problemType.message}\n </Text>\n )}\n </div>\n )}\n\n {selectedProblem && activeTab === 'criar-pedido' && (\n <form onSubmit={handleSubmit(onSubmit)} className=\"space-y-4\">\n <div className=\"space-y-1\">\n <Input\n size=\"large\"\n variant=\"rounded\"\n label=\"Título\"\n placeholder=\"Digite o título\"\n {...register('title')}\n errorMessage={errors.title?.message}\n />\n </div>\n <div className=\"space-y-1\">\n <TextArea\n size=\"large\"\n label=\"Descrição\"\n placeholder=\"Descreva o problema aqui\"\n {...register('description')}\n errorMessage={errors.description?.message}\n />\n </div>\n <Button\n size=\"large\"\n className=\"float-end mt-10\"\n type=\"submit\"\n disabled={isSubmitting}\n >\n {isSubmitting ? 'Enviando...' : 'Enviar Pedido'}\n </Button>\n\n {/* Error message */}\n {submitError && (\n <div className=\"mt-4 p-4 bg-red-100 border border-red-400 text-red-700 rounded\">\n <Text size=\"sm\" className=\"text-red-700\">\n {submitError}\n </Text>\n </div>\n )}\n </form>\n )}\n\n {/* Content for Historico tab */}\n {activeTab === 'historico' && (\n <div className=\"space-y-6\">\n {/* Filtros */}\n <div className=\"flex gap-4\">\n <div className=\"flex flex-col flex-1/2 space-y-1\">\n <Select\n label=\"Status\"\n size=\"large\"\n value={statusFilter}\n onValueChange={setStatusFilter}\n >\n <SelectTrigger variant=\"rounded\" className=\"\">\n <SelectValue placeholder=\"Todos\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"todos\">Todos</SelectItem>\n <SelectItem value={SupportStatus.ABERTO}>\n Aberto\n </SelectItem>\n <SelectItem value={SupportStatus.RESPONDIDO}>\n Respondido\n </SelectItem>\n <SelectItem value={SupportStatus.ENCERRADO}>\n Encerrado\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"flex flex-col flex-1/2 space-y-1\">\n <Select\n label=\"Tipo\"\n size=\"large\"\n value={categoryFilter}\n onValueChange={setCategoryFilter}\n >\n <SelectTrigger variant=\"rounded\" className=\"\">\n <SelectValue placeholder=\"Todos\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"todos\">Todos</SelectItem>\n <SelectItem value={SupportCategory.TECNICO}>\n <BugIcon size={16} /> Técnico\n </SelectItem>\n <SelectItem value={SupportCategory.ACESSO}>\n <KeyIcon size={16} /> Acesso\n </SelectItem>\n <SelectItem value={SupportCategory.OUTROS}>\n <InfoIcon size={16} /> Outros\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n </div>\n\n {/* Lista de tickets */}\n {(() => {\n if (loadingTickets) {\n return <TicketSkeleton />;\n }\n\n if (Object.keys(groupedTickets).length === 0) {\n return <EmptyState imageSrc={emptyImage} />;\n }\n\n return (\n <div className=\"space-y-6\">\n {Object.entries(groupedTickets)\n .sort(\n ([a], [b]) =>\n new Date(b).getTime() - new Date(a).getTime()\n )\n .map(([date, tickets]) => (\n <TicketGroup\n key={date}\n date={date}\n tickets={tickets}\n onTicketClick={handleTicketClick}\n />\n ))}\n </div>\n );\n })()}\n\n {/* Paginação */}\n {!loadingTickets && totalPages > 1 && (\n <div className=\"flex justify-center items-center gap-4 mt-6\">\n <Button\n variant=\"outline\"\n size=\"small\"\n onClick={handlePrevPage}\n disabled={currentPage === 1}\n >\n Anterior\n </Button>\n <Text size=\"sm\" className=\"text-text-600\">\n Página {currentPage} de {totalPages}\n </Text>\n <Button\n variant=\"outline\"\n size=\"small\"\n onClick={handleNextPage}\n disabled={currentPage === totalPages}\n >\n Próxima\n </Button>\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n\n {/* Modal do ticket */}\n {selectedTicket && (\n <TicketModal\n ticket={selectedTicket}\n isOpen={isModalOpen}\n onClose={handleModalClose}\n onTicketClose={handleTicketClose}\n apiClient={apiClient}\n userId={userId}\n />\n )}\n\n {/* Success Toast */}\n {showSuccessToast && (\n <div className=\"fixed top-4 left-1/2 transform -translate-x-1/2 z-50\">\n <Toast\n title=\"Pedido enviado!\"\n description=\"Agora você pode acompanhar o andamento do seu pedido.\"\n variant=\"solid\"\n onClose={() => setShowSuccessToast(false)}\n />\n </div>\n )}\n\n {/* Close Success Toast */}\n {showCloseSuccessToast && (\n <div className=\"fixed top-4 left-1/2 transform -translate-x-1/2 z-50\">\n <Toast\n title=\"Pedido encerrado!\"\n description=\"\"\n variant=\"solid\"\n onClose={() => setShowCloseSuccessToast(false)}\n />\n </div>\n )}\n\n {/* Close Error Toast */}\n {showCloseErrorToast && (\n <div className=\"fixed top-4 left-1/2 transform -translate-x-1/2 z-50\">\n <Toast\n title=\"Erro ao encerrar pedido\"\n description=\"Não foi possível encerrar o pedido. Tente novamente.\"\n variant=\"solid\"\n action=\"warning\"\n onClose={() => setShowCloseErrorToast(false)}\n />\n </div>\n )}\n </div>\n );\n};\n\nexport default Support;\n","import { z } from 'zod';\n\n// Schema de validação para o formulário de suporte\nexport const supportSchema = z.object({\n // Tipo de problema selecionado\n problemType: z.enum(['tecnico', 'acesso', 'outros'], {\n error: () =>\n 'Campo obrigatório! Por favor, preencha este campo para continuar.',\n }),\n\n // Título do problema\n title: z\n .string()\n .min(1, 'Campo obrigatório! Por favor, preencha este campo para continuar.')\n .min(5, 'Título deve ter pelo menos 5 caracteres')\n .max(100, 'Título deve ter no máximo 100 caracteres')\n .trim(),\n\n // Descrição do problema\n description: z\n .string()\n .min(1, 'Campo obrigatório! Por favor, preencha este campo para continuar.')\n .min(10, 'Descrição deve ter pelo menos 10 caracteres')\n .max(1000, 'Descrição deve ter no máximo 1000 caracteres')\n .trim(),\n});\n\n// Type inferido do schema\nexport type SupportFormData = z.infer<typeof supportSchema>;\n","import { ButtonHTMLAttributes, ReactNode, forwardRef } from 'react';\nimport { cn } from '../../../utils/utils';\nimport Badge from '../../Badge/Badge';\nimport Button from '../../Button/Button';\nimport Text from '../../Text/Text';\n\n/** Nível do item na árvore do menu lateral. */\nexport type SidebarMenuItemVariant = 'main' | 'sub';\n\n/**\n * Paleta do estado ativo.\n *\n * - `theme` (padrão): segue `primary-*`, ou seja, se adapta à whitelabel /\n * instituição — verde no analytica, azul no parana, vermelho no paraiba.\n * - `info`: segue a rampa `info-*` do tema. Atenção: nem todo tema usa azul\n * aqui (no analytica a rampa `info` é roxa).\n * - `blue`: o azul literal do Figma do SAC, idêntico em qualquer tema. Use\n * quando a tela precisa bater com o Figma e não com a marca do cliente.\n */\nexport type SidebarMenuItemActiveTone = 'theme' | 'info' | 'blue';\n\nconst ACTIVE_CLASSES: Record<SidebarMenuItemActiveTone, string> = {\n theme: 'bg-primary-50 text-primary-700',\n info: 'bg-info-background text-info-800',\n blue: 'bg-[#EBF2FE] text-[#1A56DB]',\n};\n\n/**\n * Tonalidade da contagem do item `main`. O `sub` ignora: ali a contagem é\n * texto puro que herda a cor do item, como no Figma.\n */\nexport type SidebarMenuItemCountTone = 'warning' | 'theme' | 'muted';\n\nconst COUNT_CLASSES: Record<SidebarMenuItemCountTone, string> = {\n warning: 'bg-warning-100 text-warning-700',\n theme: 'bg-primary-100 text-primary-800',\n muted: 'bg-background-muted text-background-800',\n};\n\nconst IDLE_CLASSES: Record<SidebarMenuItemVariant, string> = {\n main: 'text-text-950 hover:bg-background-50',\n sub: 'text-text-600 hover:bg-background-50',\n};\n\n/**\n * Peso do rótulo, no vocabulário do `Text`. Fica no rótulo e não no botão\n * porque o `Text` escreve o próprio `font-*`: um peso herdado do botão seria\n * sobrescrito pelo default (`normal`) do componente.\n */\nconst LABEL_WEIGHT: Record<SidebarMenuItemVariant, 'medium' | 'normal'> = {\n main: 'medium',\n sub: 'normal',\n};\n\n/** Escala do item. `md` é o tamanho do Figma. */\nexport type SidebarMenuItemSize = 'sm' | 'md';\n\n/**\n * Espaçamento, tipografia e ícone andam juntos porque o recuo do sub é\n * derivado deles: o sub precisa alinhar com o *rótulo* do main, ou seja\n * `padding` + ícone + `gap`. Separar isso em props soltas deixaria o consumidor\n * desalinhar os dois níveis sem perceber.\n *\n * - `md`: px-3 (12) + ícone 20 + gap-3 (12) = 44px = `pl-11`\n * - `sm`: px-2 (8) + ícone 16 + gap-2 (8) = 32px = `pl-8`\n *\n * O `[&>svg]:size-*` força o ícone do consumidor a caber na caixa: as props\n * `width`/`height` que o Phosphor escreve no `<svg>` são atributos de\n * apresentação, então qualquer regra CSS ganha delas. Assim um\n * `<Icon size={20} />` passado num item `sm` encolhe em vez de vazar.\n *\n * `label` é o mesmo tamanho do `item`, escrito no vocabulário do `Text`. A\n * classe continua no botão porque a contagem do `sub` é texto puro e herda dali.\n */\nconst SIZE_CLASSES: Record<\n SidebarMenuItemSize,\n {\n item: string;\n subIndent: string;\n icon: string;\n label: 'xs' | 'sm';\n badge: 'small' | 'medium';\n }\n> = {\n sm: {\n item: 'gap-2 px-2 py-1.5 text-xs',\n subIndent: 'pl-8',\n icon: 'size-4 [&>svg]:size-4',\n label: 'xs',\n badge: 'small',\n },\n md: {\n item: 'gap-3 px-3 py-2.5 text-sm',\n subIndent: 'pl-11',\n icon: 'size-5 [&>svg]:size-5',\n label: 'sm',\n badge: 'medium',\n },\n};\n\nexport type SidebarMenuItemProps = {\n /** Texto do item. */\n label: string;\n /** Ícone à esquerda. Renderizado apenas em `variant=\"main\"`. */\n icon?: ReactNode;\n /** Contagem exibida à direita. `0` é exibido; omitir esconde. */\n count?: number;\n /** Marca o item como o destino atual da navegação. */\n active?: boolean;\n /** Nível do item: `main` (com ícone) ou `sub` (recuado). */\n variant?: SidebarMenuItemVariant;\n /** Escala do item. `md` (padrão) é o tamanho do Figma; `sm` é compacto. */\n size?: SidebarMenuItemSize;\n /** Paleta do estado ativo. Ignorada quando o item não está ativo. */\n activeTone?: SidebarMenuItemActiveTone;\n /** Tonalidade da pílula de contagem do `main`. Ignorada pelo `sub`. */\n countTone?: SidebarMenuItemCountTone;\n /** Classes CSS adicionais. */\n className?: string;\n} & ButtonHTMLAttributes<HTMLButtonElement>;\n\nconst BASE_CLASSES =\n 'w-full flex items-center rounded-lg text-left cursor-pointer transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indicator-info disabled:opacity-50 disabled:cursor-not-allowed disabled:pointer-events-none';\n\n/**\n * Item do menu lateral do SAC.\n *\n * Combina os dois eixos do Figma (\"Componentes – Suporte\" → Menu lateral /\n * Item): tipo (`main` | `sub`) e estado (`active`). O main leva ícone e mostra\n * a contagem numa pílula laranja; o sub é recuado, sem ícone, e mostra a\n * contagem como texto que herda a cor do item.\n *\n * Renderiza o `Button` da lib na variante `raw` (`type=\"button\"`, sem estilo\n * próprio) com `onClick` — a navegação fica a cargo do consumidor, sem acoplar a\n * lib a um router.\n *\n * @example\n * ```tsx\n * <SidebarMenuItem\n * icon={<SquaresFourIcon size={20} />}\n * label=\"Dashboard\"\n * count={4}\n * active={pathname === '/dashboard'}\n * onClick={() => navigate('/dashboard')}\n * />\n * <SidebarMenuItem label=\"Meus chamados\" variant=\"sub\" count={4} />\n * ```\n */\nexport const SidebarMenuItem = forwardRef<\n HTMLButtonElement,\n SidebarMenuItemProps\n>(\n (\n {\n label,\n icon,\n count,\n active = false,\n variant = 'main',\n size = 'md',\n activeTone = 'theme',\n countTone = 'warning',\n className,\n ...props\n },\n ref\n ) => {\n const scale = SIZE_CLASSES[size];\n const stateClasses = active ? ACTIVE_CLASSES[activeTone] : undefined;\n const showIcon = variant === 'main' && Boolean(icon);\n\n return (\n <Button\n ref={ref}\n variant=\"raw\"\n aria-current={active ? 'page' : undefined}\n className={cn(\n BASE_CLASSES,\n scale.item,\n variant === 'sub' && scale.subIndent,\n stateClasses ?? IDLE_CLASSES[variant],\n className\n )}\n {...props}\n >\n {showIcon && (\n <span\n data-testid=\"sidebar-menu-item-icon\"\n aria-hidden=\"true\"\n className={cn(\n 'flex items-center justify-center shrink-0',\n scale.icon\n )}\n >\n {icon}\n </span>\n )}\n <Text\n as=\"span\"\n size={scale.label}\n weight={LABEL_WEIGHT[variant]}\n color=\"text-inherit\"\n className=\"flex-1 truncate\"\n >\n {label}\n </Text>\n {count !== undefined && (\n <SidebarMenuItemCount\n count={count}\n variant={variant}\n badgeSize={scale.badge}\n tone={countTone}\n />\n )}\n </Button>\n );\n }\n);\n\nSidebarMenuItem.displayName = 'SidebarMenuItem';\n\n/**\n * A contagem do main é uma pílula laranja; a do sub é texto que herda a cor do\n * item — o `Badge` entra pelo layout/espaçamento e a tonalidade vem do Figma\n * (`warning-100`/`warning-700`, mais saturada que o `warning` padrão do Badge).\n */\nconst SidebarMenuItemCount = ({\n count,\n variant,\n badgeSize,\n tone,\n}: {\n count: number;\n variant: SidebarMenuItemVariant;\n badgeSize: 'small' | 'medium';\n tone: SidebarMenuItemCountTone;\n}) => {\n // Sem classe de tipografia: o número herda tamanho e cor do próprio item.\n if (variant === 'sub') {\n return (\n <span\n data-testid=\"sidebar-menu-item-count\"\n className=\"shrink-0 tabular-nums\"\n >\n {count}\n </span>\n );\n }\n\n return (\n <Badge\n data-testid=\"sidebar-menu-item-count\"\n action=\"warning\"\n size={badgeSize}\n className={cn(\n 'shrink-0 rounded-full font-medium tabular-nums min-w-6',\n COUNT_CLASSES[tone]\n )}\n >\n {count}\n </Badge>\n );\n};\n\nexport default SidebarMenuItem;\n","import { ButtonHTMLAttributes, ReactNode, forwardRef } from 'react';\nimport { cn } from '../../../utils/utils';\nimport { Avatar } from '../../Avatar/Avatar';\nimport Badge from '../../Badge/Badge';\nimport Button from '../../Button/Button';\nimport Text from '../../Text/Text';\nimport { formatTicketTime } from '../utils/formatTicketTime';\n\n/**\n * Fundo da linha. É um eixo puramente visual: a lib não amarra significado a\n * cada cor, quem consome decide o que `danger` quer dizer (SLA, prioridade,\n * ticket reaberto). O hover sobrepõe qualquer tone.\n *\n * As cores vêm dos tokens do tema (`primary-50` é o azul claro do Figma no\n * light e um azul escuro no dark), para a linha seguir o modo escuro. Só a\n * barra e o avatar ficam no azul literal do Figma. Escritas por extenso porque\n * o Tailwind varre o código-fonte e não resolve classe interpolada.\n */\nexport type TicketListItemTone = 'default' | 'info' | 'danger';\n\nconst TONE_CLASSES: Record<TicketListItemTone, string> = {\n default: 'bg-transparent',\n info: 'bg-primary-50',\n danger: 'bg-error-background',\n};\n\n/** Tonalidade das badges. Mapeia para as rampas do tema, como o `Badge`. */\nexport type TicketListItemBadgeTone =\n | 'muted'\n | 'warning'\n | 'info'\n | 'success'\n | 'error';\n\nconst BADGE_TONE_CLASSES: Record<TicketListItemBadgeTone, string> = {\n muted: 'bg-transparent text-text-700 border border-border-300',\n warning: 'bg-warning-100 text-warning-700',\n info: 'bg-info text-info-800',\n success: 'bg-success text-success-800',\n error: 'bg-error-background text-error-700',\n};\n\nconst BADGE_CLASSES = 'shrink-0 rounded-md font-medium uppercase';\n\n/** Escala do item. `md` é o tamanho do Figma. */\nexport type TicketListItemSize = 'sm' | 'md' | 'lg';\n\n/** Tamanhos aceitos pelo `Text`, para os campos tipográficos da escala. */\ntype TicketListItemTextSize = '2xs' | 'xs' | 'sm' | 'md' | 'lg';\n\n/**\n * Espaçamento, avatar, tipografia e ícone andam juntos numa tabela só porque a\n * linha só lê bem quando escalam na mesma proporção: um avatar de 48 ao lado de\n * um nome `text-sm` desalinha a coluna de texto. Separar isso em props soltas\n * deixaria o consumidor quebrar o alinhamento sem perceber.\n *\n * `name`, `time`, `meta` e `message` são tamanhos do `Text`, não classes: quem\n * renderiza esses textos é o componente da lib, que escreve o próprio `text-*`.\n *\n * O `[&>svg]:size-*` força o ícone de canal do consumidor a caber na caixa: as\n * props `width`/`height` que o Phosphor escreve no `<svg>` são atributos de\n * apresentação, então qualquer regra CSS ganha delas.\n */\nconst SIZE_CLASSES: Record<\n TicketListItemSize,\n {\n item: string;\n rows: string;\n avatar: number;\n name: TicketListItemTextSize;\n time: TicketListItemTextSize;\n meta: TicketListItemTextSize;\n message: TicketListItemTextSize;\n badge: 'small' | 'medium';\n icon: string;\n bar: string;\n dot: string;\n }\n> = {\n sm: {\n item: 'gap-2 p-3',\n rows: 'gap-0.5',\n avatar: 32,\n name: 'sm',\n time: '2xs',\n meta: 'xs',\n message: 'xs',\n badge: 'small',\n icon: '[&>svg]:size-3.5',\n bar: 'w-0.5',\n dot: 'size-1.5',\n },\n md: {\n item: 'gap-3 p-4',\n rows: 'gap-1',\n avatar: 40,\n name: 'md',\n time: 'xs',\n meta: 'sm',\n message: 'sm',\n badge: 'small',\n icon: '[&>svg]:size-4',\n bar: 'w-1',\n dot: 'size-2',\n },\n lg: {\n item: 'gap-4 p-5',\n rows: 'gap-1.5',\n avatar: 48,\n name: 'lg',\n time: 'sm',\n meta: 'md',\n message: 'md',\n badge: 'medium',\n icon: '[&>svg]:size-5',\n bar: 'w-1.5',\n dot: 'size-2.5',\n },\n};\n\nconst BASE_CLASSES =\n 'group relative flex w-full items-start text-left cursor-pointer transition-colors hover:bg-primary-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indicator-info disabled:opacity-50 disabled:cursor-not-allowed disabled:pointer-events-none';\n\nexport type TicketListItemProps = {\n /** Nome de quem abriu o ticket. */\n name: string;\n /** Momento da última mensagem. A lib formata o texto relativo. */\n lastMessageAt: Date | string;\n /** Acende o ponto azul antes do tempo e anuncia \"Não lido\". */\n unread?: boolean;\n /**\n * Quantas mensagens ainda não foram lidas. Acima de zero, troca o ponto por\n * uma pílula com o número (`99+` a partir de 100) e já marca a linha como não\n * lida, sem precisar de `unread`.\n */\n unreadCount?: number;\n /** Foto. Sem foto, o avatar mostra as iniciais de `name`. */\n avatarSrc?: string;\n /** Badge do perfil. Texto livre: o vocabulário do SAC ainda não está fechado. */\n profileLabel?: string;\n /** Tonalidade da badge de perfil. Default `muted` (contornada). */\n profileTone?: TicketListItemBadgeTone;\n /** Instituição de origem. */\n organization?: string;\n /** Prévia da última mensagem, truncada em uma linha. */\n message?: string;\n /** Badge do atendimento. Texto livre. */\n attendanceLabel?: string;\n /** Tonalidade da badge de atendimento. Default `warning`, o pêssego do Figma. */\n attendanceTone?: TicketListItemBadgeTone;\n /** Ícone do canal de origem. */\n channelIcon?: ReactNode;\n /** Código do ticket, como vier do app (ex.: `#4826`). */\n ticketCode?: string;\n /** Fundo da linha. */\n tone?: TicketListItemTone;\n /** Escala do item. `md` (padrão) é o tamanho do Figma. */\n size?: TicketListItemSize;\n /** Classes CSS adicionais. */\n className?: string;\n} & ButtonHTMLAttributes<HTMLButtonElement>;\n\n/** Acima disso a pílula de não lidas mostra `99+`. */\nconst MAX_UNREAD_SHOWN = 99;\n\n/** Rótulo lido por leitor de tela na pílula de não lidas. */\nconst formatUnreadLabel = (count: number): string =>\n count === 1 ? '1 mensagem não lida' : `${count} mensagens não lidas`;\n\n/**\n * Linha da lista de tickets do SAC.\n *\n * Reproduz o frame \"Lista de tickets – item\" do Figma (\"Componentes –\n * Suporte\"): avatar, nome, tempo da última mensagem, badge de perfil,\n * instituição, prévia da conversa, badge de atendimento, canal e código.\n *\n * Só `name` e `lastMessageAt` são obrigatórios; cada bloco desaparece quando a\n * prop não vem, então uma lista sem instituição ou sem canal continua alinhada.\n *\n * Renderiza o `Button` da lib na variante `raw` (`type=\"button\"`, sem estilo\n * próprio) com `onClick` — a navegação fica a cargo do consumidor, sem acoplar a\n * lib a um router.\n *\n * @example\n * ```tsx\n * <TicketListItem\n * name=\"Ana Clara Mendes\"\n * lastMessageAt={ticket.updatedAt}\n * profileLabel=\"ESTUDANTE\"\n * organization=\"CE Santos Dumont\"\n * message=\"IA: Entendi. Vou transferir você para um atendente.\"\n * attendanceLabel=\"HUMANO\"\n * channelIcon={<DeviceMobileIcon size={16} />}\n * ticketCode=\"#4826\"\n * tone={ticket.id === selectedId ? 'info' : 'default'}\n * onClick={() => select(ticket.id)}\n * />\n * ```\n */\nexport const TicketListItem = forwardRef<\n HTMLButtonElement,\n TicketListItemProps\n>(\n (\n {\n name,\n lastMessageAt,\n unread = false,\n unreadCount = 0,\n avatarSrc,\n profileLabel,\n profileTone = 'muted',\n organization,\n message,\n attendanceLabel,\n attendanceTone = 'warning',\n channelIcon,\n ticketCode,\n tone = 'default',\n size = 'md',\n className,\n ...props\n },\n ref\n ) => {\n const scale = SIZE_CLASSES[size];\n\n return (\n <Button\n ref={ref}\n variant=\"raw\"\n className={cn(BASE_CLASSES, scale.item, TONE_CLASSES[tone], className)}\n {...props}\n >\n <span\n data-testid=\"ticket-list-item-bar\"\n aria-hidden=\"true\"\n className={cn(\n 'absolute inset-y-0 left-0 bg-[#1C61B2] transition-opacity',\n scale.bar,\n tone === 'info'\n ? 'opacity-100'\n : 'opacity-0 group-hover:opacity-100'\n )}\n />\n\n <Avatar\n src={avatarSrc}\n name={name}\n fallback=\"initials\"\n size={scale.avatar}\n className=\"bg-[#1C61B2] text-white\"\n />\n\n <span className={cn('flex min-w-0 flex-1 flex-col', scale.rows)}>\n <span className=\"flex items-center gap-2\">\n <Text\n as=\"span\"\n size={scale.name}\n weight=\"bold\"\n className=\"min-w-0 flex-1 truncate\"\n >\n {name}\n </Text>\n {unreadCount > 0 && (\n <Text\n as=\"span\"\n size=\"xs\"\n weight=\"bold\"\n color=\"text-white\"\n data-testid=\"ticket-list-item-unread-count\"\n aria-label={formatUnreadLabel(unreadCount)}\n className=\"shrink-0 min-w-5 h-5 px-1.5 rounded-full bg-[#1C61B2] flex items-center justify-center\"\n >\n {unreadCount > MAX_UNREAD_SHOWN\n ? `${MAX_UNREAD_SHOWN}+`\n : unreadCount}\n </Text>\n )}\n {unread && unreadCount <= 0 && (\n <>\n <span\n data-testid=\"ticket-list-item-unread\"\n aria-hidden=\"true\"\n className={cn(\n 'shrink-0 rounded-full bg-[#1C61B2]',\n scale.dot\n )}\n />\n <span className=\"sr-only\">Não lido</span>\n </>\n )}\n <Text\n as=\"span\"\n size={scale.time}\n color=\"text-text-600\"\n className=\"shrink-0\"\n >\n {formatTicketTime(lastMessageAt)}\n </Text>\n </span>\n\n {(profileLabel || organization) && (\n <span className=\"flex min-w-0 items-center gap-2\">\n {profileLabel && (\n <Badge\n data-testid=\"ticket-list-item-profile\"\n size={scale.badge}\n className={cn(BADGE_CLASSES, BADGE_TONE_CLASSES[profileTone])}\n >\n {profileLabel}\n </Badge>\n )}\n {organization && (\n <Text\n as=\"span\"\n size={scale.meta}\n color=\"text-text-600\"\n className=\"min-w-0 truncate\"\n >\n {organization}\n </Text>\n )}\n </span>\n )}\n\n {message && (\n <Text\n as=\"span\"\n size={scale.message}\n color=\"text-text-700\"\n className=\"truncate\"\n >\n {message}\n </Text>\n )}\n\n {(attendanceLabel || channelIcon || ticketCode) && (\n <span className=\"flex items-center gap-2\">\n {attendanceLabel && (\n <Badge\n data-testid=\"ticket-list-item-attendance\"\n size={scale.badge}\n className={cn(\n BADGE_CLASSES,\n BADGE_TONE_CLASSES[attendanceTone]\n )}\n >\n {attendanceLabel}\n </Badge>\n )}\n {channelIcon && (\n <span\n data-testid=\"ticket-list-item-channel\"\n aria-hidden=\"true\"\n className={cn(\n 'flex shrink-0 items-center text-text-600',\n scale.icon\n )}\n >\n {channelIcon}\n </span>\n )}\n {ticketCode && (\n <Text\n as=\"span\"\n size={scale.meta}\n color=\"text-text-600\"\n className=\"shrink-0 tabular-nums\"\n >\n {ticketCode}\n </Text>\n )}\n </span>\n )}\n </span>\n </Button>\n );\n }\n);\n\nTicketListItem.displayName = 'TicketListItem';\n\nexport default TicketListItem;\n","const MINUTE_MS = 60_000;\nconst HOUR_MS = 60 * MINUTE_MS;\nconst DAY_MS = 24 * HOUR_MS;\nconst WEEK_MS = 7 * DAY_MS;\n\n/**\n * Tempo decorrido desde a última mensagem, no formato curto do Figma do SAC.\n *\n * Os limiares são: menos de um minuto vira `agora`; abaixo de uma hora, minutos\n * (`6 min`); abaixo de um dia, horas (`2 h`); abaixo de uma semana, dias\n * (`3 d`); daí em diante a data curta (`12/09/2026`), porque \"há 43 d\" não\n * ajuda ninguém a localizar o atendimento.\n *\n * Recebe `now` por parâmetro para o teste fixar o relógio sem `fakeTimers`, e\n * cai no relógio real quando omitido.\n *\n * Data inválida devolve string vazia: o item prefere não mostrar nada a mostrar\n * `NaN min`.\n *\n * @example\n * ```ts\n * formatTicketTime(ticket.lastMessageAt); // \"6 min\"\n * ```\n */\nexport const formatTicketTime = (\n value: Date | string,\n now: Date = new Date()\n): string => {\n const date = value instanceof Date ? value : new Date(value);\n\n if (Number.isNaN(date.getTime())) {\n return '';\n }\n\n const elapsed = now.getTime() - date.getTime();\n\n if (elapsed < MINUTE_MS) {\n return 'agora';\n }\n\n if (elapsed < HOUR_MS) {\n return `${Math.floor(elapsed / MINUTE_MS)} min`;\n }\n\n if (elapsed < DAY_MS) {\n return `${Math.floor(elapsed / HOUR_MS)} h`;\n }\n\n if (elapsed < WEEK_MS) {\n return `${Math.floor(elapsed / DAY_MS)} d`;\n }\n\n return date.toLocaleDateString('pt-BR');\n};\n","import { ReactNode, useRef } from 'react';\nimport { cn } from '../../../utils/utils';\nimport EmptyState from '../../EmptyState/EmptyState';\nimport { Skeleton, SkeletonCircle } from '../../Skeleton/Skeleton';\nimport { useInfiniteScrollSentinel } from '../hooks/useInfiniteScrollSentinel';\nimport {\n TicketListItem,\n TicketListItemProps,\n TicketListItemSize,\n} from './TicketListItem';\n\n/** Um ticket da lista: as props do item mais o `id` que identifica a seleção. */\nexport type TicketListItemData = Omit<TicketListItemProps, 'onClick'> & {\n id: string;\n};\n\n/** Quantos skeletons o rodapé mostra enquanto a próxima página carrega. */\nconst LOADING_MORE_SKELETONS = 2;\n\nexport type TicketListProps = {\n /** Tickets já carregados, na ordem em que devem aparecer. */\n tickets: TicketListItemData[];\n /** `id` do ticket aberto no painel. */\n selectedId?: string;\n /** Chamado com o `id` do ticket clicado. */\n onSelect?: (id: string) => void;\n /** Primeira carga: substitui a lista por skeletons. */\n loading?: boolean;\n /** Paginação em curso: skeletons no rodapé, sem esconder o que já carregou. */\n loadingMore?: boolean;\n /** Ainda há páginas a buscar. */\n hasMore?: boolean;\n /** Chamado quando a sentinela do fim da lista entra na viewport. */\n onLoadMore?: () => void;\n /** Quantos skeletons exibir na primeira carga. Default 5. */\n skeletonCount?: number;\n /** Substitui o estado vazio padrão. */\n emptyState?: ReactNode;\n /** Escala repassada a todos os itens. `md` (padrão) é o tamanho do Figma. */\n size?: TicketListItemSize;\n /** Classes CSS adicionais. */\n className?: string;\n};\n\n/**\n * Espaçamento e avatar do esqueleto, espelhando o `SIZE_CLASSES` do item para\n * que a lista não mude de altura quando os dados chegam.\n */\nconst SKELETON_SIZE: Record<\n TicketListItemSize,\n { item: string; avatar: number }\n> = {\n sm: { item: 'gap-2 p-3', avatar: 32 },\n md: { item: 'gap-3 p-4', avatar: 40 },\n lg: { item: 'gap-4 p-5', avatar: 48 },\n};\n\n/**\n * Esqueleto no formato da linha: círculo do avatar mais três faixas de texto.\n * Extraído do componente porque o JSX dele já decide entre três caminhos de\n * render, e aninhar o `Array.from` ali dentro vira issue de manutenibilidade.\n */\nconst TicketListSkeletons = ({\n count,\n size,\n}: {\n count: number;\n size: TicketListItemSize;\n}) => (\n <>\n {Array.from({ length: count }, (_, index) => (\n <div\n key={index}\n data-testid=\"ticket-list-skeleton\"\n className={cn('flex items-start', SKELETON_SIZE[size].item)}\n >\n <SkeletonCircle\n width={SKELETON_SIZE[size].avatar}\n height={SKELETON_SIZE[size].avatar}\n />\n <div className=\"flex flex-1 flex-col gap-2\">\n <Skeleton width=\"60%\" />\n <Skeleton width=\"40%\" />\n <Skeleton width=\"80%\" />\n </div>\n </div>\n ))}\n </>\n);\n\n/**\n * Lista de tickets do SAC.\n *\n * Empilha `TicketListItem`, separa com divisores, marca o selecionado e pagina\n * por scroll infinito. A seleção é controlada: o app diz *qual* ticket está\n * aberto e a lista decide *como* isso aparece (o tone `info` do Figma),\n * sobrepondo o `tone` que o próprio ticket tenha pedido.\n *\n * O divisor vive aqui, e não no item, porque o item reaproveitado fora da lista\n * — no topo de uma conversa aberta, por exemplo — não deve carregar borda.\n *\n * @example\n * ```tsx\n * <TicketList\n * tickets={tickets}\n * selectedId={selectedId}\n * onSelect={setSelectedId}\n * loading={isLoading}\n * loadingMore={isFetchingNextPage}\n * hasMore={hasNextPage}\n * onLoadMore={fetchNextPage}\n * />\n * ```\n */\nexport const TicketList = ({\n tickets,\n selectedId,\n onSelect,\n loading = false,\n loadingMore = false,\n hasMore = false,\n onLoadMore,\n skeletonCount = 5,\n emptyState,\n size = 'md',\n className,\n}: TicketListProps) => {\n const sentinelRef = useRef<HTMLDivElement>(null);\n\n useInfiniteScrollSentinel({\n ref: sentinelRef,\n enabled: hasMore && !loading && !loadingMore,\n onIntersect: onLoadMore,\n });\n\n if (loading) {\n return (\n <div className={cn('flex flex-col', className)}>\n <TicketListSkeletons count={skeletonCount} size={size} />\n </div>\n );\n }\n\n if (tickets.length === 0) {\n return (\n <div className={cn('flex flex-col', className)}>\n {emptyState ?? (\n <EmptyState\n size=\"compact\"\n title=\"Nenhum ticket encontrado\"\n description=\"Não há atendimentos para exibir no momento.\"\n />\n )}\n </div>\n );\n }\n\n return (\n <div role=\"list\" className={cn('flex flex-col', className)}>\n {tickets.map(({ id, tone, ...ticket }, index) => {\n const selected = id === selectedId;\n\n return (\n <div\n key={id}\n role=\"listitem\"\n className={cn(\n index < tickets.length - 1 && 'border-b border-border-100'\n )}\n >\n <TicketListItem\n {...ticket}\n size={size}\n tone={selected ? 'info' : tone}\n aria-current={selected ? 'true' : undefined}\n onClick={() => onSelect?.(id)}\n />\n </div>\n );\n })}\n\n {loadingMore && (\n <TicketListSkeletons count={LOADING_MORE_SKELETONS} size={size} />\n )}\n\n <div ref={sentinelRef} aria-hidden=\"true\" className=\"h-px shrink-0\" />\n </div>\n );\n};\n\nexport default TicketList;\n","import { RefObject, useEffect, useRef } from 'react';\n\nexport type UseInfiniteScrollSentinelOptions = {\n /** Elemento sentinela, normalmente um `<div>` de 1px após o último item. */\n ref: RefObject<HTMLElement | null>;\n /** Observa enquanto `true`. Desligue durante carregamento e no fim da lista. */\n enabled?: boolean;\n /** Chamado quando a sentinela entra na viewport. */\n onIntersect?: () => void;\n /** Fração visível que dispara. Default `0.1`, como no `useLessonBank`. */\n threshold?: number;\n};\n\n/**\n * Dispara `onIntersect` quando a sentinela entra na viewport — o scroll\n * infinito, sem conhecer lista nem paginação.\n *\n * O callback é guardado numa ref de propósito. Consumidores costumam passar uma\n * arrow nova a cada render; se ela entrasse nas dependências do efeito, o\n * observer seria destruído e recriado a cada render e voltaria a disparar\n * imediatamente enquanto a sentinela estivesse visível — um laço de\n * `onLoadMore`. Assim o observer só é recriado quando o alvo, o `enabled` ou o\n * `threshold` mudam, e ainda chama sempre a versão mais recente do callback.\n *\n * @example\n * ```tsx\n * const sentinelRef = useRef<HTMLDivElement>(null);\n * useInfiniteScrollSentinel({\n * ref: sentinelRef,\n * enabled: hasMore && !loading,\n * onIntersect: onLoadMore,\n * });\n * ```\n */\nexport const useInfiniteScrollSentinel = ({\n ref,\n enabled = true,\n onIntersect,\n threshold = 0.1,\n}: UseInfiniteScrollSentinelOptions): void => {\n const callbackRef = useRef(onIntersect);\n\n useEffect(() => {\n callbackRef.current = onIntersect;\n }, [onIntersect]);\n\n const hasCallback = Boolean(onIntersect);\n\n useEffect(() => {\n const target = ref.current;\n\n if (!target || !enabled || !hasCallback) {\n return;\n }\n\n const observer = new IntersectionObserver(\n (entries) => {\n if (entries[0]?.isIntersecting) {\n callbackRef.current?.();\n }\n },\n { threshold }\n );\n\n observer.observe(target);\n\n return () => observer.disconnect();\n }, [ref, enabled, hasCallback, threshold]);\n};\n"]}
|
|
@@ -10,7 +10,7 @@ var _chunkKRYBXYOBjs = require('./chunk-KRYBXYOB.js');
|
|
|
10
10
|
var _chunkJVDEOFXDjs = require('./chunk-JVDEOFXD.js');
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
var
|
|
13
|
+
var _chunkCOT4KW3Hjs = require('./chunk-COT4KW3H.js');
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
var _chunkANT66KVKjs = require('./chunk-ANT66KVK.js');
|
|
@@ -141,7 +141,7 @@ var CheckboxListItem = _react.forwardRef.call(void 0,
|
|
|
141
141
|
const isDisabled = groupDisabled || itemDisabled;
|
|
142
142
|
const currentState = isDisabled ? "disabled" : state;
|
|
143
143
|
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
144
|
-
|
|
144
|
+
_chunkCOT4KW3Hjs.CheckBox_default,
|
|
145
145
|
{
|
|
146
146
|
ref,
|
|
147
147
|
id: inputId,
|
|
@@ -341,4 +341,4 @@ var MultipleChoiceList = ({
|
|
|
341
341
|
|
|
342
342
|
|
|
343
343
|
exports.CheckboxListItem = CheckboxListItem; exports.CheckboxList_default = CheckboxList_default; exports.MultipleChoiceList = MultipleChoiceList;
|
|
344
|
-
//# sourceMappingURL=chunk-
|
|
344
|
+
//# sourceMappingURL=chunk-VWLWSO4J.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-4RD55E4R.js","../src/components/MultipleChoice/MultipleChoice.tsx","../src/components/CheckBox/CheckboxList.tsx"],"names":["jsx"],"mappings":"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","file":"/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-4RD55E4R.js","sourcesContent":[null,"import { HtmlHTMLAttributes, useEffect, useState } from 'react';\nimport CheckboxList, { CheckboxListItem } from '../CheckBox/CheckboxList';\nimport { cn } from '../../utils/utils';\nimport { CheckCircleIcon } from '@phosphor-icons/react/dist/csr/CheckCircle';\nimport { XCircleIcon } from '@phosphor-icons/react/dist/csr/XCircle';\nimport { CheckIcon } from '@phosphor-icons/react/dist/csr/Check';\nimport Badge from '../Badge/Badge';\nimport { HtmlMathRenderer } from '../HtmlMathRenderer';\nimport { QuizVariant } from '../Quiz/Quiz.types';\nimport { OptionStatus } from '../../enums/Options';\nimport {\n ROW_INTERACTION_CLASSES,\n STRETCHED_LABEL_CLASSES,\n} from '../Alternative/choiceRowClasses';\nimport Text from '../Text/Text';\n\ninterface Choice {\n value: string;\n label: string;\n status?: OptionStatus;\n disabled?: boolean;\n}\n\ninterface MultipleChoiceListProps extends HtmlHTMLAttributes<HTMLDivElement> {\n choices: Choice[];\n disabled?: boolean;\n name?: string;\n selectedValues?: string[];\n onHandleSelectedValues?: (values: string[]) => void;\n mode?: 'interactive' | 'readonly';\n /** Id of the element that names the group (e.g. the question heading) */\n labelledBy?: string;\n /** Id(s) of the element(s) that describe the group (e.g. the statement) */\n describedBy?: string;\n}\n\nconst MultipleChoiceList = ({\n disabled = false,\n className = '',\n choices,\n name,\n selectedValues,\n onHandleSelectedValues,\n mode = QuizVariant.INTERACTIVE,\n labelledBy,\n describedBy,\n}: MultipleChoiceListProps) => {\n // A heading passed by the consumer names the group; otherwise fall back to\n // a fixed, readable label instead of the generated group name.\n const groupA11yProps = {\n role: 'group',\n ...(labelledBy\n ? { 'aria-labelledby': labelledBy, 'aria-label': undefined }\n : { 'aria-label': 'Alternativas' }),\n 'aria-describedby': describedBy,\n };\n const [actualValue, setActualValue] = useState(selectedValues);\n\n // Mirror the incoming prop into local state, but only when its *value*\n // actually changed. Comparing by reference alone would re-set state on every\n // render where the parent hands us a new-but-equal array, which feeds an\n // infinite re-render loop when the parent also subscribes to the store.\n useEffect(() => {\n setActualValue((prev) =>\n JSON.stringify(prev) === JSON.stringify(selectedValues)\n ? prev\n : selectedValues\n );\n }, [selectedValues]);\n const getStatusBadge = (status: Choice['status']) => {\n switch (status) {\n case OptionStatus.CORRECT:\n return (\n <Badge\n variant=\"solid\"\n action=\"success\"\n iconLeft={<CheckCircleIcon aria-hidden=\"true\" />}\n >\n Resposta correta\n </Badge>\n );\n case OptionStatus.INCORRECT:\n return (\n <Badge\n variant=\"solid\"\n action=\"error\"\n iconLeft={<XCircleIcon aria-hidden=\"true\" />}\n >\n Resposta incorreta\n </Badge>\n );\n default:\n return null;\n }\n };\n\n const getStatusStyles = (status: Choice['status']) => {\n switch (status) {\n case OptionStatus.CORRECT:\n return 'bg-success-background border-success-300';\n case OptionStatus.INCORRECT:\n return 'bg-error-background border-error-300';\n default:\n return `bg-background border-border-100`;\n }\n };\n\n const renderVisualCheckbox = (isSelected: boolean, isDisabled: boolean) => {\n const checkboxClasses = cn(\n 'w-5 h-5 rounded border-2 cursor-default transition-all duration-200 flex items-center justify-center',\n isSelected\n ? 'border-primary-950 bg-primary-950 text-text'\n : 'border-border-400 bg-background',\n isDisabled && 'opacity-40 cursor-not-allowed'\n );\n\n return (\n // Puramente decorativo: o estado sai no texto `sr-only` da linha.\n <div className={checkboxClasses} aria-hidden=\"true\">\n {isSelected && <CheckIcon size={16} weight=\"bold\" />}\n </div>\n );\n };\n\n if (mode === 'readonly') {\n return (\n <div {...groupA11yProps} className={cn('flex flex-col gap-2', className)}>\n {choices.map((choice, i) => {\n const isSelected = actualValue?.includes(choice.value) || false;\n const statusStyles = getStatusStyles(choice.status);\n const statusBadge = getStatusBadge(choice.status);\n const isDisabled = choice.disabled || disabled;\n\n /*\n * Resultado só de leitura: não há controle para operar, então a linha\n * não finge ser um checkbox. A leitura sai do texto, na ordem:\n * posição, enunciado da alternativa, status e o que o aluno marcou.\n */\n return (\n <div\n key={`readonly-${choice.value}-${i}`}\n className={cn(\n 'flex flex-row justify-between gap-2 items-start p-2 rounded-lg transition-all',\n statusStyles,\n choice.disabled ? 'opacity-50 cursor-not-allowed' : ''\n )}\n >\n <Text as=\"span\" className=\"sr-only\">\n {`Alternativa ${i + 1} de ${choices.length}`}\n </Text>\n <div className=\"flex items-center gap-2 flex-1\">\n {renderVisualCheckbox(isSelected, isDisabled)}\n <HtmlMathRenderer\n content={choice.label}\n className={cn(\n 'flex-1',\n isSelected ||\n (choice.status && choice.status != OptionStatus.NEUTRAL)\n ? 'text-text-950'\n : 'text-text-600',\n isDisabled ? 'cursor-not-allowed' : 'cursor-default'\n )}\n />\n </div>\n {statusBadge && (\n <div className=\"flex-shrink-0\">{statusBadge}</div>\n )}\n {/* Única fonte do que o aluno escolheu para o leitor de tela. */}\n <Text as=\"span\" className=\"sr-only\">\n {isSelected ? 'Você marcou' : 'Não marcada'}\n </Text>\n </div>\n );\n })}\n </div>\n );\n }\n return (\n <div\n className={cn(\n 'flex flex-row justify-between gap-2 items-start p-2 rounded-lg transition-all',\n disabled ? 'opacity-50 cursor-not-allowed' : '',\n className\n )}\n >\n <CheckboxList\n name={name}\n {...groupA11yProps}\n values={actualValue}\n onValuesChange={(v) => {\n setActualValue(v);\n onHandleSelectedValues?.(v);\n }}\n disabled={disabled}\n >\n {choices.map((choice, i) => (\n <div\n key={`interactive-${choice.value}-${i}`}\n className={cn(\n 'flex flex-row gap-2 items-center p-2 rounded-lg transition-all',\n ROW_INTERACTION_CLASSES,\n choice.disabled || disabled\n ? 'cursor-not-allowed'\n : 'cursor-pointer hover:bg-background-50'\n )}\n >\n <CheckboxListItem\n value={choice.value}\n id={`interactive-${choice.value}-${i}`}\n disabled={choice.disabled || disabled}\n />\n\n <label\n htmlFor={`interactive-${choice.value}-${i}`}\n className={cn(\n 'flex-1',\n STRETCHED_LABEL_CLASSES,\n actualValue?.includes(choice.value)\n ? 'text-text-950'\n : 'text-text-600',\n choice.disabled || disabled\n ? 'cursor-not-allowed'\n : 'cursor-pointer'\n )}\n >\n <HtmlMathRenderer content={choice.label} />\n </label>\n </div>\n ))}\n </CheckboxList>\n </div>\n );\n};\n\nexport { MultipleChoiceList };\n","import {\n InputHTMLAttributes,\n HTMLAttributes,\n ReactNode,\n forwardRef,\n useId,\n useEffect,\n useRef,\n Children,\n cloneElement,\n isValidElement,\n ReactElement,\n} from 'react';\nimport { create, StoreApi, useStore } from 'zustand';\nimport CheckBox from './CheckBox';\nimport { cn } from '../../utils/utils';\n\n/**\n * CheckboxList size variants\n */\ntype CheckboxListSize = 'small' | 'medium' | 'large';\n\n/**\n * CheckboxList visual state\n */\ntype CheckboxListState =\n | 'default'\n | 'hovered'\n | 'focused'\n | 'invalid'\n | 'disabled';\n\n/**\n * CheckboxList store interface\n */\ninterface CheckboxListStore {\n values: string[];\n setValues: (values: string[]) => void;\n toggleValue: (value: string) => void;\n onValuesChange?: (values: string[]) => void;\n disabled: boolean;\n name: string;\n}\n\ntype CheckboxListStoreApi = StoreApi<CheckboxListStore>;\n\n/**\n * Create a new CheckboxList store\n */\nconst createCheckboxListStore = (\n name: string,\n defaultValues: string[],\n disabled: boolean,\n onValuesChange?: (values: string[]) => void\n): CheckboxListStoreApi =>\n create<CheckboxListStore>((set, get) => ({\n values: defaultValues,\n setValues: (values) => {\n if (!get().disabled) {\n set({ values });\n get().onValuesChange?.(values);\n }\n },\n toggleValue: (value) => {\n if (!get().disabled) {\n const currentValues = get().values;\n const newValues = currentValues.includes(value)\n ? currentValues.filter((v) => v !== value)\n : [...currentValues, value];\n set({ values: newValues });\n get().onValuesChange?.(newValues);\n }\n },\n onValuesChange,\n disabled,\n name,\n }));\n\n/**\n * Hook to access CheckboxList store\n */\nexport const useCheckboxListStore = (externalStore?: CheckboxListStoreApi) => {\n if (!externalStore) {\n throw new Error('CheckboxListItem must be used within a CheckboxList');\n }\n return externalStore;\n};\n\n/**\n * Inject store into CheckboxListItem children\n */\nconst injectStore = (\n children: ReactNode,\n store: CheckboxListStoreApi\n): ReactNode =>\n Children.map(children, (child) => {\n if (!isValidElement(child)) return child;\n const typedChild = child as ReactElement<CheckboxListItemProps>;\n const shouldInject = typedChild.type === CheckboxListItem;\n return cloneElement(typedChild, {\n ...(shouldInject ? { store } : {}),\n ...(typedChild.props.children\n ? { children: injectStore(typedChild.props.children, store) }\n : {}),\n });\n });\n\n/**\n * CheckboxList component props interface\n */\nexport type CheckboxListProps = {\n /** Current selected values */\n values?: string[];\n /** Default selected values for uncontrolled usage */\n defaultValues?: string[];\n /** Callback when selection changes */\n onValuesChange?: (values: string[]) => void;\n /** Group name for all checkboxes */\n name?: string;\n /** Disabled state for the entire group */\n disabled?: boolean;\n /** Additional CSS classes */\n className?: string;\n /** Children components */\n children: ReactNode;\n} & Omit<HTMLAttributes<HTMLDivElement>, 'onChange' | 'defaultValues'>;\n\n/**\n * CheckboxList component for flexible checkbox group composition\n *\n * Uses Zustand for state management with automatic store injection.\n * Allows complete control over layout and styling by composing with CheckboxListItem.\n *\n * @example\n * ```tsx\n * <CheckboxList defaultValues={[\"option1\"]} onValuesChange={setValues}>\n * <div className=\"flex items-center gap-3\">\n * <CheckboxListItem value=\"option1\" id=\"c1\" />\n * <label htmlFor=\"c1\">Option 1</label>\n * </div>\n * <div className=\"flex items-center gap-3\">\n * <CheckboxListItem value=\"option2\" id=\"c2\" />\n * <label htmlFor=\"c2\">Option 2</label>\n * </div>\n * </CheckboxList>\n * ```\n */\nconst CheckboxList = forwardRef<HTMLDivElement, CheckboxListProps>(\n (\n {\n values: propValues,\n defaultValues = [],\n onValuesChange,\n name: propName,\n disabled = false,\n className = '',\n children,\n ...props\n },\n ref\n ) => {\n // Generate unique name if not provided\n const generatedId = useId();\n const name = propName || `checkbox-list-${generatedId}`;\n\n // Create store reference\n const storeRef = useRef<CheckboxListStoreApi>(null);\n storeRef.current ??= createCheckboxListStore(\n name,\n defaultValues,\n disabled,\n onValuesChange\n );\n const store = storeRef.current;\n\n // Get store actions\n const { setValues } = useStore(store, (s) => s);\n\n // Call onValuesChange with initial values\n useEffect(() => {\n const currentValues = store.getState().values;\n if (currentValues.length > 0 && onValuesChange) {\n onValuesChange(currentValues);\n }\n }, []);\n\n // Handle controlled values changes\n useEffect(() => {\n if (propValues !== undefined) {\n setValues(propValues);\n }\n }, [propValues, setValues]);\n\n // Update disabled state\n useEffect(() => {\n store.setState({ disabled });\n }, [disabled, store]);\n\n return (\n <div\n ref={ref}\n className={cn('flex flex-col gap-2 w-full', className)}\n aria-label={name}\n {...props}\n >\n {injectStore(children, store)}\n </div>\n );\n }\n);\n\nCheckboxList.displayName = 'CheckboxList';\n\n/**\n * CheckboxListItem component props interface\n */\nexport type CheckboxListItemProps = {\n /** Value for this checkbox item */\n value: string;\n /** Store reference (automatically injected by CheckboxList) */\n store?: CheckboxListStoreApi;\n /** Disabled state for this specific item */\n disabled?: boolean;\n /** Size variant */\n size?: CheckboxListSize;\n /** Visual state */\n state?: CheckboxListState;\n /** Additional CSS classes */\n className?: string;\n} & Omit<\n InputHTMLAttributes<HTMLInputElement>,\n 'type' | 'name' | 'value' | 'checked' | 'onChange' | 'size'\n>;\n\n/**\n * CheckboxListItem component for use within CheckboxList\n *\n * A checkbox without label that works within CheckboxList context.\n * Provides just the checkbox input for maximum flexibility in composition.\n *\n * @example\n * ```tsx\n * <CheckboxList defaultValues={[\"option1\"]}>\n * <div className=\"flex items-center gap-3\">\n * <CheckboxListItem value=\"option1\" id=\"c1\" />\n * <label htmlFor=\"c1\">Option 1</label>\n * </div>\n * </CheckboxList>\n * ```\n */\nconst CheckboxListItem = forwardRef<HTMLInputElement, CheckboxListItemProps>(\n (\n {\n value,\n store: externalStore,\n disabled: itemDisabled,\n size = 'medium',\n state = 'default',\n className = '',\n id,\n ...props\n },\n ref\n ) => {\n // Get store and state\n const store = useCheckboxListStore(externalStore);\n const {\n values: groupValues,\n toggleValue,\n disabled: groupDisabled,\n name,\n } = useStore(store);\n\n // Generate unique ID if not provided\n const generatedId = useId();\n const inputId = id ?? `checkbox-item-${generatedId}`;\n\n // Determine states\n const isChecked = groupValues.includes(value);\n const isDisabled = groupDisabled || itemDisabled;\n const currentState = isDisabled ? 'disabled' : state;\n\n // Use standard CheckBox component for consistency and simplicity\n return (\n <CheckBox\n ref={ref}\n id={inputId}\n name={name}\n value={value}\n checked={isChecked}\n disabled={isDisabled}\n size={size}\n state={currentState}\n className={className}\n onChange={() => {\n if (!isDisabled) {\n toggleValue(value);\n }\n }}\n {...props}\n />\n );\n }\n);\n\nCheckboxListItem.displayName = 'CheckboxListItem';\n\nexport default CheckboxList;\nexport { CheckboxListItem };\n"]}
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-VWLWSO4J.js","../src/components/MultipleChoice/MultipleChoice.tsx","../src/components/CheckBox/CheckboxList.tsx"],"names":["jsx"],"mappings":"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","file":"/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-VWLWSO4J.js","sourcesContent":[null,"import { HtmlHTMLAttributes, useEffect, useState } from 'react';\nimport CheckboxList, { CheckboxListItem } from '../CheckBox/CheckboxList';\nimport { cn } from '../../utils/utils';\nimport { CheckCircleIcon } from '@phosphor-icons/react/dist/csr/CheckCircle';\nimport { XCircleIcon } from '@phosphor-icons/react/dist/csr/XCircle';\nimport { CheckIcon } from '@phosphor-icons/react/dist/csr/Check';\nimport Badge from '../Badge/Badge';\nimport { HtmlMathRenderer } from '../HtmlMathRenderer';\nimport { QuizVariant } from '../Quiz/Quiz.types';\nimport { OptionStatus } from '../../enums/Options';\nimport {\n ROW_INTERACTION_CLASSES,\n STRETCHED_LABEL_CLASSES,\n} from '../Alternative/choiceRowClasses';\nimport Text from '../Text/Text';\n\ninterface Choice {\n value: string;\n label: string;\n status?: OptionStatus;\n disabled?: boolean;\n}\n\ninterface MultipleChoiceListProps extends HtmlHTMLAttributes<HTMLDivElement> {\n choices: Choice[];\n disabled?: boolean;\n name?: string;\n selectedValues?: string[];\n onHandleSelectedValues?: (values: string[]) => void;\n mode?: 'interactive' | 'readonly';\n /** Id of the element that names the group (e.g. the question heading) */\n labelledBy?: string;\n /** Id(s) of the element(s) that describe the group (e.g. the statement) */\n describedBy?: string;\n}\n\nconst MultipleChoiceList = ({\n disabled = false,\n className = '',\n choices,\n name,\n selectedValues,\n onHandleSelectedValues,\n mode = QuizVariant.INTERACTIVE,\n labelledBy,\n describedBy,\n}: MultipleChoiceListProps) => {\n // A heading passed by the consumer names the group; otherwise fall back to\n // a fixed, readable label instead of the generated group name.\n const groupA11yProps = {\n role: 'group',\n ...(labelledBy\n ? { 'aria-labelledby': labelledBy, 'aria-label': undefined }\n : { 'aria-label': 'Alternativas' }),\n 'aria-describedby': describedBy,\n };\n const [actualValue, setActualValue] = useState(selectedValues);\n\n // Mirror the incoming prop into local state, but only when its *value*\n // actually changed. Comparing by reference alone would re-set state on every\n // render where the parent hands us a new-but-equal array, which feeds an\n // infinite re-render loop when the parent also subscribes to the store.\n useEffect(() => {\n setActualValue((prev) =>\n JSON.stringify(prev) === JSON.stringify(selectedValues)\n ? prev\n : selectedValues\n );\n }, [selectedValues]);\n const getStatusBadge = (status: Choice['status']) => {\n switch (status) {\n case OptionStatus.CORRECT:\n return (\n <Badge\n variant=\"solid\"\n action=\"success\"\n iconLeft={<CheckCircleIcon aria-hidden=\"true\" />}\n >\n Resposta correta\n </Badge>\n );\n case OptionStatus.INCORRECT:\n return (\n <Badge\n variant=\"solid\"\n action=\"error\"\n iconLeft={<XCircleIcon aria-hidden=\"true\" />}\n >\n Resposta incorreta\n </Badge>\n );\n default:\n return null;\n }\n };\n\n const getStatusStyles = (status: Choice['status']) => {\n switch (status) {\n case OptionStatus.CORRECT:\n return 'bg-success-background border-success-300';\n case OptionStatus.INCORRECT:\n return 'bg-error-background border-error-300';\n default:\n return `bg-background border-border-100`;\n }\n };\n\n const renderVisualCheckbox = (isSelected: boolean, isDisabled: boolean) => {\n const checkboxClasses = cn(\n 'w-5 h-5 rounded border-2 cursor-default transition-all duration-200 flex items-center justify-center',\n isSelected\n ? 'border-primary-950 bg-primary-950 text-text'\n : 'border-border-400 bg-background',\n isDisabled && 'opacity-40 cursor-not-allowed'\n );\n\n return (\n // Puramente decorativo: o estado sai no texto `sr-only` da linha.\n <div className={checkboxClasses} aria-hidden=\"true\">\n {isSelected && <CheckIcon size={16} weight=\"bold\" />}\n </div>\n );\n };\n\n if (mode === 'readonly') {\n return (\n <div {...groupA11yProps} className={cn('flex flex-col gap-2', className)}>\n {choices.map((choice, i) => {\n const isSelected = actualValue?.includes(choice.value) || false;\n const statusStyles = getStatusStyles(choice.status);\n const statusBadge = getStatusBadge(choice.status);\n const isDisabled = choice.disabled || disabled;\n\n /*\n * Resultado só de leitura: não há controle para operar, então a linha\n * não finge ser um checkbox. A leitura sai do texto, na ordem:\n * posição, enunciado da alternativa, status e o que o aluno marcou.\n */\n return (\n <div\n key={`readonly-${choice.value}-${i}`}\n className={cn(\n 'flex flex-row justify-between gap-2 items-start p-2 rounded-lg transition-all',\n statusStyles,\n choice.disabled ? 'opacity-50 cursor-not-allowed' : ''\n )}\n >\n <Text as=\"span\" className=\"sr-only\">\n {`Alternativa ${i + 1} de ${choices.length}`}\n </Text>\n <div className=\"flex items-center gap-2 flex-1\">\n {renderVisualCheckbox(isSelected, isDisabled)}\n <HtmlMathRenderer\n content={choice.label}\n className={cn(\n 'flex-1',\n isSelected ||\n (choice.status && choice.status != OptionStatus.NEUTRAL)\n ? 'text-text-950'\n : 'text-text-600',\n isDisabled ? 'cursor-not-allowed' : 'cursor-default'\n )}\n />\n </div>\n {statusBadge && (\n <div className=\"flex-shrink-0\">{statusBadge}</div>\n )}\n {/* Única fonte do que o aluno escolheu para o leitor de tela. */}\n <Text as=\"span\" className=\"sr-only\">\n {isSelected ? 'Você marcou' : 'Não marcada'}\n </Text>\n </div>\n );\n })}\n </div>\n );\n }\n return (\n <div\n className={cn(\n 'flex flex-row justify-between gap-2 items-start p-2 rounded-lg transition-all',\n disabled ? 'opacity-50 cursor-not-allowed' : '',\n className\n )}\n >\n <CheckboxList\n name={name}\n {...groupA11yProps}\n values={actualValue}\n onValuesChange={(v) => {\n setActualValue(v);\n onHandleSelectedValues?.(v);\n }}\n disabled={disabled}\n >\n {choices.map((choice, i) => (\n <div\n key={`interactive-${choice.value}-${i}`}\n className={cn(\n 'flex flex-row gap-2 items-center p-2 rounded-lg transition-all',\n ROW_INTERACTION_CLASSES,\n choice.disabled || disabled\n ? 'cursor-not-allowed'\n : 'cursor-pointer hover:bg-background-50'\n )}\n >\n <CheckboxListItem\n value={choice.value}\n id={`interactive-${choice.value}-${i}`}\n disabled={choice.disabled || disabled}\n />\n\n <label\n htmlFor={`interactive-${choice.value}-${i}`}\n className={cn(\n 'flex-1',\n STRETCHED_LABEL_CLASSES,\n actualValue?.includes(choice.value)\n ? 'text-text-950'\n : 'text-text-600',\n choice.disabled || disabled\n ? 'cursor-not-allowed'\n : 'cursor-pointer'\n )}\n >\n <HtmlMathRenderer content={choice.label} />\n </label>\n </div>\n ))}\n </CheckboxList>\n </div>\n );\n};\n\nexport { MultipleChoiceList };\n","import {\n InputHTMLAttributes,\n HTMLAttributes,\n ReactNode,\n forwardRef,\n useId,\n useEffect,\n useRef,\n Children,\n cloneElement,\n isValidElement,\n ReactElement,\n} from 'react';\nimport { create, StoreApi, useStore } from 'zustand';\nimport CheckBox from './CheckBox';\nimport { cn } from '../../utils/utils';\n\n/**\n * CheckboxList size variants\n */\ntype CheckboxListSize = 'small' | 'medium' | 'large';\n\n/**\n * CheckboxList visual state\n */\ntype CheckboxListState =\n | 'default'\n | 'hovered'\n | 'focused'\n | 'invalid'\n | 'disabled';\n\n/**\n * CheckboxList store interface\n */\ninterface CheckboxListStore {\n values: string[];\n setValues: (values: string[]) => void;\n toggleValue: (value: string) => void;\n onValuesChange?: (values: string[]) => void;\n disabled: boolean;\n name: string;\n}\n\ntype CheckboxListStoreApi = StoreApi<CheckboxListStore>;\n\n/**\n * Create a new CheckboxList store\n */\nconst createCheckboxListStore = (\n name: string,\n defaultValues: string[],\n disabled: boolean,\n onValuesChange?: (values: string[]) => void\n): CheckboxListStoreApi =>\n create<CheckboxListStore>((set, get) => ({\n values: defaultValues,\n setValues: (values) => {\n if (!get().disabled) {\n set({ values });\n get().onValuesChange?.(values);\n }\n },\n toggleValue: (value) => {\n if (!get().disabled) {\n const currentValues = get().values;\n const newValues = currentValues.includes(value)\n ? currentValues.filter((v) => v !== value)\n : [...currentValues, value];\n set({ values: newValues });\n get().onValuesChange?.(newValues);\n }\n },\n onValuesChange,\n disabled,\n name,\n }));\n\n/**\n * Hook to access CheckboxList store\n */\nexport const useCheckboxListStore = (externalStore?: CheckboxListStoreApi) => {\n if (!externalStore) {\n throw new Error('CheckboxListItem must be used within a CheckboxList');\n }\n return externalStore;\n};\n\n/**\n * Inject store into CheckboxListItem children\n */\nconst injectStore = (\n children: ReactNode,\n store: CheckboxListStoreApi\n): ReactNode =>\n Children.map(children, (child) => {\n if (!isValidElement(child)) return child;\n const typedChild = child as ReactElement<CheckboxListItemProps>;\n const shouldInject = typedChild.type === CheckboxListItem;\n return cloneElement(typedChild, {\n ...(shouldInject ? { store } : {}),\n ...(typedChild.props.children\n ? { children: injectStore(typedChild.props.children, store) }\n : {}),\n });\n });\n\n/**\n * CheckboxList component props interface\n */\nexport type CheckboxListProps = {\n /** Current selected values */\n values?: string[];\n /** Default selected values for uncontrolled usage */\n defaultValues?: string[];\n /** Callback when selection changes */\n onValuesChange?: (values: string[]) => void;\n /** Group name for all checkboxes */\n name?: string;\n /** Disabled state for the entire group */\n disabled?: boolean;\n /** Additional CSS classes */\n className?: string;\n /** Children components */\n children: ReactNode;\n} & Omit<HTMLAttributes<HTMLDivElement>, 'onChange' | 'defaultValues'>;\n\n/**\n * CheckboxList component for flexible checkbox group composition\n *\n * Uses Zustand for state management with automatic store injection.\n * Allows complete control over layout and styling by composing with CheckboxListItem.\n *\n * @example\n * ```tsx\n * <CheckboxList defaultValues={[\"option1\"]} onValuesChange={setValues}>\n * <div className=\"flex items-center gap-3\">\n * <CheckboxListItem value=\"option1\" id=\"c1\" />\n * <label htmlFor=\"c1\">Option 1</label>\n * </div>\n * <div className=\"flex items-center gap-3\">\n * <CheckboxListItem value=\"option2\" id=\"c2\" />\n * <label htmlFor=\"c2\">Option 2</label>\n * </div>\n * </CheckboxList>\n * ```\n */\nconst CheckboxList = forwardRef<HTMLDivElement, CheckboxListProps>(\n (\n {\n values: propValues,\n defaultValues = [],\n onValuesChange,\n name: propName,\n disabled = false,\n className = '',\n children,\n ...props\n },\n ref\n ) => {\n // Generate unique name if not provided\n const generatedId = useId();\n const name = propName || `checkbox-list-${generatedId}`;\n\n // Create store reference\n const storeRef = useRef<CheckboxListStoreApi>(null);\n storeRef.current ??= createCheckboxListStore(\n name,\n defaultValues,\n disabled,\n onValuesChange\n );\n const store = storeRef.current;\n\n // Get store actions\n const { setValues } = useStore(store, (s) => s);\n\n // Call onValuesChange with initial values\n useEffect(() => {\n const currentValues = store.getState().values;\n if (currentValues.length > 0 && onValuesChange) {\n onValuesChange(currentValues);\n }\n }, []);\n\n // Handle controlled values changes\n useEffect(() => {\n if (propValues !== undefined) {\n setValues(propValues);\n }\n }, [propValues, setValues]);\n\n // Update disabled state\n useEffect(() => {\n store.setState({ disabled });\n }, [disabled, store]);\n\n return (\n <div\n ref={ref}\n className={cn('flex flex-col gap-2 w-full', className)}\n aria-label={name}\n {...props}\n >\n {injectStore(children, store)}\n </div>\n );\n }\n);\n\nCheckboxList.displayName = 'CheckboxList';\n\n/**\n * CheckboxListItem component props interface\n */\nexport type CheckboxListItemProps = {\n /** Value for this checkbox item */\n value: string;\n /** Store reference (automatically injected by CheckboxList) */\n store?: CheckboxListStoreApi;\n /** Disabled state for this specific item */\n disabled?: boolean;\n /** Size variant */\n size?: CheckboxListSize;\n /** Visual state */\n state?: CheckboxListState;\n /** Additional CSS classes */\n className?: string;\n} & Omit<\n InputHTMLAttributes<HTMLInputElement>,\n 'type' | 'name' | 'value' | 'checked' | 'onChange' | 'size'\n>;\n\n/**\n * CheckboxListItem component for use within CheckboxList\n *\n * A checkbox without label that works within CheckboxList context.\n * Provides just the checkbox input for maximum flexibility in composition.\n *\n * @example\n * ```tsx\n * <CheckboxList defaultValues={[\"option1\"]}>\n * <div className=\"flex items-center gap-3\">\n * <CheckboxListItem value=\"option1\" id=\"c1\" />\n * <label htmlFor=\"c1\">Option 1</label>\n * </div>\n * </CheckboxList>\n * ```\n */\nconst CheckboxListItem = forwardRef<HTMLInputElement, CheckboxListItemProps>(\n (\n {\n value,\n store: externalStore,\n disabled: itemDisabled,\n size = 'medium',\n state = 'default',\n className = '',\n id,\n ...props\n },\n ref\n ) => {\n // Get store and state\n const store = useCheckboxListStore(externalStore);\n const {\n values: groupValues,\n toggleValue,\n disabled: groupDisabled,\n name,\n } = useStore(store);\n\n // Generate unique ID if not provided\n const generatedId = useId();\n const inputId = id ?? `checkbox-item-${generatedId}`;\n\n // Determine states\n const isChecked = groupValues.includes(value);\n const isDisabled = groupDisabled || itemDisabled;\n const currentState = isDisabled ? 'disabled' : state;\n\n // Use standard CheckBox component for consistency and simplicity\n return (\n <CheckBox\n ref={ref}\n id={inputId}\n name={name}\n value={value}\n checked={isChecked}\n disabled={isDisabled}\n size={size}\n state={currentState}\n className={className}\n onChange={() => {\n if (!isDisabled) {\n toggleValue(value);\n }\n }}\n {...props}\n />\n );\n }\n);\n\nCheckboxListItem.displayName = 'CheckboxListItem';\n\nexport default CheckboxList;\nexport { CheckboxListItem };\n"]}
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
QuizImageQuestion,
|
|
16
16
|
QuizMultipleChoice,
|
|
17
17
|
QuizTrueOrFalse
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-IIQCS3A2.mjs";
|
|
19
19
|
import {
|
|
20
20
|
CorrectionSourceTag_default
|
|
21
21
|
} from "./chunk-4CBGO4DE.mjs";
|
|
@@ -48,7 +48,7 @@ import {
|
|
|
48
48
|
} from "./chunk-ROS5XGTQ.mjs";
|
|
49
49
|
import {
|
|
50
50
|
Modal_default
|
|
51
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-LODDYDTP.mjs";
|
|
52
52
|
import {
|
|
53
53
|
Button_default
|
|
54
54
|
} from "./chunk-ZQZBOTZJ.mjs";
|
|
@@ -954,4 +954,4 @@ export {
|
|
|
954
954
|
QuizQuestionList,
|
|
955
955
|
QuizFooter
|
|
956
956
|
};
|
|
957
|
-
//# sourceMappingURL=chunk-
|
|
957
|
+
//# sourceMappingURL=chunk-W3CWEZDB.mjs.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 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
3
|
|
|
4
|
-
var
|
|
4
|
+
var _chunkZQQJTO6Tjs = require('./chunk-ZQQJTO6T.js');
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
var _chunkD4BRJ4ZNjs = require('./chunk-D4BRJ4ZN.js');
|
|
@@ -33,7 +33,7 @@ function MathNodeView({ node, editor, getPos }) {
|
|
|
33
33
|
displayMode: display
|
|
34
34
|
});
|
|
35
35
|
} catch (e) {
|
|
36
|
-
return `<span class="text-error-600">${
|
|
36
|
+
return `<span class="text-error-600">${_chunkZQQJTO6Tjs.escapeHtmlText.call(void 0, latex)}</span>`;
|
|
37
37
|
}
|
|
38
38
|
}, [latex, display]);
|
|
39
39
|
const handleClick = () => {
|
|
@@ -153,7 +153,7 @@ var MathNode = _core.Node.create({
|
|
|
153
153
|
new (0, _state.Plugin)({
|
|
154
154
|
key: new (0, _state.PluginKey)("mathInlinePaste"),
|
|
155
155
|
props: {
|
|
156
|
-
transformPastedHTML: (html) =>
|
|
156
|
+
transformPastedHTML: (html) => _chunkZQQJTO6Tjs.processLatexInHtml.call(void 0, html),
|
|
157
157
|
handlePaste: (_view, event) => {
|
|
158
158
|
const clipboard = event.clipboardData;
|
|
159
159
|
if (!clipboard || clipboard.getData("text/html")) return false;
|
|
@@ -161,8 +161,8 @@ var MathNode = _core.Node.create({
|
|
|
161
161
|
if (!text || !(text.includes("$") || text.includes(String.raw`\begin{`))) {
|
|
162
162
|
return false;
|
|
163
163
|
}
|
|
164
|
-
const html =
|
|
165
|
-
_chunkD4BRJ4ZNjs.normalizeLineBreaksInHtml.call(void 0,
|
|
164
|
+
const html = _chunkZQQJTO6Tjs.processLatexInHtml.call(void 0,
|
|
165
|
+
_chunkD4BRJ4ZNjs.normalizeLineBreaksInHtml.call(void 0, _chunkZQQJTO6Tjs.escapeHtmlText.call(void 0, text), { inline: true })
|
|
166
166
|
);
|
|
167
167
|
if (!html.includes(`data-type="${_chunkOLZ65XLFjs.MATH_SPAN_TYPE}"`)) return false;
|
|
168
168
|
editor.commands.insertContent(html);
|
|
@@ -225,4 +225,4 @@ var MathNode = _core.Node.create({
|
|
|
225
225
|
|
|
226
226
|
|
|
227
227
|
exports.MathNode = MathNode;
|
|
228
|
-
//# sourceMappingURL=chunk-
|
|
228
|
+
//# sourceMappingURL=chunk-W7NNH4VY.js.map
|