@techzyapp/ui-library 1.0.46 → 1.0.47
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/README.md +1 -1
- package/dist/AdminRoot-BRN_MlHp.cjs +2 -0
- package/dist/AdminRoot-BRN_MlHp.cjs.map +1 -0
- package/dist/AdminRoot-CtqPtYxo.js +107 -0
- package/dist/AdminRoot-CtqPtYxo.js.map +1 -0
- package/dist/{Alert-BU7GlQna.js → Alert-Bo_XgY-A.js} +3 -3
- package/dist/{Alert-BU7GlQna.js.map → Alert-Bo_XgY-A.js.map} +1 -1
- package/dist/{Alert-CVQOjuEq.cjs → Alert-QvfNBhlU.cjs} +2 -2
- package/dist/{Alert-CVQOjuEq.cjs.map → Alert-QvfNBhlU.cjs.map} +1 -1
- package/dist/AuthGuard-CAaQZ2y7.cjs +2 -0
- package/dist/AuthGuard-CAaQZ2y7.cjs.map +1 -0
- package/dist/AuthGuard-vqKf2PF9.js +102 -0
- package/dist/AuthGuard-vqKf2PF9.js.map +1 -0
- package/dist/{Breadcrumbs-BMz_YVPa.js → Breadcrumbs-BEv57tuJ.js} +3 -3
- package/dist/{Breadcrumbs-BMz_YVPa.js.map → Breadcrumbs-BEv57tuJ.js.map} +1 -1
- package/dist/{Breadcrumbs-BbC0o4JE.cjs → Breadcrumbs-CqGS32x5.cjs} +2 -2
- package/dist/{Breadcrumbs-BbC0o4JE.cjs.map → Breadcrumbs-CqGS32x5.cjs.map} +1 -1
- package/dist/{Button-mBZOvgyZ.cjs → Button-BtiFpRie.cjs} +2 -2
- package/dist/{Button-mBZOvgyZ.cjs.map → Button-BtiFpRie.cjs.map} +1 -1
- package/dist/{Button-C415LPw_.js → Button-DZWYeAno.js} +2 -2
- package/dist/{Button-C415LPw_.js.map → Button-DZWYeAno.js.map} +1 -1
- package/dist/{Calendar-B0f6h9-A.js → Calendar-7W9xNVBZ.js} +3 -3
- package/dist/{Calendar-B0f6h9-A.js.map → Calendar-7W9xNVBZ.js.map} +1 -1
- package/dist/{Calendar-hO051hfk.cjs → Calendar-Bgh_3Vk2.cjs} +2 -2
- package/dist/{Calendar-hO051hfk.cjs.map → Calendar-Bgh_3Vk2.cjs.map} +1 -1
- package/dist/{Card-BdNr5row.cjs → Card-KfmWG9Uz.cjs} +2 -2
- package/dist/{Card-BdNr5row.cjs.map → Card-KfmWG9Uz.cjs.map} +1 -1
- package/dist/{Card-ssUNaOF_.js → Card-ckOd617g.js} +3 -3
- package/dist/{Card-ssUNaOF_.js.map → Card-ckOd617g.js.map} +1 -1
- package/dist/{Chip-BpJN4rzY.cjs → Chip-BDUsue_R.cjs} +2 -2
- package/dist/{Chip-BpJN4rzY.cjs.map → Chip-BDUsue_R.cjs.map} +1 -1
- package/dist/{Chip-C0x-6g2h.js → Chip-Crzm7Eux.js} +2 -2
- package/dist/{Chip-C0x-6g2h.js.map → Chip-Crzm7Eux.js.map} +1 -1
- package/dist/{CodeBlock-DKnWINdV.js → CodeBlock-CX8_dMPD.js} +3 -3
- package/dist/{CodeBlock-DKnWINdV.js.map → CodeBlock-CX8_dMPD.js.map} +1 -1
- package/dist/{CodeBlock-DTrzN95i.cjs → CodeBlock-rnGAu2DQ.cjs} +2 -2
- package/dist/{CodeBlock-DTrzN95i.cjs.map → CodeBlock-rnGAu2DQ.cjs.map} +1 -1
- package/dist/{ColorPicker-Doaegll4.cjs → ColorPicker-BaAdcqR9.cjs} +2 -2
- package/dist/{ColorPicker-Doaegll4.cjs.map → ColorPicker-BaAdcqR9.cjs.map} +1 -1
- package/dist/{ColorPicker-Bidev2DJ.js → ColorPicker-CwLivdAt.js} +3 -3
- package/dist/{ColorPicker-Bidev2DJ.js.map → ColorPicker-CwLivdAt.js.map} +1 -1
- package/dist/{ColorPickerPanel-DThSuUoz.js → ColorPickerPanel-CkrSIf35.js} +2 -2
- package/dist/{ColorPickerPanel-DThSuUoz.js.map → ColorPickerPanel-CkrSIf35.js.map} +1 -1
- package/dist/{ColorPickerPanel-048Fj7wv.cjs → ColorPickerPanel-IOhJJF1R.cjs} +2 -2
- package/dist/{ColorPickerPanel-048Fj7wv.cjs.map → ColorPickerPanel-IOhJJF1R.cjs.map} +1 -1
- package/dist/{ColorRamp-CGw4D9bf.cjs → ColorRamp-BCy8a7ks.cjs} +2 -2
- package/dist/{ColorRamp-CGw4D9bf.cjs.map → ColorRamp-BCy8a7ks.cjs.map} +1 -1
- package/dist/{ColorRamp-Reb0q69d.js → ColorRamp-DbFOsspz.js} +2 -2
- package/dist/{ColorRamp-Reb0q69d.js.map → ColorRamp-DbFOsspz.js.map} +1 -1
- package/dist/ConfigProvider-CYSpuSMJ.cjs +2 -0
- package/dist/ConfigProvider-CYSpuSMJ.cjs.map +1 -0
- package/dist/ConfigProvider-DtyUlWk6.js +394 -0
- package/dist/ConfigProvider-DtyUlWk6.js.map +1 -0
- package/dist/{CopyButton-Cnab62vt.cjs → CopyButton-DUG5s3TM.cjs} +2 -2
- package/dist/{CopyButton-Cnab62vt.cjs.map → CopyButton-DUG5s3TM.cjs.map} +1 -1
- package/dist/{CopyButton-Dm8-V4ku.js → CopyButton-LURMuaYw.js} +3 -3
- package/dist/{CopyButton-Dm8-V4ku.js.map → CopyButton-LURMuaYw.js.map} +1 -1
- package/dist/{DatePicker-CaGeW_-j.cjs → DatePicker-Bw9gLB8o.cjs} +2 -2
- package/dist/{DatePicker-CaGeW_-j.cjs.map → DatePicker-Bw9gLB8o.cjs.map} +1 -1
- package/dist/{DatePicker-C4MTCmDn.js → DatePicker-CSIBYSZt.js} +4 -4
- package/dist/{DatePicker-C4MTCmDn.js.map → DatePicker-CSIBYSZt.js.map} +1 -1
- package/dist/{DateTimePicker-B0CjHKPV.js → DateTimePicker-C9F2yJMf.js} +7 -7
- package/dist/{DateTimePicker-B0CjHKPV.js.map → DateTimePicker-C9F2yJMf.js.map} +1 -1
- package/dist/{DateTimePicker-DXKaAYey.cjs → DateTimePicker-kikKdt0F.cjs} +2 -2
- package/dist/{DateTimePicker-DXKaAYey.cjs.map → DateTimePicker-kikKdt0F.cjs.map} +1 -1
- package/dist/{DescriptionList-BSDwobDc.cjs → DescriptionList-DnGkHdzT.cjs} +2 -2
- package/dist/{DescriptionList-BSDwobDc.cjs.map → DescriptionList-DnGkHdzT.cjs.map} +1 -1
- package/dist/{DescriptionList-BkUS5egS.js → DescriptionList-kfNXbf_D.js} +4 -4
- package/dist/{DescriptionList-BkUS5egS.js.map → DescriptionList-kfNXbf_D.js.map} +1 -1
- package/dist/{EmptyState-CkkFHKrh.cjs → EmptyState-BM5LrRLq.cjs} +2 -2
- package/dist/{EmptyState-CkkFHKrh.cjs.map → EmptyState-BM5LrRLq.cjs.map} +1 -1
- package/dist/{EmptyState-DXoaPC7o.js → EmptyState-DrSj2XV_.js} +2 -2
- package/dist/{EmptyState-DXoaPC7o.js.map → EmptyState-DrSj2XV_.js.map} +1 -1
- package/dist/{ErrorBoundary-CSP_Ctg6.js → ErrorBoundary-DsP4hO_V.js} +3 -3
- package/dist/{ErrorBoundary-CSP_Ctg6.js.map → ErrorBoundary-DsP4hO_V.js.map} +1 -1
- package/dist/{ErrorBoundary-tZjKtO28.cjs → ErrorBoundary-yz669VEu.cjs} +2 -2
- package/dist/{ErrorBoundary-tZjKtO28.cjs.map → ErrorBoundary-yz669VEu.cjs.map} +1 -1
- package/dist/{ErrorState-JH4JdrTI.cjs → ErrorState-BThPIYaM.cjs} +2 -2
- package/dist/{ErrorState-JH4JdrTI.cjs.map → ErrorState-BThPIYaM.cjs.map} +1 -1
- package/dist/{ErrorState-WYsly5-i.js → ErrorState-DEngucdq.js} +7 -7
- package/dist/{ErrorState-WYsly5-i.js.map → ErrorState-DEngucdq.js.map} +1 -1
- package/dist/{FileCard-D4TB3qGG.js → FileCard-CmCESTQd.js} +3 -3
- package/dist/{FileCard-D4TB3qGG.js.map → FileCard-CmCESTQd.js.map} +1 -1
- package/dist/{FileCard-BIfPqeek.cjs → FileCard-wxDT2rj9.cjs} +2 -2
- package/dist/{FileCard-BIfPqeek.cjs.map → FileCard-wxDT2rj9.cjs.map} +1 -1
- package/dist/{FileUploader-YE_DfTNC.cjs → FileUploader-DBNRp5eT.cjs} +2 -2
- package/dist/{FileUploader-YE_DfTNC.cjs.map → FileUploader-DBNRp5eT.cjs.map} +1 -1
- package/dist/{FileUploader-DPVF76Ha.js → FileUploader-Dp1r4Sxc.js} +29 -29
- package/dist/{FileUploader-DPVF76Ha.js.map → FileUploader-Dp1r4Sxc.js.map} +1 -1
- package/dist/{FullscreenToggle-ipX55Nj4.cjs → FullscreenToggle-DVdQriWB.cjs} +2 -2
- package/dist/{FullscreenToggle-ipX55Nj4.cjs.map → FullscreenToggle-DVdQriWB.cjs.map} +1 -1
- package/dist/{FullscreenToggle-CxwGPLdd.js → FullscreenToggle-WGsbE3Op.js} +3 -3
- package/dist/{FullscreenToggle-CxwGPLdd.js.map → FullscreenToggle-WGsbE3Op.js.map} +1 -1
- package/dist/{IconButton-U_sr2Ahy.cjs → IconButton-DSPdv-oI.cjs} +2 -2
- package/dist/{IconButton-U_sr2Ahy.cjs.map → IconButton-DSPdv-oI.cjs.map} +1 -1
- package/dist/{IconButton-re6xITGO.js → IconButton-iWbUJAz7.js} +2 -2
- package/dist/{IconButton-re6xITGO.js.map → IconButton-iWbUJAz7.js.map} +1 -1
- package/dist/{ImageEditor-BwrG1fk7.js → ImageEditor-BDNys8pq.js} +5 -5
- package/dist/{ImageEditor-BwrG1fk7.js.map → ImageEditor-BDNys8pq.js.map} +1 -1
- package/dist/{ImageEditor-1n50vo_v.cjs → ImageEditor-C40dp2-V.cjs} +2 -2
- package/dist/{ImageEditor-1n50vo_v.cjs.map → ImageEditor-C40dp2-V.cjs.map} +1 -1
- package/dist/{Loader-7v1QBvHY.js → Loader-DD1vfqmN.js} +2 -2
- package/dist/{Loader-7v1QBvHY.js.map → Loader-DD1vfqmN.js.map} +1 -1
- package/dist/{Loader-BE3SQr7W.cjs → Loader-RyFTP2X5.cjs} +2 -2
- package/dist/{Loader-BE3SQr7W.cjs.map → Loader-RyFTP2X5.cjs.map} +1 -1
- package/dist/{LocationPicker-CVJ4jVn2.cjs → LocationPicker-B594f0bz.cjs} +2 -2
- package/dist/{LocationPicker-CVJ4jVn2.cjs.map → LocationPicker-B594f0bz.cjs.map} +1 -1
- package/dist/{LocationPicker-BvKtZFq0.js → LocationPicker-DpmYaYyd.js} +6 -6
- package/dist/{LocationPicker-BvKtZFq0.js.map → LocationPicker-DpmYaYyd.js.map} +1 -1
- package/dist/{Modal-CxODxl81.cjs → Modal-7cCok6fV.cjs} +2 -2
- package/dist/{Modal-CxODxl81.cjs.map → Modal-7cCok6fV.cjs.map} +1 -1
- package/dist/{Modal-DpoiMMM3.js → Modal-DVGTD2Ck.js} +3 -3
- package/dist/{Modal-DpoiMMM3.js.map → Modal-DVGTD2Ck.js.map} +1 -1
- package/dist/{MultiSelect-B7KwEhL5.js → MultiSelect-D-X833xt.js} +4 -4
- package/dist/{MultiSelect-B7KwEhL5.js.map → MultiSelect-D-X833xt.js.map} +1 -1
- package/dist/{MultiSelect-2GouMRTl.cjs → MultiSelect-DTKNjUDH.cjs} +2 -2
- package/dist/{MultiSelect-2GouMRTl.cjs.map → MultiSelect-DTKNjUDH.cjs.map} +1 -1
- package/dist/{NumberField-ThojS4K3.js → NumberField-OPOl0Yph.js} +3 -3
- package/dist/{NumberField-ThojS4K3.js.map → NumberField-OPOl0Yph.js.map} +1 -1
- package/dist/{NumberField-o2z2QNK1.cjs → NumberField-Xz4yQMlm.cjs} +2 -2
- package/dist/{NumberField-o2z2QNK1.cjs.map → NumberField-Xz4yQMlm.cjs.map} +1 -1
- package/dist/{OtpField-C3MlMZ2F.js → OtpField-CLrDMNtS.js} +2 -2
- package/dist/{OtpField-C3MlMZ2F.js.map → OtpField-CLrDMNtS.js.map} +1 -1
- package/dist/{OtpField-BhZq44vV.cjs → OtpField-kd0YghZq.cjs} +2 -2
- package/dist/{OtpField-BhZq44vV.cjs.map → OtpField-kd0YghZq.cjs.map} +1 -1
- package/dist/{PageError-63Gk6fVC.js → PageError-BIiZDzey.js} +5 -5
- package/dist/{PageError-63Gk6fVC.js.map → PageError-BIiZDzey.js.map} +1 -1
- package/dist/{PageError-CCKWbrc5.cjs → PageError-v6MAH_OL.cjs} +2 -2
- package/dist/{PageError-CCKWbrc5.cjs.map → PageError-v6MAH_OL.cjs.map} +1 -1
- package/dist/{PageLayout-BekkDBtT.js → PageLayout-BjaPfXvb.js} +4 -4
- package/dist/{PageLayout-BekkDBtT.js.map → PageLayout-BjaPfXvb.js.map} +1 -1
- package/dist/{PageLayout-CDPUYu6A.cjs → PageLayout-DH3jochw.cjs} +2 -2
- package/dist/{PageLayout-CDPUYu6A.cjs.map → PageLayout-DH3jochw.cjs.map} +1 -1
- package/dist/{PageNotFound-BD3zX3cd.js → PageNotFound-C1oSsMG-.js} +5 -5
- package/dist/{PageNotFound-BD3zX3cd.js.map → PageNotFound-C1oSsMG-.js.map} +1 -1
- package/dist/{PageNotFound-CTR6htwa.cjs → PageNotFound-Cse4bROv.cjs} +2 -2
- package/dist/{PageNotFound-CTR6htwa.cjs.map → PageNotFound-Cse4bROv.cjs.map} +1 -1
- package/dist/{Pagination-qKjISBJ9.js → Pagination-BNJdqcu4.js} +2 -2
- package/dist/{Pagination-qKjISBJ9.js.map → Pagination-BNJdqcu4.js.map} +1 -1
- package/dist/{Pagination-BJvLUjQ0.cjs → Pagination-DkmfEmgK.cjs} +2 -2
- package/dist/{Pagination-BJvLUjQ0.cjs.map → Pagination-DkmfEmgK.cjs.map} +1 -1
- package/dist/{PaletteField-y8KpR4Ap.js → PaletteField-Cdky6Zka.js} +3 -3
- package/dist/{PaletteField-y8KpR4Ap.js.map → PaletteField-Cdky6Zka.js.map} +1 -1
- package/dist/{PaletteField-CDS9CJW9.cjs → PaletteField-DqZl1mK0.cjs} +2 -2
- package/dist/{PaletteField-CDS9CJW9.cjs.map → PaletteField-DqZl1mK0.cjs.map} +1 -1
- package/dist/{PhoneField-OjsuevPx.js → PhoneField-DmFaJJEa.js} +4 -4
- package/dist/{PhoneField-OjsuevPx.js.map → PhoneField-DmFaJJEa.js.map} +1 -1
- package/dist/{PhoneField-Df3J6Hhg.cjs → PhoneField-jq-3_i_b.cjs} +2 -2
- package/dist/{PhoneField-Df3J6Hhg.cjs.map → PhoneField-jq-3_i_b.cjs.map} +1 -1
- package/dist/{Popconfirm-aCyniPnH.js → Popconfirm-D-8ZG2WR.js} +3 -3
- package/dist/{Popconfirm-aCyniPnH.js.map → Popconfirm-D-8ZG2WR.js.map} +1 -1
- package/dist/{Popconfirm-BKzJ_EZy.cjs → Popconfirm-KOE9gGi6.cjs} +2 -2
- package/dist/{Popconfirm-BKzJ_EZy.cjs.map → Popconfirm-KOE9gGi6.cjs.map} +1 -1
- package/dist/{Progress-DWOoLd8u.cjs → Progress-7EyhPtnu.cjs} +2 -2
- package/dist/{Progress-DWOoLd8u.cjs.map → Progress-7EyhPtnu.cjs.map} +1 -1
- package/dist/{Progress-DzxbkcaD.js → Progress-CdX666FP.js} +2 -2
- package/dist/{Progress-DzxbkcaD.js.map → Progress-CdX666FP.js.map} +1 -1
- package/dist/{QrCode-C8uAPiHq.cjs → QrCode-ClIJjjvF.cjs} +2 -2
- package/dist/{QrCode-C8uAPiHq.cjs.map → QrCode-ClIJjjvF.cjs.map} +1 -1
- package/dist/{QrCode-DaJYqBc1.js → QrCode-D7ocSDi7.js} +2 -2
- package/dist/{QrCode-DaJYqBc1.js.map → QrCode-D7ocSDi7.js.map} +1 -1
- package/dist/{RemoveDialog-MhEU5Zl3.js → RemoveDialog-DTzRPLaT.js} +5 -5
- package/dist/{RemoveDialog-MhEU5Zl3.js.map → RemoveDialog-DTzRPLaT.js.map} +1 -1
- package/dist/{RemoveDialog-BnOtR6-q.cjs → RemoveDialog-UsSX5z8Y.cjs} +2 -2
- package/dist/{RemoveDialog-BnOtR6-q.cjs.map → RemoveDialog-UsSX5z8Y.cjs.map} +1 -1
- package/dist/{RichTextEditor-zkoxujnO.js → RichTextEditor-BMctlkVC.js} +7 -7
- package/dist/{RichTextEditor-zkoxujnO.js.map → RichTextEditor-BMctlkVC.js.map} +1 -1
- package/dist/{RichTextEditor-Cnrnvv1f.cjs → RichTextEditor-Bh0Q3dIW.cjs} +2 -2
- package/dist/{RichTextEditor-Cnrnvv1f.cjs.map → RichTextEditor-Bh0Q3dIW.cjs.map} +1 -1
- package/dist/{RootLayout-Z9PuRfsa.cjs → RootLayout-BztZetpk.cjs} +2 -2
- package/dist/{RootLayout-Z9PuRfsa.cjs.map → RootLayout-BztZetpk.cjs.map} +1 -1
- package/dist/{RootLayout-C4r9i5Go.js → RootLayout-CTkv4iQJ.js} +14 -14
- package/dist/{RootLayout-C4r9i5Go.js.map → RootLayout-CTkv4iQJ.js.map} +1 -1
- package/dist/{Select-CylqFHce.cjs → Select-BzVyK6Ne.cjs} +2 -2
- package/dist/{Select-CylqFHce.cjs.map → Select-BzVyK6Ne.cjs.map} +1 -1
- package/dist/{Select-jT94L1vq.js → Select-CmonDIIU.js} +3 -3
- package/dist/{Select-jT94L1vq.js.map → Select-CmonDIIU.js.map} +1 -1
- package/dist/{Sidebar-B1O2RsbR.js → Sidebar-CLr-DyQ_.js} +3 -3
- package/dist/{Sidebar-B1O2RsbR.js.map → Sidebar-CLr-DyQ_.js.map} +1 -1
- package/dist/{Sidebar-Bcm0fgVm.cjs → Sidebar-CM-jZfj5.cjs} +2 -2
- package/dist/{Sidebar-Bcm0fgVm.cjs.map → Sidebar-CM-jZfj5.cjs.map} +1 -1
- package/dist/{Slider-DC-ugZwT.js → Slider-C7Wb3q_F.js} +2 -2
- package/dist/{Slider-DC-ugZwT.js.map → Slider-C7Wb3q_F.js.map} +1 -1
- package/dist/{Slider-CV7ug0WF.cjs → Slider-Oe9VSAdy.cjs} +2 -2
- package/dist/{Slider-CV7ug0WF.cjs.map → Slider-Oe9VSAdy.cjs.map} +1 -1
- package/dist/{SpeedDial-C6yiMUe8.js → SpeedDial-CCGQlwn2.js} +2 -2
- package/dist/{SpeedDial-C6yiMUe8.js.map → SpeedDial-CCGQlwn2.js.map} +1 -1
- package/dist/{SpeedDial-DOgm2DDX.cjs → SpeedDial-DpIXoYHB.cjs} +2 -2
- package/dist/{SpeedDial-DOgm2DDX.cjs.map → SpeedDial-DpIXoYHB.cjs.map} +1 -1
- package/dist/{Stepper-BZdYGpBN.js → Stepper-D_WKS1RG.js} +2 -2
- package/dist/{Stepper-BZdYGpBN.js.map → Stepper-D_WKS1RG.js.map} +1 -1
- package/dist/{Stepper-DqM86TGV.cjs → Stepper-PBDU60G_.cjs} +2 -2
- package/dist/{Stepper-DqM86TGV.cjs.map → Stepper-PBDU60G_.cjs.map} +1 -1
- package/dist/{Table-BgaCwRDQ.cjs → Table-CZ4n4-TN.cjs} +2 -2
- package/dist/{Table-BgaCwRDQ.cjs.map → Table-CZ4n4-TN.cjs.map} +1 -1
- package/dist/{Table-FZlVWoYi.js → Table-DZQVa_PE.js} +16 -16
- package/dist/{Table-FZlVWoYi.js.map → Table-DZQVa_PE.js.map} +1 -1
- package/dist/{Tabs-BqQPkorY.js → Tabs-B063mP-v.js} +12 -12
- package/dist/{Tabs-BqQPkorY.js.map → Tabs-B063mP-v.js.map} +1 -1
- package/dist/{Tabs-kGeyFhJ6.cjs → Tabs-Byhqm-TE.cjs} +2 -2
- package/dist/{Tabs-kGeyFhJ6.cjs.map → Tabs-Byhqm-TE.cjs.map} +1 -1
- package/dist/{TagsField-B_sjp48X.cjs → TagsField-g_LtwYgz.cjs} +2 -2
- package/dist/{TagsField-B_sjp48X.cjs.map → TagsField-g_LtwYgz.cjs.map} +1 -1
- package/dist/{TagsField-ByTx9JXK.js → TagsField-hQFYyNcM.js} +4 -4
- package/dist/{TagsField-ByTx9JXK.js.map → TagsField-hQFYyNcM.js.map} +1 -1
- package/dist/{TextField-CBYJIfau.cjs → TextField-D4s2hGSd.cjs} +2 -2
- package/dist/{TextField-CBYJIfau.cjs.map → TextField-D4s2hGSd.cjs.map} +1 -1
- package/dist/{TextField-CyKIx-d-.js → TextField-Dfpk0jOg.js} +3 -3
- package/dist/{TextField-CyKIx-d-.js.map → TextField-Dfpk0jOg.js.map} +1 -1
- package/dist/{ThemeToggle-Dg6IishB.js → ThemeToggle-BQQ3eswr.js} +7 -7
- package/dist/{ThemeToggle-Dg6IishB.js.map → ThemeToggle-BQQ3eswr.js.map} +1 -1
- package/dist/{ThemeToggle-D2dIqiBa.cjs → ThemeToggle-BTTI7Jz0.cjs} +2 -2
- package/dist/{ThemeToggle-D2dIqiBa.cjs.map → ThemeToggle-BTTI7Jz0.cjs.map} +1 -1
- package/dist/{TimeColumns-Cx8J5qzW.js → TimeColumns-BpjhrNCq.js} +2 -2
- package/dist/{TimeColumns-Cx8J5qzW.js.map → TimeColumns-BpjhrNCq.js.map} +1 -1
- package/dist/{TimeColumns-DVmK_T_P.cjs → TimeColumns-DZYGWWG_.cjs} +2 -2
- package/dist/{TimeColumns-DVmK_T_P.cjs.map → TimeColumns-DZYGWWG_.cjs.map} +1 -1
- package/dist/{TimePicker-0nZOPRKp.cjs → TimePicker-DChtZgBs.cjs} +2 -2
- package/dist/{TimePicker-0nZOPRKp.cjs.map → TimePicker-DChtZgBs.cjs.map} +1 -1
- package/dist/{TimePicker-sAhtvqQ4.js → TimePicker-mzoMIlpq.js} +5 -5
- package/dist/{TimePicker-sAhtvqQ4.js.map → TimePicker-mzoMIlpq.js.map} +1 -1
- package/dist/{Toaster-BOW9rzLq.js → Toaster-79DvOW80.js} +8 -8
- package/dist/{Toaster-BOW9rzLq.js.map → Toaster-79DvOW80.js.map} +1 -1
- package/dist/{Toaster-DYGo92ke.cjs → Toaster-lonArt-H.cjs} +2 -2
- package/dist/{Toaster-DYGo92ke.cjs.map → Toaster-lonArt-H.cjs.map} +1 -1
- package/dist/{TranslatedFields-C_DuLotV.cjs → TranslatedFields-BYpMrYaw.cjs} +2 -2
- package/dist/{TranslatedFields-C_DuLotV.cjs.map → TranslatedFields-BYpMrYaw.cjs.map} +1 -1
- package/dist/{TranslatedFields-CcE0td9p.js → TranslatedFields-CHHtXO_n.js} +9 -9
- package/dist/{TranslatedFields-CcE0td9p.js.map → TranslatedFields-CHHtXO_n.js.map} +1 -1
- package/dist/{UserCard-DeONbaKj.js → UserCard-BJFNP_nl.js} +3 -3
- package/dist/{UserCard-DeONbaKj.js.map → UserCard-BJFNP_nl.js.map} +1 -1
- package/dist/{UserCard-DLVptkLr.cjs → UserCard-SlkCgZS9.cjs} +2 -2
- package/dist/{UserCard-DLVptkLr.cjs.map → UserCard-SlkCgZS9.cjs.map} +1 -1
- package/dist/app/AdminRoot.d.cts +9 -4
- package/dist/app/AdminRoot.d.ts +9 -4
- package/dist/auth/AuthGuard.d.cts +9 -3
- package/dist/auth/AuthGuard.d.ts +9 -3
- package/dist/auth/authLayoutRoute.d.cts +11 -3
- package/dist/auth/authLayoutRoute.d.ts +11 -3
- package/dist/auth/authRedirect.d.cts +64 -0
- package/dist/auth/authRedirect.d.ts +64 -0
- package/dist/authLayoutRoute-DCG9gCZ8.cjs +2 -0
- package/dist/authLayoutRoute-DCG9gCZ8.cjs.map +1 -0
- package/dist/authLayoutRoute-TuEqVizw.js +15 -0
- package/dist/authLayoutRoute-TuEqVizw.js.map +1 -0
- package/dist/components/Alert/index.cjs +1 -1
- package/dist/components/Alert/index.js +1 -1
- package/dist/components/Breadcrumbs/index.cjs +1 -1
- package/dist/components/Breadcrumbs/index.js +1 -1
- package/dist/components/Button/index.cjs +1 -1
- package/dist/components/Button/index.js +1 -1
- package/dist/components/Card/index.cjs +1 -1
- package/dist/components/Card/index.js +1 -1
- package/dist/components/Chip/index.cjs +1 -1
- package/dist/components/Chip/index.js +1 -1
- package/dist/components/CodeBlock/index.cjs +1 -1
- package/dist/components/CodeBlock/index.js +1 -1
- package/dist/components/ColorPicker/index.cjs +1 -1
- package/dist/components/ColorPicker/index.js +1 -1
- package/dist/components/ColorRamp/index.cjs +1 -1
- package/dist/components/ColorRamp/index.js +1 -1
- package/dist/components/CopyButton/index.cjs +1 -1
- package/dist/components/CopyButton/index.js +1 -1
- package/dist/components/DatePicker/index.cjs +1 -1
- package/dist/components/DatePicker/index.js +1 -1
- package/dist/components/DateTimePicker/index.cjs +1 -1
- package/dist/components/DateTimePicker/index.js +1 -1
- package/dist/components/DescriptionList/index.cjs +1 -1
- package/dist/components/DescriptionList/index.js +1 -1
- package/dist/components/EmptyState/index.cjs +1 -1
- package/dist/components/EmptyState/index.js +1 -1
- package/dist/components/ErrorState/index.cjs +1 -1
- package/dist/components/ErrorState/index.js +2 -2
- package/dist/components/FileCard/index.cjs +1 -1
- package/dist/components/FileCard/index.js +1 -1
- package/dist/components/FileUploader/index.cjs +1 -1
- package/dist/components/FileUploader/index.js +1 -1
- package/dist/components/FullscreenToggle/index.cjs +1 -1
- package/dist/components/FullscreenToggle/index.js +1 -1
- package/dist/components/IconButton/index.cjs +1 -1
- package/dist/components/IconButton/index.js +1 -1
- package/dist/components/ImageEditor/index.cjs +1 -1
- package/dist/components/ImageEditor/index.js +1 -1
- package/dist/components/Loader/index.cjs +1 -1
- package/dist/components/Loader/index.js +1 -1
- package/dist/components/LocationPicker/index.cjs +1 -1
- package/dist/components/LocationPicker/index.js +1 -1
- package/dist/components/Modal/index.cjs +1 -1
- package/dist/components/Modal/index.js +1 -1
- package/dist/components/MultiSelect/index.cjs +1 -1
- package/dist/components/MultiSelect/index.js +1 -1
- package/dist/components/NumberField/index.cjs +1 -1
- package/dist/components/NumberField/index.js +1 -1
- package/dist/components/OtpField/index.cjs +1 -1
- package/dist/components/OtpField/index.js +1 -1
- package/dist/components/PageError/index.cjs +1 -1
- package/dist/components/PageError/index.js +1 -1
- package/dist/components/PageLayout/index.cjs +1 -1
- package/dist/components/PageLayout/index.js +1 -1
- package/dist/components/PageNotFound/index.cjs +1 -1
- package/dist/components/PageNotFound/index.js +1 -1
- package/dist/components/Pagination/index.cjs +1 -1
- package/dist/components/Pagination/index.js +1 -1
- package/dist/components/PaletteField/index.cjs +1 -1
- package/dist/components/PaletteField/index.js +1 -1
- package/dist/components/PhoneField/index.cjs +1 -1
- package/dist/components/PhoneField/index.js +1 -1
- package/dist/components/Popconfirm/index.cjs +1 -1
- package/dist/components/Popconfirm/index.js +1 -1
- package/dist/components/Progress/index.cjs +1 -1
- package/dist/components/Progress/index.js +1 -1
- package/dist/components/QrCode/index.cjs +1 -1
- package/dist/components/QrCode/index.js +1 -1
- package/dist/components/RemoveDialog/index.cjs +1 -1
- package/dist/components/RemoveDialog/index.js +1 -1
- package/dist/components/RichTextEditor/index.cjs +1 -1
- package/dist/components/RichTextEditor/index.js +1 -1
- package/dist/components/RootLayout/index.cjs +1 -1
- package/dist/components/RootLayout/index.js +1 -1
- package/dist/components/Select/index.cjs +1 -1
- package/dist/components/Select/index.js +1 -1
- package/dist/components/Sidebar/index.cjs +1 -1
- package/dist/components/Sidebar/index.js +1 -1
- package/dist/components/Slider/index.cjs +1 -1
- package/dist/components/Slider/index.js +1 -1
- package/dist/components/SpeedDial/index.cjs +1 -1
- package/dist/components/SpeedDial/index.js +1 -1
- package/dist/components/Stepper/index.cjs +1 -1
- package/dist/components/Stepper/index.js +1 -1
- package/dist/components/Table/index.cjs +1 -1
- package/dist/components/Table/index.js +1 -1
- package/dist/components/Tabs/index.cjs +1 -1
- package/dist/components/Tabs/index.js +1 -1
- package/dist/components/TagsField/index.cjs +1 -1
- package/dist/components/TagsField/index.js +1 -1
- package/dist/components/TextField/index.cjs +1 -1
- package/dist/components/TextField/index.js +1 -1
- package/dist/components/ThemeToggle/index.cjs +1 -1
- package/dist/components/ThemeToggle/index.js +1 -1
- package/dist/components/TimePicker/index.cjs +1 -1
- package/dist/components/TimePicker/index.js +1 -1
- package/dist/components/Toast/index.cjs +1 -1
- package/dist/components/Toast/index.js +1 -1
- package/dist/components/TranslatedFields/index.cjs +1 -1
- package/dist/components/TranslatedFields/index.js +1 -1
- package/dist/components/UserCard/index.cjs +1 -1
- package/dist/components/UserCard/index.js +1 -1
- package/dist/entries/app.cjs +1 -1
- package/dist/entries/app.js +1 -1
- package/dist/entries/auth.cjs +1 -1
- package/dist/entries/auth.d.cts +1 -0
- package/dist/entries/auth.d.ts +1 -0
- package/dist/entries/auth.js +7 -4
- package/dist/entries/components.cjs +1 -1
- package/dist/entries/components.js +52 -52
- package/dist/entries/i18n.cjs +1 -1
- package/dist/entries/i18n.js +1 -1
- package/dist/entries/theme.cjs +1 -1
- package/dist/entries/theme.d.cts +1 -1
- package/dist/entries/theme.d.ts +1 -1
- package/dist/entries/theme.js +20 -18
- package/dist/index.cjs +1 -1
- package/dist/index.js +259 -254
- package/dist/theme/ConfigProvider.d.cts +17 -0
- package/dist/theme/ConfigProvider.d.ts +17 -0
- package/dist/theme/index.d.cts +1 -1
- package/dist/theme/index.d.ts +1 -1
- package/dist/{useHomeTo-BL3e8Sc6.js → useHomeTo-BLSvhJd5.js} +2 -2
- package/dist/{useHomeTo-BL3e8Sc6.js.map → useHomeTo-BLSvhJd5.js.map} +1 -1
- package/dist/{useHomeTo-W1PDW5CU.cjs → useHomeTo-cXCg1tf0.cjs} +2 -2
- package/dist/{useHomeTo-W1PDW5CU.cjs.map → useHomeTo-cXCg1tf0.cjs.map} +1 -1
- package/dist/{useOptionMenu-CVl7VHXl.cjs → useOptionMenu-6ZffgbYG.cjs} +2 -2
- package/dist/{useOptionMenu-CVl7VHXl.cjs.map → useOptionMenu-6ZffgbYG.cjs.map} +1 -1
- package/dist/{useOptionMenu-BkKiZ6Ax.js → useOptionMenu-CxM6FHXL.js} +3 -3
- package/dist/{useOptionMenu-BkKiZ6Ax.js.map → useOptionMenu-CxM6FHXL.js.map} +1 -1
- package/package.json +1 -1
- package/dist/AdminRoot-BZ1v5vN9.js +0 -101
- package/dist/AdminRoot-BZ1v5vN9.js.map +0 -1
- package/dist/AdminRoot-DJ4-UMAB.cjs +0 -2
- package/dist/AdminRoot-DJ4-UMAB.cjs.map +0 -1
- package/dist/AuthGuard-CVklwDbj.js +0 -7
- package/dist/AuthGuard-CVklwDbj.js.map +0 -1
- package/dist/AuthGuard-kfOZviar.cjs +0 -2
- package/dist/AuthGuard-kfOZviar.cjs.map +0 -1
- package/dist/ConfigProvider-DBU6rOIA.cjs +0 -2
- package/dist/ConfigProvider-DBU6rOIA.cjs.map +0 -1
- package/dist/ConfigProvider-DVDGtCUc.js +0 -386
- package/dist/ConfigProvider-DVDGtCUc.js.map +0 -1
- package/dist/authLayoutRoute-B10sXioW.js +0 -11
- package/dist/authLayoutRoute-B10sXioW.js.map +0 -1
- package/dist/authLayoutRoute-BVQ4LhuU.cjs +0 -2
- package/dist/authLayoutRoute-BVQ4LhuU.cjs.map +0 -1
package/README.md
CHANGED
|
@@ -132,7 +132,7 @@ Import from the scoped surfaces (the root `.` re-exports everything too):
|
|
|
132
132
|
| `@techzyapp/ui-library/i18n` | `useT`, `useTranslations`, `useLanguage` + message types |
|
|
133
133
|
| `@techzyapp/ui-library/icons` | `Icon`, `IconName`, `ICON_NAMES`, `loadIcon` / `preloadIcons` (lazy icons) |
|
|
134
134
|
| `@techzyapp/ui-library/helpers` | RBAC + translation + `Table` query helpers + palette / contrast |
|
|
135
|
-
| `@techzyapp/ui-library/auth` | `AuthGuard`, `authLayoutRoute` (TanStack-Router auth gating)
|
|
135
|
+
| `@techzyapp/ui-library/auth` | `AuthGuard`, `authLayoutRoute` (TanStack-Router auth gating), `useAuthRedirect` / `getAuthRedirect` / `clearAuthRedirect` (back to the page after sign-in) |
|
|
136
136
|
| `@techzyapp/ui-library/app` | `AdminRoot` — the whole admin root route (shell + guard + session gate + Toaster) |
|
|
137
137
|
| `@techzyapp/ui-library/css/reset.css` · `/css/styles.css` | the two stylesheets |
|
|
138
138
|
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";const e=require("react/jsx-runtime"),s=require("@tanstack/react-router"),b=require("./errorMessage-C7N4KvUS.cjs"),u=require("./AuthGuard-CAaQZ2y7.cjs"),q=require("./ConfigProvider-CYSpuSMJ.cjs"),z=require("./Toaster-lonArt-H.cjs"),G=require("./AuthLayout-Bzlsvicf.cjs"),M=require("./Col-BdQeyKEX.cjs"),A=require("./ErrorBoundary-yz669VEu.cjs"),p=require("./Button-BtiFpRie.cjs"),k=require("./RootLayout-BztZetpk.cjs"),F=require("./Loader-RyFTP2X5.cjs"),P="_pending_1jy0z_2",w={pending:P},D=({logo:y,logoTo:L,getUser:S,onLogout:C,authRouteId:g="/_auth",loginPath:c="/login",showUserCard:O,sidebarVariant:T,header:v,errorBoundary:d=!0,toaster:a=!0,pending:m=!1,pendingFallback:E,unavailable:t,unavailableFallback:R})=>{const i=q.useT(),K=s.useNavigate(),W=s.useRouter(),_=q.useRedirectQueryKey();u.configureAuthRedirect({queryKey:_,loginPath:c,isAuthPath:r=>W.getMatchedRoutes(r).matchedRoutes.some(o=>o.id.startsWith(g))});const f=a===!1?null:e.jsx(z.Toaster,{...typeof a=="object"?a:void 0}),B=s.useRouterState({select:r=>r.matches.some(o=>o.routeId.startsWith(g))}),N=s.useRouterState({select:r=>{var o;return(o=r.location)==null?void 0:o.pathname}}),l=()=>{u.beginSignOut(),C(),Promise.resolve(K({to:c})).finally(u.endSignOut)};if(m||t){let r;if(m)r=E??e.jsx("div",{className:w.pending,"aria-busy":"true",children:e.jsx(F.Loader,{size:"lg"})});else if(t){const o=t.reason??(b.getErrorStatus(t.error)===403?"forbidden":"unreachable");if(R)r=R({error:t.error,reason:o,retry:t.onRetry,signOut:l});else{const h=o==="unreachable"?t.onRetry:void 0,x=o==="forbidden";r=e.jsx(G.AuthLayout,{logo:y,icon:t.icon||void 0,color:t.color??"error",title:i(x?"adminRoot.noAccessTitle":"adminRoot.unreachableTitle"),subtitle:i(x?"adminRoot.noAccessSubtitle":"adminRoot.unreachableSubtitle"),children:e.jsxs(M.Col,{gap:16,children:[e.jsx(A.QueryError,{variant:"alert",error:t.error}),h?e.jsx(p.Button,{fullWidth:!0,onClick:h,children:i("errorState.retry")}):null,e.jsx(p.Button,{fullWidth:!0,variant:h?"filled":"contained",onClick:l,children:i("userCard.signOut")})]})})}}return e.jsxs(e.Fragment,{children:[r,f]})}const n=S(),j=d===!1?e.jsx(s.Outlet,{}):e.jsx(A.ErrorBoundary,{...d===!0?{}:d,resetKeys:[N],children:e.jsx(s.Outlet,{})}),Q=B?j:e.jsx(u.AuthGuard,{isAuthenticated:n!=null,redirectTo:c,children:e.jsx(k.RootLayout,{logo:y,logoTo:L,sidebarVariant:T,toaster:!1,header:{user:n?{name:n.name,email:n.email,avatar:n.avatar}:void 0,onLogout:l,...v},showUserCard:O,children:j})});return e.jsxs(e.Fragment,{children:[Q,f]})};exports.AdminRoot=D;
|
|
2
|
+
//# sourceMappingURL=AdminRoot-BRN_MlHp.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AdminRoot-BRN_MlHp.cjs","sources":["../src/app/AdminRoot.tsx"],"sourcesContent":["import type { ReactNode } from 'react'\nimport {\n Outlet,\n useNavigate,\n useRouter,\n useRouterState,\n type LinkProps,\n} from '@tanstack/react-router'\nimport {\n AuthLayout,\n Button,\n Col,\n ErrorBoundary,\n Loader,\n QueryError,\n RootLayout,\n Toaster,\n type ErrorBoundaryProps,\n type ToasterProps,\n type IconName,\n type RootLayoutHeader,\n type RootLayoutProps,\n} from '../components'\nimport { getErrorStatus } from '../components/ErrorState/errorMessage'\nimport { useRedirectQueryKey, useT, type ThemeColor } from '../theme'\nimport { AuthGuard } from '../auth/AuthGuard'\nimport { beginSignOut, configureAuthRedirect, endSignOut } from '../auth/authRedirect'\nimport styles from './AdminRoot.module.css'\n\n/** Why the session can't be used — see `AdminRootUnavailable.reason`. */\nexport type AdminRootUnavailableReason = 'forbidden' | 'unreachable'\n\n/** The `unavailable` state of `AdminRoot` — the session could not be checked, or may not be used here. */\nexport interface AdminRootUnavailable {\n /** What failed — passed to `QueryError` (message, trace id). */\n error: unknown\n /**\n * Why. `'forbidden'` = a valid session this panel may not use (no retry, only Sign Out).\n * `'unreachable'` = the check itself failed (Try Again + Sign Out). Defaults to `'forbidden'` when the\n * error carries HTTP status 403 (`error.status` or `error.response.status`), else `'unreachable'`.\n */\n reason?: AdminRootUnavailableReason\n /** Re-runs the session check. Shown as \"Try Again\" for `'unreachable'` only. */\n onRetry?: () => void\n /**\n * The `AuthLayout` icon. Default: none — apps differ here (one shows a tinted `CloudCross`, another keeps\n * every auth page icon-free), so it's the app's choice.\n */\n icon?: IconName | false\n /** Tint for `icon` (`AuthLayout`'s `color`). Default `'error'`. */\n color?: ThemeColor\n}\n\n/** What an `unavailableFallback` receives. */\nexport interface AdminRootUnavailableFallbackProps {\n /** The `unavailable.error`. */\n error: unknown\n /** The resolved reason (explicit, or inferred from a 403). */\n reason: AdminRootUnavailableReason\n /** `unavailable.onRetry`, when given — whatever the reason (the fallback decides whether to offer it). */\n retry?: () => void\n /** The shell's Sign Out: `onLogout()`, then navigate to plain `loginPath` (no return target is remembered). */\n signOut: () => void\n}\n\n/** The minimal user shape `AdminRoot` reads — apps pass their own richer type via the generic. */\nexport interface AdminUser {\n name?: string\n email?: string\n avatar?: string\n}\n\nexport interface AdminRootProps<U extends AdminUser = AdminUser> {\n /** Brand mark for the sidebar top. */\n logo?: ReactNode\n /**\n * Where clicking the logo goes — the first menu page by default (see `RootLayout`'s `logoTo`); a path to\n * send it elsewhere, or `false` for a non-clickable logo.\n */\n logoTo?: RootLayoutProps['logoTo']\n /** Current user, or `null` when signed out. */\n getUser: () => U | null\n /** Clears the session; `AdminRoot` navigates to `loginPath` afterwards. */\n onLogout: () => void\n /** Route-id prefix for standalone public pages (rendered outside the shell). Default `'/_auth'`. */\n authRouteId?: string\n /**\n * Guard target for signed-out visitors + post-logout redirect. Default `'/login'`. A session that ends by\n * itself (an expired token, a 401, revoked in another tab) reaches it through `AuthGuard`, which remembers\n * the page (`?redirect=…` — read it back with `useAuthRedirect`); an explicit Sign Out remembers nothing.\n */\n loginPath?: string\n /**\n * Show a `UserCard` (the user + Sign Out) at the bottom of the sidebar — passed to `RootLayout`. Unset, the\n * app-wide `config.sidebar.userCard` applies (default `false`, hidden).\n */\n showUserCard?: boolean\n /**\n * The sidebar's look, passed to `RootLayout` — `'floating'` or `'docked'` (flush to the edges). **Unset\n * (recommended)**, each user picks it in the header Settings drawer (saved), defaulting to the app-wide\n * `config.sidebar.variant` (`'floating'` when unset). **Set**, it pins the look and the drawer's Sidebar\n * section is hidden.\n */\n sidebarVariant?: RootLayoutProps['sidebarVariant']\n /**\n * Extra `RootLayout` header config, merged **over** the defaults (the app's fields win). Flows through\n * unchanged — e.g. **`header.menu`** (`HeaderMenuItem[]`) adds items to the account menu above Sign out.\n */\n header?: RootLayoutHeader\n /**\n * Wrap the page content in an `ErrorBoundary` (reset on navigation), so a crashing page shows an\n * `ErrorState` inside the shell instead of a white screen. Default `true`; `false` opts out; an object\n * configures it (e.g. `{ onError: Sentry.captureException }` or a custom `fallback`). It only catches what\n * the router doesn't: TanStack Router catches a route's component / `loader` / `beforeLoad` errors in its own\n * per-route boundary, so page crashes need `createRouter({ defaultErrorComponent: PageError })`.\n */\n errorBoundary?: boolean | Omit<ErrorBoundaryProps, 'children' | 'resetKeys'>\n /**\n * The one app-wide toast viewport AdminRoot mounts (the inner `RootLayout`'s is always off, so there's never a\n * second one). Unset / `true` → `<Toaster />`, following the app-wide `config.toast`; `ToasterProps`\n * (`{ position, duration }`) → this shell's override, anything unset still falls back to `config.toast`;\n * `false` → no viewport (e.g. the app mounts its own `<Toaster>`). Same shape as `RootLayout`'s `toaster`.\n */\n toaster?: boolean | ToasterProps\n /**\n * The app is still finding out who is signed in (e.g. verifying a stored token or refreshing a cookie\n * session). While `true`, AdminRoot renders only `pendingFallback` — no shell, no public page, no\n * `AuthGuard`, and `getUser()` isn't read — so a signed-in admin is never redirected to sign-in before the\n * check resolves. Route `beforeLoad` guards (e.g. `authLayoutRoute`) still run in the router, independent\n * of this — they must tolerate the unknown state themselves. No minimum display time. Default `false`.\n */\n pending?: boolean\n /** What to show while `pending`. Default: a `Loader size=\"lg\"` centred in the full viewport. */\n pendingFallback?: ReactNode\n /**\n * The session could not be checked, or the server will not serve this account here. While set, AdminRoot\n * renders a standalone `AuthLayout` screen (the app's `logo`, a `QueryError`, Try Again / Sign Out) instead\n * of the shell or a public page — and never redirects. Sign Out calls `onLogout` then navigates to\n * `loginPath`, so **`onLogout` must clear whatever set `unavailable`** (or this screen shows again).\n * `pending` wins when both are set. `null` / `undefined` = not unavailable (the default).\n */\n unavailable?: AdminRootUnavailable | null\n /** Replaces the whole `unavailable` screen — for an app that needs its own wording or extra actions. */\n unavailableFallback?: (props: AdminRootUnavailableFallbackProps) => ReactNode\n}\n\n/**\n * Root-route component for admin apps — it wires up the whole shell orchestration so an app only has to\n * supply `logo` + `getUser` + `onLogout`. Public pages (route id under `authRouteId`) render standalone;\n * everything else renders inside the guarded admin shell (`RootLayout`, with an optional sidebar `UserCard`), gated by\n * `AuthGuard` (signed-out visitors bounce to `loginPath?redirect=<the page>`, so a lost session or a shared\n * link returns there after sign-in — see `useAuthRedirect`). Sign Out clears the session and navigates to\n * plain `loginPath`, remembering nothing. Mounts exactly one app-wide `<Toaster/>` (`toaster`; none with `toaster={false}` — the inner\n * `RootLayout` always gets `toaster={false}`),\n * and wraps the page in an `ErrorBoundary` that resets on navigation (`errorBoundary`, default on).\n * While the app is still checking the session, pass `pending` (a full-screen loader instead of a premature\n * sign-in redirect); when the check failed or the server refuses this account, pass `unavailable` (a\n * standalone \"Cannot Reach the Server\" / \"No Access\" screen with Try Again / Sign Out). The `Toaster` stays\n * mounted in both.\n *\n * `loginPath` is a plain string, cast loosely to the router's `to` type (the library can't know the\n * app's typed route tree). The generic `<U>` preserves the app's own user type through `getUser`.\n *\n * @example\n * // routes/__root.tsx\n * export const Route = createRootRoute({\n * component: () => {\n * const { status, error, retry } = useSession()\n * return (\n * <AdminRoot<AuthUser>\n * pending={status === 'loading'}\n * unavailable={status === 'unavailable' ? { error, onRetry: retry } : null}\n * logo={<Logo />}\n * getUser={getUser}\n * onLogout={logout}\n * />\n * )\n * },\n * })\n */\nexport const AdminRoot = <U extends AdminUser = AdminUser>({\n logo,\n logoTo,\n getUser,\n onLogout,\n authRouteId = '/_auth',\n loginPath = '/login',\n showUserCard,\n sidebarVariant,\n header,\n errorBoundary = true,\n toaster = true,\n pending = false,\n pendingFallback,\n unavailable,\n unavailableFallback,\n}: AdminRootProps<U>) => {\n const t = useT()\n const navigate = useNavigate()\n const router = useRouter()\n const redirectQueryKey = useRedirectQueryKey()\n // the return-after-sign-in settings (known before any guard renders, e.g. on a cold /login?…) and its\n // safety check: never back onto the login page or a public auth page\n configureAuthRedirect({\n queryKey: redirectQueryKey,\n loginPath,\n isAuthPath: (path) =>\n router.getMatchedRoutes(path).matchedRoutes.some((r) => r.id.startsWith(authRouteId)),\n })\n // the single app-wide toast viewport (props → config.toast → built-in defaults, resolved inside Toaster)\n const toasterNode =\n toaster === false ? null : <Toaster {...(typeof toaster === 'object' ? toaster : undefined)} />\n const isAuthRoute = useRouterState({\n select: (s) => s.matches.some((m) => m.routeId.startsWith(authRouteId)),\n })\n const pathname = useRouterState({ select: (s) => s.location?.pathname })\n // an explicit Sign Out: the admin chose to leave, so nothing is remembered for the next sign-in\n const handleLogout = () => {\n beginSignOut()\n onLogout()\n void Promise.resolve(navigate({ to: loginPath as LinkProps['to'] })).finally(endSignOut)\n }\n\n // the session isn't known yet / can't be used — a standalone screen instead of the shell or a public\n // page (so no AuthGuard redirect, no sign-in flash). The Toaster stays, so a bootstrap toast isn't lost.\n if (pending || unavailable) {\n let gate: ReactNode\n if (pending) {\n gate = pendingFallback ?? (\n <div className={styles.pending} aria-busy=\"true\">\n <Loader size=\"lg\" />\n </div>\n )\n } else if (unavailable) {\n const reason: AdminRootUnavailableReason =\n unavailable.reason ??\n (getErrorStatus(unavailable.error) === 403 ? 'forbidden' : 'unreachable')\n if (unavailableFallback) {\n gate = unavailableFallback({\n error: unavailable.error,\n reason,\n retry: unavailable.onRetry,\n signOut: handleLogout,\n })\n } else {\n const retry = reason === 'unreachable' ? unavailable.onRetry : undefined\n const forbidden = reason === 'forbidden'\n gate = (\n <AuthLayout\n logo={logo}\n icon={unavailable.icon || undefined}\n color={unavailable.color ?? 'error'}\n title={t(forbidden ? 'adminRoot.noAccessTitle' : 'adminRoot.unreachableTitle')}\n subtitle={t(forbidden ? 'adminRoot.noAccessSubtitle' : 'adminRoot.unreachableSubtitle')}\n >\n <Col gap={16}>\n <QueryError variant=\"alert\" error={unavailable.error} />\n {retry ? (\n <Button fullWidth onClick={retry}>\n {t('errorState.retry')}\n </Button>\n ) : null}\n <Button fullWidth variant={retry ? 'filled' : 'contained'} onClick={handleLogout}>\n {t('userCard.signOut')}\n </Button>\n </Col>\n </AuthLayout>\n )\n }\n }\n return (\n <>\n {gate}\n {toasterNode}\n </>\n )\n }\n\n const user = getUser()\n // the routed page, inside an ErrorBoundary that resets whenever the path changes\n const page =\n errorBoundary === false ? (\n <Outlet />\n ) : (\n <ErrorBoundary {...(errorBoundary === true ? {} : errorBoundary)} resetKeys={[pathname]}>\n <Outlet />\n </ErrorBoundary>\n )\n const content = isAuthRoute ? (\n page\n ) : (\n <AuthGuard isAuthenticated={user != null} redirectTo={loginPath}>\n <RootLayout\n logo={logo}\n logoTo={logoTo}\n sidebarVariant={sidebarVariant}\n toaster={false}\n header={{\n user: user ? { name: user.name, email: user.email, avatar: user.avatar } : undefined,\n onLogout: handleLogout,\n ...header,\n }}\n showUserCard={showUserCard}\n >\n {page}\n </RootLayout>\n </AuthGuard>\n )\n return (\n <>\n {content}\n {toasterNode}\n </>\n )\n}\n"],"names":["AdminRoot","logo","logoTo","getUser","onLogout","authRouteId","loginPath","showUserCard","sidebarVariant","header","errorBoundary","toaster","pending","pendingFallback","unavailable","unavailableFallback","t","useT","navigate","useNavigate","router","useRouter","redirectQueryKey","useRedirectQueryKey","configureAuthRedirect","path","r","toasterNode","jsx","Toaster","isAuthRoute","useRouterState","s","m","pathname","_a","handleLogout","beginSignOut","endSignOut","gate","styles","Loader","reason","getErrorStatus","retry","forbidden","AuthLayout","jsxs","Col","QueryError","Button","Fragment","user","page","Outlet","ErrorBoundary","content","AuthGuard","RootLayout"],"mappings":"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"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { jsx as e, jsxs as m, Fragment as A } from "react/jsx-runtime";
|
|
2
|
+
import { useNavigate as k, useRouter as q, useRouterState as S, Outlet as L } from "@tanstack/react-router";
|
|
3
|
+
import { c as B } from "./errorMessage-C83fB2h5.js";
|
|
4
|
+
import { a as G, A as M, e as w, b as D } from "./AuthGuard-vqKf2PF9.js";
|
|
5
|
+
import { a as F, m as H } from "./ConfigProvider-DtyUlWk6.js";
|
|
6
|
+
import { T as I } from "./Toaster-79DvOW80.js";
|
|
7
|
+
import { A as J } from "./AuthLayout-BI1wLuDl.js";
|
|
8
|
+
import { C as P } from "./Col-B51RlwWP.js";
|
|
9
|
+
import { Q as U, E as V } from "./ErrorBoundary-DsP4hO_V.js";
|
|
10
|
+
import { B as T } from "./Button-DZWYeAno.js";
|
|
11
|
+
import { R as X } from "./RootLayout-CTkv4iQJ.js";
|
|
12
|
+
import { L as Y } from "./Loader-DD1vfqmN.js";
|
|
13
|
+
const Z = "_pending_1jy0z_2", $ = {
|
|
14
|
+
pending: Z
|
|
15
|
+
}, le = ({
|
|
16
|
+
logo: l,
|
|
17
|
+
logoTo: C,
|
|
18
|
+
getUser: O,
|
|
19
|
+
onLogout: j,
|
|
20
|
+
authRouteId: h = "/_auth",
|
|
21
|
+
loginPath: n = "/login",
|
|
22
|
+
showUserCard: E,
|
|
23
|
+
sidebarVariant: K,
|
|
24
|
+
header: Q,
|
|
25
|
+
errorBoundary: c = !0,
|
|
26
|
+
toaster: a = !0,
|
|
27
|
+
pending: f = !1,
|
|
28
|
+
pendingFallback: W,
|
|
29
|
+
unavailable: t,
|
|
30
|
+
unavailableFallback: p
|
|
31
|
+
}) => {
|
|
32
|
+
const i = F(), _ = k(), b = q(), v = H();
|
|
33
|
+
G({
|
|
34
|
+
queryKey: v,
|
|
35
|
+
loginPath: n,
|
|
36
|
+
isAuthPath: (r) => b.getMatchedRoutes(r).matchedRoutes.some((o) => o.id.startsWith(h))
|
|
37
|
+
});
|
|
38
|
+
const y = a === !1 ? null : /* @__PURE__ */ e(I, { ...typeof a == "object" ? a : void 0 }), x = S({
|
|
39
|
+
select: (r) => r.matches.some((o) => o.routeId.startsWith(h))
|
|
40
|
+
}), N = S({ select: (r) => {
|
|
41
|
+
var o;
|
|
42
|
+
return (o = r.location) == null ? void 0 : o.pathname;
|
|
43
|
+
} }), d = () => {
|
|
44
|
+
D(), j(), Promise.resolve(_({ to: n })).finally(w);
|
|
45
|
+
};
|
|
46
|
+
if (f || t) {
|
|
47
|
+
let r;
|
|
48
|
+
if (f)
|
|
49
|
+
r = W ?? /* @__PURE__ */ e("div", { className: $.pending, "aria-busy": "true", children: /* @__PURE__ */ e(Y, { size: "lg" }) });
|
|
50
|
+
else if (t) {
|
|
51
|
+
const o = t.reason ?? (B(t.error) === 403 ? "forbidden" : "unreachable");
|
|
52
|
+
if (p)
|
|
53
|
+
r = p({
|
|
54
|
+
error: t.error,
|
|
55
|
+
reason: o,
|
|
56
|
+
retry: t.onRetry,
|
|
57
|
+
signOut: d
|
|
58
|
+
});
|
|
59
|
+
else {
|
|
60
|
+
const u = o === "unreachable" ? t.onRetry : void 0, R = o === "forbidden";
|
|
61
|
+
r = /* @__PURE__ */ e(
|
|
62
|
+
J,
|
|
63
|
+
{
|
|
64
|
+
logo: l,
|
|
65
|
+
icon: t.icon || void 0,
|
|
66
|
+
color: t.color ?? "error",
|
|
67
|
+
title: i(R ? "adminRoot.noAccessTitle" : "adminRoot.unreachableTitle"),
|
|
68
|
+
subtitle: i(R ? "adminRoot.noAccessSubtitle" : "adminRoot.unreachableSubtitle"),
|
|
69
|
+
children: /* @__PURE__ */ m(P, { gap: 16, children: [
|
|
70
|
+
/* @__PURE__ */ e(U, { variant: "alert", error: t.error }),
|
|
71
|
+
u ? /* @__PURE__ */ e(T, { fullWidth: !0, onClick: u, children: i("errorState.retry") }) : null,
|
|
72
|
+
/* @__PURE__ */ e(T, { fullWidth: !0, variant: u ? "filled" : "contained", onClick: d, children: i("userCard.signOut") })
|
|
73
|
+
] })
|
|
74
|
+
}
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return /* @__PURE__ */ m(A, { children: [
|
|
79
|
+
r,
|
|
80
|
+
y
|
|
81
|
+
] });
|
|
82
|
+
}
|
|
83
|
+
const s = O(), g = c === !1 ? /* @__PURE__ */ e(L, {}) : /* @__PURE__ */ e(V, { ...c === !0 ? {} : c, resetKeys: [N], children: /* @__PURE__ */ e(L, {}) }), z = x ? g : /* @__PURE__ */ e(M, { isAuthenticated: s != null, redirectTo: n, children: /* @__PURE__ */ e(
|
|
84
|
+
X,
|
|
85
|
+
{
|
|
86
|
+
logo: l,
|
|
87
|
+
logoTo: C,
|
|
88
|
+
sidebarVariant: K,
|
|
89
|
+
toaster: !1,
|
|
90
|
+
header: {
|
|
91
|
+
user: s ? { name: s.name, email: s.email, avatar: s.avatar } : void 0,
|
|
92
|
+
onLogout: d,
|
|
93
|
+
...Q
|
|
94
|
+
},
|
|
95
|
+
showUserCard: E,
|
|
96
|
+
children: g
|
|
97
|
+
}
|
|
98
|
+
) });
|
|
99
|
+
return /* @__PURE__ */ m(A, { children: [
|
|
100
|
+
z,
|
|
101
|
+
y
|
|
102
|
+
] });
|
|
103
|
+
};
|
|
104
|
+
export {
|
|
105
|
+
le as A
|
|
106
|
+
};
|
|
107
|
+
//# sourceMappingURL=AdminRoot-CtqPtYxo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AdminRoot-CtqPtYxo.js","sources":["../src/app/AdminRoot.tsx"],"sourcesContent":["import type { ReactNode } from 'react'\nimport {\n Outlet,\n useNavigate,\n useRouter,\n useRouterState,\n type LinkProps,\n} from '@tanstack/react-router'\nimport {\n AuthLayout,\n Button,\n Col,\n ErrorBoundary,\n Loader,\n QueryError,\n RootLayout,\n Toaster,\n type ErrorBoundaryProps,\n type ToasterProps,\n type IconName,\n type RootLayoutHeader,\n type RootLayoutProps,\n} from '../components'\nimport { getErrorStatus } from '../components/ErrorState/errorMessage'\nimport { useRedirectQueryKey, useT, type ThemeColor } from '../theme'\nimport { AuthGuard } from '../auth/AuthGuard'\nimport { beginSignOut, configureAuthRedirect, endSignOut } from '../auth/authRedirect'\nimport styles from './AdminRoot.module.css'\n\n/** Why the session can't be used — see `AdminRootUnavailable.reason`. */\nexport type AdminRootUnavailableReason = 'forbidden' | 'unreachable'\n\n/** The `unavailable` state of `AdminRoot` — the session could not be checked, or may not be used here. */\nexport interface AdminRootUnavailable {\n /** What failed — passed to `QueryError` (message, trace id). */\n error: unknown\n /**\n * Why. `'forbidden'` = a valid session this panel may not use (no retry, only Sign Out).\n * `'unreachable'` = the check itself failed (Try Again + Sign Out). Defaults to `'forbidden'` when the\n * error carries HTTP status 403 (`error.status` or `error.response.status`), else `'unreachable'`.\n */\n reason?: AdminRootUnavailableReason\n /** Re-runs the session check. Shown as \"Try Again\" for `'unreachable'` only. */\n onRetry?: () => void\n /**\n * The `AuthLayout` icon. Default: none — apps differ here (one shows a tinted `CloudCross`, another keeps\n * every auth page icon-free), so it's the app's choice.\n */\n icon?: IconName | false\n /** Tint for `icon` (`AuthLayout`'s `color`). Default `'error'`. */\n color?: ThemeColor\n}\n\n/** What an `unavailableFallback` receives. */\nexport interface AdminRootUnavailableFallbackProps {\n /** The `unavailable.error`. */\n error: unknown\n /** The resolved reason (explicit, or inferred from a 403). */\n reason: AdminRootUnavailableReason\n /** `unavailable.onRetry`, when given — whatever the reason (the fallback decides whether to offer it). */\n retry?: () => void\n /** The shell's Sign Out: `onLogout()`, then navigate to plain `loginPath` (no return target is remembered). */\n signOut: () => void\n}\n\n/** The minimal user shape `AdminRoot` reads — apps pass their own richer type via the generic. */\nexport interface AdminUser {\n name?: string\n email?: string\n avatar?: string\n}\n\nexport interface AdminRootProps<U extends AdminUser = AdminUser> {\n /** Brand mark for the sidebar top. */\n logo?: ReactNode\n /**\n * Where clicking the logo goes — the first menu page by default (see `RootLayout`'s `logoTo`); a path to\n * send it elsewhere, or `false` for a non-clickable logo.\n */\n logoTo?: RootLayoutProps['logoTo']\n /** Current user, or `null` when signed out. */\n getUser: () => U | null\n /** Clears the session; `AdminRoot` navigates to `loginPath` afterwards. */\n onLogout: () => void\n /** Route-id prefix for standalone public pages (rendered outside the shell). Default `'/_auth'`. */\n authRouteId?: string\n /**\n * Guard target for signed-out visitors + post-logout redirect. Default `'/login'`. A session that ends by\n * itself (an expired token, a 401, revoked in another tab) reaches it through `AuthGuard`, which remembers\n * the page (`?redirect=…` — read it back with `useAuthRedirect`); an explicit Sign Out remembers nothing.\n */\n loginPath?: string\n /**\n * Show a `UserCard` (the user + Sign Out) at the bottom of the sidebar — passed to `RootLayout`. Unset, the\n * app-wide `config.sidebar.userCard` applies (default `false`, hidden).\n */\n showUserCard?: boolean\n /**\n * The sidebar's look, passed to `RootLayout` — `'floating'` or `'docked'` (flush to the edges). **Unset\n * (recommended)**, each user picks it in the header Settings drawer (saved), defaulting to the app-wide\n * `config.sidebar.variant` (`'floating'` when unset). **Set**, it pins the look and the drawer's Sidebar\n * section is hidden.\n */\n sidebarVariant?: RootLayoutProps['sidebarVariant']\n /**\n * Extra `RootLayout` header config, merged **over** the defaults (the app's fields win). Flows through\n * unchanged — e.g. **`header.menu`** (`HeaderMenuItem[]`) adds items to the account menu above Sign out.\n */\n header?: RootLayoutHeader\n /**\n * Wrap the page content in an `ErrorBoundary` (reset on navigation), so a crashing page shows an\n * `ErrorState` inside the shell instead of a white screen. Default `true`; `false` opts out; an object\n * configures it (e.g. `{ onError: Sentry.captureException }` or a custom `fallback`). It only catches what\n * the router doesn't: TanStack Router catches a route's component / `loader` / `beforeLoad` errors in its own\n * per-route boundary, so page crashes need `createRouter({ defaultErrorComponent: PageError })`.\n */\n errorBoundary?: boolean | Omit<ErrorBoundaryProps, 'children' | 'resetKeys'>\n /**\n * The one app-wide toast viewport AdminRoot mounts (the inner `RootLayout`'s is always off, so there's never a\n * second one). Unset / `true` → `<Toaster />`, following the app-wide `config.toast`; `ToasterProps`\n * (`{ position, duration }`) → this shell's override, anything unset still falls back to `config.toast`;\n * `false` → no viewport (e.g. the app mounts its own `<Toaster>`). Same shape as `RootLayout`'s `toaster`.\n */\n toaster?: boolean | ToasterProps\n /**\n * The app is still finding out who is signed in (e.g. verifying a stored token or refreshing a cookie\n * session). While `true`, AdminRoot renders only `pendingFallback` — no shell, no public page, no\n * `AuthGuard`, and `getUser()` isn't read — so a signed-in admin is never redirected to sign-in before the\n * check resolves. Route `beforeLoad` guards (e.g. `authLayoutRoute`) still run in the router, independent\n * of this — they must tolerate the unknown state themselves. No minimum display time. Default `false`.\n */\n pending?: boolean\n /** What to show while `pending`. Default: a `Loader size=\"lg\"` centred in the full viewport. */\n pendingFallback?: ReactNode\n /**\n * The session could not be checked, or the server will not serve this account here. While set, AdminRoot\n * renders a standalone `AuthLayout` screen (the app's `logo`, a `QueryError`, Try Again / Sign Out) instead\n * of the shell or a public page — and never redirects. Sign Out calls `onLogout` then navigates to\n * `loginPath`, so **`onLogout` must clear whatever set `unavailable`** (or this screen shows again).\n * `pending` wins when both are set. `null` / `undefined` = not unavailable (the default).\n */\n unavailable?: AdminRootUnavailable | null\n /** Replaces the whole `unavailable` screen — for an app that needs its own wording or extra actions. */\n unavailableFallback?: (props: AdminRootUnavailableFallbackProps) => ReactNode\n}\n\n/**\n * Root-route component for admin apps — it wires up the whole shell orchestration so an app only has to\n * supply `logo` + `getUser` + `onLogout`. Public pages (route id under `authRouteId`) render standalone;\n * everything else renders inside the guarded admin shell (`RootLayout`, with an optional sidebar `UserCard`), gated by\n * `AuthGuard` (signed-out visitors bounce to `loginPath?redirect=<the page>`, so a lost session or a shared\n * link returns there after sign-in — see `useAuthRedirect`). Sign Out clears the session and navigates to\n * plain `loginPath`, remembering nothing. Mounts exactly one app-wide `<Toaster/>` (`toaster`; none with `toaster={false}` — the inner\n * `RootLayout` always gets `toaster={false}`),\n * and wraps the page in an `ErrorBoundary` that resets on navigation (`errorBoundary`, default on).\n * While the app is still checking the session, pass `pending` (a full-screen loader instead of a premature\n * sign-in redirect); when the check failed or the server refuses this account, pass `unavailable` (a\n * standalone \"Cannot Reach the Server\" / \"No Access\" screen with Try Again / Sign Out). The `Toaster` stays\n * mounted in both.\n *\n * `loginPath` is a plain string, cast loosely to the router's `to` type (the library can't know the\n * app's typed route tree). The generic `<U>` preserves the app's own user type through `getUser`.\n *\n * @example\n * // routes/__root.tsx\n * export const Route = createRootRoute({\n * component: () => {\n * const { status, error, retry } = useSession()\n * return (\n * <AdminRoot<AuthUser>\n * pending={status === 'loading'}\n * unavailable={status === 'unavailable' ? { error, onRetry: retry } : null}\n * logo={<Logo />}\n * getUser={getUser}\n * onLogout={logout}\n * />\n * )\n * },\n * })\n */\nexport const AdminRoot = <U extends AdminUser = AdminUser>({\n logo,\n logoTo,\n getUser,\n onLogout,\n authRouteId = '/_auth',\n loginPath = '/login',\n showUserCard,\n sidebarVariant,\n header,\n errorBoundary = true,\n toaster = true,\n pending = false,\n pendingFallback,\n unavailable,\n unavailableFallback,\n}: AdminRootProps<U>) => {\n const t = useT()\n const navigate = useNavigate()\n const router = useRouter()\n const redirectQueryKey = useRedirectQueryKey()\n // the return-after-sign-in settings (known before any guard renders, e.g. on a cold /login?…) and its\n // safety check: never back onto the login page or a public auth page\n configureAuthRedirect({\n queryKey: redirectQueryKey,\n loginPath,\n isAuthPath: (path) =>\n router.getMatchedRoutes(path).matchedRoutes.some((r) => r.id.startsWith(authRouteId)),\n })\n // the single app-wide toast viewport (props → config.toast → built-in defaults, resolved inside Toaster)\n const toasterNode =\n toaster === false ? null : <Toaster {...(typeof toaster === 'object' ? toaster : undefined)} />\n const isAuthRoute = useRouterState({\n select: (s) => s.matches.some((m) => m.routeId.startsWith(authRouteId)),\n })\n const pathname = useRouterState({ select: (s) => s.location?.pathname })\n // an explicit Sign Out: the admin chose to leave, so nothing is remembered for the next sign-in\n const handleLogout = () => {\n beginSignOut()\n onLogout()\n void Promise.resolve(navigate({ to: loginPath as LinkProps['to'] })).finally(endSignOut)\n }\n\n // the session isn't known yet / can't be used — a standalone screen instead of the shell or a public\n // page (so no AuthGuard redirect, no sign-in flash). The Toaster stays, so a bootstrap toast isn't lost.\n if (pending || unavailable) {\n let gate: ReactNode\n if (pending) {\n gate = pendingFallback ?? (\n <div className={styles.pending} aria-busy=\"true\">\n <Loader size=\"lg\" />\n </div>\n )\n } else if (unavailable) {\n const reason: AdminRootUnavailableReason =\n unavailable.reason ??\n (getErrorStatus(unavailable.error) === 403 ? 'forbidden' : 'unreachable')\n if (unavailableFallback) {\n gate = unavailableFallback({\n error: unavailable.error,\n reason,\n retry: unavailable.onRetry,\n signOut: handleLogout,\n })\n } else {\n const retry = reason === 'unreachable' ? unavailable.onRetry : undefined\n const forbidden = reason === 'forbidden'\n gate = (\n <AuthLayout\n logo={logo}\n icon={unavailable.icon || undefined}\n color={unavailable.color ?? 'error'}\n title={t(forbidden ? 'adminRoot.noAccessTitle' : 'adminRoot.unreachableTitle')}\n subtitle={t(forbidden ? 'adminRoot.noAccessSubtitle' : 'adminRoot.unreachableSubtitle')}\n >\n <Col gap={16}>\n <QueryError variant=\"alert\" error={unavailable.error} />\n {retry ? (\n <Button fullWidth onClick={retry}>\n {t('errorState.retry')}\n </Button>\n ) : null}\n <Button fullWidth variant={retry ? 'filled' : 'contained'} onClick={handleLogout}>\n {t('userCard.signOut')}\n </Button>\n </Col>\n </AuthLayout>\n )\n }\n }\n return (\n <>\n {gate}\n {toasterNode}\n </>\n )\n }\n\n const user = getUser()\n // the routed page, inside an ErrorBoundary that resets whenever the path changes\n const page =\n errorBoundary === false ? (\n <Outlet />\n ) : (\n <ErrorBoundary {...(errorBoundary === true ? {} : errorBoundary)} resetKeys={[pathname]}>\n <Outlet />\n </ErrorBoundary>\n )\n const content = isAuthRoute ? (\n page\n ) : (\n <AuthGuard isAuthenticated={user != null} redirectTo={loginPath}>\n <RootLayout\n logo={logo}\n logoTo={logoTo}\n sidebarVariant={sidebarVariant}\n toaster={false}\n header={{\n user: user ? { name: user.name, email: user.email, avatar: user.avatar } : undefined,\n onLogout: handleLogout,\n ...header,\n }}\n showUserCard={showUserCard}\n >\n {page}\n </RootLayout>\n </AuthGuard>\n )\n return (\n <>\n {content}\n {toasterNode}\n </>\n )\n}\n"],"names":["AdminRoot","logo","logoTo","getUser","onLogout","authRouteId","loginPath","showUserCard","sidebarVariant","header","errorBoundary","toaster","pending","pendingFallback","unavailable","unavailableFallback","t","useT","navigate","useNavigate","router","useRouter","redirectQueryKey","useRedirectQueryKey","configureAuthRedirect","path","r","toasterNode","jsx","Toaster","isAuthRoute","useRouterState","s","m","pathname","_a","handleLogout","beginSignOut","endSignOut","gate","styles","Loader","reason","getErrorStatus","retry","forbidden","AuthLayout","jsxs","Col","QueryError","Button","Fragment","user","page","Outlet","ErrorBoundary","content","AuthGuard","RootLayout"],"mappings":"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"}
|
|
@@ -2,8 +2,8 @@ import { jsx as n, jsxs as N } from "react/jsx-runtime";
|
|
|
2
2
|
import { forwardRef as g } from "react";
|
|
3
3
|
import { clsx as p } from "clsx";
|
|
4
4
|
import { b as a, a as C } from "./Icon-B7DJn8Tw.js";
|
|
5
|
-
import { I } from "./IconButton-
|
|
6
|
-
import { a as x } from "./ConfigProvider-
|
|
5
|
+
import { I } from "./IconButton-iWbUJAz7.js";
|
|
6
|
+
import { a as x } from "./ConfigProvider-DtyUlWk6.js";
|
|
7
7
|
const b = "_alert_ujn1a_3", h = "_filled_ujn1a_19", v = "_contained_ujn1a_22", A = "_outlined_ujn1a_26", z = "_text_ujn1a_30", E = "_icon_ujn1a_35", T = "_message_ujn1a_44", w = "_action_ujn1a_50", y = "_close_ujn1a_57", t = {
|
|
8
8
|
alert: b,
|
|
9
9
|
filled: h,
|
|
@@ -67,4 +67,4 @@ const b = "_alert_ujn1a_3", h = "_filled_ujn1a_19", v = "_contained_ujn1a_22", A
|
|
|
67
67
|
export {
|
|
68
68
|
R as A
|
|
69
69
|
};
|
|
70
|
-
//# sourceMappingURL=Alert-
|
|
70
|
+
//# sourceMappingURL=Alert-Bo_XgY-A.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Alert-
|
|
1
|
+
{"version":3,"file":"Alert-Bo_XgY-A.js","sources":["../src/components/Alert/Alert.tsx"],"sourcesContent":["import { forwardRef, type CSSProperties, type HTMLAttributes, type ReactNode } from 'react'\nimport { clsx } from 'clsx'\nimport { Icon } from '../Icon'\nimport { IconButton } from '../IconButton'\nimport { ICON_NAMES, type IconName } from '../../icons/names'\nimport { useT, type ThemeColor } from '../../theme'\nimport styles from './Alert.module.css'\n\nexport type AlertVariant = 'contained' | 'filled' | 'outlined' | 'text'\n\nconst ICON_NAME_SET = new Set<string>(ICON_NAMES)\n\n/** Default leading icon per semantic color (other colors fall back to `InfoCircle`). */\nconst DEFAULT_ICON: Partial<Record<ThemeColor, IconName>> = {\n success: 'TickCircle',\n error: 'CloseCircle',\n warning: 'Warning',\n info: 'InfoCircle',\n}\n\nexport interface AlertProps extends Omit<HTMLAttributes<HTMLDivElement>, 'color' | 'title'> {\n /** Tint style. Defaults to `filled` (the soft tint). */\n variant?: AlertVariant\n /** Brand / semantic palette token that tints the alert. Defaults to `info`. */\n color?: ThemeColor\n /**\n * Leading icon — a known `IconName`, any node, or `false` to hide it. Defaults to the semantic icon\n * for `color` (success → `TickCircle`, error → `CloseCircle`, warning → `Warning`, info → `InfoCircle`).\n */\n icon?: IconName | ReactNode | false\n /** Trailing action (e.g. an `UNDO` button), placed before the close button. */\n action?: ReactNode\n /** When provided, a trailing × close button appears that calls this. */\n onClose?: () => void\n /** Accessible label for the close button. Defaults to the localized \"Close\" (`common.close`). */\n closeLabel?: string\n /** Alert message. */\n children?: ReactNode\n}\n\n/**\n * A message banner — the library's inline feedback surface (info, success, warning, error). Tinted by\n * `color` via the shared `--tz-btn-rgb` pattern across the 4 standard `variant`s; a semantic leading\n * `icon` is auto-picked per color (override with `icon`, or `icon={false}` to drop it). An optional\n * `action` slot (e.g. an `UNDO` button) and an `onClose` × button trail the message. `role=\"alert\"`.\n */\nexport const Alert = forwardRef<HTMLDivElement, AlertProps>(function Alert(\n {\n variant = 'filled',\n color = 'info',\n icon,\n action,\n onClose,\n closeLabel,\n className,\n style,\n children,\n ...props\n },\n ref,\n) {\n const t = useT()\n const renderedIcon =\n icon === false ? null : icon == null ? (\n <Icon name={DEFAULT_ICON[color] ?? 'InfoCircle'} />\n ) : typeof icon === 'string' && ICON_NAME_SET.has(icon) ? (\n <Icon name={icon as IconName} />\n ) : (\n icon\n )\n\n return (\n <div\n ref={ref}\n role=\"alert\"\n className={clsx(styles.alert, styles[variant], className)}\n style={\n {\n '--tz-btn-rgb': `var(--tz-color-${color}-rgb)`,\n '--tz-btn-on': `var(--tz-color-${color}-contrast, #fff)`,\n ...style,\n } as CSSProperties\n }\n {...props}\n >\n {renderedIcon != null && (\n <span className={styles.icon} aria-hidden>\n {renderedIcon}\n </span>\n )}\n <div className={styles.message}>{children}</div>\n {action != null && <div className={styles.action}>{action}</div>}\n {onClose && (\n <IconButton\n variant=\"text\"\n color={color}\n size=\"sm\"\n className={styles.close}\n aria-label={closeLabel ?? t('common.close')}\n onClick={onClose}\n >\n <Icon name=\"Close\" />\n </IconButton>\n )}\n </div>\n )\n})\n"],"names":["ICON_NAME_SET","ICON_NAMES","DEFAULT_ICON","Alert","forwardRef","variant","color","icon","action","onClose","closeLabel","className","style","children","props","ref","t","useT","renderedIcon","jsx","Icon","jsxs","clsx","styles","IconButton"],"mappings":";;;;;;;;;;;;;;;;GAUMA,IAAgB,IAAI,IAAYC,CAAU,GAG1CC,IAAsD;AAAA,EAC1D,SAAS;AAAA,EACT,OAAO;AAAA,EACP,SAAS;AAAA,EACT,MAAM;AACR,GA4BaC,IAAQC,EAAuC,SAC1D;AAAA,EACE,SAAAC,IAAU;AAAA,EACV,OAAAC,IAAQ;AAAA,EACR,MAAAC;AAAA,EACA,QAAAC;AAAA,EACA,SAAAC;AAAA,EACA,YAAAC;AAAA,EACA,WAAAC;AAAA,EACA,OAAAC;AAAA,EACA,UAAAC;AAAA,EACA,GAAGC;AACL,GACAC,GACA;AACA,QAAMC,IAAIC,EAAA,GACJC,IACJX,MAAS,KAAQ,OAAOA,KAAQ,OAC9B,gBAAAY,EAACC,GAAA,EAAK,MAAMlB,EAAaI,CAAK,KAAK,cAAc,IAC/C,OAAOC,KAAS,YAAYP,EAAc,IAAIO,CAAI,IACpD,gBAAAY,EAACC,GAAA,EAAK,MAAMb,EAAA,CAAkB,IAE9BA;AAGJ,SACE,gBAAAc;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAAN;AAAA,MACA,MAAK;AAAA,MACL,WAAWO,EAAKC,EAAO,OAAOA,EAAOlB,CAAO,GAAGM,CAAS;AAAA,MACxD,OACE;AAAA,QACE,gBAAgB,kBAAkBL,CAAK;AAAA,QACvC,eAAe,kBAAkBA,CAAK;AAAA,QACtC,GAAGM;AAAA,MAAA;AAAA,MAGN,GAAGE;AAAA,MAEH,UAAA;AAAA,QAAAI,KAAgB,0BACd,QAAA,EAAK,WAAWK,EAAO,MAAM,eAAW,IACtC,UAAAL,EAAA,CACH;AAAA,QAEF,gBAAAC,EAAC,OAAA,EAAI,WAAWI,EAAO,SAAU,UAAAV,GAAS;AAAA,QACzCL,KAAU,QAAQ,gBAAAW,EAAC,SAAI,WAAWI,EAAO,QAAS,UAAAf,GAAO;AAAA,QACzDC,KACC,gBAAAU;AAAA,UAACK;AAAA,UAAA;AAAA,YACC,SAAQ;AAAA,YACR,OAAAlB;AAAA,YACA,MAAK;AAAA,YACL,WAAWiB,EAAO;AAAA,YAClB,cAAYb,KAAcM,EAAE,cAAc;AAAA,YAC1C,SAASP;AAAA,YAET,UAAA,gBAAAU,EAACC,GAAA,EAAK,MAAK,QAAA,CAAQ;AAAA,UAAA;AAAA,QAAA;AAAA,MACrB;AAAA,IAAA;AAAA,EAAA;AAIR,CAAC;"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";const e=require("react/jsx-runtime"),x=require("react"),I=require("clsx"),c=require("./Icon-CBg21lKA.cjs"),g=require("./IconButton-
|
|
2
|
-
//# sourceMappingURL=Alert-
|
|
1
|
+
"use strict";const e=require("react/jsx-runtime"),x=require("react"),I=require("clsx"),c=require("./Icon-CBg21lKA.cjs"),g=require("./IconButton-DSPdv-oI.cjs"),C=require("./ConfigProvider-CYSpuSMJ.cjs"),N="_alert_ujn1a_3",v="_filled_ujn1a_19",h="_contained_ujn1a_22",q="_outlined_ujn1a_26",A="_text_ujn1a_30",b="_icon_ujn1a_35",z="_message_ujn1a_44",E="_action_ujn1a_50",T="_close_ujn1a_57",s={alert:N,filled:v,contained:h,outlined:q,text:A,icon:b,message:z,action:E,close:T},w=new Set(c.ICON_NAMES),y={success:"TickCircle",error:"CloseCircle",warning:"Warning",info:"InfoCircle"},O=x.forwardRef(function({variant:r="filled",color:t="info",icon:n,action:o,onClose:a,closeLabel:i,className:u,style:_,children:d,...j},f){const m=C.useT(),l=n===!1?null:n==null?e.jsx(c.Icon,{name:y[t]??"InfoCircle"}):typeof n=="string"&&w.has(n)?e.jsx(c.Icon,{name:n}):n;return e.jsxs("div",{ref:f,role:"alert",className:I.clsx(s.alert,s[r],u),style:{"--tz-btn-rgb":`var(--tz-color-${t}-rgb)`,"--tz-btn-on":`var(--tz-color-${t}-contrast, #fff)`,..._},...j,children:[l!=null&&e.jsx("span",{className:s.icon,"aria-hidden":!0,children:l}),e.jsx("div",{className:s.message,children:d}),o!=null&&e.jsx("div",{className:s.action,children:o}),a&&e.jsx(g.IconButton,{variant:"text",color:t,size:"sm",className:s.close,"aria-label":i??m("common.close"),onClick:a,children:e.jsx(c.Icon,{name:"Close"})})]})});exports.Alert=O;
|
|
2
|
+
//# sourceMappingURL=Alert-QvfNBhlU.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Alert-
|
|
1
|
+
{"version":3,"file":"Alert-QvfNBhlU.cjs","sources":["../src/components/Alert/Alert.tsx"],"sourcesContent":["import { forwardRef, type CSSProperties, type HTMLAttributes, type ReactNode } from 'react'\nimport { clsx } from 'clsx'\nimport { Icon } from '../Icon'\nimport { IconButton } from '../IconButton'\nimport { ICON_NAMES, type IconName } from '../../icons/names'\nimport { useT, type ThemeColor } from '../../theme'\nimport styles from './Alert.module.css'\n\nexport type AlertVariant = 'contained' | 'filled' | 'outlined' | 'text'\n\nconst ICON_NAME_SET = new Set<string>(ICON_NAMES)\n\n/** Default leading icon per semantic color (other colors fall back to `InfoCircle`). */\nconst DEFAULT_ICON: Partial<Record<ThemeColor, IconName>> = {\n success: 'TickCircle',\n error: 'CloseCircle',\n warning: 'Warning',\n info: 'InfoCircle',\n}\n\nexport interface AlertProps extends Omit<HTMLAttributes<HTMLDivElement>, 'color' | 'title'> {\n /** Tint style. Defaults to `filled` (the soft tint). */\n variant?: AlertVariant\n /** Brand / semantic palette token that tints the alert. Defaults to `info`. */\n color?: ThemeColor\n /**\n * Leading icon — a known `IconName`, any node, or `false` to hide it. Defaults to the semantic icon\n * for `color` (success → `TickCircle`, error → `CloseCircle`, warning → `Warning`, info → `InfoCircle`).\n */\n icon?: IconName | ReactNode | false\n /** Trailing action (e.g. an `UNDO` button), placed before the close button. */\n action?: ReactNode\n /** When provided, a trailing × close button appears that calls this. */\n onClose?: () => void\n /** Accessible label for the close button. Defaults to the localized \"Close\" (`common.close`). */\n closeLabel?: string\n /** Alert message. */\n children?: ReactNode\n}\n\n/**\n * A message banner — the library's inline feedback surface (info, success, warning, error). Tinted by\n * `color` via the shared `--tz-btn-rgb` pattern across the 4 standard `variant`s; a semantic leading\n * `icon` is auto-picked per color (override with `icon`, or `icon={false}` to drop it). An optional\n * `action` slot (e.g. an `UNDO` button) and an `onClose` × button trail the message. `role=\"alert\"`.\n */\nexport const Alert = forwardRef<HTMLDivElement, AlertProps>(function Alert(\n {\n variant = 'filled',\n color = 'info',\n icon,\n action,\n onClose,\n closeLabel,\n className,\n style,\n children,\n ...props\n },\n ref,\n) {\n const t = useT()\n const renderedIcon =\n icon === false ? null : icon == null ? (\n <Icon name={DEFAULT_ICON[color] ?? 'InfoCircle'} />\n ) : typeof icon === 'string' && ICON_NAME_SET.has(icon) ? (\n <Icon name={icon as IconName} />\n ) : (\n icon\n )\n\n return (\n <div\n ref={ref}\n role=\"alert\"\n className={clsx(styles.alert, styles[variant], className)}\n style={\n {\n '--tz-btn-rgb': `var(--tz-color-${color}-rgb)`,\n '--tz-btn-on': `var(--tz-color-${color}-contrast, #fff)`,\n ...style,\n } as CSSProperties\n }\n {...props}\n >\n {renderedIcon != null && (\n <span className={styles.icon} aria-hidden>\n {renderedIcon}\n </span>\n )}\n <div className={styles.message}>{children}</div>\n {action != null && <div className={styles.action}>{action}</div>}\n {onClose && (\n <IconButton\n variant=\"text\"\n color={color}\n size=\"sm\"\n className={styles.close}\n aria-label={closeLabel ?? t('common.close')}\n onClick={onClose}\n >\n <Icon name=\"Close\" />\n </IconButton>\n )}\n </div>\n )\n})\n"],"names":["ICON_NAME_SET","ICON_NAMES","DEFAULT_ICON","Alert","forwardRef","variant","color","icon","action","onClose","closeLabel","className","style","children","props","ref","t","useT","renderedIcon","jsx","Icon","jsxs","clsx","styles","IconButton"],"mappings":"2dAUMA,EAAgB,IAAI,IAAYC,YAAU,EAG1CC,EAAsD,CAC1D,QAAS,aACT,MAAO,cACP,QAAS,UACT,KAAM,YACR,EA4BaC,EAAQC,EAAAA,WAAuC,SAC1D,CACE,QAAAC,EAAU,SACV,MAAAC,EAAQ,OACR,KAAAC,EACA,OAAAC,EACA,QAAAC,EACA,WAAAC,EACA,UAAAC,EACA,MAAAC,EACA,SAAAC,EACA,GAAGC,CACL,EACAC,EACA,CACA,MAAMC,EAAIC,EAAAA,KAAA,EACJC,EACJX,IAAS,GAAQ,KAAOA,GAAQ,KAC9BY,EAAAA,IAACC,EAAAA,KAAA,CAAK,KAAMlB,EAAaI,CAAK,GAAK,aAAc,EAC/C,OAAOC,GAAS,UAAYP,EAAc,IAAIO,CAAI,EACpDY,EAAAA,IAACC,EAAAA,KAAA,CAAK,KAAMb,CAAA,CAAkB,EAE9BA,EAGJ,OACEc,EAAAA,KAAC,MAAA,CACC,IAAAN,EACA,KAAK,QACL,UAAWO,EAAAA,KAAKC,EAAO,MAAOA,EAAOlB,CAAO,EAAGM,CAAS,EACxD,MACE,CACE,eAAgB,kBAAkBL,CAAK,QACvC,cAAe,kBAAkBA,CAAK,mBACtC,GAAGM,CAAA,EAGN,GAAGE,EAEH,SAAA,CAAAI,GAAgB,YACd,OAAA,CAAK,UAAWK,EAAO,KAAM,cAAW,GACtC,SAAAL,CAAA,CACH,EAEFC,EAAAA,IAAC,MAAA,CAAI,UAAWI,EAAO,QAAU,SAAAV,EAAS,EACzCL,GAAU,MAAQW,EAAAA,IAAC,OAAI,UAAWI,EAAO,OAAS,SAAAf,EAAO,EACzDC,GACCU,EAAAA,IAACK,EAAAA,WAAA,CACC,QAAQ,OACR,MAAAlB,EACA,KAAK,KACL,UAAWiB,EAAO,MAClB,aAAYb,GAAcM,EAAE,cAAc,EAC1C,QAASP,EAET,SAAAU,EAAAA,IAACC,EAAAA,KAAA,CAAK,KAAK,OAAA,CAAQ,CAAA,CAAA,CACrB,CAAA,CAAA,CAIR,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";const l=require("react/jsx-runtime"),h=require("@tanstack/react-router"),a=require("react"),d=require("./ConfigProvider-CYSpuSMJ.cjs"),S=2048;let c=null,s=!1;const o={queryKey:d.DEFAULT_REDIRECT_QUERY_KEY,loginPath:"/login",isAuthPath:null};function g(t){Object.assign(o,t)}const R=()=>typeof window<"u",$=()=>typeof window>"u"?"http://localhost":window.location.origin,q=(t,e)=>{const n=e.length>1?e.replace(/\/+$/,""):e;return t===n||t.startsWith(`${n}/`)};function O(t,{loginPath:e,isAuthPath:n,origin:u=$()}){if(typeof t!="string"||t.length===0||t.length>S||!t.startsWith("/")||t.startsWith("//")||t.startsWith("/\\"))return null;let r;try{r=new URL(t,u)}catch{return null}if(r.origin!==u||r.pathname.startsWith("//")||q(r.pathname,e))return null;try{if(n!=null&&n(r.pathname))return null}catch{}return`${r.pathname}${r.search}${r.hash}`}const f=t=>O(t,{loginPath:o.loginPath,isAuthPath:o.isAuthPath}),K=(t,e)=>{try{return new URLSearchParams(t).get(e)}catch{return null}};function y(t,e="/",n=o.queryKey){return f(K(t,n))??(R()?f(c):null)??e}function U(t){if(s||!R())return null;const e=f(t);return!e||e==="/"?null:(c=e,e)}function _(){c=null,s=R()}function P(){s=!1}function W(){c=null,s=!1}function b(t="/"){return y(typeof window>"u"?"":window.location.search,t)}function j(t="/"){const e=d.useRedirectQueryKey(),n=h.useRouterState({select:u=>u.location.searchStr});return g({queryKey:e}),y(n,t,e)}function C(){c=null}const L=({isAuthenticated:t,redirectTo:e="/login",children:n})=>{const u=typeof t=="function"?t():t,r=d.useRedirectQueryKey(),A=h.useRouter();g({queryKey:r,loginPath:e});const i=a.useRef(void 0);if(u)i.current=void 0;else if(i.current===void 0){const{pathname:w,searchStr:E,hash:m}=A.state.location;i.current=U(`${w}${E}${m?`#${m}`:""}`)}const p=a.useMemo(()=>u?null:l.jsx(h.Navigate,{to:e,search:i.current?{[r]:i.current}:{},replace:!0}),[u,e,r]);return a.useEffect(()=>{u&&W()},[u]),u?l.jsx(l.Fragment,{children:n}):p};exports.AuthGuard=L;exports.beginSignOut=_;exports.clearAuthRedirect=C;exports.configureAuthRedirect=g;exports.endSignOut=P;exports.getAuthRedirect=b;exports.resolveAuthRedirect=y;exports.useAuthRedirect=j;
|
|
2
|
+
//# sourceMappingURL=AuthGuard-CAaQZ2y7.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthGuard-CAaQZ2y7.cjs","sources":["../src/auth/authRedirect.ts","../src/auth/AuthGuard.tsx"],"sourcesContent":["// Return-after-sign-in: where `AuthGuard` sent a signed-out visitor away from, read back once they've\n// signed in. The target travels in the login URL (`?redirect=…`) and, for a multi-step sign-in that moves\n// between auth routes and drops the query string, in a module-level slot for this tab. Memory only — a\n// path can carry record ids, so it never goes to localStorage / sessionStorage.\nimport { useRouterState } from '@tanstack/react-router'\nimport { DEFAULT_REDIRECT_QUERY_KEY, useRedirectQueryKey } from '../theme/ConfigProvider'\n\n/** The longest target accepted (characters) — anything longer is treated as crafted. */\nexport const AUTH_REDIRECT_MAX_LENGTH = 2048\n\n/** What the safety check needs to know about the app's sign-in pages. */\nexport interface AuthRedirectContext {\n /** The sign-in page — the target may not be it, or a step under it (`/login/mfa`). */\n loginPath: string\n /** Whether a path belongs to a public auth page (under `authRouteId`) — registered by `AdminRoot`. */\n isAuthPath?: ((pathname: string) => boolean) | null\n /** The origin a target must stay on. Defaults to `window.location.origin`. */\n origin?: string\n}\n\n// The tab's state. `settings` is what the guard / shell last told us (the configured param name, the\n// login path, the auth-page matcher), so `getAuthRedirect` works outside React with no arguments.\nlet remembered: string | null = null\nlet signingOut = false\nconst settings: Required<Omit<AuthRedirectContext, 'origin'>> & { queryKey: string } = {\n queryKey: DEFAULT_REDIRECT_QUERY_KEY,\n loginPath: '/login',\n isAuthPath: null,\n}\n\n/** @internal Update what the module knows about the app (called by `AuthGuard` / `AdminRoot` / the hook). */\nexport function configureAuthRedirect(next: Partial<typeof settings>) {\n Object.assign(settings, next)\n}\n\n// the memory slot is per browser tab — on a server it would be shared between visitors, so it's off there\nconst isBrowser = () => typeof window !== 'undefined'\n\nconst currentOrigin = () =>\n typeof window === 'undefined' ? 'http://localhost' : window.location.origin\n\nconst isUnder = (pathname: string, base: string) => {\n const b = base.length > 1 ? base.replace(/\\/+$/, '') : base\n return pathname === b || pathname.startsWith(`${b}/`)\n}\n\n/**\n * The target, normalized to `pathname + search + hash`, when it's safe to navigate to — else `null`.\n * Safe = a string of at most `AUTH_REDIRECT_MAX_LENGTH` characters, starting with a single `/`, that\n * resolves to the same origin (rejects `https://evil.example`, `//evil.example`, `/\\evil.example`,\n * `javascript:…`), and isn't the login path, a step under it, or a public auth page.\n */\nexport function safeAuthRedirect(\n value: unknown,\n { loginPath, isAuthPath, origin = currentOrigin() }: AuthRedirectContext,\n): string | null {\n if (typeof value !== 'string' || value.length === 0 || value.length > AUTH_REDIRECT_MAX_LENGTH)\n return null\n if (!value.startsWith('/') || value.startsWith('//') || value.startsWith('/\\\\')) return null\n let url: URL\n try {\n url = new URL(value, origin)\n } catch {\n return null\n }\n // the parser drops tabs / newlines, so `/\\t/evil.example` only shows its real origin here\n if (url.origin !== origin) return null\n // …and collapses `/./`, `%2e` and `\\` — `/.//evil.example` normalizes to `//evil.example`\n if (url.pathname.startsWith('//')) return null\n if (isUnder(url.pathname, loginPath)) return null\n try {\n if (isAuthPath?.(url.pathname)) return null\n } catch {\n // an unmatchable path isn't an auth page\n }\n return `${url.pathname}${url.search}${url.hash}`\n}\n\n/** The safety check with the module's current settings. */\nconst safe = (value: unknown) =>\n safeAuthRedirect(value, { loginPath: settings.loginPath, isAuthPath: settings.isAuthPath })\n\n/** Read a param out of a raw search string (`?a=1&b=2`). */\nconst paramOf = (searchStr: string, key: string) => {\n try {\n return new URLSearchParams(searchStr).get(key)\n } catch {\n return null\n }\n}\n\n/** @internal The target for a search string: its param, else the remembered one, else `fallback`. */\nexport function resolveAuthRedirect(\n searchStr: string,\n fallback = '/',\n queryKey = settings.queryKey,\n) {\n return safe(paramOf(searchStr, queryKey)) ?? (isBrowser() ? safe(remembered) : null) ?? fallback\n}\n\n/**\n * @internal Remember a target for this tab — returns it (normalized) when it's worth remembering, `null`\n * otherwise (unsafe, `/`, the login path, or an explicit Sign Out is under way).\n */\nexport function rememberAuthRedirect(target: string): string | null {\n if (signingOut || !isBrowser()) return null\n const value = safe(target)\n if (!value || value === '/') return null\n remembered = value\n return value\n}\n\n/**\n * @internal An explicit Sign Out: forget the target and remember nothing until `endSignOut` (once the\n * navigation to the login page has settled) or the next sign-in.\n */\nexport function beginSignOut() {\n remembered = null\n signingOut = isBrowser()\n}\n\n/** @internal The Sign Out navigation settled — later guard redirects remember their page again. */\nexport function endSignOut() {\n signingOut = false\n}\n\n/** @internal Signed in (the guard rendered its content): the target is spent, Sign Out is over. */\nexport function authRedirectConsumed() {\n remembered = null\n signingOut = false\n}\n\n/**\n * Where to go after a successful sign-in, outside React (a route `beforeLoad`, a mutation's `onSuccess`):\n * the `?redirect=` param of `window.location` if it's safe, else the target remembered in this tab, else\n * `fallback` (default `'/'`). The param name follows `config.keys.redirectQueryKey` once the guard, the\n * shell or `useAuthRedirect` has rendered.\n */\nexport function getAuthRedirect(fallback = '/'): string {\n return resolveAuthRedirect(typeof window === 'undefined' ? '' : window.location.search, fallback)\n}\n\n/**\n * Where to go after a successful sign-in: the `?redirect=` param of the router's location if it's safe,\n * else the target remembered in this tab, else `fallback` (default `'/'`). Pure — it doesn't clear\n * anything; the target is forgotten once `AuthGuard` renders signed-in content (or `clearAuthRedirect`).\n *\n * @example\n * const to = useAuthRedirect('/')\n * if (status === 'authenticated') return <Navigate to={to} replace />\n */\nexport function useAuthRedirect(fallback = '/'): string {\n const queryKey = useRedirectQueryKey()\n const searchStr = useRouterState({ select: (s) => s.location.searchStr })\n configureAuthRedirect({ queryKey })\n return resolveAuthRedirect(searchStr, fallback, queryKey)\n}\n\n/**\n * Forget the remembered target. `AuthGuard` already does this once it renders signed-in content, so a\n * later sign-in in the same tab doesn't reuse it — call it yourself only when you navigate elsewhere.\n */\nexport function clearAuthRedirect(): void {\n remembered = null\n}\n\n/** @internal Test-only: back to a fresh tab. */\nexport function resetAuthRedirect() {\n remembered = null\n signingOut = false\n Object.assign(settings, {\n queryKey: DEFAULT_REDIRECT_QUERY_KEY,\n loginPath: '/login',\n isAuthPath: null,\n })\n}\n","import { Navigate, useRouter, type LinkProps } from '@tanstack/react-router'\nimport { useEffect, useMemo, useRef, type ReactNode } from 'react'\nimport { useRedirectQueryKey } from '../theme/ConfigProvider'\nimport { authRedirectConsumed, configureAuthRedirect, rememberAuthRedirect } from './authRedirect'\n\nexport interface AuthGuardProps {\n /** Session check — a boolean, or a function that returns one (evaluated on render). */\n isAuthenticated: boolean | (() => boolean)\n /** Where to send an unauthenticated visitor. Defaults to `'/login'`. */\n redirectTo?: string\n /** The protected content, rendered only when authenticated. */\n children: ReactNode\n}\n\n/**\n * Component-level auth guard: renders `children` only when authenticated, otherwise redirects to\n * `redirectTo` via `<Navigate replace>` (so Back from the login page doesn't bounce off the guard).\n *\n * The redirect **remembers the page**: it adds `?redirect=<path + search + hash>` to the login URL (the\n * param name follows `config.keys.redirectQueryKey`) and keeps the same target in memory for this tab, so\n * a multi-step sign-in that drops the query string still knows it. Read it back after sign-in with\n * `useAuthRedirect` / `getAuthRedirect`. Nothing is remembered from `/`, from the login path itself, or\n * during an explicit Sign Out (`AdminRoot`'s). Once it renders signed-in content, the target is forgotten.\n *\n * Requires a `@tanstack/react-router` context (it renders `<Navigate>`), so use it inside a routed\n * tree. `redirectTo` is a plain string — the library can't know the app's typed route tree, so it's\n * cast loosely to the router's `to` type.\n *\n * @example\n * <AuthGuard isAuthenticated={session.isAuthenticated} redirectTo=\"/login\">\n * <Dashboard />\n * </AuthGuard>\n */\nexport const AuthGuard = ({ isAuthenticated, redirectTo = '/login', children }: AuthGuardProps) => {\n const ok = typeof isAuthenticated === 'function' ? isAuthenticated() : isAuthenticated\n const queryKey = useRedirectQueryKey()\n const router = useRouter()\n configureAuthRedirect({ queryKey, loginPath: redirectTo })\n // The target is taken once, when the guard first turns the visitor away, and read without subscribing:\n // the router moves its location to the login URL before the login page mounts, so a later render here\n // would read that instead (and a `<Navigate>` whose props change navigates again).\n const target = useRef<string | null | undefined>(undefined)\n if (ok) target.current = undefined\n else if (target.current === undefined) {\n const { pathname, searchStr, hash } = router.state.location\n target.current = rememberAuthRedirect(`${pathname}${searchStr}${hash ? `#${hash}` : ''}`)\n }\n const redirect = useMemo(\n () =>\n ok ? null : (\n <Navigate\n to={redirectTo as LinkProps['to']}\n search={(target.current ? { [queryKey]: target.current } : {}) as LinkProps['search']}\n replace\n />\n ),\n [ok, redirectTo, queryKey],\n )\n\n // signed in: a remembered target is spent (and a Sign Out is over) — idempotent, so StrictMode is fine\n useEffect(() => {\n if (ok) authRedirectConsumed()\n }, [ok])\n\n return ok ? <>{children}</> : redirect\n}\n"],"names":["AUTH_REDIRECT_MAX_LENGTH","remembered","signingOut","settings","DEFAULT_REDIRECT_QUERY_KEY","configureAuthRedirect","next","isBrowser","currentOrigin","isUnder","pathname","base","b","safeAuthRedirect","value","loginPath","isAuthPath","origin","url","safe","paramOf","searchStr","key","resolveAuthRedirect","fallback","queryKey","rememberAuthRedirect","target","beginSignOut","endSignOut","authRedirectConsumed","getAuthRedirect","useAuthRedirect","useRedirectQueryKey","useRouterState","s","clearAuthRedirect","AuthGuard","isAuthenticated","redirectTo","children","ok","router","useRouter","useRef","hash","redirect","useMemo","jsx","Navigate","useEffect","Fragment"],"mappings":"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"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { jsx as h, Fragment as A } from "react/jsx-runtime";
|
|
2
|
+
import { useRouterState as E, useRouter as $, Navigate as S } from "@tanstack/react-router";
|
|
3
|
+
import { useRef as K, useMemo as O, useEffect as U } from "react";
|
|
4
|
+
import { d as _, m as d } from "./ConfigProvider-DtyUlWk6.js";
|
|
5
|
+
const W = 2048;
|
|
6
|
+
let i = null, c = !1;
|
|
7
|
+
const s = {
|
|
8
|
+
queryKey: _,
|
|
9
|
+
loginPath: "/login",
|
|
10
|
+
isAuthPath: null
|
|
11
|
+
};
|
|
12
|
+
function g(t) {
|
|
13
|
+
Object.assign(s, t);
|
|
14
|
+
}
|
|
15
|
+
const a = () => typeof window < "u", b = () => typeof window > "u" ? "http://localhost" : window.location.origin, q = (t, n) => {
|
|
16
|
+
const e = n.length > 1 ? n.replace(/\/+$/, "") : n;
|
|
17
|
+
return t === e || t.startsWith(`${e}/`);
|
|
18
|
+
};
|
|
19
|
+
function L(t, { loginPath: n, isAuthPath: e, origin: u = b() }) {
|
|
20
|
+
if (typeof t != "string" || t.length === 0 || t.length > W || !t.startsWith("/") || t.startsWith("//") || t.startsWith("/\\")) return null;
|
|
21
|
+
let r;
|
|
22
|
+
try {
|
|
23
|
+
r = new URL(t, u);
|
|
24
|
+
} catch {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
if (r.origin !== u || r.pathname.startsWith("//") || q(r.pathname, n)) return null;
|
|
28
|
+
try {
|
|
29
|
+
if (e != null && e(r.pathname)) return null;
|
|
30
|
+
} catch {
|
|
31
|
+
}
|
|
32
|
+
return `${r.pathname}${r.search}${r.hash}`;
|
|
33
|
+
}
|
|
34
|
+
const l = (t) => L(t, { loginPath: s.loginPath, isAuthPath: s.isAuthPath }), P = (t, n) => {
|
|
35
|
+
try {
|
|
36
|
+
return new URLSearchParams(t).get(n);
|
|
37
|
+
} catch {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
function m(t, n = "/", e = s.queryKey) {
|
|
42
|
+
return l(P(t, e)) ?? (a() ? l(i) : null) ?? n;
|
|
43
|
+
}
|
|
44
|
+
function C(t) {
|
|
45
|
+
if (c || !a()) return null;
|
|
46
|
+
const n = l(t);
|
|
47
|
+
return !n || n === "/" ? null : (i = n, n);
|
|
48
|
+
}
|
|
49
|
+
function G() {
|
|
50
|
+
i = null, c = a();
|
|
51
|
+
}
|
|
52
|
+
function H() {
|
|
53
|
+
c = !1;
|
|
54
|
+
}
|
|
55
|
+
function D() {
|
|
56
|
+
i = null, c = !1;
|
|
57
|
+
}
|
|
58
|
+
function I(t = "/") {
|
|
59
|
+
return m(typeof window > "u" ? "" : window.location.search, t);
|
|
60
|
+
}
|
|
61
|
+
function M(t = "/") {
|
|
62
|
+
const n = d(), e = E({ select: (u) => u.location.searchStr });
|
|
63
|
+
return g({ queryKey: n }), m(e, t, n);
|
|
64
|
+
}
|
|
65
|
+
function N() {
|
|
66
|
+
i = null;
|
|
67
|
+
}
|
|
68
|
+
const Q = ({ isAuthenticated: t, redirectTo: n = "/login", children: e }) => {
|
|
69
|
+
const u = typeof t == "function" ? t() : t, r = d(), R = $();
|
|
70
|
+
g({ queryKey: r, loginPath: n });
|
|
71
|
+
const o = K(void 0);
|
|
72
|
+
if (u) o.current = void 0;
|
|
73
|
+
else if (o.current === void 0) {
|
|
74
|
+
const { pathname: y, searchStr: w, hash: f } = R.state.location;
|
|
75
|
+
o.current = C(`${y}${w}${f ? `#${f}` : ""}`);
|
|
76
|
+
}
|
|
77
|
+
const p = O(
|
|
78
|
+
() => u ? null : /* @__PURE__ */ h(
|
|
79
|
+
S,
|
|
80
|
+
{
|
|
81
|
+
to: n,
|
|
82
|
+
search: o.current ? { [r]: o.current } : {},
|
|
83
|
+
replace: !0
|
|
84
|
+
}
|
|
85
|
+
),
|
|
86
|
+
[u, n, r]
|
|
87
|
+
);
|
|
88
|
+
return U(() => {
|
|
89
|
+
u && D();
|
|
90
|
+
}, [u]), u ? /* @__PURE__ */ h(A, { children: e }) : p;
|
|
91
|
+
};
|
|
92
|
+
export {
|
|
93
|
+
Q as A,
|
|
94
|
+
g as a,
|
|
95
|
+
G as b,
|
|
96
|
+
N as c,
|
|
97
|
+
H as e,
|
|
98
|
+
I as g,
|
|
99
|
+
m as r,
|
|
100
|
+
M as u
|
|
101
|
+
};
|
|
102
|
+
//# sourceMappingURL=AuthGuard-vqKf2PF9.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthGuard-vqKf2PF9.js","sources":["../src/auth/authRedirect.ts","../src/auth/AuthGuard.tsx"],"sourcesContent":["// Return-after-sign-in: where `AuthGuard` sent a signed-out visitor away from, read back once they've\n// signed in. The target travels in the login URL (`?redirect=…`) and, for a multi-step sign-in that moves\n// between auth routes and drops the query string, in a module-level slot for this tab. Memory only — a\n// path can carry record ids, so it never goes to localStorage / sessionStorage.\nimport { useRouterState } from '@tanstack/react-router'\nimport { DEFAULT_REDIRECT_QUERY_KEY, useRedirectQueryKey } from '../theme/ConfigProvider'\n\n/** The longest target accepted (characters) — anything longer is treated as crafted. */\nexport const AUTH_REDIRECT_MAX_LENGTH = 2048\n\n/** What the safety check needs to know about the app's sign-in pages. */\nexport interface AuthRedirectContext {\n /** The sign-in page — the target may not be it, or a step under it (`/login/mfa`). */\n loginPath: string\n /** Whether a path belongs to a public auth page (under `authRouteId`) — registered by `AdminRoot`. */\n isAuthPath?: ((pathname: string) => boolean) | null\n /** The origin a target must stay on. Defaults to `window.location.origin`. */\n origin?: string\n}\n\n// The tab's state. `settings` is what the guard / shell last told us (the configured param name, the\n// login path, the auth-page matcher), so `getAuthRedirect` works outside React with no arguments.\nlet remembered: string | null = null\nlet signingOut = false\nconst settings: Required<Omit<AuthRedirectContext, 'origin'>> & { queryKey: string } = {\n queryKey: DEFAULT_REDIRECT_QUERY_KEY,\n loginPath: '/login',\n isAuthPath: null,\n}\n\n/** @internal Update what the module knows about the app (called by `AuthGuard` / `AdminRoot` / the hook). */\nexport function configureAuthRedirect(next: Partial<typeof settings>) {\n Object.assign(settings, next)\n}\n\n// the memory slot is per browser tab — on a server it would be shared between visitors, so it's off there\nconst isBrowser = () => typeof window !== 'undefined'\n\nconst currentOrigin = () =>\n typeof window === 'undefined' ? 'http://localhost' : window.location.origin\n\nconst isUnder = (pathname: string, base: string) => {\n const b = base.length > 1 ? base.replace(/\\/+$/, '') : base\n return pathname === b || pathname.startsWith(`${b}/`)\n}\n\n/**\n * The target, normalized to `pathname + search + hash`, when it's safe to navigate to — else `null`.\n * Safe = a string of at most `AUTH_REDIRECT_MAX_LENGTH` characters, starting with a single `/`, that\n * resolves to the same origin (rejects `https://evil.example`, `//evil.example`, `/\\evil.example`,\n * `javascript:…`), and isn't the login path, a step under it, or a public auth page.\n */\nexport function safeAuthRedirect(\n value: unknown,\n { loginPath, isAuthPath, origin = currentOrigin() }: AuthRedirectContext,\n): string | null {\n if (typeof value !== 'string' || value.length === 0 || value.length > AUTH_REDIRECT_MAX_LENGTH)\n return null\n if (!value.startsWith('/') || value.startsWith('//') || value.startsWith('/\\\\')) return null\n let url: URL\n try {\n url = new URL(value, origin)\n } catch {\n return null\n }\n // the parser drops tabs / newlines, so `/\\t/evil.example` only shows its real origin here\n if (url.origin !== origin) return null\n // …and collapses `/./`, `%2e` and `\\` — `/.//evil.example` normalizes to `//evil.example`\n if (url.pathname.startsWith('//')) return null\n if (isUnder(url.pathname, loginPath)) return null\n try {\n if (isAuthPath?.(url.pathname)) return null\n } catch {\n // an unmatchable path isn't an auth page\n }\n return `${url.pathname}${url.search}${url.hash}`\n}\n\n/** The safety check with the module's current settings. */\nconst safe = (value: unknown) =>\n safeAuthRedirect(value, { loginPath: settings.loginPath, isAuthPath: settings.isAuthPath })\n\n/** Read a param out of a raw search string (`?a=1&b=2`). */\nconst paramOf = (searchStr: string, key: string) => {\n try {\n return new URLSearchParams(searchStr).get(key)\n } catch {\n return null\n }\n}\n\n/** @internal The target for a search string: its param, else the remembered one, else `fallback`. */\nexport function resolveAuthRedirect(\n searchStr: string,\n fallback = '/',\n queryKey = settings.queryKey,\n) {\n return safe(paramOf(searchStr, queryKey)) ?? (isBrowser() ? safe(remembered) : null) ?? fallback\n}\n\n/**\n * @internal Remember a target for this tab — returns it (normalized) when it's worth remembering, `null`\n * otherwise (unsafe, `/`, the login path, or an explicit Sign Out is under way).\n */\nexport function rememberAuthRedirect(target: string): string | null {\n if (signingOut || !isBrowser()) return null\n const value = safe(target)\n if (!value || value === '/') return null\n remembered = value\n return value\n}\n\n/**\n * @internal An explicit Sign Out: forget the target and remember nothing until `endSignOut` (once the\n * navigation to the login page has settled) or the next sign-in.\n */\nexport function beginSignOut() {\n remembered = null\n signingOut = isBrowser()\n}\n\n/** @internal The Sign Out navigation settled — later guard redirects remember their page again. */\nexport function endSignOut() {\n signingOut = false\n}\n\n/** @internal Signed in (the guard rendered its content): the target is spent, Sign Out is over. */\nexport function authRedirectConsumed() {\n remembered = null\n signingOut = false\n}\n\n/**\n * Where to go after a successful sign-in, outside React (a route `beforeLoad`, a mutation's `onSuccess`):\n * the `?redirect=` param of `window.location` if it's safe, else the target remembered in this tab, else\n * `fallback` (default `'/'`). The param name follows `config.keys.redirectQueryKey` once the guard, the\n * shell or `useAuthRedirect` has rendered.\n */\nexport function getAuthRedirect(fallback = '/'): string {\n return resolveAuthRedirect(typeof window === 'undefined' ? '' : window.location.search, fallback)\n}\n\n/**\n * Where to go after a successful sign-in: the `?redirect=` param of the router's location if it's safe,\n * else the target remembered in this tab, else `fallback` (default `'/'`). Pure — it doesn't clear\n * anything; the target is forgotten once `AuthGuard` renders signed-in content (or `clearAuthRedirect`).\n *\n * @example\n * const to = useAuthRedirect('/')\n * if (status === 'authenticated') return <Navigate to={to} replace />\n */\nexport function useAuthRedirect(fallback = '/'): string {\n const queryKey = useRedirectQueryKey()\n const searchStr = useRouterState({ select: (s) => s.location.searchStr })\n configureAuthRedirect({ queryKey })\n return resolveAuthRedirect(searchStr, fallback, queryKey)\n}\n\n/**\n * Forget the remembered target. `AuthGuard` already does this once it renders signed-in content, so a\n * later sign-in in the same tab doesn't reuse it — call it yourself only when you navigate elsewhere.\n */\nexport function clearAuthRedirect(): void {\n remembered = null\n}\n\n/** @internal Test-only: back to a fresh tab. */\nexport function resetAuthRedirect() {\n remembered = null\n signingOut = false\n Object.assign(settings, {\n queryKey: DEFAULT_REDIRECT_QUERY_KEY,\n loginPath: '/login',\n isAuthPath: null,\n })\n}\n","import { Navigate, useRouter, type LinkProps } from '@tanstack/react-router'\nimport { useEffect, useMemo, useRef, type ReactNode } from 'react'\nimport { useRedirectQueryKey } from '../theme/ConfigProvider'\nimport { authRedirectConsumed, configureAuthRedirect, rememberAuthRedirect } from './authRedirect'\n\nexport interface AuthGuardProps {\n /** Session check — a boolean, or a function that returns one (evaluated on render). */\n isAuthenticated: boolean | (() => boolean)\n /** Where to send an unauthenticated visitor. Defaults to `'/login'`. */\n redirectTo?: string\n /** The protected content, rendered only when authenticated. */\n children: ReactNode\n}\n\n/**\n * Component-level auth guard: renders `children` only when authenticated, otherwise redirects to\n * `redirectTo` via `<Navigate replace>` (so Back from the login page doesn't bounce off the guard).\n *\n * The redirect **remembers the page**: it adds `?redirect=<path + search + hash>` to the login URL (the\n * param name follows `config.keys.redirectQueryKey`) and keeps the same target in memory for this tab, so\n * a multi-step sign-in that drops the query string still knows it. Read it back after sign-in with\n * `useAuthRedirect` / `getAuthRedirect`. Nothing is remembered from `/`, from the login path itself, or\n * during an explicit Sign Out (`AdminRoot`'s). Once it renders signed-in content, the target is forgotten.\n *\n * Requires a `@tanstack/react-router` context (it renders `<Navigate>`), so use it inside a routed\n * tree. `redirectTo` is a plain string — the library can't know the app's typed route tree, so it's\n * cast loosely to the router's `to` type.\n *\n * @example\n * <AuthGuard isAuthenticated={session.isAuthenticated} redirectTo=\"/login\">\n * <Dashboard />\n * </AuthGuard>\n */\nexport const AuthGuard = ({ isAuthenticated, redirectTo = '/login', children }: AuthGuardProps) => {\n const ok = typeof isAuthenticated === 'function' ? isAuthenticated() : isAuthenticated\n const queryKey = useRedirectQueryKey()\n const router = useRouter()\n configureAuthRedirect({ queryKey, loginPath: redirectTo })\n // The target is taken once, when the guard first turns the visitor away, and read without subscribing:\n // the router moves its location to the login URL before the login page mounts, so a later render here\n // would read that instead (and a `<Navigate>` whose props change navigates again).\n const target = useRef<string | null | undefined>(undefined)\n if (ok) target.current = undefined\n else if (target.current === undefined) {\n const { pathname, searchStr, hash } = router.state.location\n target.current = rememberAuthRedirect(`${pathname}${searchStr}${hash ? `#${hash}` : ''}`)\n }\n const redirect = useMemo(\n () =>\n ok ? null : (\n <Navigate\n to={redirectTo as LinkProps['to']}\n search={(target.current ? { [queryKey]: target.current } : {}) as LinkProps['search']}\n replace\n />\n ),\n [ok, redirectTo, queryKey],\n )\n\n // signed in: a remembered target is spent (and a Sign Out is over) — idempotent, so StrictMode is fine\n useEffect(() => {\n if (ok) authRedirectConsumed()\n }, [ok])\n\n return ok ? <>{children}</> : redirect\n}\n"],"names":["AUTH_REDIRECT_MAX_LENGTH","remembered","signingOut","settings","DEFAULT_REDIRECT_QUERY_KEY","configureAuthRedirect","next","isBrowser","currentOrigin","isUnder","pathname","base","b","safeAuthRedirect","value","loginPath","isAuthPath","origin","url","safe","paramOf","searchStr","key","resolveAuthRedirect","fallback","queryKey","rememberAuthRedirect","target","beginSignOut","endSignOut","authRedirectConsumed","getAuthRedirect","useAuthRedirect","useRedirectQueryKey","useRouterState","s","clearAuthRedirect","AuthGuard","isAuthenticated","redirectTo","children","ok","router","useRouter","useRef","hash","redirect","useMemo","jsx","Navigate","useEffect","Fragment"],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsx as a, jsxs as i } from "react/jsx-runtime";
|
|
2
2
|
import { Link as u } from "@tanstack/react-router";
|
|
3
3
|
import { b as l, a as _ } from "./Icon-B7DJn8Tw.js";
|
|
4
|
-
import { u as h } from "./Sidebar-
|
|
5
|
-
import { a as d } from "./ConfigProvider-
|
|
4
|
+
import { u as h } from "./Sidebar-CLr-DyQ_.js";
|
|
5
|
+
import { a as d } from "./ConfigProvider-DtyUlWk6.js";
|
|
6
6
|
const p = "_breadcrumbs_9gbua_4", N = "_list_9gbua_8", g = "_item_9gbua_18", f = "_home_9gbua_27", k = "_separator_9gbua_41", S = "_link_9gbua_52", T = "_current_9gbua_65", e = {
|
|
7
7
|
breadcrumbs: p,
|
|
8
8
|
list: N,
|
|
@@ -31,4 +31,4 @@ function w({ separator: s = "ArrowRight4" } = {}) {
|
|
|
31
31
|
export {
|
|
32
32
|
w as B
|
|
33
33
|
};
|
|
34
|
-
//# sourceMappingURL=Breadcrumbs-
|
|
34
|
+
//# sourceMappingURL=Breadcrumbs-BEv57tuJ.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Breadcrumbs-
|
|
1
|
+
{"version":3,"file":"Breadcrumbs-BEv57tuJ.js","sources":["../src/components/Breadcrumbs/Breadcrumbs.tsx"],"sourcesContent":["import type { ReactNode } from 'react'\nimport { Link, type LinkProps } from '@tanstack/react-router'\nimport { useT } from '../../theme'\nimport { Icon } from '../Icon'\nimport { ICON_NAMES, type IconName } from '../../icons/names'\nimport { useBreadcrumbs } from '../Sidebar/Sidebar'\nimport styles from './Breadcrumbs.module.css'\n\nconst linkTo = (to: string) => to as LinkProps['to']\nconst ICON_NAME_SET = new Set<string>(ICON_NAMES)\n\nexport interface BreadcrumbsProps {\n /**\n * Separator between crumbs. A known `IconName` (the default `\"ArrowRight4\"`) renders as an icon; any\n * other string renders as plain text; or pass a node.\n */\n separator?: IconName | ReactNode\n}\n\nfunction Separator({ separator }: { separator: IconName | ReactNode }) {\n if (typeof separator === 'string' && ICON_NAME_SET.has(separator)) {\n return <Icon name={separator as IconName} size=\"sm\" className={styles.separator} />\n }\n return (\n <span className={styles.separator} aria-hidden=\"true\">\n {separator}\n </span>\n )\n}\n\n/**\n * Auto-generated breadcrumb trail for the current route, rendered at the top of `RootLayout`'s\n * content. It always starts with a home icon that links to the first allowed menu page (the same\n * target as `FirstRouteRedirect`), followed by one crumb per matched route that declares a\n * `staticData.name`. Intermediate crumbs link to their page when navigable; the current page is\n * plain text. Renders nothing when no path prefix has a name and the leaf route has no\n * `staticData.breadcrumb`. Token-only styling.\n */\nexport function Breadcrumbs({ separator = 'ArrowRight4' }: BreadcrumbsProps = {}) {\n const { homeTo, items } = useBreadcrumbs()\n const t = useT()\n if (items.length === 0) return null\n\n return (\n <nav aria-label={t('breadcrumbs.label')} className={styles.breadcrumbs}>\n <ol className={styles.list}>\n <li className={styles.item}>\n {homeTo ? (\n <Link to={linkTo(homeTo)} className={styles.home} aria-label={t('breadcrumbs.home')}>\n <Icon name=\"Home2\" size=\"sm\" />\n </Link>\n ) : (\n <span className={styles.home} aria-label={t('breadcrumbs.home')}>\n <Icon name=\"Home2\" size=\"sm\" />\n </span>\n )}\n </li>\n {items.map((item, index) => {\n const isLast = index === items.length - 1\n return (\n <li className={styles.item} key={`${item.label}-${index}`}>\n <Separator separator={separator} />\n {item.to && !isLast ? (\n <Link to={linkTo(item.to)} className={styles.link}>\n {item.label}\n </Link>\n ) : (\n <span className={styles.current} aria-current={isLast ? 'page' : undefined}>\n {item.label}\n </span>\n )}\n </li>\n )\n })}\n </ol>\n </nav>\n )\n}\n"],"names":["linkTo","to","ICON_NAME_SET","ICON_NAMES","Separator","separator","jsx","Icon","styles","Breadcrumbs","homeTo","items","useBreadcrumbs","useT","jsxs","Link","item","index","isLast"],"mappings":";;;;;;;;;;;;;GAQMA,IAAS,CAACC,MAAeA,GACzBC,IAAgB,IAAI,IAAYC,CAAU;AAUhD,SAASC,EAAU,EAAE,WAAAC,KAAkD;AACrE,SAAI,OAAOA,KAAc,YAAYH,EAAc,IAAIG,CAAS,IACvD,gBAAAC,EAACC,KAAK,MAAMF,GAAuB,MAAK,MAAK,WAAWG,EAAO,WAAW,sBAGhF,QAAA,EAAK,WAAWA,EAAO,WAAW,eAAY,QAC5C,UAAAH,GACH;AAEJ;AAUO,SAASI,EAAY,EAAE,WAAAJ,IAAY,cAAA,IAAoC,CAAA,GAAI;AAChF,QAAM,EAAE,QAAAK,GAAQ,OAAAC,EAAA,IAAUC,EAAA,GACpB,IAAIC,EAAA;AACV,SAAIF,EAAM,WAAW,IAAU,OAG7B,gBAAAL,EAAC,OAAA,EAAI,cAAY,EAAE,mBAAmB,GAAG,WAAWE,EAAO,aACzD,UAAA,gBAAAM,EAAC,MAAA,EAAG,WAAWN,EAAO,MACpB,UAAA;AAAA,IAAA,gBAAAF,EAAC,QAAG,WAAWE,EAAO,MACnB,UAAAE,IACC,gBAAAJ,EAACS,KAAK,IAAIf,EAAOU,CAAM,GAAG,WAAWF,EAAO,MAAM,cAAY,EAAE,kBAAkB,GAChF,4BAACD,GAAA,EAAK,MAAK,SAAQ,MAAK,MAAK,EAAA,CAC/B,sBAEC,QAAA,EAAK,WAAWC,EAAO,MAAM,cAAY,EAAE,kBAAkB,GAC5D,4BAACD,GAAA,EAAK,MAAK,SAAQ,MAAK,MAAK,GAC/B,EAAA,CAEJ;AAAA,IACCI,EAAM,IAAI,CAACK,GAAMC,MAAU;AAC1B,YAAMC,IAASD,MAAUN,EAAM,SAAS;AACxC,aACE,gBAAAG,EAAC,MAAA,EAAG,WAAWN,EAAO,MACpB,UAAA;AAAA,QAAA,gBAAAF,EAACF,KAAU,WAAAC,GAAsB;AAAA,QAChCW,EAAK,MAAM,CAACE,IACX,gBAAAZ,EAACS,GAAA,EAAK,IAAIf,EAAOgB,EAAK,EAAE,GAAG,WAAWR,EAAO,MAC1C,UAAAQ,EAAK,MAAA,CACR,IAEA,gBAAAV,EAAC,QAAA,EAAK,WAAWE,EAAO,SAAS,gBAAcU,IAAS,SAAS,QAC9D,UAAAF,EAAK,MAAA,CACR;AAAA,MAAA,EAAA,GAT6B,GAAGA,EAAK,KAAK,IAAIC,CAAK,EAWvD;AAAA,IAEJ,CAAC;AAAA,EAAA,EAAA,CACH,EAAA,CACF;AAEJ;"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";const e=require("react/jsx-runtime"),u=require("@tanstack/react-router"),n=require("./Icon-CBg21lKA.cjs"),b=require("./Sidebar-
|
|
2
|
-
//# sourceMappingURL=Breadcrumbs-
|
|
1
|
+
"use strict";const e=require("react/jsx-runtime"),u=require("@tanstack/react-router"),n=require("./Icon-CBg21lKA.cjs"),b=require("./Sidebar-CM-jZfj5.cjs"),_=require("./ConfigProvider-CYSpuSMJ.cjs"),d="_breadcrumbs_9gbua_4",h="_list_9gbua_8",j="_item_9gbua_18",N="_home_9gbua_27",g="_separator_9gbua_41",x="_link_9gbua_52",p="_current_9gbua_65",s={breadcrumbs:d,list:h,item:j,home:N,separator:g,link:x,current:p},m=r=>r,k=new Set(n.ICON_NAMES);function f({separator:r}){return typeof r=="string"&&k.has(r)?e.jsx(n.Icon,{name:r,size:"sm",className:s.separator}):e.jsx("span",{className:s.separator,"aria-hidden":"true",children:r})}function I({separator:r="ArrowRight4"}={}){const{homeTo:i,items:c}=b.useBreadcrumbs(),t=_.useT();return c.length===0?null:e.jsx("nav",{"aria-label":t("breadcrumbs.label"),className:s.breadcrumbs,children:e.jsxs("ol",{className:s.list,children:[e.jsx("li",{className:s.item,children:i?e.jsx(u.Link,{to:m(i),className:s.home,"aria-label":t("breadcrumbs.home"),children:e.jsx(n.Icon,{name:"Home2",size:"sm"})}):e.jsx("span",{className:s.home,"aria-label":t("breadcrumbs.home"),children:e.jsx(n.Icon,{name:"Home2",size:"sm"})})}),c.map((a,l)=>{const o=l===c.length-1;return e.jsxs("li",{className:s.item,children:[e.jsx(f,{separator:r}),a.to&&!o?e.jsx(u.Link,{to:m(a.to),className:s.link,children:a.label}):e.jsx("span",{className:s.current,"aria-current":o?"page":void 0,children:a.label})]},`${a.label}-${l}`)})]})})}exports.Breadcrumbs=I;
|
|
2
|
+
//# sourceMappingURL=Breadcrumbs-CqGS32x5.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Breadcrumbs-
|
|
1
|
+
{"version":3,"file":"Breadcrumbs-CqGS32x5.cjs","sources":["../src/components/Breadcrumbs/Breadcrumbs.tsx"],"sourcesContent":["import type { ReactNode } from 'react'\nimport { Link, type LinkProps } from '@tanstack/react-router'\nimport { useT } from '../../theme'\nimport { Icon } from '../Icon'\nimport { ICON_NAMES, type IconName } from '../../icons/names'\nimport { useBreadcrumbs } from '../Sidebar/Sidebar'\nimport styles from './Breadcrumbs.module.css'\n\nconst linkTo = (to: string) => to as LinkProps['to']\nconst ICON_NAME_SET = new Set<string>(ICON_NAMES)\n\nexport interface BreadcrumbsProps {\n /**\n * Separator between crumbs. A known `IconName` (the default `\"ArrowRight4\"`) renders as an icon; any\n * other string renders as plain text; or pass a node.\n */\n separator?: IconName | ReactNode\n}\n\nfunction Separator({ separator }: { separator: IconName | ReactNode }) {\n if (typeof separator === 'string' && ICON_NAME_SET.has(separator)) {\n return <Icon name={separator as IconName} size=\"sm\" className={styles.separator} />\n }\n return (\n <span className={styles.separator} aria-hidden=\"true\">\n {separator}\n </span>\n )\n}\n\n/**\n * Auto-generated breadcrumb trail for the current route, rendered at the top of `RootLayout`'s\n * content. It always starts with a home icon that links to the first allowed menu page (the same\n * target as `FirstRouteRedirect`), followed by one crumb per matched route that declares a\n * `staticData.name`. Intermediate crumbs link to their page when navigable; the current page is\n * plain text. Renders nothing when no path prefix has a name and the leaf route has no\n * `staticData.breadcrumb`. Token-only styling.\n */\nexport function Breadcrumbs({ separator = 'ArrowRight4' }: BreadcrumbsProps = {}) {\n const { homeTo, items } = useBreadcrumbs()\n const t = useT()\n if (items.length === 0) return null\n\n return (\n <nav aria-label={t('breadcrumbs.label')} className={styles.breadcrumbs}>\n <ol className={styles.list}>\n <li className={styles.item}>\n {homeTo ? (\n <Link to={linkTo(homeTo)} className={styles.home} aria-label={t('breadcrumbs.home')}>\n <Icon name=\"Home2\" size=\"sm\" />\n </Link>\n ) : (\n <span className={styles.home} aria-label={t('breadcrumbs.home')}>\n <Icon name=\"Home2\" size=\"sm\" />\n </span>\n )}\n </li>\n {items.map((item, index) => {\n const isLast = index === items.length - 1\n return (\n <li className={styles.item} key={`${item.label}-${index}`}>\n <Separator separator={separator} />\n {item.to && !isLast ? (\n <Link to={linkTo(item.to)} className={styles.link}>\n {item.label}\n </Link>\n ) : (\n <span className={styles.current} aria-current={isLast ? 'page' : undefined}>\n {item.label}\n </span>\n )}\n </li>\n )\n })}\n </ol>\n </nav>\n )\n}\n"],"names":["linkTo","to","ICON_NAME_SET","ICON_NAMES","Separator","separator","jsx","Icon","styles","Breadcrumbs","homeTo","items","useBreadcrumbs","useT","jsxs","Link","item","index","isLast"],"mappings":"4ZAQMA,EAAUC,GAAeA,EACzBC,EAAgB,IAAI,IAAYC,YAAU,EAUhD,SAASC,EAAU,CAAE,UAAAC,GAAkD,CACrE,OAAI,OAAOA,GAAc,UAAYH,EAAc,IAAIG,CAAS,EACvDC,MAACC,EAAAA,MAAK,KAAMF,EAAuB,KAAK,KAAK,UAAWG,EAAO,UAAW,QAGhF,OAAA,CAAK,UAAWA,EAAO,UAAW,cAAY,OAC5C,SAAAH,EACH,CAEJ,CAUO,SAASI,EAAY,CAAE,UAAAJ,EAAY,aAAA,EAAoC,CAAA,EAAI,CAChF,KAAM,CAAE,OAAAK,EAAQ,MAAAC,CAAA,EAAUC,iBAAA,EACpB,EAAIC,EAAAA,KAAA,EACV,OAAIF,EAAM,SAAW,EAAU,KAG7BL,EAAAA,IAAC,MAAA,CAAI,aAAY,EAAE,mBAAmB,EAAG,UAAWE,EAAO,YACzD,SAAAM,EAAAA,KAAC,KAAA,CAAG,UAAWN,EAAO,KACpB,SAAA,CAAAF,EAAAA,IAAC,MAAG,UAAWE,EAAO,KACnB,SAAAE,EACCJ,EAAAA,IAACS,EAAAA,MAAK,GAAIf,EAAOU,CAAM,EAAG,UAAWF,EAAO,KAAM,aAAY,EAAE,kBAAkB,EAChF,eAACD,EAAAA,KAAA,CAAK,KAAK,QAAQ,KAAK,KAAK,CAAA,CAC/B,QAEC,OAAA,CAAK,UAAWC,EAAO,KAAM,aAAY,EAAE,kBAAkB,EAC5D,eAACD,EAAAA,KAAA,CAAK,KAAK,QAAQ,KAAK,KAAK,EAC/B,CAAA,CAEJ,EACCI,EAAM,IAAI,CAACK,EAAMC,IAAU,CAC1B,MAAMC,EAASD,IAAUN,EAAM,OAAS,EACxC,OACEG,EAAAA,KAAC,KAAA,CAAG,UAAWN,EAAO,KACpB,SAAA,CAAAF,MAACF,GAAU,UAAAC,EAAsB,EAChCW,EAAK,IAAM,CAACE,EACXZ,EAAAA,IAACS,EAAAA,KAAA,CAAK,GAAIf,EAAOgB,EAAK,EAAE,EAAG,UAAWR,EAAO,KAC1C,SAAAQ,EAAK,KAAA,CACR,EAEAV,EAAAA,IAAC,OAAA,CAAK,UAAWE,EAAO,QAAS,eAAcU,EAAS,OAAS,OAC9D,SAAAF,EAAK,KAAA,CACR,CAAA,CAAA,EAT6B,GAAGA,EAAK,KAAK,IAAIC,CAAK,EAWvD,CAEJ,CAAC,CAAA,CAAA,CACH,CAAA,CACF,CAEJ"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";const s=require("react/jsx-runtime"),c=require("react"),W=require("clsx"),f=require("./Loader-
|
|
2
|
-
//# sourceMappingURL=Button-
|
|
1
|
+
"use strict";const s=require("react/jsx-runtime"),c=require("react"),W=require("clsx"),f=require("./Loader-RyFTP2X5.cjs"),p="_button_1jlfc_1",v="_sm_1jlfc_23",y="_md_1jlfc_29",B="_lg_1jlfc_35",E="_contained_1jlfc_42",L="_filled_1jlfc_54",N="_outlined_1jlfc_65",R="_text_1jlfc_78",$="_fullWidth_1jlfc_90",w="_rounded_1jlfc_94",A="_disabled_1jlfc_102",V="_loading_1jlfc_106",k="_label_1jlfc_111",t={button:p,sm:v,md:y,lg:B,contained:E,filled:L,outlined:N,text:R,fullWidth:$,rounded:w,disabled:A,loading:V,label:k},C=c.forwardRef(function({variant:i="contained",color:d="accent",size:e="md",loading:l=!1,fullWidth:b=!1,rounded:j=!1,disabled:_=!1,startIcon:a,endIcon:m,className:x,style:h,type:g="button",children:o,...q},z){const r=l&&!a,u=n=>c.isValidElement(n)?c.cloneElement(n,{size:n.props.size??e}):n;return s.jsxs("button",{ref:z,type:g,disabled:_||l,"aria-busy":l||void 0,className:W.clsx(t.button,t[i],t[e],b&&t.fullWidth,j&&t.rounded,l&&t.loading,_&&t.disabled,x),style:{"--tz-btn-rgb":`var(--tz-color-${d}-rgb)`,"--tz-btn-on":`var(--tz-color-${d}-contrast, #fff)`,...h},...q,children:[l&&!r?s.jsx(f.Loader,{size:e,"aria-hidden":"true"}):u(a),o!=null&&o!==!1&&s.jsx("span",{className:t.label,children:o}),r?s.jsx(f.Loader,{size:e,"aria-hidden":"true"}):!l&&u(m)]})});exports.Button=C;
|
|
2
|
+
//# sourceMappingURL=Button-BtiFpRie.cjs.map
|