@mesob/auth-react 0.3.5 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-35TCGAW3.js +98 -0
- package/dist/chunk-35TCGAW3.js.map +1 -0
- package/dist/chunk-3BZC4VVD.js +36 -0
- package/dist/chunk-3BZC4VVD.js.map +1 -0
- package/dist/chunk-45UCLKH2.js +188 -0
- package/dist/chunk-45UCLKH2.js.map +1 -0
- package/dist/chunk-55BMNC4S.js +115 -0
- package/dist/chunk-55BMNC4S.js.map +1 -0
- package/dist/chunk-5F5FZMHE.js +94 -0
- package/dist/chunk-5F5FZMHE.js.map +1 -0
- package/dist/chunk-5M7I7WNH.js +31 -0
- package/dist/chunk-5M7I7WNH.js.map +1 -0
- package/dist/chunk-72YRO3A7.js +288 -0
- package/dist/chunk-72YRO3A7.js.map +1 -0
- package/dist/chunk-7KXTL6NT.js +48 -0
- package/dist/chunk-7KXTL6NT.js.map +1 -0
- package/dist/chunk-AIMD6R6U.js +466 -0
- package/dist/chunk-AIMD6R6U.js.map +1 -0
- package/dist/chunk-BGSHXIHI.js +953 -0
- package/dist/chunk-BGSHXIHI.js.map +1 -0
- package/dist/chunk-BZ42QPXE.js +271 -0
- package/dist/chunk-BZ42QPXE.js.map +1 -0
- package/dist/chunk-C26NPUPI.js +272 -0
- package/dist/chunk-C26NPUPI.js.map +1 -0
- package/dist/chunk-C2KFZ57H.js +194 -0
- package/dist/chunk-C2KFZ57H.js.map +1 -0
- package/dist/chunk-C5ZW7FD2.js +46 -0
- package/dist/chunk-C5ZW7FD2.js.map +1 -0
- package/dist/chunk-DPH2PHK3.js +32 -0
- package/dist/chunk-DPH2PHK3.js.map +1 -0
- package/dist/chunk-EQ4346FE.js +139 -0
- package/dist/chunk-EQ4346FE.js.map +1 -0
- package/dist/chunk-FAHN63DA.js +535 -0
- package/dist/chunk-FAHN63DA.js.map +1 -0
- package/dist/chunk-FBABIA5J.js +345 -0
- package/dist/chunk-FBABIA5J.js.map +1 -0
- package/dist/chunk-FFR5UHTS.js +99 -0
- package/dist/chunk-FFR5UHTS.js.map +1 -0
- package/dist/chunk-FHOLUOOZ.js +164 -0
- package/dist/chunk-FHOLUOOZ.js.map +1 -0
- package/dist/chunk-G2AW2H36.js +11 -0
- package/dist/chunk-G2AW2H36.js.map +1 -0
- package/dist/chunk-G7SCXCCM.js +89 -0
- package/dist/chunk-G7SCXCCM.js.map +1 -0
- package/dist/chunk-GP7GIUI3.js +64 -0
- package/dist/chunk-GP7GIUI3.js.map +1 -0
- package/dist/chunk-GRT6EBR6.js +93 -0
- package/dist/chunk-GRT6EBR6.js.map +1 -0
- package/dist/chunk-GXKBVCVS.js +102 -0
- package/dist/chunk-GXKBVCVS.js.map +1 -0
- package/dist/chunk-HOO2VLNM.js +305 -0
- package/dist/chunk-HOO2VLNM.js.map +1 -0
- package/dist/chunk-II5MLBSB.js +183 -0
- package/dist/chunk-II5MLBSB.js.map +1 -0
- package/dist/chunk-ISNNPMF7.js +95 -0
- package/dist/chunk-ISNNPMF7.js.map +1 -0
- package/dist/chunk-JB6XVST4.js +141 -0
- package/dist/chunk-JB6XVST4.js.map +1 -0
- package/dist/chunk-JUHBVG5Q.js +303 -0
- package/dist/chunk-JUHBVG5Q.js.map +1 -0
- package/dist/chunk-JZZJCBAE.js +118 -0
- package/dist/chunk-JZZJCBAE.js.map +1 -0
- package/dist/chunk-KWG4DSB5.js +55 -0
- package/dist/chunk-KWG4DSB5.js.map +1 -0
- package/dist/chunk-L4CGIO2I.js +265 -0
- package/dist/chunk-L4CGIO2I.js.map +1 -0
- package/dist/chunk-LNG736CV.js +19 -0
- package/dist/chunk-LNG736CV.js.map +1 -0
- package/dist/chunk-LSYKVFJA.js +98 -0
- package/dist/chunk-LSYKVFJA.js.map +1 -0
- package/dist/chunk-LZR4YUDV.js +107 -0
- package/dist/chunk-LZR4YUDV.js.map +1 -0
- package/dist/chunk-MELNS4QH.js +255 -0
- package/dist/chunk-MELNS4QH.js.map +1 -0
- package/dist/chunk-MS2JUZ3N.js +94 -0
- package/dist/chunk-MS2JUZ3N.js.map +1 -0
- package/dist/chunk-NEO72TMH.js +32 -0
- package/dist/chunk-NEO72TMH.js.map +1 -0
- package/dist/chunk-NJPNTAAT.js +68 -0
- package/dist/chunk-NJPNTAAT.js.map +1 -0
- package/dist/chunk-NPW7D2HZ.js +16 -0
- package/dist/chunk-NPW7D2HZ.js.map +1 -0
- package/dist/chunk-OAN4EXU4.js +310 -0
- package/dist/chunk-OAN4EXU4.js.map +1 -0
- package/dist/chunk-OFLSINVU.js +138 -0
- package/dist/chunk-OFLSINVU.js.map +1 -0
- package/dist/chunk-OHIIMUQC.js +286 -0
- package/dist/chunk-OHIIMUQC.js.map +1 -0
- package/dist/chunk-OQGJX37L.js +239 -0
- package/dist/chunk-OQGJX37L.js.map +1 -0
- package/dist/chunk-OYHH7HQG.js +65 -0
- package/dist/chunk-OYHH7HQG.js.map +1 -0
- package/dist/chunk-PSRIZMWJ.js +486 -0
- package/dist/chunk-PSRIZMWJ.js.map +1 -0
- package/dist/chunk-QNCE2B5O.js +23 -0
- package/dist/chunk-QNCE2B5O.js.map +1 -0
- package/dist/chunk-RLPZFLAS.js +23 -0
- package/dist/chunk-RLPZFLAS.js.map +1 -0
- package/dist/chunk-RT5C7IAE.js +38 -0
- package/dist/chunk-RT5C7IAE.js.map +1 -0
- package/dist/chunk-S3CXCCKL.js +272 -0
- package/dist/chunk-S3CXCCKL.js.map +1 -0
- package/dist/chunk-SOCZK4CV.js +69 -0
- package/dist/chunk-SOCZK4CV.js.map +1 -0
- package/dist/chunk-T6P7UHVP.js +34 -0
- package/dist/chunk-T6P7UHVP.js.map +1 -0
- package/dist/chunk-TFVBER3Y.js +52 -0
- package/dist/chunk-TFVBER3Y.js.map +1 -0
- package/dist/chunk-UXOZ2TME.js +104 -0
- package/dist/chunk-UXOZ2TME.js.map +1 -0
- package/dist/chunk-V2W3WPCZ.js +22 -0
- package/dist/chunk-V2W3WPCZ.js.map +1 -0
- package/dist/chunk-YZ264S2L.js +286 -0
- package/dist/chunk-YZ264S2L.js.map +1 -0
- package/dist/chunk-ZESFGO3K.js +28 -0
- package/dist/chunk-ZESFGO3K.js.map +1 -0
- package/dist/chunk-ZG6WFZHX.js +143 -0
- package/dist/chunk-ZG6WFZHX.js.map +1 -0
- package/dist/components/auth/auth-card.d.ts +3 -6
- package/dist/components/auth/auth-card.js +3 -7
- package/dist/components/auth/auth-card.js.map +1 -1
- package/dist/components/auth/auth-layout.d.ts +3 -6
- package/dist/components/auth/auth-layout.js +3 -28
- package/dist/components/auth/auth-layout.js.map +1 -1
- package/dist/components/auth/countdown.d.ts +2 -5
- package/dist/components/auth/countdown.js +5 -130
- package/dist/components/auth/countdown.js.map +1 -1
- package/dist/components/auth/forgot-password.d.ts +1 -5
- package/dist/components/auth/forgot-password.js +6 -361
- package/dist/components/auth/forgot-password.js.map +1 -1
- package/dist/components/auth/reset-password-form.d.ts +2 -5
- package/dist/components/auth/reset-password-form.js +6 -483
- package/dist/components/auth/reset-password-form.js.map +1 -1
- package/dist/components/auth/set-password.d.ts +6 -0
- package/dist/components/auth/set-password.js +13 -0
- package/dist/components/auth/set-password.js.map +1 -0
- package/dist/components/auth/sign-in.d.ts +2 -5
- package/dist/components/auth/sign-in.js +7 -540
- package/dist/components/auth/sign-in.js.map +1 -1
- package/dist/components/auth/sign-up.d.ts +2 -5
- package/dist/components/auth/sign-up.js +6 -509
- package/dist/components/auth/sign-up.js.map +1 -1
- package/dist/components/auth/verification-form.d.ts +13 -2
- package/dist/components/auth/verification-form.js +5 -217
- package/dist/components/auth/verification-form.js.map +1 -1
- package/dist/components/auth/verify-email.d.ts +2 -5
- package/dist/components/auth/verify-email.js +8 -523
- package/dist/components/auth/verify-email.js.map +1 -1
- package/dist/components/auth/verify-phone.d.ts +2 -5
- package/dist/components/auth/verify-phone.js +8 -528
- package/dist/components/auth/verify-phone.js.map +1 -1
- package/dist/components/authorization/deny.d.ts +8 -0
- package/dist/components/authorization/deny.js +9 -0
- package/dist/components/authorization/deny.js.map +1 -0
- package/dist/components/authorization/grant.d.ts +9 -0
- package/dist/components/authorization/grant.js +9 -0
- package/dist/components/authorization/grant.js.map +1 -0
- package/dist/components/error-boundary.d.ts +6 -10
- package/dist/components/error-boundary.js +4 -43
- package/dist/components/error-boundary.js.map +1 -1
- package/dist/components/iam/permission-selector.d.ts +16 -0
- package/dist/components/iam/permission-selector.js +9 -0
- package/dist/components/iam/permission-selector.js.map +1 -0
- package/dist/components/iam/permissions-page.d.ts +1 -0
- package/dist/components/iam/permissions-page.js +10 -0
- package/dist/components/iam/permissions-page.js.map +1 -0
- package/dist/components/iam/permissions.d.ts +1 -5
- package/dist/components/iam/permissions.js +5 -217
- package/dist/components/iam/permissions.js.map +1 -1
- package/dist/components/iam/role-detail-layout.d.ts +8 -0
- package/dist/components/iam/role-detail-layout.js +9 -0
- package/dist/components/iam/role-detail-layout.js.map +1 -0
- package/dist/components/iam/role-detail-page.d.ts +6 -0
- package/dist/components/iam/role-detail-page.js +9 -0
- package/dist/components/iam/role-detail-page.js.map +1 -0
- package/dist/components/iam/role-permissions-page.d.ts +5 -0
- package/dist/components/iam/role-permissions-page.js +10 -0
- package/dist/components/iam/role-permissions-page.js.map +1 -0
- package/dist/components/iam/roles-page.d.ts +1 -0
- package/dist/components/iam/roles-page.js +13 -0
- package/dist/components/iam/roles-page.js.map +1 -0
- package/dist/components/iam/roles.d.ts +1 -5
- package/dist/components/iam/roles.js +5 -215
- package/dist/components/iam/roles.js.map +1 -1
- package/dist/components/iam/sessions-page.d.ts +1 -0
- package/dist/components/iam/sessions-page.js +12 -0
- package/dist/components/iam/sessions-page.js.map +1 -0
- package/dist/components/iam/sessions.d.ts +1 -5
- package/dist/components/iam/sessions.js +5 -198
- package/dist/components/iam/sessions.js.map +1 -1
- package/dist/components/iam/tenants-page.d.ts +1 -0
- package/dist/components/iam/tenants-page.js +13 -0
- package/dist/components/iam/tenants-page.js.map +1 -0
- package/dist/components/iam/tenants.d.ts +1 -5
- package/dist/components/iam/tenants.js +5 -204
- package/dist/components/iam/tenants.js.map +1 -1
- package/dist/components/iam/users-page.d.ts +1 -0
- package/dist/components/iam/users-page.js +13 -0
- package/dist/components/iam/users-page.js.map +1 -0
- package/dist/components/iam/users.d.ts +1 -5
- package/dist/components/iam/users.js +5 -213
- package/dist/components/iam/users.js.map +1 -1
- package/dist/components/profile/account.d.ts +1 -5
- package/dist/components/profile/account.js +5 -61
- package/dist/components/profile/account.js.map +1 -1
- package/dist/components/profile/change-email-form.d.ts +1 -5
- package/dist/components/profile/change-email-form.js +9 -735
- package/dist/components/profile/change-email-form.js.map +1 -1
- package/dist/components/profile/change-password-form.d.ts +1 -5
- package/dist/components/profile/change-password-form.js +3 -262
- package/dist/components/profile/change-password-form.js.map +1 -1
- package/dist/components/profile/change-phone-form.d.ts +1 -5
- package/dist/components/profile/change-phone-form.js +10 -772
- package/dist/components/profile/change-phone-form.js.map +1 -1
- package/dist/components/profile/change-profile.d.ts +3 -6
- package/dist/components/profile/change-profile.js +2 -32
- package/dist/components/profile/change-profile.js.map +1 -1
- package/dist/components/profile/otp-verification-modal.d.ts +2 -5
- package/dist/components/profile/otp-verification-modal.js +6 -266
- package/dist/components/profile/otp-verification-modal.js.map +1 -1
- package/dist/components/profile/profile-layout.d.ts +4 -0
- package/dist/components/profile/profile-layout.js +10 -0
- package/dist/components/profile/profile-layout.js.map +1 -0
- package/dist/components/profile/request-change-email-form.d.ts +2 -5
- package/dist/components/profile/request-change-email-form.js +4 -285
- package/dist/components/profile/request-change-email-form.js.map +1 -1
- package/dist/components/profile/request-change-phone-form.d.ts +2 -5
- package/dist/components/profile/request-change-phone-form.js +5 -323
- package/dist/components/profile/request-change-phone-form.js.map +1 -1
- package/dist/components/profile/security.d.ts +1 -5
- package/dist/components/profile/security.js +15 -1474
- package/dist/components/profile/security.js.map +1 -1
- package/dist/components/profile/verify-change-email-form.d.ts +2 -5
- package/dist/components/profile/verify-change-email-form.js +7 -407
- package/dist/components/profile/verify-change-email-form.js.map +1 -1
- package/dist/components/profile/verify-change-phone-form.d.ts +2 -5
- package/dist/components/profile/verify-change-phone-form.js +7 -411
- package/dist/components/profile/verify-change-phone-form.js.map +1 -1
- package/dist/components/shared/data-table.d.ts +5 -8
- package/dist/components/shared/data-table.js +3 -79
- package/dist/components/shared/data-table.js.map +1 -1
- package/dist/components/skeletons/auth-form-skeleton.d.ts +1 -5
- package/dist/components/skeletons/auth-form-skeleton.js +3 -27
- package/dist/components/skeletons/auth-form-skeleton.js.map +1 -1
- package/dist/components/skeletons/profile-skeleton.d.ts +1 -5
- package/dist/components/skeletons/profile-skeleton.js +3 -28
- package/dist/components/skeletons/profile-skeleton.js.map +1 -1
- package/dist/components/skeletons/table-skeleton.d.ts +2 -5
- package/dist/components/skeletons/table-skeleton.js +3 -34
- package/dist/components/skeletons/table-skeleton.js.map +1 -1
- package/dist/constants/auth.error.codes.d.ts +5 -0
- package/dist/hooks/use-session-cookie-name.d.ts +1 -0
- package/dist/hooks/use-translator.d.ts +1 -0
- package/dist/index.d.ts +50 -84
- package/dist/index.js +160 -3861
- package/dist/index.js.map +1 -1
- package/dist/lib/query-options.d.ts +10 -0
- package/dist/lib/translations.d.ts +3 -0
- package/dist/pages/auth/forgot-password.d.ts +3 -0
- package/dist/pages/auth/forgot-password.js +22 -0
- package/dist/pages/auth/forgot-password.js.map +1 -0
- package/dist/pages/auth/layout.d.ts +4 -0
- package/dist/pages/auth/layout.js +39 -0
- package/dist/pages/auth/layout.js.map +1 -0
- package/dist/pages/auth/reset-password.d.ts +7 -0
- package/dist/pages/auth/reset-password.js +33 -0
- package/dist/pages/auth/reset-password.js.map +1 -0
- package/dist/pages/auth/set-password.d.ts +7 -0
- package/dist/pages/auth/set-password.js +28 -0
- package/dist/pages/auth/set-password.js.map +1 -0
- package/dist/pages/auth/sign-in.d.ts +7 -0
- package/dist/pages/auth/sign-in.js +26 -0
- package/dist/pages/auth/sign-in.js.map +1 -0
- package/dist/pages/auth/sign-up.d.ts +7 -0
- package/dist/pages/auth/sign-up.js +33 -0
- package/dist/pages/auth/sign-up.js.map +1 -0
- package/dist/pages/auth/verify-email.d.ts +7 -0
- package/dist/pages/auth/verify-email.js +38 -0
- package/dist/pages/auth/verify-email.js.map +1 -0
- package/dist/pages/auth/verify-phone.d.ts +7 -0
- package/dist/pages/auth/verify-phone.js +47 -0
- package/dist/pages/auth/verify-phone.js.map +1 -0
- package/dist/pages/iam/permissions/_components/permission-card.d.ts +6 -0
- package/dist/pages/iam/permissions/_components/permissions-data.d.ts +7 -0
- package/dist/pages/iam/permissions/_components/permissions-list.d.ts +14 -0
- package/dist/pages/iam/permissions.d.ts +1 -0
- package/dist/pages/iam/permissions.js +10 -0
- package/dist/pages/iam/permissions.js.map +1 -0
- package/dist/pages/iam/role-detail-layout.d.ts +9 -0
- package/dist/pages/iam/role-detail-layout.js +18 -0
- package/dist/pages/iam/role-detail-layout.js.map +1 -0
- package/dist/pages/iam/role-detail.d.ts +9 -0
- package/dist/pages/iam/role-detail.js +22 -0
- package/dist/pages/iam/role-detail.js.map +1 -0
- package/dist/pages/iam/role-permissions.d.ts +9 -0
- package/dist/pages/iam/role-permissions.js +23 -0
- package/dist/pages/iam/role-permissions.js.map +1 -0
- package/dist/pages/iam/role-users.d.ts +9 -0
- package/dist/pages/iam/role-users.js +26 -0
- package/dist/pages/iam/role-users.js.map +1 -0
- package/dist/pages/iam/roles/_components/role-card.d.ts +7 -0
- package/dist/pages/iam/roles/_components/role-form.d.ts +9 -0
- package/dist/pages/iam/roles/_components/role-selector.d.ts +11 -0
- package/dist/pages/iam/roles/_components/roles-data.d.ts +16 -0
- package/dist/pages/iam/roles/_components/roles-list.d.ts +15 -0
- package/dist/pages/iam/roles/users/_components/role-users-page.d.ts +5 -0
- package/dist/pages/iam/roles.d.ts +1 -0
- package/dist/pages/iam/roles.js +13 -0
- package/dist/pages/iam/roles.js.map +1 -0
- package/dist/pages/iam/sessions/_components/session-card.d.ts +6 -0
- package/dist/pages/iam/sessions/_components/sessions-data.d.ts +7 -0
- package/dist/pages/iam/sessions/_components/sessions-list.d.ts +14 -0
- package/dist/pages/iam/sessions.d.ts +1 -0
- package/dist/pages/iam/sessions.js +12 -0
- package/dist/pages/iam/sessions.js.map +1 -0
- package/dist/pages/iam/shared/navigation.d.ts +8 -0
- package/dist/pages/iam/shared/page-helpers.d.ts +12 -0
- package/dist/pages/iam/tenant-detail.d.ts +7 -0
- package/dist/pages/iam/tenant-detail.js +18 -0
- package/dist/pages/iam/tenant-detail.js.map +1 -0
- package/dist/pages/iam/tenants/_components/tenant-card.d.ts +6 -0
- package/dist/pages/iam/tenants/_components/tenant-form.d.ts +9 -0
- package/dist/pages/iam/tenants/_components/tenant-selector.d.ts +13 -0
- package/dist/pages/iam/tenants/_components/tenants-data.d.ts +12 -0
- package/dist/pages/iam/tenants/_components/tenants-list.d.ts +15 -0
- package/dist/pages/iam/tenants/tenant-detail-page-content.d.ts +5 -0
- package/dist/pages/iam/tenants.d.ts +1 -0
- package/dist/pages/iam/tenants.js +13 -0
- package/dist/pages/iam/tenants.js.map +1 -0
- package/dist/pages/iam/user-activity.d.ts +7 -0
- package/dist/pages/iam/user-activity.js +21 -0
- package/dist/pages/iam/user-activity.js.map +1 -0
- package/dist/pages/iam/user-detail-layout.d.ts +9 -0
- package/dist/pages/iam/user-detail-layout.js +18 -0
- package/dist/pages/iam/user-detail-layout.js.map +1 -0
- package/dist/pages/iam/user-detail.d.ts +7 -0
- package/dist/pages/iam/user-detail.js +15 -0
- package/dist/pages/iam/user-detail.js.map +1 -0
- package/dist/pages/iam/users/_components/bulk-invite-user-form.d.ts +6 -0
- package/dist/pages/iam/users/_components/invite-user-form.d.ts +6 -0
- package/dist/pages/iam/users/_components/invite-user-shared.d.ts +25 -0
- package/dist/pages/iam/users/_components/user-card.d.ts +6 -0
- package/dist/pages/iam/users/_components/user-detail-layout-content.d.ts +6 -0
- package/dist/pages/iam/users/_components/user-detail-page-content.d.ts +5 -0
- package/dist/pages/iam/users/_components/user-form.d.ts +9 -0
- package/dist/pages/iam/users/_components/user-selector.d.ts +12 -0
- package/dist/pages/iam/users/_components/users-data.d.ts +22 -0
- package/dist/pages/iam/users/_components/users-list.d.ts +15 -0
- package/dist/pages/iam/users/activity/_components/role-section.d.ts +3 -0
- package/dist/pages/iam/users/activity/user-activity-page-content.d.ts +5 -0
- package/dist/pages/iam/users.d.ts +1 -0
- package/dist/pages/iam/users.js +13 -0
- package/dist/pages/iam/users.js.map +1 -0
- package/dist/pages/profile/_components/profile-sidebar.d.ts +1 -0
- package/dist/pages/profile/account.d.ts +1 -0
- package/dist/pages/profile/account.js +33 -0
- package/dist/pages/profile/account.js.map +1 -0
- package/dist/pages/profile/layout.d.ts +1 -0
- package/dist/pages/profile/layout.js +10 -0
- package/dist/pages/profile/layout.js.map +1 -0
- package/dist/pages/profile/security.d.ts +1 -0
- package/dist/pages/profile/security.js +44 -0
- package/dist/pages/profile/security.js.map +1 -0
- package/dist/provider.d.ts +53 -0
- package/dist/types.d.ts +96 -0
- package/dist/utils/cookie.d.ts +2 -0
- package/dist/utils/custom-fetch.d.ts +2 -0
- package/dist/utils/handle-error.d.ts +7 -0
- package/dist/utils/normalize-phone.d.ts +1 -0
- package/package.json +103 -4
- package/dist/types-vcfvnAzQ.d.ts +0 -69
- package/dist/verification-form-ipSRTtQB.d.ts +0 -22
package/dist/index.js
CHANGED
|
@@ -1,3875 +1,155 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
|
|
3
|
-
// src/components/auth/auth-card.tsx
|
|
4
|
-
import { Card } from "@mesob/ui/components";
|
|
5
|
-
import { jsx } from "react/jsx-runtime";
|
|
6
|
-
var AuthCard = ({ children }) => {
|
|
7
|
-
return /* @__PURE__ */ jsx("div", { className: "flex min-h-screen w-full p-4 items-center justify-center", children: /* @__PURE__ */ jsx("div", { className: "w-full min-w-[280px] max-w-[28rem] shrink-0", children: /* @__PURE__ */ jsx(Card, { padding: "lg", children }) }) });
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
// src/components/auth/forgot-password.tsx
|
|
11
|
-
import { zodResolver } from "@hookform/resolvers/zod";
|
|
12
2
|
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
AlertTitle,
|
|
16
|
-
Button,
|
|
17
|
-
Form,
|
|
18
|
-
FormControl,
|
|
19
|
-
FormField,
|
|
20
|
-
FormItem,
|
|
21
|
-
FormLabel,
|
|
22
|
-
FormMessage,
|
|
23
|
-
Input
|
|
24
|
-
} from "@mesob/ui/components";
|
|
25
|
-
import { useMesob as useMesob2 } from "@mesob/ui/providers";
|
|
26
|
-
import { IconAlertCircle } from "@tabler/icons-react";
|
|
27
|
-
import { useEffect, useState as useState2 } from "react";
|
|
28
|
-
import { useForm } from "react-hook-form";
|
|
29
|
-
import { toast } from "sonner";
|
|
30
|
-
import { z } from "zod";
|
|
31
|
-
|
|
32
|
-
// src/hooks/use-translator.ts
|
|
33
|
-
import { useMesob } from "@mesob/ui/providers";
|
|
34
|
-
|
|
35
|
-
// src/lib/translations.ts
|
|
36
|
-
function createTranslator(messages, namespace) {
|
|
37
|
-
return (key, params) => {
|
|
38
|
-
const fullKey = namespace ? `${namespace}.${key}` : key;
|
|
39
|
-
const keys = fullKey.split(".");
|
|
40
|
-
let value = messages;
|
|
41
|
-
for (const k of keys) {
|
|
42
|
-
if (value && typeof value === "object" && value !== null) {
|
|
43
|
-
value = value[k];
|
|
44
|
-
} else {
|
|
45
|
-
return fullKey;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
if (typeof value !== "string") {
|
|
49
|
-
return fullKey;
|
|
50
|
-
}
|
|
51
|
-
if (params) {
|
|
52
|
-
return value.replace(
|
|
53
|
-
/\{(\w+)\}/g,
|
|
54
|
-
(_, param) => String(params[param] ?? `{${param}}`)
|
|
55
|
-
);
|
|
56
|
-
}
|
|
57
|
-
return value;
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// src/provider.tsx
|
|
62
|
-
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
63
|
-
import { deepmerge } from "deepmerge-ts";
|
|
64
|
-
import createFetchClient from "openapi-fetch";
|
|
65
|
-
import createClient from "openapi-react-query";
|
|
66
|
-
import { createContext, useContext, useMemo, useState } from "react";
|
|
67
|
-
|
|
68
|
-
// src/types.ts
|
|
69
|
-
var defaultAuthClientConfig = {
|
|
70
|
-
features: {
|
|
71
|
-
enableSignup: true,
|
|
72
|
-
enablePasswordReset: true,
|
|
73
|
-
enableEmailSignup: true,
|
|
74
|
-
enablePhoneSignup: true,
|
|
75
|
-
enableSocialSignup: false,
|
|
76
|
-
socialProviders: []
|
|
77
|
-
},
|
|
78
|
-
navigation: {
|
|
79
|
-
locale: "en"
|
|
80
|
-
},
|
|
81
|
-
cookiePrefix: "msb",
|
|
82
|
-
phoneRegex: /^(\+2519|\+2517|2519|2517|09|07)\d{8}$/
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
// src/utils/cookie.ts
|
|
86
|
-
var isProduction = typeof process !== "undefined" && process.env.NODE_ENV === "production";
|
|
87
|
-
var getSessionCookieName = (config) => {
|
|
88
|
-
const prefix = config.cookiePrefix || "";
|
|
89
|
-
const baseName = "session_token";
|
|
90
|
-
if (prefix) {
|
|
91
|
-
return `${prefix}_${baseName}`;
|
|
92
|
-
}
|
|
93
|
-
return isProduction ? "__Host-session_token" : baseName;
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
// src/utils/custom-fetch.ts
|
|
97
|
-
var createCustomFetch = (_config) => {
|
|
98
|
-
return (input, init) => {
|
|
99
|
-
if (input instanceof Request) {
|
|
100
|
-
return fetch(input, { ...init, credentials: "include" });
|
|
101
|
-
}
|
|
102
|
-
return fetch(input, { ...init, credentials: "include" });
|
|
103
|
-
};
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
// src/provider.tsx
|
|
107
|
-
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
108
|
-
function isServer() {
|
|
109
|
-
return typeof document === "undefined";
|
|
110
|
-
}
|
|
111
|
-
function hasAuthCookie(_cookieName) {
|
|
112
|
-
return false;
|
|
113
|
-
}
|
|
114
|
-
var SessionContext = createContext(null);
|
|
115
|
-
var ApiContext = createContext(null);
|
|
116
|
-
var ConfigContext = createContext(null);
|
|
117
|
-
var queryClient = new QueryClient({
|
|
118
|
-
defaultOptions: {
|
|
119
|
-
queries: {
|
|
120
|
-
refetchOnWindowFocus: false
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
});
|
|
124
|
-
function useSession() {
|
|
125
|
-
const context = useContext(SessionContext);
|
|
126
|
-
if (!context) {
|
|
127
|
-
throw new Error("useSession must be used within MesobAuthProvider");
|
|
128
|
-
}
|
|
129
|
-
return context;
|
|
130
|
-
}
|
|
131
|
-
function useApi() {
|
|
132
|
-
const context = useContext(ApiContext);
|
|
133
|
-
if (!context) {
|
|
134
|
-
throw new Error("useApi must be used within MesobAuthProvider");
|
|
135
|
-
}
|
|
136
|
-
return context;
|
|
137
|
-
}
|
|
138
|
-
function useConfig() {
|
|
139
|
-
const context = useContext(ConfigContext);
|
|
140
|
-
if (!context) {
|
|
141
|
-
throw new Error("useConfig must be used within MesobAuthProvider");
|
|
142
|
-
}
|
|
143
|
-
return context;
|
|
144
|
-
}
|
|
145
|
-
function useHasAuthCookie() {
|
|
146
|
-
const { status } = useSession();
|
|
147
|
-
return status === "authenticated" || status === "loading";
|
|
148
|
-
}
|
|
149
|
-
function MesobAuthProvider({
|
|
150
|
-
config,
|
|
151
|
-
children
|
|
152
|
-
}) {
|
|
153
|
-
const mergedConfig = useMemo(
|
|
154
|
-
() => deepmerge(
|
|
155
|
-
{ ...defaultAuthClientConfig },
|
|
156
|
-
config
|
|
157
|
-
),
|
|
158
|
-
[config]
|
|
159
|
-
);
|
|
160
|
-
const api = useMemo(
|
|
161
|
-
() => createFetchClient({
|
|
162
|
-
baseUrl: mergedConfig.baseURL,
|
|
163
|
-
fetch: createCustomFetch(mergedConfig)
|
|
164
|
-
}),
|
|
165
|
-
[mergedConfig]
|
|
166
|
-
);
|
|
167
|
-
const hooks = useMemo(() => createClient(api), [api]);
|
|
168
|
-
const cookieName = useMemo(
|
|
169
|
-
() => getSessionCookieName(mergedConfig),
|
|
170
|
-
[mergedConfig]
|
|
171
|
-
);
|
|
172
|
-
return /* @__PURE__ */ jsx2(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx2(
|
|
173
|
-
AuthStateProvider,
|
|
174
|
-
{
|
|
175
|
-
config: mergedConfig,
|
|
176
|
-
hooks,
|
|
177
|
-
cookieName,
|
|
178
|
-
children
|
|
179
|
-
}
|
|
180
|
-
) });
|
|
181
|
-
}
|
|
182
|
-
function AuthStateProvider({
|
|
183
|
-
config,
|
|
184
|
-
hooks,
|
|
185
|
-
cookieName,
|
|
186
|
-
children
|
|
187
|
-
}) {
|
|
188
|
-
const [override, setOverride] = useState(null);
|
|
189
|
-
const {
|
|
190
|
-
data: sessionData,
|
|
191
|
-
isLoading,
|
|
192
|
-
isFetched,
|
|
193
|
-
error: sessionError,
|
|
194
|
-
refetch
|
|
195
|
-
} = hooks.useQuery(
|
|
196
|
-
"get",
|
|
197
|
-
"/session",
|
|
198
|
-
{},
|
|
199
|
-
{
|
|
200
|
-
enabled: !(override || isServer()),
|
|
201
|
-
refetchOnMount: false,
|
|
202
|
-
refetchOnWindowFocus: false,
|
|
203
|
-
refetchOnReconnect: false,
|
|
204
|
-
retry: false,
|
|
205
|
-
gcTime: 0,
|
|
206
|
-
staleTime: 0
|
|
207
|
-
}
|
|
208
|
-
);
|
|
209
|
-
const user = override?.user ?? sessionData?.user ?? null;
|
|
210
|
-
const session = override?.session ?? sessionData?.session ?? null;
|
|
211
|
-
const error = override?.error ?? sessionError;
|
|
212
|
-
const errorStatus = (() => {
|
|
213
|
-
if (!sessionError) {
|
|
214
|
-
return null;
|
|
215
|
-
}
|
|
216
|
-
const err = sessionError;
|
|
217
|
-
return err.status ?? null;
|
|
218
|
-
})();
|
|
219
|
-
const isNetworkError = (() => {
|
|
220
|
-
if (!sessionError) {
|
|
221
|
-
return false;
|
|
222
|
-
}
|
|
223
|
-
const error2 = sessionError;
|
|
224
|
-
const errorMessage = error2.message || String(error2) || JSON.stringify(error2);
|
|
225
|
-
if (error2 instanceof TypeError || error2 instanceof DOMException || error2.name === "TypeError" || errorMessage.includes("Failed to fetch") || errorMessage.includes("ERR_CONNECTION_REFUSED") || errorMessage.includes("NetworkError") || errorMessage.includes("Network request failed") || errorMessage.includes("fetch failed")) {
|
|
226
|
-
return true;
|
|
227
|
-
}
|
|
228
|
-
if (error2.cause) {
|
|
229
|
-
const causeStr = String(error2.cause);
|
|
230
|
-
if (causeStr.includes("Failed to fetch") || causeStr.includes("ERR_CONNECTION_REFUSED") || causeStr.includes("NetworkError")) {
|
|
231
|
-
return true;
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
return false;
|
|
235
|
-
})();
|
|
236
|
-
const status = (() => {
|
|
237
|
-
if (override) {
|
|
238
|
-
return override.status;
|
|
239
|
-
}
|
|
240
|
-
if (isServer()) {
|
|
241
|
-
return "loading";
|
|
242
|
-
}
|
|
243
|
-
if (user && session) {
|
|
244
|
-
return "authenticated";
|
|
245
|
-
}
|
|
246
|
-
if (isNetworkError || errorStatus === 401) {
|
|
247
|
-
return "unauthenticated";
|
|
248
|
-
}
|
|
249
|
-
if (sessionError && !isNetworkError && errorStatus !== 401) {
|
|
250
|
-
if (errorStatus && errorStatus >= 500) {
|
|
251
|
-
return "authenticated";
|
|
252
|
-
}
|
|
253
|
-
if (isFetched) {
|
|
254
|
-
return "unauthenticated";
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
if (isLoading || !isFetched) {
|
|
258
|
-
return "loading";
|
|
259
|
-
}
|
|
260
|
-
if (isFetched && !user && !session) {
|
|
261
|
-
return "unauthenticated";
|
|
262
|
-
}
|
|
263
|
-
return "unauthenticated";
|
|
264
|
-
})();
|
|
265
|
-
const signOutMutation = hooks.useMutation("post", "/sign-out");
|
|
266
|
-
const t = createTranslator(config.messages || {});
|
|
267
|
-
const setAuth = (auth) => {
|
|
268
|
-
setOverride({
|
|
269
|
-
user: auth.user,
|
|
270
|
-
session: auth.session,
|
|
271
|
-
status: "authenticated",
|
|
272
|
-
error: null
|
|
273
|
-
});
|
|
274
|
-
};
|
|
275
|
-
const clearAuth = () => {
|
|
276
|
-
setOverride({
|
|
277
|
-
user: null,
|
|
278
|
-
session: null,
|
|
279
|
-
status: "unauthenticated",
|
|
280
|
-
error: null
|
|
281
|
-
});
|
|
282
|
-
};
|
|
283
|
-
const refresh = async () => {
|
|
284
|
-
setOverride(null);
|
|
285
|
-
await refetch();
|
|
286
|
-
};
|
|
287
|
-
const signOut = async () => {
|
|
288
|
-
try {
|
|
289
|
-
await signOutMutation.mutateAsync({});
|
|
290
|
-
} finally {
|
|
291
|
-
clearAuth();
|
|
292
|
-
}
|
|
293
|
-
};
|
|
294
|
-
return /* @__PURE__ */ jsx2(ConfigContext.Provider, { value: { config, cookieName, t }, children: /* @__PURE__ */ jsx2(ApiContext.Provider, { value: { hooks, setAuth, clearAuth, refresh }, children: /* @__PURE__ */ jsx2(
|
|
295
|
-
SessionContext.Provider,
|
|
296
|
-
{
|
|
297
|
-
value: {
|
|
298
|
-
user,
|
|
299
|
-
session,
|
|
300
|
-
status,
|
|
301
|
-
error,
|
|
302
|
-
isLoading: status === "loading",
|
|
303
|
-
isAuthenticated: status === "authenticated",
|
|
304
|
-
refresh,
|
|
305
|
-
signOut
|
|
306
|
-
},
|
|
307
|
-
children
|
|
308
|
-
}
|
|
309
|
-
) }) });
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
// src/hooks/use-translator.ts
|
|
313
|
-
function useTranslator(namespace) {
|
|
314
|
-
const mesob = useMesob();
|
|
315
|
-
const { config } = useConfig();
|
|
316
|
-
if (mesob?.t) {
|
|
317
|
-
return (key, params) => {
|
|
318
|
-
const fullKey = namespace ? `${namespace}.${key}` : key;
|
|
319
|
-
return mesob.t?.(fullKey, params) ?? fullKey;
|
|
320
|
-
};
|
|
321
|
-
}
|
|
322
|
-
return createTranslator(config.messages || {}, namespace);
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
// src/constants/auth.error.codes.ts
|
|
326
|
-
var AUTH_ERROR_MAPPING = {
|
|
327
|
-
USER_NOT_FOUND: {
|
|
328
|
-
title: "Account Not Found",
|
|
329
|
-
description: "We could not find an account with that identifier. Please check your spelling or sign up."
|
|
330
|
-
},
|
|
331
|
-
INVALID_PASSWORD: {
|
|
332
|
-
title: "Invalid Password",
|
|
333
|
-
description: "The password you entered is incorrect. Please try again."
|
|
334
|
-
},
|
|
335
|
-
USER_EXISTS: {
|
|
336
|
-
title: "Account Already Exists",
|
|
337
|
-
description: "An account with this identifier already exists. Please sign in instead."
|
|
338
|
-
},
|
|
339
|
-
VERIFICATION_EXPIRED: {
|
|
340
|
-
title: "Verification Expired",
|
|
341
|
-
description: "The verification code or link has expired. Please request a new one."
|
|
342
|
-
},
|
|
343
|
-
VERIFICATION_MISMATCH: {
|
|
344
|
-
title: "Invalid Code",
|
|
345
|
-
description: "The verification code you entered is invalid. Please double-check and try again."
|
|
346
|
-
},
|
|
347
|
-
VERIFICATION_NOT_FOUND: {
|
|
348
|
-
title: "Verification Not Found",
|
|
349
|
-
description: "We could not find a pending verification request. Please restart the process."
|
|
350
|
-
},
|
|
351
|
-
TOO_MANY_ATTEMPTS: {
|
|
352
|
-
title: "Too Many Attempts",
|
|
353
|
-
description: "You have made too many requests recently. Please wait a moment before trying again."
|
|
354
|
-
},
|
|
355
|
-
REQUIRES_VERIFICATION: {
|
|
356
|
-
title: "Verification Required",
|
|
357
|
-
description: "You need to verify your account before you can continue. Please check your email or phone."
|
|
358
|
-
},
|
|
359
|
-
UNAUTHORIZED: {
|
|
360
|
-
title: "Unauthorized",
|
|
361
|
-
description: "You are not authorized to perform this action. Please sign in again."
|
|
362
|
-
},
|
|
363
|
-
ACCESS_DENIED: {
|
|
364
|
-
title: "Access Denied",
|
|
365
|
-
description: "You do not have permission to access this resource. Please contact support if you believe this is an error."
|
|
366
|
-
},
|
|
367
|
-
HAS_NO_PASSWORD: {
|
|
368
|
-
title: "No Password Set",
|
|
369
|
-
description: "Your account does not have a password set (e.g. social login). Please sign in with your provider or reset your password."
|
|
370
|
-
}
|
|
371
|
-
};
|
|
372
|
-
var validCodes = Object.keys(AUTH_ERROR_MAPPING);
|
|
373
|
-
|
|
374
|
-
// src/utils/handle-error.ts
|
|
375
|
-
function isAuthError(err) {
|
|
376
|
-
return typeof err === "object" && err !== null && "message" in err && typeof err.message === "string";
|
|
377
|
-
}
|
|
378
|
-
function extractErrorCode(err) {
|
|
379
|
-
if (err.code && validCodes.includes(err.code)) {
|
|
380
|
-
return err.code;
|
|
381
|
-
}
|
|
382
|
-
if (err.message) {
|
|
383
|
-
const messageUpper = err.message.toUpperCase().trim();
|
|
384
|
-
if (validCodes.includes(messageUpper)) {
|
|
385
|
-
return messageUpper;
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
return "";
|
|
389
|
-
}
|
|
390
|
-
function sanitizeErrorMessage(message) {
|
|
391
|
-
const lowerMessage = message.toLowerCase();
|
|
392
|
-
const isDatabaseError = lowerMessage.includes("failed query") || lowerMessage.includes("select") || lowerMessage.includes("insert") || lowerMessage.includes("update") || lowerMessage.includes("delete") || lowerMessage.includes("from") || lowerMessage.includes("where") || lowerMessage.includes("limit") || lowerMessage.includes("params:") || lowerMessage.includes("query") || message.includes('"iam".') || message.includes('"tenants"') || message.includes('"users"') || message.includes('"sessions"') || message.includes('"accounts"') || lowerMessage.includes("relation") || lowerMessage.includes("column") || lowerMessage.includes("syntax error") || lowerMessage.includes("database") || lowerMessage.includes("postgres") || lowerMessage.includes("sql");
|
|
393
|
-
if (isDatabaseError) {
|
|
394
|
-
return "An error occurred while processing your request";
|
|
395
|
-
}
|
|
396
|
-
return message;
|
|
397
|
-
}
|
|
398
|
-
function handleAuthError(err, setError, t) {
|
|
399
|
-
const errorCode = extractErrorCode(err);
|
|
400
|
-
if (errorCode && AUTH_ERROR_MAPPING[errorCode]) {
|
|
401
|
-
const mapping = AUTH_ERROR_MAPPING[errorCode];
|
|
402
|
-
setError({
|
|
403
|
-
title: mapping.title,
|
|
404
|
-
description: mapping.description
|
|
405
|
-
});
|
|
406
|
-
return;
|
|
407
|
-
}
|
|
408
|
-
const sanitizedMessage = sanitizeErrorMessage(
|
|
409
|
-
err.message || t("errors.fallback")
|
|
410
|
-
);
|
|
411
|
-
setError({
|
|
412
|
-
title: t("errors.fallback"),
|
|
413
|
-
description: sanitizedMessage
|
|
414
|
-
});
|
|
415
|
-
}
|
|
416
|
-
function handleGenericError(err, setError, t) {
|
|
417
|
-
const rawMessage = err instanceof Error ? err.message : t("errors.fallback");
|
|
418
|
-
const sanitizedMessage = sanitizeErrorMessage(rawMessage);
|
|
419
|
-
setError({
|
|
420
|
-
title: "Error",
|
|
421
|
-
description: sanitizedMessage
|
|
422
|
-
});
|
|
423
|
-
}
|
|
424
|
-
var handleError = (err, setError, t) => {
|
|
425
|
-
if (isAuthError(err)) {
|
|
426
|
-
handleAuthError(err, setError, t);
|
|
427
|
-
} else {
|
|
428
|
-
handleGenericError(err, setError, t);
|
|
429
|
-
}
|
|
430
|
-
};
|
|
431
|
-
|
|
432
|
-
// src/components/auth/auth-layout.tsx
|
|
433
|
-
import { jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
434
|
-
var AuthLayout = ({
|
|
435
|
-
title,
|
|
436
|
-
description,
|
|
437
|
-
children,
|
|
438
|
-
footer,
|
|
439
|
-
logoImage
|
|
440
|
-
}) => {
|
|
441
|
-
return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
442
|
-
/* @__PURE__ */ jsx3("div", { className: "flex size-8 mb-6 w-full items-center justify-center rounded-md", children: /* @__PURE__ */ jsx3(
|
|
443
|
-
"img",
|
|
444
|
-
{
|
|
445
|
-
src: logoImage || "",
|
|
446
|
-
alt: title,
|
|
447
|
-
width: 42,
|
|
448
|
-
height: 42
|
|
449
|
-
}
|
|
450
|
-
) }),
|
|
451
|
-
/* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
452
|
-
/* @__PURE__ */ jsx3("h1", { className: "text-2xl font-bold tracking-tight", children: title }),
|
|
453
|
-
description && /* @__PURE__ */ jsx3("p", { className: "mt-2 text-sm text-muted-foreground", children: description })
|
|
454
|
-
] }),
|
|
455
|
-
children,
|
|
456
|
-
footer && /* @__PURE__ */ jsx3("div", { className: "mt-2 w-full", children: /* @__PURE__ */ jsx3("div", { className: "w-full text-center text-sm text-muted-foreground", children: footer }) })
|
|
457
|
-
] });
|
|
458
|
-
};
|
|
459
|
-
|
|
460
|
-
// src/components/auth/forgot-password.tsx
|
|
461
|
-
import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
462
|
-
var forgotPasswordSchema = (t) => z.object({
|
|
463
|
-
account: z.string().min(1, t("errors.accountRequired"))
|
|
464
|
-
});
|
|
465
|
-
var ForgotPassword = () => {
|
|
466
|
-
const { hooks } = useApi();
|
|
467
|
-
const { config } = useConfig();
|
|
468
|
-
const mesob = useMesob2();
|
|
469
|
-
const t = useTranslator("Auth.forgotPassword");
|
|
470
|
-
const Link = mesob?.navigation?.Link;
|
|
471
|
-
const [isLoading, setIsLoading] = useState2(false);
|
|
472
|
-
const [error, setError] = useState2(null);
|
|
473
|
-
const forgotPasswordMutation = hooks.useMutation("post", "/password/forgot");
|
|
474
|
-
const signInLink = config.navigation?.links?.signIn || "/auth/sign-in";
|
|
475
|
-
const onNavigate = config.navigation?.onNavigate || ((path) => {
|
|
476
|
-
if (typeof window !== "undefined") {
|
|
477
|
-
window.location.href = path;
|
|
478
|
-
}
|
|
479
|
-
});
|
|
480
|
-
const logoImage = config.ui.logoImage;
|
|
481
|
-
const form = useForm({
|
|
482
|
-
resolver: zodResolver(forgotPasswordSchema(t)),
|
|
483
|
-
defaultValues: {
|
|
484
|
-
account: ""
|
|
485
|
-
}
|
|
486
|
-
});
|
|
487
|
-
useEffect(() => {
|
|
488
|
-
if (error) {
|
|
489
|
-
toast.error(error.title || "Error", {
|
|
490
|
-
description: error.description
|
|
491
|
-
});
|
|
492
|
-
}
|
|
493
|
-
}, [error]);
|
|
494
|
-
const handleSubmit = form.handleSubmit(async (values) => {
|
|
495
|
-
setIsLoading(true);
|
|
496
|
-
setError(null);
|
|
497
|
-
try {
|
|
498
|
-
const res = await forgotPasswordMutation.mutateAsync({
|
|
499
|
-
body: {
|
|
500
|
-
identifier: values.account
|
|
501
|
-
}
|
|
502
|
-
});
|
|
503
|
-
if ("verificationId" in res && res.verificationId) {
|
|
504
|
-
onNavigate(`/auth/reset-password?verificationId=${res.verificationId}`);
|
|
505
|
-
} else {
|
|
506
|
-
onNavigate(
|
|
507
|
-
`/auth/reset-password?identifier=${encodeURIComponent(values.account)}`
|
|
508
|
-
);
|
|
509
|
-
}
|
|
510
|
-
} catch (err) {
|
|
511
|
-
handleError(err, setError, t);
|
|
512
|
-
} finally {
|
|
513
|
-
setIsLoading(false);
|
|
514
|
-
}
|
|
515
|
-
});
|
|
516
|
-
let errorContent = null;
|
|
517
|
-
if (error) {
|
|
518
|
-
if (typeof error === "string") {
|
|
519
|
-
errorContent = { title: "Error", description: error };
|
|
520
|
-
} else {
|
|
521
|
-
errorContent = error;
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
|
-
return /* @__PURE__ */ jsxs2(
|
|
525
|
-
AuthLayout,
|
|
526
|
-
{
|
|
527
|
-
title: config.ui.name,
|
|
528
|
-
description: t("description"),
|
|
529
|
-
logoImage,
|
|
530
|
-
footer: Link ? /* @__PURE__ */ jsx4(Link, { href: signInLink, className: "text-primary hover:underline", children: t("footer.backToSignIn") }) : /* @__PURE__ */ jsx4(
|
|
531
|
-
"a",
|
|
532
|
-
{
|
|
533
|
-
href: signInLink,
|
|
534
|
-
onClick: (e) => {
|
|
535
|
-
e.preventDefault();
|
|
536
|
-
onNavigate(signInLink);
|
|
537
|
-
},
|
|
538
|
-
className: "text-primary hover:underline",
|
|
539
|
-
children: t("footer.backToSignIn")
|
|
540
|
-
}
|
|
541
|
-
),
|
|
542
|
-
children: [
|
|
543
|
-
/* @__PURE__ */ jsx4(Form, { ...form, children: /* @__PURE__ */ jsxs2(
|
|
544
|
-
"form",
|
|
545
|
-
{
|
|
546
|
-
id: "forgot-password-form",
|
|
547
|
-
onSubmit: handleSubmit,
|
|
548
|
-
className: "space-y-4",
|
|
549
|
-
children: [
|
|
550
|
-
/* @__PURE__ */ jsx4(
|
|
551
|
-
FormField,
|
|
552
|
-
{
|
|
553
|
-
control: form.control,
|
|
554
|
-
name: "account",
|
|
555
|
-
render: ({ field }) => /* @__PURE__ */ jsxs2(FormItem, { children: [
|
|
556
|
-
/* @__PURE__ */ jsx4(FormLabel, { children: t("form.accountLabel") }),
|
|
557
|
-
/* @__PURE__ */ jsx4(FormControl, { children: /* @__PURE__ */ jsx4(Input, { ...field, type: "text" }) }),
|
|
558
|
-
/* @__PURE__ */ jsx4(FormMessage, {})
|
|
559
|
-
] })
|
|
560
|
-
}
|
|
561
|
-
),
|
|
562
|
-
/* @__PURE__ */ jsx4(
|
|
563
|
-
Button,
|
|
564
|
-
{
|
|
565
|
-
type: "submit",
|
|
566
|
-
form: "forgot-password-form",
|
|
567
|
-
className: "w-full",
|
|
568
|
-
disabled: isLoading || forgotPasswordMutation.isPending,
|
|
569
|
-
loading: isLoading || forgotPasswordMutation.isPending,
|
|
570
|
-
children: isLoading || forgotPasswordMutation.isPending ? t("form.submitting") : t("form.submit")
|
|
571
|
-
}
|
|
572
|
-
)
|
|
573
|
-
]
|
|
574
|
-
}
|
|
575
|
-
) }),
|
|
576
|
-
errorContent && /* @__PURE__ */ jsxs2(Alert, { variant: "destructive", className: "mt-4", children: [
|
|
577
|
-
/* @__PURE__ */ jsx4(IconAlertCircle, { className: "h-4 w-4" }),
|
|
578
|
-
/* @__PURE__ */ jsx4(AlertTitle, { children: errorContent.title }),
|
|
579
|
-
/* @__PURE__ */ jsx4(AlertDescription, { children: errorContent.description })
|
|
580
|
-
] })
|
|
581
|
-
]
|
|
582
|
-
}
|
|
583
|
-
);
|
|
584
|
-
};
|
|
585
|
-
|
|
586
|
-
// src/components/auth/reset-password-form.tsx
|
|
587
|
-
import { zodResolver as zodResolver2 } from "@hookform/resolvers/zod";
|
|
3
|
+
TenantDetailPageContent
|
|
4
|
+
} from "./chunk-OFLSINVU.js";
|
|
588
5
|
import {
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
AlertTitle as AlertTitle2,
|
|
592
|
-
Button as Button2,
|
|
593
|
-
Form as Form2,
|
|
594
|
-
FormControl as FormControl2,
|
|
595
|
-
FormField as FormField2,
|
|
596
|
-
FormItem as FormItem2,
|
|
597
|
-
FormLabel as FormLabel2,
|
|
598
|
-
FormMessage as FormMessage2,
|
|
599
|
-
Input as Input2,
|
|
600
|
-
InputOTP,
|
|
601
|
-
InputOTPGroup,
|
|
602
|
-
InputOTPSlot,
|
|
603
|
-
useFormField
|
|
604
|
-
} from "@mesob/ui/components";
|
|
605
|
-
import { useMesob as useMesob3 } from "@mesob/ui/providers";
|
|
606
|
-
import { IconAlertCircle as IconAlertCircle2, IconEye, IconEyeOff } from "@tabler/icons-react";
|
|
607
|
-
import { useEffect as useEffect2, useState as useState3 } from "react";
|
|
608
|
-
import { useForm as useForm2 } from "react-hook-form";
|
|
609
|
-
import { toast as toast2 } from "sonner";
|
|
610
|
-
import { z as z2 } from "zod";
|
|
611
|
-
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
612
|
-
function PasswordInput({ field, show, onToggle }) {
|
|
613
|
-
const { formItemId, error } = useFormField();
|
|
614
|
-
return /* @__PURE__ */ jsxs3("div", { className: "relative", children: [
|
|
615
|
-
/* @__PURE__ */ jsx5(
|
|
616
|
-
Input2,
|
|
617
|
-
{
|
|
618
|
-
...field,
|
|
619
|
-
id: formItemId,
|
|
620
|
-
type: show ? "text" : "password",
|
|
621
|
-
"aria-invalid": !!error,
|
|
622
|
-
className: "pr-10"
|
|
623
|
-
}
|
|
624
|
-
),
|
|
625
|
-
/* @__PURE__ */ jsx5(
|
|
626
|
-
Button2,
|
|
627
|
-
{
|
|
628
|
-
type: "button",
|
|
629
|
-
variant: "ghost",
|
|
630
|
-
size: "icon",
|
|
631
|
-
className: "absolute right-0 top-0 h-full px-3 text-muted-foreground hover:text-foreground",
|
|
632
|
-
onClick: onToggle,
|
|
633
|
-
"aria-label": show ? "Hide password" : "Show password",
|
|
634
|
-
children: show ? /* @__PURE__ */ jsx5(IconEyeOff, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx5(IconEye, { className: "h-4 w-4" })
|
|
635
|
-
}
|
|
636
|
-
)
|
|
637
|
-
] });
|
|
638
|
-
}
|
|
639
|
-
var resetPasswordSchema = (t) => z2.object({
|
|
640
|
-
code: z2.string().length(6, t("errors.codeLength")),
|
|
641
|
-
password: z2.string().min(8, t("errors.passwordLength")),
|
|
642
|
-
confirmPassword: z2.string()
|
|
643
|
-
}).refine((data) => data.password === data.confirmPassword, {
|
|
644
|
-
message: t("errors.passwordsMismatch"),
|
|
645
|
-
path: ["confirmPassword"]
|
|
646
|
-
});
|
|
647
|
-
var ResetPasswordForm = ({
|
|
648
|
-
verificationId,
|
|
649
|
-
redirectUrl
|
|
650
|
-
}) => {
|
|
651
|
-
const { hooks, refresh } = useApi();
|
|
652
|
-
const { config } = useConfig();
|
|
653
|
-
const mesob = useMesob3();
|
|
654
|
-
const Link = mesob?.navigation?.Link;
|
|
655
|
-
const t = useTranslator("Auth.resetPassword");
|
|
656
|
-
const common = useTranslator("Common");
|
|
657
|
-
const [isLoading, setIsLoading] = useState3(false);
|
|
658
|
-
const [error, setError] = useState3(null);
|
|
659
|
-
const [showPassword, setShowPassword] = useState3(false);
|
|
660
|
-
const resetPasswordMutation = hooks.useMutation("post", "/password/reset");
|
|
661
|
-
const signInLink = config.navigation?.links?.signIn || "/auth/sign-in";
|
|
662
|
-
const forgotPasswordLink = config.navigation?.links?.forgotPassword || "/auth/forgot-password";
|
|
663
|
-
const onNavigate = config.navigation?.onNavigate || ((path) => {
|
|
664
|
-
if (typeof window !== "undefined") {
|
|
665
|
-
window.location.href = path;
|
|
666
|
-
}
|
|
667
|
-
});
|
|
668
|
-
const logoImage = config.ui.logoImage;
|
|
669
|
-
const defaultRedirect = redirectUrl || config.navigation?.defaultRedirectUrl || "/";
|
|
670
|
-
const form = useForm2({
|
|
671
|
-
resolver: zodResolver2(resetPasswordSchema(t)),
|
|
672
|
-
defaultValues: {
|
|
673
|
-
code: "",
|
|
674
|
-
password: "",
|
|
675
|
-
confirmPassword: ""
|
|
676
|
-
}
|
|
677
|
-
});
|
|
678
|
-
useEffect2(() => {
|
|
679
|
-
if (error) {
|
|
680
|
-
toast2.error(error.title || "Error", {
|
|
681
|
-
description: error.description
|
|
682
|
-
});
|
|
683
|
-
}
|
|
684
|
-
}, [error]);
|
|
685
|
-
const handleSubmit = form.handleSubmit(async (values) => {
|
|
686
|
-
if (!verificationId) {
|
|
687
|
-
setError({
|
|
688
|
-
title: t("errors.fallback"),
|
|
689
|
-
description: t("errors.missingVerificationId")
|
|
690
|
-
});
|
|
691
|
-
return;
|
|
692
|
-
}
|
|
693
|
-
setIsLoading(true);
|
|
694
|
-
setError(null);
|
|
695
|
-
try {
|
|
696
|
-
await resetPasswordMutation.mutateAsync({
|
|
697
|
-
body: {
|
|
698
|
-
verificationId,
|
|
699
|
-
code: values.code,
|
|
700
|
-
password: values.password
|
|
701
|
-
}
|
|
702
|
-
});
|
|
703
|
-
await refresh();
|
|
704
|
-
onNavigate(defaultRedirect);
|
|
705
|
-
} catch (err) {
|
|
706
|
-
handleError(err, setError, t);
|
|
707
|
-
} finally {
|
|
708
|
-
setIsLoading(false);
|
|
709
|
-
}
|
|
710
|
-
});
|
|
711
|
-
if (!verificationId) {
|
|
712
|
-
return /* @__PURE__ */ jsx5(
|
|
713
|
-
AuthLayout,
|
|
714
|
-
{
|
|
715
|
-
title: common("invalidLinkTitle"),
|
|
716
|
-
description: common("invalidLinkDescription"),
|
|
717
|
-
logoImage,
|
|
718
|
-
footer: /* @__PURE__ */ jsx5(
|
|
719
|
-
Link,
|
|
720
|
-
{
|
|
721
|
-
href: forgotPasswordLink,
|
|
722
|
-
className: "text-primary hover:underline",
|
|
723
|
-
children: t("footer.requestNew")
|
|
724
|
-
}
|
|
725
|
-
),
|
|
726
|
-
children: /* @__PURE__ */ jsx5("div", {})
|
|
727
|
-
}
|
|
728
|
-
);
|
|
729
|
-
}
|
|
730
|
-
let errorContent = null;
|
|
731
|
-
if (error) {
|
|
732
|
-
if (typeof error === "string") {
|
|
733
|
-
errorContent = { title: "Error", description: error };
|
|
734
|
-
} else {
|
|
735
|
-
errorContent = error;
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
|
-
return /* @__PURE__ */ jsxs3(
|
|
739
|
-
AuthLayout,
|
|
740
|
-
{
|
|
741
|
-
title: config.ui.name,
|
|
742
|
-
description: t("description"),
|
|
743
|
-
logoImage,
|
|
744
|
-
footer: /* @__PURE__ */ jsxs3("div", { className: "flex items-center justify-between w-full gap-2", children: [
|
|
745
|
-
/* @__PURE__ */ jsx5(Link, { href: signInLink, className: "text-primary hover:underline", children: t("footer.backToSignIn") }),
|
|
746
|
-
/* @__PURE__ */ jsx5(
|
|
747
|
-
Link,
|
|
748
|
-
{
|
|
749
|
-
href: forgotPasswordLink,
|
|
750
|
-
className: "text-primary hover:underline",
|
|
751
|
-
children: t("footer.changeAccount")
|
|
752
|
-
}
|
|
753
|
-
)
|
|
754
|
-
] }),
|
|
755
|
-
children: [
|
|
756
|
-
/* @__PURE__ */ jsx5(Form2, { ...form, children: /* @__PURE__ */ jsxs3(
|
|
757
|
-
"form",
|
|
758
|
-
{
|
|
759
|
-
id: "reset-password-form",
|
|
760
|
-
onSubmit: handleSubmit,
|
|
761
|
-
className: "space-y-4",
|
|
762
|
-
children: [
|
|
763
|
-
/* @__PURE__ */ jsx5(
|
|
764
|
-
FormField2,
|
|
765
|
-
{
|
|
766
|
-
control: form.control,
|
|
767
|
-
name: "code",
|
|
768
|
-
render: ({ field }) => /* @__PURE__ */ jsxs3(FormItem2, { children: [
|
|
769
|
-
/* @__PURE__ */ jsx5("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx5(FormLabel2, { children: t("form.codeLabel") }) }),
|
|
770
|
-
/* @__PURE__ */ jsx5(FormControl2, { children: /* @__PURE__ */ jsx5(
|
|
771
|
-
InputOTP,
|
|
772
|
-
{
|
|
773
|
-
maxLength: 6,
|
|
774
|
-
value: field.value,
|
|
775
|
-
onChange: field.onChange,
|
|
776
|
-
onBlur: field.onBlur,
|
|
777
|
-
containerClassName: "gap-4 flex justify-center mt-2",
|
|
778
|
-
children: /* @__PURE__ */ jsxs3(InputOTPGroup, { className: "gap-3 *:data-[slot=input-otp-slot]:h-12 *:data-[slot=input-otp-slot]:w-12 *:data-[slot=input-otp-slot]:rounded-md *:data-[slot=input-otp-slot]:border *:data-[slot=input-otp-slot]:text-xl", children: [
|
|
779
|
-
/* @__PURE__ */ jsx5(InputOTPSlot, { className: "h-12", index: 0 }),
|
|
780
|
-
/* @__PURE__ */ jsx5(InputOTPSlot, { className: "h-12", index: 1 }),
|
|
781
|
-
/* @__PURE__ */ jsx5(InputOTPSlot, { className: "h-12", index: 2 }),
|
|
782
|
-
/* @__PURE__ */ jsx5(InputOTPSlot, { className: "h-12", index: 3 }),
|
|
783
|
-
/* @__PURE__ */ jsx5(InputOTPSlot, { className: "h-12", index: 4 }),
|
|
784
|
-
/* @__PURE__ */ jsx5(InputOTPSlot, { className: "h-12", index: 5 })
|
|
785
|
-
] })
|
|
786
|
-
}
|
|
787
|
-
) }),
|
|
788
|
-
/* @__PURE__ */ jsx5(FormMessage2, {})
|
|
789
|
-
] })
|
|
790
|
-
}
|
|
791
|
-
),
|
|
792
|
-
/* @__PURE__ */ jsx5(
|
|
793
|
-
FormField2,
|
|
794
|
-
{
|
|
795
|
-
control: form.control,
|
|
796
|
-
name: "password",
|
|
797
|
-
render: ({ field }) => /* @__PURE__ */ jsxs3(FormItem2, { children: [
|
|
798
|
-
/* @__PURE__ */ jsx5(FormLabel2, { children: t("form.passwordLabel") }),
|
|
799
|
-
/* @__PURE__ */ jsx5(
|
|
800
|
-
PasswordInput,
|
|
801
|
-
{
|
|
802
|
-
field,
|
|
803
|
-
show: showPassword,
|
|
804
|
-
onToggle: () => setShowPassword(!showPassword)
|
|
805
|
-
}
|
|
806
|
-
),
|
|
807
|
-
/* @__PURE__ */ jsx5(FormMessage2, {})
|
|
808
|
-
] })
|
|
809
|
-
}
|
|
810
|
-
),
|
|
811
|
-
/* @__PURE__ */ jsx5(
|
|
812
|
-
FormField2,
|
|
813
|
-
{
|
|
814
|
-
control: form.control,
|
|
815
|
-
name: "confirmPassword",
|
|
816
|
-
render: ({ field }) => /* @__PURE__ */ jsxs3(FormItem2, { children: [
|
|
817
|
-
/* @__PURE__ */ jsx5(FormLabel2, { children: t("form.confirmPasswordLabel") }),
|
|
818
|
-
/* @__PURE__ */ jsx5(
|
|
819
|
-
PasswordInput,
|
|
820
|
-
{
|
|
821
|
-
field,
|
|
822
|
-
show: showPassword,
|
|
823
|
-
onToggle: () => setShowPassword(!showPassword)
|
|
824
|
-
}
|
|
825
|
-
),
|
|
826
|
-
/* @__PURE__ */ jsx5(FormMessage2, {})
|
|
827
|
-
] })
|
|
828
|
-
}
|
|
829
|
-
),
|
|
830
|
-
/* @__PURE__ */ jsx5(
|
|
831
|
-
Button2,
|
|
832
|
-
{
|
|
833
|
-
type: "submit",
|
|
834
|
-
form: "reset-password-form",
|
|
835
|
-
className: "w-full",
|
|
836
|
-
disabled: isLoading || resetPasswordMutation.isPending,
|
|
837
|
-
loading: isLoading || resetPasswordMutation.isPending,
|
|
838
|
-
children: isLoading || resetPasswordMutation.isPending ? t("form.submitting") : t("form.submit")
|
|
839
|
-
}
|
|
840
|
-
)
|
|
841
|
-
]
|
|
842
|
-
}
|
|
843
|
-
) }),
|
|
844
|
-
errorContent && /* @__PURE__ */ jsxs3(Alert2, { variant: "destructive", className: "mt-4", children: [
|
|
845
|
-
/* @__PURE__ */ jsx5(IconAlertCircle2, { className: "h-4 w-4" }),
|
|
846
|
-
/* @__PURE__ */ jsx5(AlertTitle2, { children: errorContent.title }),
|
|
847
|
-
/* @__PURE__ */ jsx5(AlertDescription2, { children: errorContent.description })
|
|
848
|
-
] })
|
|
849
|
-
]
|
|
850
|
-
}
|
|
851
|
-
);
|
|
852
|
-
};
|
|
853
|
-
|
|
854
|
-
// src/components/auth/sign-in.tsx
|
|
855
|
-
import { zodResolver as zodResolver3 } from "@hookform/resolvers/zod";
|
|
6
|
+
UserDetailLayoutContent
|
|
7
|
+
} from "./chunk-SOCZK4CV.js";
|
|
856
8
|
import {
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
AlertTitle as AlertTitle3,
|
|
860
|
-
Button as Button3,
|
|
861
|
-
Form as Form3,
|
|
862
|
-
FormControl as FormControl3,
|
|
863
|
-
FormField as FormField3,
|
|
864
|
-
FormItem as FormItem3,
|
|
865
|
-
FormLabel as FormLabel3,
|
|
866
|
-
FormMessage as FormMessage3,
|
|
867
|
-
Input as Input3,
|
|
868
|
-
useFormField as useFormField2
|
|
869
|
-
} from "@mesob/ui/components";
|
|
870
|
-
import { useMesob as useMesob4 } from "@mesob/ui/providers";
|
|
871
|
-
import { IconAlertCircle as IconAlertCircle3, IconEye as IconEye2, IconEyeOff as IconEyeOff2 } from "@tabler/icons-react";
|
|
872
|
-
import { useEffect as useEffect3, useState as useState4 } from "react";
|
|
873
|
-
import { useForm as useForm3 } from "react-hook-form";
|
|
874
|
-
import { toast as toast3 } from "sonner";
|
|
875
|
-
import { z as z3 } from "zod";
|
|
876
|
-
|
|
877
|
-
// src/utils/normalize-phone.ts
|
|
878
|
-
function normalizePhone(phone) {
|
|
879
|
-
const cleaned = phone.trim().replace(/\s/g, "");
|
|
880
|
-
if (cleaned.startsWith("+2519") || cleaned.startsWith("+2517")) {
|
|
881
|
-
return cleaned;
|
|
882
|
-
}
|
|
883
|
-
if (cleaned.startsWith("2519") || cleaned.startsWith("2517")) {
|
|
884
|
-
return `+${cleaned}`;
|
|
885
|
-
}
|
|
886
|
-
if (cleaned.startsWith("09") || cleaned.startsWith("07")) {
|
|
887
|
-
return `+251${cleaned.slice(1)}`;
|
|
888
|
-
}
|
|
889
|
-
if ((cleaned.startsWith("9") || cleaned.startsWith("7")) && cleaned.length === 9) {
|
|
890
|
-
return `+251${cleaned}`;
|
|
891
|
-
}
|
|
892
|
-
return cleaned;
|
|
893
|
-
}
|
|
894
|
-
|
|
895
|
-
// src/components/auth/sign-in.tsx
|
|
896
|
-
import { Fragment, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
897
|
-
var isPhone = (s) => /^\+?[0-9()[\]\s-]{6,}$/.test(s);
|
|
898
|
-
function PasswordInput2({ field, show, onToggle }) {
|
|
899
|
-
const { formItemId, error } = useFormField2();
|
|
900
|
-
return /* @__PURE__ */ jsxs4("div", { className: "relative", children: [
|
|
901
|
-
/* @__PURE__ */ jsx6(
|
|
902
|
-
Input3,
|
|
903
|
-
{
|
|
904
|
-
...field,
|
|
905
|
-
id: formItemId,
|
|
906
|
-
type: show ? "text" : "password",
|
|
907
|
-
autoComplete: "current-password",
|
|
908
|
-
"aria-invalid": !!error,
|
|
909
|
-
className: "pr-10"
|
|
910
|
-
}
|
|
911
|
-
),
|
|
912
|
-
/* @__PURE__ */ jsx6(
|
|
913
|
-
Button3,
|
|
914
|
-
{
|
|
915
|
-
type: "button",
|
|
916
|
-
variant: "ghost",
|
|
917
|
-
size: "icon",
|
|
918
|
-
className: "absolute right-0 top-0 h-full px-3 text-muted-foreground hover:text-foreground",
|
|
919
|
-
onClick: onToggle,
|
|
920
|
-
"aria-label": show ? "Hide password" : "Show password",
|
|
921
|
-
children: show ? /* @__PURE__ */ jsx6(IconEyeOff2, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx6(IconEye2, { className: "h-4 w-4" })
|
|
922
|
-
}
|
|
923
|
-
)
|
|
924
|
-
] });
|
|
925
|
-
}
|
|
926
|
-
var signInSchema = (t, phoneRegex) => z3.object({
|
|
927
|
-
username: z3.string().trim().min(1, { message: t("errors.requiredField") }).refine(
|
|
928
|
-
(val) => {
|
|
929
|
-
const isEmail = z3.email().safeParse(val).success;
|
|
930
|
-
const isPhone3 = phoneRegex.test(val);
|
|
931
|
-
return isEmail || isPhone3;
|
|
932
|
-
},
|
|
933
|
-
{ message: t("errors.invalidEmailOrPhone") }
|
|
934
|
-
),
|
|
935
|
-
password: z3.union([
|
|
936
|
-
z3.literal(""),
|
|
937
|
-
z3.string().min(8, t("errors.passwordLength")).max(128, t("errors.longPasswordError"))
|
|
938
|
-
]).optional()
|
|
939
|
-
});
|
|
940
|
-
var SignIn = ({ redirectUrl } = {}) => {
|
|
941
|
-
const { hooks, setAuth } = useApi();
|
|
942
|
-
const { config } = useConfig();
|
|
943
|
-
const mesob = useMesob4();
|
|
944
|
-
const t = useTranslator("Auth.signIn");
|
|
945
|
-
const Link = mesob?.navigation?.Link;
|
|
946
|
-
const [isLoading, setIsLoading] = useState4(false);
|
|
947
|
-
const [error, setError] = useState4(null);
|
|
948
|
-
const [showPasswordField, setShowPasswordField] = useState4(false);
|
|
949
|
-
const [showPassword, setShowPassword] = useState4(false);
|
|
950
|
-
const [username, setUsername] = useState4("");
|
|
951
|
-
const [isChecking, setIsChecking] = useState4(false);
|
|
952
|
-
const checkUserMutation = hooks.useMutation("post", "/check-account");
|
|
953
|
-
const signInMutation = hooks.useMutation("post", "/sign-in");
|
|
954
|
-
const phoneRegex = typeof config.phoneRegex === "string" ? new RegExp(config.phoneRegex) : config.phoneRegex || /^(\+2519|\+2517|2519|2517|09|07)\d{8}$/;
|
|
955
|
-
const defaultRedirect = redirectUrl || config.navigation?.defaultRedirectUrl || "/dashboard";
|
|
956
|
-
const forgotPasswordLink = config.navigation?.links?.forgotPassword || "/auth/forgot-password";
|
|
957
|
-
const signUpLink = config.navigation?.links?.signUp || "/auth/sign-up";
|
|
958
|
-
const onNavigate = config.navigation?.onNavigate || ((path) => {
|
|
959
|
-
if (typeof window !== "undefined") {
|
|
960
|
-
window.location.href = path;
|
|
961
|
-
}
|
|
962
|
-
});
|
|
963
|
-
const logoImage = config.ui.logoImage;
|
|
964
|
-
const form = useForm3({
|
|
965
|
-
resolver: zodResolver3(signInSchema(t, phoneRegex)),
|
|
966
|
-
defaultValues: { username: "", password: "" },
|
|
967
|
-
mode: "onBlur"
|
|
968
|
-
});
|
|
969
|
-
useEffect3(() => {
|
|
970
|
-
if (error) {
|
|
971
|
-
toast3.error(error.title || "Error", {
|
|
972
|
-
description: error.description
|
|
973
|
-
});
|
|
974
|
-
}
|
|
975
|
-
}, [error]);
|
|
976
|
-
const handleCheckAccount = async (usernameValue) => {
|
|
977
|
-
setIsChecking(true);
|
|
978
|
-
try {
|
|
979
|
-
const normalizedUsername = phoneRegex.test(usernameValue) ? normalizePhone(usernameValue) : usernameValue;
|
|
980
|
-
const result = await checkUserMutation.mutateAsync({
|
|
981
|
-
body: {
|
|
982
|
-
username: normalizedUsername
|
|
983
|
-
}
|
|
984
|
-
});
|
|
985
|
-
if (result.exists) {
|
|
986
|
-
setUsername(normalizedUsername);
|
|
987
|
-
form.setValue("username", normalizedUsername);
|
|
988
|
-
setShowPasswordField(true);
|
|
989
|
-
} else {
|
|
990
|
-
const email = isPhone(normalizedUsername) ? "" : normalizedUsername;
|
|
991
|
-
const redirectParam = defaultRedirect ? `&redirect=${encodeURIComponent(defaultRedirect)}` : "";
|
|
992
|
-
if (email) {
|
|
993
|
-
onNavigate(
|
|
994
|
-
`${signUpLink}?email=${encodeURIComponent(email)}${redirectParam}`
|
|
995
|
-
);
|
|
996
|
-
} else {
|
|
997
|
-
onNavigate(
|
|
998
|
-
`${signUpLink}?phone=${encodeURIComponent(normalizedUsername)}${redirectParam}`
|
|
999
|
-
);
|
|
1000
|
-
}
|
|
1001
|
-
}
|
|
1002
|
-
} catch {
|
|
1003
|
-
form.setError("username", { message: t("errors.checkAccountFailed") });
|
|
1004
|
-
} finally {
|
|
1005
|
-
setIsChecking(false);
|
|
1006
|
-
}
|
|
1007
|
-
};
|
|
1008
|
-
const onSubmit = async (values) => {
|
|
1009
|
-
if (showPasswordField) {
|
|
1010
|
-
const pwd = values.password;
|
|
1011
|
-
if (!pwd || pwd.length < 8) {
|
|
1012
|
-
form.setError("password", { message: t("errors.passwordLength") });
|
|
1013
|
-
return;
|
|
1014
|
-
}
|
|
1015
|
-
await handlePasswordSubmit({ password: pwd });
|
|
1016
|
-
} else {
|
|
1017
|
-
await handleCheckAccount(values.username);
|
|
1018
|
-
}
|
|
1019
|
-
};
|
|
1020
|
-
const handlePasswordSubmit = async (values) => {
|
|
1021
|
-
setIsLoading(true);
|
|
1022
|
-
setError(null);
|
|
1023
|
-
try {
|
|
1024
|
-
const res = await signInMutation.mutateAsync({
|
|
1025
|
-
body: {
|
|
1026
|
-
identifier: username,
|
|
1027
|
-
password: values.password
|
|
1028
|
-
}
|
|
1029
|
-
});
|
|
1030
|
-
if ("verificationId" in res && res.verificationId) {
|
|
1031
|
-
const redirectParam = defaultRedirect ? `&redirect=${encodeURIComponent(defaultRedirect)}` : "";
|
|
1032
|
-
const verifyPath = isPhone(username) ? `/auth/verify-phone?context=sign-in&verificationId=${res.verificationId}&identifier=${encodeURIComponent(username)}${redirectParam}` : `/auth/verify-email?verificationId=${res.verificationId}${redirectParam}`;
|
|
1033
|
-
onNavigate(verifyPath);
|
|
1034
|
-
return;
|
|
1035
|
-
}
|
|
1036
|
-
if ("user" in res && "session" in res) {
|
|
1037
|
-
setAuth(res);
|
|
1038
|
-
}
|
|
1039
|
-
onNavigate(defaultRedirect);
|
|
1040
|
-
} catch (err) {
|
|
1041
|
-
handleError(err, setError, t);
|
|
1042
|
-
} finally {
|
|
1043
|
-
setIsLoading(false);
|
|
1044
|
-
}
|
|
1045
|
-
};
|
|
1046
|
-
const handleBack = () => {
|
|
1047
|
-
setShowPasswordField(false);
|
|
1048
|
-
setUsername("");
|
|
1049
|
-
form.setValue("password", "");
|
|
1050
|
-
};
|
|
1051
|
-
const isSubmitting = isLoading || checkUserMutation.isPending || signInMutation.isPending || isChecking;
|
|
1052
|
-
let submitLabel = t("form.continue");
|
|
1053
|
-
if (isSubmitting) {
|
|
1054
|
-
submitLabel = showPasswordField ? t("form.submitting") : t("form.checking");
|
|
1055
|
-
} else if (showPasswordField) {
|
|
1056
|
-
submitLabel = t("form.submit");
|
|
1057
|
-
}
|
|
1058
|
-
let errorContent = null;
|
|
1059
|
-
if (error) {
|
|
1060
|
-
if (typeof error === "string") {
|
|
1061
|
-
errorContent = { title: "Error", description: error };
|
|
1062
|
-
} else {
|
|
1063
|
-
errorContent = error;
|
|
1064
|
-
}
|
|
1065
|
-
}
|
|
1066
|
-
const formContent = /* @__PURE__ */ jsx6(Form3, { ...form, children: /* @__PURE__ */ jsxs4(
|
|
1067
|
-
"form",
|
|
1068
|
-
{
|
|
1069
|
-
id: "sign-in-form",
|
|
1070
|
-
onSubmit: form.handleSubmit(onSubmit),
|
|
1071
|
-
className: "space-y-4",
|
|
1072
|
-
children: [
|
|
1073
|
-
showPasswordField ? /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
1074
|
-
/* @__PURE__ */ jsxs4(FormItem3, { children: [
|
|
1075
|
-
/* @__PURE__ */ jsxs4(FormLabel3, { className: "flex justify-between items-center", children: [
|
|
1076
|
-
t("form.accountLabel"),
|
|
1077
|
-
/* @__PURE__ */ jsx6(
|
|
1078
|
-
Button3,
|
|
1079
|
-
{
|
|
1080
|
-
type: "button",
|
|
1081
|
-
variant: "link",
|
|
1082
|
-
size: "sm",
|
|
1083
|
-
className: "p-0 m-0 h-auto",
|
|
1084
|
-
onClick: handleBack,
|
|
1085
|
-
children: t("changeAccount")
|
|
1086
|
-
}
|
|
1087
|
-
)
|
|
1088
|
-
] }),
|
|
1089
|
-
/* @__PURE__ */ jsx6(
|
|
1090
|
-
Input3,
|
|
1091
|
-
{
|
|
1092
|
-
id: "sign-in-username",
|
|
1093
|
-
type: "text",
|
|
1094
|
-
value: username,
|
|
1095
|
-
autoComplete: "username",
|
|
1096
|
-
disabled: true
|
|
1097
|
-
}
|
|
1098
|
-
)
|
|
1099
|
-
] }),
|
|
1100
|
-
/* @__PURE__ */ jsx6(
|
|
1101
|
-
FormField3,
|
|
1102
|
-
{
|
|
1103
|
-
control: form.control,
|
|
1104
|
-
name: "password",
|
|
1105
|
-
render: ({ field }) => /* @__PURE__ */ jsxs4(FormItem3, { children: [
|
|
1106
|
-
/* @__PURE__ */ jsx6(FormLabel3, { children: t("form.passwordLabel") }),
|
|
1107
|
-
/* @__PURE__ */ jsx6(
|
|
1108
|
-
PasswordInput2,
|
|
1109
|
-
{
|
|
1110
|
-
field: { ...field, value: field.value ?? "" },
|
|
1111
|
-
show: showPassword,
|
|
1112
|
-
onToggle: () => setShowPassword(!showPassword)
|
|
1113
|
-
}
|
|
1114
|
-
),
|
|
1115
|
-
/* @__PURE__ */ jsx6(FormMessage3, {})
|
|
1116
|
-
] })
|
|
1117
|
-
}
|
|
1118
|
-
)
|
|
1119
|
-
] }) : /* @__PURE__ */ jsx6(
|
|
1120
|
-
FormField3,
|
|
1121
|
-
{
|
|
1122
|
-
control: form.control,
|
|
1123
|
-
name: "username",
|
|
1124
|
-
render: ({ field }) => /* @__PURE__ */ jsxs4(FormItem3, { children: [
|
|
1125
|
-
/* @__PURE__ */ jsx6(FormLabel3, { children: t("form.accountLabel") }),
|
|
1126
|
-
/* @__PURE__ */ jsx6(FormControl3, { children: /* @__PURE__ */ jsx6(Input3, { ...field, type: "text", autoComplete: "username" }) }),
|
|
1127
|
-
/* @__PURE__ */ jsx6(FormMessage3, {})
|
|
1128
|
-
] })
|
|
1129
|
-
}
|
|
1130
|
-
),
|
|
1131
|
-
/* @__PURE__ */ jsx6(
|
|
1132
|
-
Button3,
|
|
1133
|
-
{
|
|
1134
|
-
type: "submit",
|
|
1135
|
-
className: "w-full",
|
|
1136
|
-
disabled: isSubmitting,
|
|
1137
|
-
loading: isSubmitting,
|
|
1138
|
-
children: submitLabel
|
|
1139
|
-
}
|
|
1140
|
-
)
|
|
1141
|
-
]
|
|
1142
|
-
}
|
|
1143
|
-
) });
|
|
1144
|
-
return /* @__PURE__ */ jsx6("div", { className: "space-y-4", children: /* @__PURE__ */ jsxs4(
|
|
1145
|
-
AuthLayout,
|
|
1146
|
-
{
|
|
1147
|
-
title: config.ui.name,
|
|
1148
|
-
description: t("description"),
|
|
1149
|
-
logoImage,
|
|
1150
|
-
footer: showPasswordField ? /* @__PURE__ */ jsx6("div", { className: "flex items-center justify-center w-full", children: Link ? /* @__PURE__ */ jsx6(
|
|
1151
|
-
Link,
|
|
1152
|
-
{
|
|
1153
|
-
href: forgotPasswordLink,
|
|
1154
|
-
className: "text-primary inline-block hover:underline",
|
|
1155
|
-
children: t("footer.forgotPassword")
|
|
1156
|
-
}
|
|
1157
|
-
) : /* @__PURE__ */ jsx6(
|
|
1158
|
-
"a",
|
|
1159
|
-
{
|
|
1160
|
-
href: forgotPasswordLink,
|
|
1161
|
-
onClick: (e) => {
|
|
1162
|
-
e.preventDefault();
|
|
1163
|
-
onNavigate(forgotPasswordLink);
|
|
1164
|
-
},
|
|
1165
|
-
className: "text-primary inline-block hover:underline",
|
|
1166
|
-
children: t("footer.forgotPassword")
|
|
1167
|
-
}
|
|
1168
|
-
) }) : void 0,
|
|
1169
|
-
children: [
|
|
1170
|
-
formContent,
|
|
1171
|
-
errorContent && /* @__PURE__ */ jsxs4(Alert3, { variant: "destructive", className: "mt-4", children: [
|
|
1172
|
-
/* @__PURE__ */ jsx6(IconAlertCircle3, { className: "h-4 w-4" }),
|
|
1173
|
-
/* @__PURE__ */ jsx6(AlertTitle3, { children: errorContent.title }),
|
|
1174
|
-
/* @__PURE__ */ jsx6(AlertDescription3, { children: errorContent.description })
|
|
1175
|
-
] })
|
|
1176
|
-
]
|
|
1177
|
-
}
|
|
1178
|
-
) });
|
|
1179
|
-
};
|
|
1180
|
-
|
|
1181
|
-
// src/components/auth/sign-up.tsx
|
|
1182
|
-
import { zodResolver as zodResolver4 } from "@hookform/resolvers/zod";
|
|
9
|
+
UserDetailPageContent
|
|
10
|
+
} from "./chunk-NJPNTAAT.js";
|
|
1183
11
|
import {
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
AlertTitle as AlertTitle4,
|
|
1187
|
-
Button as Button4,
|
|
1188
|
-
Form as Form4,
|
|
1189
|
-
FormControl as FormControl4,
|
|
1190
|
-
FormField as FormField4,
|
|
1191
|
-
FormItem as FormItem4,
|
|
1192
|
-
FormLabel as FormLabel4,
|
|
1193
|
-
FormMessage as FormMessage4,
|
|
1194
|
-
Input as Input4,
|
|
1195
|
-
useFormField as useFormField3
|
|
1196
|
-
} from "@mesob/ui/components";
|
|
1197
|
-
import { useMesob as useMesob5 } from "@mesob/ui/providers";
|
|
1198
|
-
import { IconAlertCircle as IconAlertCircle4, IconEye as IconEye3, IconEyeOff as IconEyeOff3 } from "@tabler/icons-react";
|
|
1199
|
-
import { useEffect as useEffect4, useState as useState5 } from "react";
|
|
1200
|
-
import { useForm as useForm4 } from "react-hook-form";
|
|
1201
|
-
import { toast as toast4 } from "sonner";
|
|
1202
|
-
import { z as z4 } from "zod";
|
|
1203
|
-
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1204
|
-
var isPhone2 = (s) => /^\+?[0-9()[\]\s-]{6,}$/.test(s);
|
|
1205
|
-
function PasswordInput3({ field, show, onToggle }) {
|
|
1206
|
-
const { formItemId, error } = useFormField3();
|
|
1207
|
-
return /* @__PURE__ */ jsxs5("div", { className: "relative", children: [
|
|
1208
|
-
/* @__PURE__ */ jsx7(
|
|
1209
|
-
Input4,
|
|
1210
|
-
{
|
|
1211
|
-
...field,
|
|
1212
|
-
id: formItemId,
|
|
1213
|
-
type: show ? "text" : "password",
|
|
1214
|
-
"aria-invalid": !!error,
|
|
1215
|
-
className: "pr-10"
|
|
1216
|
-
}
|
|
1217
|
-
),
|
|
1218
|
-
/* @__PURE__ */ jsx7(
|
|
1219
|
-
Button4,
|
|
1220
|
-
{
|
|
1221
|
-
type: "button",
|
|
1222
|
-
variant: "ghost",
|
|
1223
|
-
size: "icon",
|
|
1224
|
-
className: "absolute right-0 top-0 h-full px-3 text-muted-foreground hover:text-foreground",
|
|
1225
|
-
onClick: onToggle,
|
|
1226
|
-
"aria-label": show ? "Hide password" : "Show password",
|
|
1227
|
-
children: show ? /* @__PURE__ */ jsx7(IconEyeOff3, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx7(IconEye3, { className: "h-4 w-4" })
|
|
1228
|
-
}
|
|
1229
|
-
)
|
|
1230
|
-
] });
|
|
1231
|
-
}
|
|
1232
|
-
var signUpSchema = (t) => z4.object({
|
|
1233
|
-
fullName: z4.string().min(1, t("errors.fullNameRequired")),
|
|
1234
|
-
identifier: z4.string().min(1, t("errors.contactRequired")).refine(
|
|
1235
|
-
(val) => {
|
|
1236
|
-
if (!val) {
|
|
1237
|
-
return false;
|
|
1238
|
-
}
|
|
1239
|
-
return val.includes("@") || isPhone2(val);
|
|
1240
|
-
},
|
|
1241
|
-
{
|
|
1242
|
-
message: t("errors.invalidEmailOrPhone")
|
|
1243
|
-
}
|
|
1244
|
-
),
|
|
1245
|
-
password: z4.string().min(8, t("errors.passwordLength")).max(128, t("errors.longPasswordError")),
|
|
1246
|
-
confirmPassword: z4.string()
|
|
1247
|
-
}).refine((data) => data.password === data.confirmPassword, {
|
|
1248
|
-
message: t("errors.passwordsMismatch"),
|
|
1249
|
-
path: ["confirmPassword"]
|
|
1250
|
-
});
|
|
1251
|
-
var SignUp = ({
|
|
1252
|
-
redirectUrl,
|
|
1253
|
-
initialIdentifier
|
|
1254
|
-
} = {}) => {
|
|
1255
|
-
const { hooks, setAuth } = useApi();
|
|
1256
|
-
const { config } = useConfig();
|
|
1257
|
-
const mesob = useMesob5();
|
|
1258
|
-
const t = useTranslator("Auth.signUp");
|
|
1259
|
-
const Link = mesob?.navigation?.Link;
|
|
1260
|
-
const [isLoading, setIsLoading] = useState5(false);
|
|
1261
|
-
const [error, setError] = useState5(null);
|
|
1262
|
-
const [showPassword, setShowPassword] = useState5(false);
|
|
1263
|
-
const [showConfirmPassword, setShowConfirmPassword] = useState5(false);
|
|
1264
|
-
const signUpMutation = hooks.useMutation("post", "/sign-up");
|
|
1265
|
-
const signInLink = config.navigation?.links?.signIn || "/auth/sign-in";
|
|
1266
|
-
const onNavigate = config.navigation?.onNavigate || ((path) => {
|
|
1267
|
-
if (typeof window !== "undefined") {
|
|
1268
|
-
window.location.href = path;
|
|
1269
|
-
}
|
|
1270
|
-
});
|
|
1271
|
-
const logoImage = config.ui.logoImage;
|
|
1272
|
-
const defaultRedirect = redirectUrl || config.navigation?.defaultRedirectUrl || "/";
|
|
1273
|
-
const hasInitialIdentifier = !!initialIdentifier;
|
|
1274
|
-
const form = useForm4({
|
|
1275
|
-
resolver: zodResolver4(signUpSchema(t)),
|
|
1276
|
-
defaultValues: {
|
|
1277
|
-
fullName: "",
|
|
1278
|
-
identifier: initialIdentifier || "",
|
|
1279
|
-
password: "",
|
|
1280
|
-
confirmPassword: ""
|
|
1281
|
-
}
|
|
1282
|
-
});
|
|
1283
|
-
useEffect4(() => {
|
|
1284
|
-
if (initialIdentifier) {
|
|
1285
|
-
form.setValue("identifier", initialIdentifier);
|
|
1286
|
-
}
|
|
1287
|
-
}, [initialIdentifier, form]);
|
|
1288
|
-
useEffect4(() => {
|
|
1289
|
-
if (error) {
|
|
1290
|
-
toast4.error(error.title || "Error", {
|
|
1291
|
-
description: error.description
|
|
1292
|
-
});
|
|
1293
|
-
}
|
|
1294
|
-
}, [error]);
|
|
1295
|
-
const handleSubmit = form.handleSubmit(async (values) => {
|
|
1296
|
-
setIsLoading(true);
|
|
1297
|
-
setError(null);
|
|
1298
|
-
try {
|
|
1299
|
-
const identifier = values.identifier;
|
|
1300
|
-
const usingPhone = isPhone2(identifier);
|
|
1301
|
-
const res = await signUpMutation.mutateAsync({
|
|
1302
|
-
body: usingPhone ? {
|
|
1303
|
-
phone: identifier,
|
|
1304
|
-
password: values.password,
|
|
1305
|
-
fullName: values.fullName,
|
|
1306
|
-
handle: values.handle
|
|
1307
|
-
} : {
|
|
1308
|
-
email: identifier,
|
|
1309
|
-
password: values.password,
|
|
1310
|
-
fullName: values.fullName,
|
|
1311
|
-
handle: values.handle
|
|
1312
|
-
}
|
|
1313
|
-
});
|
|
1314
|
-
if ("verificationId" in res && res.verificationId) {
|
|
1315
|
-
const redirectParam = defaultRedirect ? `&redirect=${encodeURIComponent(defaultRedirect)}` : "";
|
|
1316
|
-
if (usingPhone) {
|
|
1317
|
-
onNavigate(
|
|
1318
|
-
`/auth/verify-phone?context=sign-up&verificationId=${res.verificationId}&phone=${encodeURIComponent(identifier)}${redirectParam}`
|
|
1319
|
-
);
|
|
1320
|
-
} else {
|
|
1321
|
-
onNavigate(
|
|
1322
|
-
`/auth/verify-email?verificationId=${res.verificationId}&email=${encodeURIComponent(identifier)}${redirectParam}`
|
|
1323
|
-
);
|
|
1324
|
-
}
|
|
1325
|
-
return;
|
|
1326
|
-
}
|
|
1327
|
-
if ("user" in res && "session" in res) {
|
|
1328
|
-
setAuth(res);
|
|
1329
|
-
}
|
|
1330
|
-
onNavigate(defaultRedirect);
|
|
1331
|
-
} catch (err) {
|
|
1332
|
-
handleError(err, setError, t);
|
|
1333
|
-
} finally {
|
|
1334
|
-
setIsLoading(false);
|
|
1335
|
-
}
|
|
1336
|
-
});
|
|
1337
|
-
const getIdentifierLabel = () => {
|
|
1338
|
-
if (!hasInitialIdentifier) {
|
|
1339
|
-
return t("form.accountLabel") || "Email/Phone";
|
|
1340
|
-
}
|
|
1341
|
-
if (initialIdentifier?.includes("@")) {
|
|
1342
|
-
return t("form.emailLabel");
|
|
1343
|
-
}
|
|
1344
|
-
return t("form.phoneLabel");
|
|
1345
|
-
};
|
|
1346
|
-
const identifierLabel = getIdentifierLabel();
|
|
1347
|
-
let errorContent = null;
|
|
1348
|
-
if (error) {
|
|
1349
|
-
if (typeof error === "string") {
|
|
1350
|
-
errorContent = { title: "Error", description: error };
|
|
1351
|
-
} else {
|
|
1352
|
-
errorContent = error;
|
|
1353
|
-
}
|
|
1354
|
-
}
|
|
1355
|
-
return /* @__PURE__ */ jsxs5(
|
|
1356
|
-
AuthLayout,
|
|
1357
|
-
{
|
|
1358
|
-
title: config.ui.name,
|
|
1359
|
-
description: t("description"),
|
|
1360
|
-
logoImage,
|
|
1361
|
-
footer: /* @__PURE__ */ jsxs5("p", { children: [
|
|
1362
|
-
t("footer.hasAccount"),
|
|
1363
|
-
" ",
|
|
1364
|
-
Link ? /* @__PURE__ */ jsx7(Link, { href: signInLink, className: "text-primary hover:underline", children: t("footer.signInCta") }) : /* @__PURE__ */ jsx7(
|
|
1365
|
-
"a",
|
|
1366
|
-
{
|
|
1367
|
-
href: signInLink,
|
|
1368
|
-
onClick: (e) => {
|
|
1369
|
-
e.preventDefault();
|
|
1370
|
-
onNavigate(signInLink);
|
|
1371
|
-
},
|
|
1372
|
-
className: "text-primary hover:underline",
|
|
1373
|
-
children: t("footer.signInCta")
|
|
1374
|
-
}
|
|
1375
|
-
)
|
|
1376
|
-
] }),
|
|
1377
|
-
children: [
|
|
1378
|
-
/* @__PURE__ */ jsx7(Form4, { ...form, children: /* @__PURE__ */ jsxs5("form", { id: "sign-up-form", onSubmit: handleSubmit, className: "space-y-4", children: [
|
|
1379
|
-
/* @__PURE__ */ jsx7(
|
|
1380
|
-
FormField4,
|
|
1381
|
-
{
|
|
1382
|
-
control: form.control,
|
|
1383
|
-
name: "fullName",
|
|
1384
|
-
render: ({ field }) => /* @__PURE__ */ jsxs5(FormItem4, { children: [
|
|
1385
|
-
/* @__PURE__ */ jsx7(FormLabel4, { children: t("form.fullNameLabel") }),
|
|
1386
|
-
/* @__PURE__ */ jsx7(FormControl4, { children: /* @__PURE__ */ jsx7(Input4, { ...field }) }),
|
|
1387
|
-
/* @__PURE__ */ jsx7(FormMessage4, {})
|
|
1388
|
-
] })
|
|
1389
|
-
}
|
|
1390
|
-
),
|
|
1391
|
-
/* @__PURE__ */ jsx7(
|
|
1392
|
-
FormField4,
|
|
1393
|
-
{
|
|
1394
|
-
control: form.control,
|
|
1395
|
-
name: "identifier",
|
|
1396
|
-
render: ({ field }) => /* @__PURE__ */ jsxs5(FormItem4, { children: [
|
|
1397
|
-
/* @__PURE__ */ jsx7(
|
|
1398
|
-
FormLabel4,
|
|
1399
|
-
{
|
|
1400
|
-
className: hasInitialIdentifier ? "block" : void 0,
|
|
1401
|
-
children: identifierLabel
|
|
1402
|
-
}
|
|
1403
|
-
),
|
|
1404
|
-
/* @__PURE__ */ jsx7(FormControl4, { children: /* @__PURE__ */ jsx7(
|
|
1405
|
-
Input4,
|
|
1406
|
-
{
|
|
1407
|
-
...field,
|
|
1408
|
-
type: field.value.includes("@") ? "email" : "tel",
|
|
1409
|
-
disabled: hasInitialIdentifier
|
|
1410
|
-
}
|
|
1411
|
-
) }),
|
|
1412
|
-
/* @__PURE__ */ jsx7(FormMessage4, {})
|
|
1413
|
-
] })
|
|
1414
|
-
}
|
|
1415
|
-
),
|
|
1416
|
-
/* @__PURE__ */ jsx7(
|
|
1417
|
-
FormField4,
|
|
1418
|
-
{
|
|
1419
|
-
control: form.control,
|
|
1420
|
-
name: "password",
|
|
1421
|
-
render: ({ field }) => /* @__PURE__ */ jsxs5(FormItem4, { children: [
|
|
1422
|
-
/* @__PURE__ */ jsx7(FormLabel4, { children: t("form.passwordLabel") }),
|
|
1423
|
-
/* @__PURE__ */ jsx7(
|
|
1424
|
-
PasswordInput3,
|
|
1425
|
-
{
|
|
1426
|
-
field,
|
|
1427
|
-
show: showPassword,
|
|
1428
|
-
onToggle: () => setShowPassword(!showPassword)
|
|
1429
|
-
}
|
|
1430
|
-
),
|
|
1431
|
-
/* @__PURE__ */ jsx7(FormMessage4, {})
|
|
1432
|
-
] })
|
|
1433
|
-
}
|
|
1434
|
-
),
|
|
1435
|
-
/* @__PURE__ */ jsx7(
|
|
1436
|
-
FormField4,
|
|
1437
|
-
{
|
|
1438
|
-
control: form.control,
|
|
1439
|
-
name: "confirmPassword",
|
|
1440
|
-
render: ({ field }) => /* @__PURE__ */ jsxs5(FormItem4, { children: [
|
|
1441
|
-
/* @__PURE__ */ jsx7(FormLabel4, { children: t("form.confirmPasswordLabel") }),
|
|
1442
|
-
/* @__PURE__ */ jsx7(
|
|
1443
|
-
PasswordInput3,
|
|
1444
|
-
{
|
|
1445
|
-
field,
|
|
1446
|
-
show: showConfirmPassword,
|
|
1447
|
-
onToggle: () => setShowConfirmPassword(!showConfirmPassword)
|
|
1448
|
-
}
|
|
1449
|
-
),
|
|
1450
|
-
/* @__PURE__ */ jsx7(FormMessage4, {})
|
|
1451
|
-
] })
|
|
1452
|
-
}
|
|
1453
|
-
),
|
|
1454
|
-
/* @__PURE__ */ jsx7(
|
|
1455
|
-
Button4,
|
|
1456
|
-
{
|
|
1457
|
-
type: "submit",
|
|
1458
|
-
form: "sign-up-form",
|
|
1459
|
-
className: "w-full",
|
|
1460
|
-
disabled: isLoading || signUpMutation.isPending,
|
|
1461
|
-
children: isLoading || signUpMutation.isPending ? t("form.submitting") : t("form.submit")
|
|
1462
|
-
}
|
|
1463
|
-
)
|
|
1464
|
-
] }) }),
|
|
1465
|
-
errorContent && /* @__PURE__ */ jsxs5(Alert4, { variant: "destructive", className: "mt-4", children: [
|
|
1466
|
-
/* @__PURE__ */ jsx7(IconAlertCircle4, { className: "h-4 w-4" }),
|
|
1467
|
-
/* @__PURE__ */ jsx7(AlertTitle4, { children: errorContent.title }),
|
|
1468
|
-
/* @__PURE__ */ jsx7(AlertDescription4, { children: errorContent.description })
|
|
1469
|
-
] })
|
|
1470
|
-
]
|
|
1471
|
-
}
|
|
1472
|
-
);
|
|
1473
|
-
};
|
|
1474
|
-
|
|
1475
|
-
// src/components/auth/verification-form.tsx
|
|
1476
|
-
import { zodResolver as zodResolver5 } from "@hookform/resolvers/zod";
|
|
12
|
+
UserActivityPageContent
|
|
13
|
+
} from "./chunk-JUHBVG5Q.js";
|
|
1477
14
|
import {
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
FormControl as FormControl5,
|
|
1481
|
-
FormField as FormField5,
|
|
1482
|
-
FormItem as FormItem5,
|
|
1483
|
-
FormLabel as FormLabel5,
|
|
1484
|
-
FormMessage as FormMessage5,
|
|
1485
|
-
InputOTP as InputOTP2,
|
|
1486
|
-
InputOTPGroup as InputOTPGroup2,
|
|
1487
|
-
InputOTPSlot as InputOTPSlot2
|
|
1488
|
-
} from "@mesob/ui/components";
|
|
1489
|
-
import { useForm as useForm5 } from "react-hook-form";
|
|
1490
|
-
import { z as z5 } from "zod";
|
|
1491
|
-
|
|
1492
|
-
// src/components/auth/countdown.tsx
|
|
1493
|
-
import { Spinner } from "@mesob/ui/components";
|
|
1494
|
-
import { useEffect as useEffect5, useState as useState6 } from "react";
|
|
1495
|
-
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1496
|
-
var Countdown = ({
|
|
1497
|
-
initialSeconds = 60,
|
|
1498
|
-
onResend,
|
|
1499
|
-
resending = false
|
|
1500
|
-
}) => {
|
|
1501
|
-
const t = useTranslator("Common");
|
|
1502
|
-
const [seconds, setSeconds] = useState6(initialSeconds);
|
|
1503
|
-
const [isResending, setIsResending] = useState6(false);
|
|
1504
|
-
useEffect5(() => {
|
|
1505
|
-
if (seconds <= 0) {
|
|
1506
|
-
return;
|
|
1507
|
-
}
|
|
1508
|
-
const timer = setInterval(() => {
|
|
1509
|
-
setSeconds((prev) => {
|
|
1510
|
-
if (prev <= 1) {
|
|
1511
|
-
clearInterval(timer);
|
|
1512
|
-
return 0;
|
|
1513
|
-
}
|
|
1514
|
-
return prev - 1;
|
|
1515
|
-
});
|
|
1516
|
-
}, 1e3);
|
|
1517
|
-
return () => clearInterval(timer);
|
|
1518
|
-
}, [seconds]);
|
|
1519
|
-
const handleResend = async () => {
|
|
1520
|
-
setIsResending(true);
|
|
1521
|
-
try {
|
|
1522
|
-
await onResend();
|
|
1523
|
-
setSeconds(initialSeconds);
|
|
1524
|
-
} catch (_error) {
|
|
1525
|
-
} finally {
|
|
1526
|
-
setIsResending(false);
|
|
1527
|
-
}
|
|
1528
|
-
};
|
|
1529
|
-
const busy = isResending || resending;
|
|
1530
|
-
if (seconds > 0) {
|
|
1531
|
-
return /* @__PURE__ */ jsx8("p", { className: "text-sm text-muted-foreground", children: t("resendIn", { seconds }) });
|
|
1532
|
-
}
|
|
1533
|
-
return /* @__PURE__ */ jsxs6(
|
|
1534
|
-
"button",
|
|
1535
|
-
{
|
|
1536
|
-
type: "button",
|
|
1537
|
-
onClick: handleResend,
|
|
1538
|
-
disabled: busy,
|
|
1539
|
-
className: "text-sm text-primary hover:underline disabled:opacity-50 flex items-center gap-1",
|
|
1540
|
-
children: [
|
|
1541
|
-
busy && /* @__PURE__ */ jsx8(Spinner, { className: "h-3 w-3" }),
|
|
1542
|
-
t("resend")
|
|
1543
|
-
]
|
|
1544
|
-
}
|
|
1545
|
-
);
|
|
1546
|
-
};
|
|
1547
|
-
|
|
1548
|
-
// src/components/auth/verification-form.tsx
|
|
1549
|
-
import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1550
|
-
var verificationSchema = (t) => z5.object({
|
|
1551
|
-
code: z5.string().length(6, t("form.codeLength"))
|
|
1552
|
-
});
|
|
1553
|
-
var VerificationForm = ({
|
|
1554
|
-
onSubmit,
|
|
1555
|
-
onResend,
|
|
1556
|
-
isLoading = false
|
|
1557
|
-
}) => {
|
|
1558
|
-
const t = useTranslator("Auth.verification");
|
|
1559
|
-
const form = useForm5({
|
|
1560
|
-
resolver: zodResolver5(verificationSchema(t)),
|
|
1561
|
-
defaultValues: { code: "" }
|
|
1562
|
-
});
|
|
1563
|
-
const handleSubmit = form.handleSubmit(async (values) => {
|
|
1564
|
-
await onSubmit(values);
|
|
1565
|
-
});
|
|
1566
|
-
const codeLength = form.watch("code").length;
|
|
1567
|
-
return /* @__PURE__ */ jsx9(Form5, { ...form, children: /* @__PURE__ */ jsxs7(
|
|
1568
|
-
"form",
|
|
1569
|
-
{
|
|
1570
|
-
id: "verification-form",
|
|
1571
|
-
onSubmit: handleSubmit,
|
|
1572
|
-
className: "space-y-4",
|
|
1573
|
-
children: [
|
|
1574
|
-
/* @__PURE__ */ jsx9(
|
|
1575
|
-
FormField5,
|
|
1576
|
-
{
|
|
1577
|
-
control: form.control,
|
|
1578
|
-
name: "code",
|
|
1579
|
-
render: ({ field }) => /* @__PURE__ */ jsxs7(FormItem5, { children: [
|
|
1580
|
-
/* @__PURE__ */ jsx9("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx9(FormLabel5, { children: t("form.codeLabel") }) }),
|
|
1581
|
-
/* @__PURE__ */ jsx9(FormControl5, { children: /* @__PURE__ */ jsx9(
|
|
1582
|
-
InputOTP2,
|
|
1583
|
-
{
|
|
1584
|
-
maxLength: 6,
|
|
1585
|
-
required: true,
|
|
1586
|
-
value: field.value ?? "",
|
|
1587
|
-
onChange: field.onChange,
|
|
1588
|
-
onBlur: field.onBlur,
|
|
1589
|
-
containerClassName: "gap-4 justify-center mb-2 flex items-center",
|
|
1590
|
-
children: /* @__PURE__ */ jsxs7(InputOTPGroup2, { className: "gap-3 *:data-[slot=input-otp-slot]:h-12 *:data-[slot=input-otp-slot]:w-12 *:data-[slot=input-otp-slot]:rounded-md *:data-[slot=input-otp-slot]:border *:data-[slot=input-otp-slot]:text-xl", children: [
|
|
1591
|
-
/* @__PURE__ */ jsx9(InputOTPSlot2, { className: "h-12", index: 0 }),
|
|
1592
|
-
/* @__PURE__ */ jsx9(InputOTPSlot2, { className: "h-12", index: 1 }),
|
|
1593
|
-
/* @__PURE__ */ jsx9(InputOTPSlot2, { className: "h-12", index: 2 }),
|
|
1594
|
-
/* @__PURE__ */ jsx9(InputOTPSlot2, { className: "h-12", index: 3 }),
|
|
1595
|
-
/* @__PURE__ */ jsx9(InputOTPSlot2, { className: "h-12", index: 4 }),
|
|
1596
|
-
/* @__PURE__ */ jsx9(InputOTPSlot2, { className: "h-12", index: 5 })
|
|
1597
|
-
] })
|
|
1598
|
-
}
|
|
1599
|
-
) }),
|
|
1600
|
-
/* @__PURE__ */ jsx9(FormMessage5, {})
|
|
1601
|
-
] })
|
|
1602
|
-
}
|
|
1603
|
-
),
|
|
1604
|
-
/* @__PURE__ */ jsx9(
|
|
1605
|
-
Button5,
|
|
1606
|
-
{
|
|
1607
|
-
type: "submit",
|
|
1608
|
-
form: "verification-form",
|
|
1609
|
-
className: "w-full",
|
|
1610
|
-
disabled: isLoading || codeLength !== 6,
|
|
1611
|
-
loading: isLoading,
|
|
1612
|
-
children: t("form.confirm")
|
|
1613
|
-
}
|
|
1614
|
-
),
|
|
1615
|
-
/* @__PURE__ */ jsx9("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx9(Countdown, { onResend, resending: isLoading }) })
|
|
1616
|
-
]
|
|
1617
|
-
}
|
|
1618
|
-
) });
|
|
1619
|
-
};
|
|
1620
|
-
|
|
1621
|
-
// src/components/auth/verify-email.tsx
|
|
1622
|
-
import { Alert as Alert5, AlertDescription as AlertDescription5, AlertTitle as AlertTitle5 } from "@mesob/ui/components";
|
|
1623
|
-
import { useMesob as useMesob6 } from "@mesob/ui/providers";
|
|
1624
|
-
import { IconAlertCircle as IconAlertCircle5 } from "@tabler/icons-react";
|
|
1625
|
-
import { useEffect as useEffect6, useState as useState7 } from "react";
|
|
1626
|
-
import { toast as toast5 } from "sonner";
|
|
1627
|
-
import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1628
|
-
var VerifyEmail = ({
|
|
1629
|
-
verificationId,
|
|
1630
|
-
email,
|
|
1631
|
-
redirectUrl
|
|
1632
|
-
}) => {
|
|
1633
|
-
const { hooks, setAuth } = useApi();
|
|
1634
|
-
const { config } = useConfig();
|
|
1635
|
-
const mesob = useMesob6();
|
|
1636
|
-
const t = useTranslator("Auth.verification");
|
|
1637
|
-
const common = useTranslator("Common");
|
|
1638
|
-
const footer = useTranslator("Auth.forgotPassword.footer");
|
|
1639
|
-
const Link = mesob?.navigation?.Link;
|
|
1640
|
-
const [isLoading, setIsLoading] = useState7(false);
|
|
1641
|
-
const [error, setError] = useState7(null);
|
|
1642
|
-
const verifyEmailMutation = hooks.useMutation(
|
|
1643
|
-
"post",
|
|
1644
|
-
"/email/verification/confirm"
|
|
1645
|
-
);
|
|
1646
|
-
const requestEmailMutation = hooks.useMutation(
|
|
1647
|
-
"post",
|
|
1648
|
-
"/email/verification/request"
|
|
1649
|
-
);
|
|
1650
|
-
const signInLink = config.navigation?.links?.signIn || "/auth/sign-in";
|
|
1651
|
-
const onNavigate = config.navigation?.onNavigate || ((path) => {
|
|
1652
|
-
if (typeof window !== "undefined") {
|
|
1653
|
-
window.location.href = path;
|
|
1654
|
-
}
|
|
1655
|
-
});
|
|
1656
|
-
const logoImage = config.ui.logoImage;
|
|
1657
|
-
const defaultRedirect = redirectUrl || config.navigation?.defaultRedirectUrl || "/";
|
|
1658
|
-
useEffect6(() => {
|
|
1659
|
-
if (error) {
|
|
1660
|
-
toast5.error(error.title || "Error", {
|
|
1661
|
-
description: error.description
|
|
1662
|
-
});
|
|
1663
|
-
}
|
|
1664
|
-
}, [error]);
|
|
1665
|
-
const handleSubmit = async (values) => {
|
|
1666
|
-
if (!verificationId) {
|
|
1667
|
-
setError({
|
|
1668
|
-
title: t("errors.fallback"),
|
|
1669
|
-
description: t("errors.missingVerificationId")
|
|
1670
|
-
});
|
|
1671
|
-
return;
|
|
1672
|
-
}
|
|
1673
|
-
setIsLoading(true);
|
|
1674
|
-
setError(null);
|
|
1675
|
-
try {
|
|
1676
|
-
const res = await verifyEmailMutation.mutateAsync({
|
|
1677
|
-
body: {
|
|
1678
|
-
verificationId,
|
|
1679
|
-
code: values.code
|
|
1680
|
-
}
|
|
1681
|
-
});
|
|
1682
|
-
if ("user" in res && "session" in res) {
|
|
1683
|
-
setAuth(res);
|
|
1684
|
-
}
|
|
1685
|
-
onNavigate(defaultRedirect);
|
|
1686
|
-
} catch (err) {
|
|
1687
|
-
handleError(err, setError, t);
|
|
1688
|
-
} finally {
|
|
1689
|
-
setIsLoading(false);
|
|
1690
|
-
}
|
|
1691
|
-
};
|
|
1692
|
-
const handleResend = async () => {
|
|
1693
|
-
setError(null);
|
|
1694
|
-
try {
|
|
1695
|
-
const res = await requestEmailMutation.mutateAsync({
|
|
1696
|
-
body: {
|
|
1697
|
-
email
|
|
1698
|
-
}
|
|
1699
|
-
});
|
|
1700
|
-
if (res.verificationId) {
|
|
1701
|
-
onNavigate(
|
|
1702
|
-
`/auth/verify-email?verificationId=${res.verificationId}&email=${encodeURIComponent(email)}`
|
|
1703
|
-
);
|
|
1704
|
-
} else {
|
|
1705
|
-
setError({
|
|
1706
|
-
title: t("errors.fallback"),
|
|
1707
|
-
description: t("errors.resendFailed")
|
|
1708
|
-
});
|
|
1709
|
-
}
|
|
1710
|
-
} catch (err) {
|
|
1711
|
-
handleError(err, setError, t);
|
|
1712
|
-
}
|
|
1713
|
-
};
|
|
1714
|
-
if (!verificationId) {
|
|
1715
|
-
return /* @__PURE__ */ jsx10(
|
|
1716
|
-
AuthLayout,
|
|
1717
|
-
{
|
|
1718
|
-
title: common("invalidLinkTitle"),
|
|
1719
|
-
description: common("invalidLinkDescription"),
|
|
1720
|
-
footer: Link ? /* @__PURE__ */ jsx10(Link, { href: signInLink, className: "text-primary hover:underline", children: footer("backToSignIn") }) : /* @__PURE__ */ jsx10(
|
|
1721
|
-
"a",
|
|
1722
|
-
{
|
|
1723
|
-
href: signInLink,
|
|
1724
|
-
onClick: (e) => {
|
|
1725
|
-
e.preventDefault();
|
|
1726
|
-
onNavigate(signInLink);
|
|
1727
|
-
},
|
|
1728
|
-
className: "text-primary hover:underline",
|
|
1729
|
-
children: footer("backToSignIn")
|
|
1730
|
-
}
|
|
1731
|
-
),
|
|
1732
|
-
children: /* @__PURE__ */ jsx10("div", {})
|
|
1733
|
-
}
|
|
1734
|
-
);
|
|
1735
|
-
}
|
|
1736
|
-
let errorContent = null;
|
|
1737
|
-
if (error) {
|
|
1738
|
-
if (typeof error === "string") {
|
|
1739
|
-
errorContent = { title: "Error", description: error };
|
|
1740
|
-
} else {
|
|
1741
|
-
errorContent = error;
|
|
1742
|
-
}
|
|
1743
|
-
}
|
|
1744
|
-
return /* @__PURE__ */ jsxs8(
|
|
1745
|
-
AuthLayout,
|
|
1746
|
-
{
|
|
1747
|
-
title: config.ui.name,
|
|
1748
|
-
description: t("email.description"),
|
|
1749
|
-
logoImage,
|
|
1750
|
-
footer: Link ? /* @__PURE__ */ jsx10(Link, { href: signInLink, className: "text-primary hover:underline", children: footer("backToSignIn") }) : /* @__PURE__ */ jsx10(
|
|
1751
|
-
"a",
|
|
1752
|
-
{
|
|
1753
|
-
href: signInLink,
|
|
1754
|
-
onClick: (e) => {
|
|
1755
|
-
e.preventDefault();
|
|
1756
|
-
onNavigate(signInLink);
|
|
1757
|
-
},
|
|
1758
|
-
className: "text-primary hover:underline",
|
|
1759
|
-
children: footer("backToSignIn")
|
|
1760
|
-
}
|
|
1761
|
-
),
|
|
1762
|
-
children: [
|
|
1763
|
-
/* @__PURE__ */ jsx10(
|
|
1764
|
-
VerificationForm,
|
|
1765
|
-
{
|
|
1766
|
-
verificationId,
|
|
1767
|
-
onSubmit: handleSubmit,
|
|
1768
|
-
onResend: handleResend,
|
|
1769
|
-
isLoading: isLoading || verifyEmailMutation.isPending || requestEmailMutation.isPending,
|
|
1770
|
-
error
|
|
1771
|
-
}
|
|
1772
|
-
),
|
|
1773
|
-
errorContent && /* @__PURE__ */ jsxs8(Alert5, { variant: "destructive", className: "mt-4", children: [
|
|
1774
|
-
/* @__PURE__ */ jsx10(IconAlertCircle5, { className: "h-4 w-4" }),
|
|
1775
|
-
/* @__PURE__ */ jsx10(AlertTitle5, { children: errorContent.title }),
|
|
1776
|
-
/* @__PURE__ */ jsx10(AlertDescription5, { children: errorContent.description })
|
|
1777
|
-
] })
|
|
1778
|
-
]
|
|
1779
|
-
}
|
|
1780
|
-
);
|
|
1781
|
-
};
|
|
1782
|
-
|
|
1783
|
-
// src/components/auth/verify-phone.tsx
|
|
1784
|
-
import { Alert as Alert6, AlertDescription as AlertDescription6, AlertTitle as AlertTitle6 } from "@mesob/ui/components";
|
|
1785
|
-
import { useMesob as useMesob7 } from "@mesob/ui/providers";
|
|
1786
|
-
import { IconAlertCircle as IconAlertCircle6 } from "@tabler/icons-react";
|
|
1787
|
-
import { useEffect as useEffect7, useState as useState8 } from "react";
|
|
1788
|
-
import { toast as toast6 } from "sonner";
|
|
1789
|
-
import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1790
|
-
var VerifyPhone = ({
|
|
1791
|
-
verificationId,
|
|
1792
|
-
context,
|
|
1793
|
-
phone = "",
|
|
1794
|
-
redirectUrl
|
|
1795
|
-
}) => {
|
|
1796
|
-
const { hooks, refresh, setAuth } = useApi();
|
|
1797
|
-
const { config } = useConfig();
|
|
1798
|
-
const mesob = useMesob7();
|
|
1799
|
-
const Link = mesob?.navigation?.Link;
|
|
1800
|
-
const t = useTranslator("Auth.verification");
|
|
1801
|
-
const common = useTranslator("Common");
|
|
1802
|
-
const footer = useTranslator("Auth.forgotPassword.footer");
|
|
1803
|
-
const [isLoading, setIsLoading] = useState8(false);
|
|
1804
|
-
const [error, setError] = useState8(null);
|
|
1805
|
-
const verifyPhoneMutation = hooks.useMutation(
|
|
1806
|
-
"post",
|
|
1807
|
-
"/phone/verification/confirm"
|
|
1808
|
-
);
|
|
1809
|
-
const requestPhoneMutation = hooks.useMutation(
|
|
1810
|
-
"post",
|
|
1811
|
-
"/phone/verification/request"
|
|
1812
|
-
);
|
|
1813
|
-
const signInLink = config.navigation?.links?.signIn || "/auth/sign-in";
|
|
1814
|
-
const onNavigate = config.navigation?.onNavigate || ((path) => {
|
|
1815
|
-
if (typeof window !== "undefined") {
|
|
1816
|
-
window.location.href = path;
|
|
1817
|
-
}
|
|
1818
|
-
});
|
|
1819
|
-
const logoImage = config.ui.logoImage;
|
|
1820
|
-
const defaultRedirect = redirectUrl || config.navigation?.defaultRedirectUrl || "/";
|
|
1821
|
-
useEffect7(() => {
|
|
1822
|
-
if (error) {
|
|
1823
|
-
toast6.error(error.title || "Error", {
|
|
1824
|
-
description: error.description
|
|
1825
|
-
});
|
|
1826
|
-
}
|
|
1827
|
-
}, [error]);
|
|
1828
|
-
const handleSubmit = async (values) => {
|
|
1829
|
-
if (!verificationId) {
|
|
1830
|
-
setError({
|
|
1831
|
-
title: t("errors.fallback"),
|
|
1832
|
-
description: t("errors.fallback")
|
|
1833
|
-
});
|
|
1834
|
-
return;
|
|
1835
|
-
}
|
|
1836
|
-
setIsLoading(true);
|
|
1837
|
-
setError(null);
|
|
1838
|
-
try {
|
|
1839
|
-
const res = await verifyPhoneMutation.mutateAsync({
|
|
1840
|
-
body: {
|
|
1841
|
-
verificationId,
|
|
1842
|
-
code: values.code,
|
|
1843
|
-
context
|
|
1844
|
-
}
|
|
1845
|
-
});
|
|
1846
|
-
if (res && "user" in res && "session" in res && res.session) {
|
|
1847
|
-
setAuth(res);
|
|
1848
|
-
onNavigate(defaultRedirect);
|
|
1849
|
-
return;
|
|
1850
|
-
}
|
|
1851
|
-
await refresh();
|
|
1852
|
-
onNavigate(defaultRedirect);
|
|
1853
|
-
} catch (err) {
|
|
1854
|
-
handleError(err, setError, t);
|
|
1855
|
-
} finally {
|
|
1856
|
-
setIsLoading(false);
|
|
1857
|
-
}
|
|
1858
|
-
};
|
|
1859
|
-
const handleResend = async () => {
|
|
1860
|
-
setError(null);
|
|
1861
|
-
try {
|
|
1862
|
-
const targetPhone = context === "sign-up" ? phone : null;
|
|
1863
|
-
if (!targetPhone) {
|
|
1864
|
-
setError({
|
|
1865
|
-
title: t("errors.fallback"),
|
|
1866
|
-
description: t("phone.missingPhone")
|
|
1867
|
-
});
|
|
1868
|
-
return;
|
|
1869
|
-
}
|
|
1870
|
-
const res = await requestPhoneMutation.mutateAsync({
|
|
1871
|
-
body: {
|
|
1872
|
-
phone: targetPhone,
|
|
1873
|
-
context
|
|
1874
|
-
}
|
|
1875
|
-
});
|
|
1876
|
-
if (res && "verificationId" in res && res.verificationId) {
|
|
1877
|
-
onNavigate(
|
|
1878
|
-
`/auth/verify-phone?context=${context}&verificationId=${res.verificationId}&phone=${targetPhone}`
|
|
1879
|
-
);
|
|
1880
|
-
return;
|
|
1881
|
-
}
|
|
1882
|
-
setError({
|
|
1883
|
-
title: t("errors.fallback"),
|
|
1884
|
-
description: t("phone.resendFailed")
|
|
1885
|
-
});
|
|
1886
|
-
} catch (err) {
|
|
1887
|
-
handleError(err, setError, t);
|
|
1888
|
-
}
|
|
1889
|
-
};
|
|
1890
|
-
if (!verificationId) {
|
|
1891
|
-
return /* @__PURE__ */ jsx11(
|
|
1892
|
-
AuthLayout,
|
|
1893
|
-
{
|
|
1894
|
-
title: common("invalidLinkTitle"),
|
|
1895
|
-
description: common("invalidLinkDescription"),
|
|
1896
|
-
footer: /* @__PURE__ */ jsx11(Link, { href: signInLink, className: "text-primary hover:underline", children: footer("backToSignIn") }),
|
|
1897
|
-
children: /* @__PURE__ */ jsx11("div", {})
|
|
1898
|
-
}
|
|
1899
|
-
);
|
|
1900
|
-
}
|
|
1901
|
-
let errorContent = null;
|
|
1902
|
-
if (error) {
|
|
1903
|
-
if (typeof error === "string") {
|
|
1904
|
-
errorContent = { title: "Error", description: error };
|
|
1905
|
-
} else {
|
|
1906
|
-
errorContent = error;
|
|
1907
|
-
}
|
|
1908
|
-
}
|
|
1909
|
-
return /* @__PURE__ */ jsxs9(
|
|
1910
|
-
AuthLayout,
|
|
1911
|
-
{
|
|
1912
|
-
title: config.ui.name,
|
|
1913
|
-
description: t("phone.description", {
|
|
1914
|
-
target: phone || t("phone.missingPhone")
|
|
1915
|
-
}),
|
|
1916
|
-
logoImage,
|
|
1917
|
-
footer: Link ? /* @__PURE__ */ jsx11(Link, { href: signInLink, className: "text-primary hover:underline", children: footer("backToSignIn") }) : /* @__PURE__ */ jsx11(
|
|
1918
|
-
"a",
|
|
1919
|
-
{
|
|
1920
|
-
href: signInLink,
|
|
1921
|
-
onClick: (e) => {
|
|
1922
|
-
e.preventDefault();
|
|
1923
|
-
onNavigate(signInLink);
|
|
1924
|
-
},
|
|
1925
|
-
className: "text-primary hover:underline",
|
|
1926
|
-
children: footer("backToSignIn")
|
|
1927
|
-
}
|
|
1928
|
-
),
|
|
1929
|
-
children: [
|
|
1930
|
-
/* @__PURE__ */ jsx11(
|
|
1931
|
-
VerificationForm,
|
|
1932
|
-
{
|
|
1933
|
-
verificationId,
|
|
1934
|
-
onSubmit: handleSubmit,
|
|
1935
|
-
onResend: handleResend,
|
|
1936
|
-
isLoading: isLoading || verifyPhoneMutation.isPending || requestPhoneMutation.isPending,
|
|
1937
|
-
error
|
|
1938
|
-
}
|
|
1939
|
-
),
|
|
1940
|
-
errorContent && /* @__PURE__ */ jsxs9(Alert6, { variant: "destructive", className: "mt-4", children: [
|
|
1941
|
-
/* @__PURE__ */ jsx11(IconAlertCircle6, { className: "h-4 w-4" }),
|
|
1942
|
-
/* @__PURE__ */ jsx11(AlertTitle6, { children: errorContent.title }),
|
|
1943
|
-
/* @__PURE__ */ jsx11(AlertDescription6, { children: errorContent.description })
|
|
1944
|
-
] })
|
|
1945
|
-
]
|
|
1946
|
-
}
|
|
1947
|
-
);
|
|
1948
|
-
};
|
|
1949
|
-
|
|
1950
|
-
// src/components/error-boundary.tsx
|
|
1951
|
-
import { Button as Button6 } from "@mesob/ui/components";
|
|
1952
|
-
import { Component } from "react";
|
|
1953
|
-
import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1954
|
-
var ErrorBoundary = class extends Component {
|
|
1955
|
-
constructor(props) {
|
|
1956
|
-
super(props);
|
|
1957
|
-
this.state = { hasError: false, error: null };
|
|
1958
|
-
}
|
|
1959
|
-
static getDerivedStateFromError(error) {
|
|
1960
|
-
return { hasError: true, error };
|
|
1961
|
-
}
|
|
1962
|
-
componentDidCatch(_error, _errorInfo) {
|
|
1963
|
-
}
|
|
1964
|
-
reset = () => {
|
|
1965
|
-
this.setState({ hasError: false, error: null });
|
|
1966
|
-
};
|
|
1967
|
-
render() {
|
|
1968
|
-
if (this.state.hasError && this.state.error) {
|
|
1969
|
-
if (this.props.fallback) {
|
|
1970
|
-
return this.props.fallback({
|
|
1971
|
-
error: this.state.error,
|
|
1972
|
-
reset: this.reset
|
|
1973
|
-
});
|
|
1974
|
-
}
|
|
1975
|
-
return /* @__PURE__ */ jsx12(ErrorFallback, { error: this.state.error, reset: this.reset });
|
|
1976
|
-
}
|
|
1977
|
-
return this.props.children;
|
|
1978
|
-
}
|
|
1979
|
-
};
|
|
1980
|
-
function ErrorFallback({ error, reset }) {
|
|
1981
|
-
return /* @__PURE__ */ jsx12("div", { className: "flex flex-col items-center justify-center min-h-[400px] p-6", children: /* @__PURE__ */ jsxs10("div", { className: "max-w-md w-full space-y-4 text-center", children: [
|
|
1982
|
-
/* @__PURE__ */ jsxs10("div", { className: "space-y-2", children: [
|
|
1983
|
-
/* @__PURE__ */ jsx12("h2", { className: "text-2xl font-bold text-destructive", children: "Something went wrong" }),
|
|
1984
|
-
/* @__PURE__ */ jsx12("p", { className: "text-muted-foreground", children: error.message || "An unexpected error occurred" })
|
|
1985
|
-
] }),
|
|
1986
|
-
/* @__PURE__ */ jsx12(Button6, { onClick: reset, variant: "outline", children: "Try again" })
|
|
1987
|
-
] }) });
|
|
1988
|
-
}
|
|
1989
|
-
function AuthErrorBoundary({ children }) {
|
|
1990
|
-
return /* @__PURE__ */ jsx12(ErrorBoundary, { children });
|
|
1991
|
-
}
|
|
1992
|
-
|
|
1993
|
-
// src/components/iam/permissions.tsx
|
|
1994
|
-
import { Badge, Button as Button7 } from "@mesob/ui/components";
|
|
1995
|
-
import { useLocale } from "next-intl";
|
|
1996
|
-
import { useState as useState9 } from "react";
|
|
1997
|
-
|
|
1998
|
-
// src/components/shared/data-table.tsx
|
|
15
|
+
RoleUsersPage
|
|
16
|
+
} from "./chunk-PSRIZMWJ.js";
|
|
1999
17
|
import {
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
TableCell,
|
|
2003
|
-
TableHead,
|
|
2004
|
-
TableHeader,
|
|
2005
|
-
TableRow
|
|
2006
|
-
} from "@mesob/ui/components";
|
|
2007
|
-
|
|
2008
|
-
// src/components/skeletons/table-skeleton.tsx
|
|
2009
|
-
import { Skeleton } from "@mesob/ui/components";
|
|
2010
|
-
import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2011
|
-
function TableSkeleton({ columns = 5, rows = 10 }) {
|
|
2012
|
-
const headerKeys = Array.from({ length: columns }, (_, i) => `header-${i}`);
|
|
2013
|
-
const rowKeys = Array.from({ length: rows }, (_, i) => `row-${i}`);
|
|
2014
|
-
const cellKeys = Array.from(
|
|
2015
|
-
{ length: rows },
|
|
2016
|
-
(_, rowIdx) => Array.from({ length: columns }, (_2, colIdx) => `cell-${rowIdx}-${colIdx}`)
|
|
2017
|
-
);
|
|
2018
|
-
return /* @__PURE__ */ jsxs11("div", { className: "w-full space-y-4", children: [
|
|
2019
|
-
/* @__PURE__ */ jsxs11("div", { className: "flex justify-between items-center", children: [
|
|
2020
|
-
/* @__PURE__ */ jsx13(Skeleton, { className: "h-8 w-48" }),
|
|
2021
|
-
/* @__PURE__ */ jsx13(Skeleton, { className: "h-10 w-32" })
|
|
2022
|
-
] }),
|
|
2023
|
-
/* @__PURE__ */ jsxs11("div", { className: "flex gap-4", children: [
|
|
2024
|
-
/* @__PURE__ */ jsx13(Skeleton, { className: "h-10 flex-1 max-w-sm" }),
|
|
2025
|
-
/* @__PURE__ */ jsx13(Skeleton, { className: "h-10 w-24" }),
|
|
2026
|
-
/* @__PURE__ */ jsx13(Skeleton, { className: "h-10 w-24" })
|
|
2027
|
-
] }),
|
|
2028
|
-
/* @__PURE__ */ jsxs11("div", { className: "border rounded-lg overflow-hidden", children: [
|
|
2029
|
-
/* @__PURE__ */ jsx13("div", { className: "flex gap-4 p-4 bg-muted", children: headerKeys.map((key) => /* @__PURE__ */ jsx13(Skeleton, { className: "h-4 flex-1" }, key)) }),
|
|
2030
|
-
rowKeys.map((rowKey, rowIdx) => /* @__PURE__ */ jsx13("div", { className: "flex gap-4 p-4 border-t", children: cellKeys[rowIdx]?.map((cellKey) => /* @__PURE__ */ jsx13(Skeleton, { className: "h-4 flex-1" }, cellKey)) }, rowKey))
|
|
2031
|
-
] }),
|
|
2032
|
-
/* @__PURE__ */ jsxs11("div", { className: "flex justify-between items-center", children: [
|
|
2033
|
-
/* @__PURE__ */ jsx13(Skeleton, { className: "h-4 w-32" }),
|
|
2034
|
-
/* @__PURE__ */ jsxs11("div", { className: "flex gap-2", children: [
|
|
2035
|
-
/* @__PURE__ */ jsx13(Skeleton, { className: "h-10 w-20" }),
|
|
2036
|
-
/* @__PURE__ */ jsx13(Skeleton, { className: "h-10 w-20" })
|
|
2037
|
-
] })
|
|
2038
|
-
] })
|
|
2039
|
-
] });
|
|
2040
|
-
}
|
|
2041
|
-
|
|
2042
|
-
// src/components/shared/data-table.tsx
|
|
2043
|
-
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2044
|
-
function DataTable({
|
|
2045
|
-
data,
|
|
2046
|
-
columns,
|
|
2047
|
-
isLoading,
|
|
2048
|
-
onRowClick,
|
|
2049
|
-
emptyMessage = "No data available",
|
|
2050
|
-
actions
|
|
2051
|
-
}) {
|
|
2052
|
-
if (isLoading) {
|
|
2053
|
-
return /* @__PURE__ */ jsx14(TableSkeleton, { columns: columns.length, rows: 5 });
|
|
2054
|
-
}
|
|
2055
|
-
if (data.length === 0) {
|
|
2056
|
-
return /* @__PURE__ */ jsxs12("div", { className: "flex flex-col items-center justify-center min-h-[400px] p-6", children: [
|
|
2057
|
-
/* @__PURE__ */ jsx14("p", { className: "text-muted-foreground", children: emptyMessage }),
|
|
2058
|
-
actions && /* @__PURE__ */ jsx14("div", { className: "mt-4", children: actions })
|
|
2059
|
-
] });
|
|
2060
|
-
}
|
|
2061
|
-
return /* @__PURE__ */ jsxs12("div", { className: "w-full space-y-4", children: [
|
|
2062
|
-
actions && /* @__PURE__ */ jsx14("div", { className: "flex justify-end", children: actions }),
|
|
2063
|
-
/* @__PURE__ */ jsx14("div", { className: "border rounded-lg overflow-hidden", children: /* @__PURE__ */ jsxs12(Table, { children: [
|
|
2064
|
-
/* @__PURE__ */ jsx14(TableHeader, { children: /* @__PURE__ */ jsx14(TableRow, { children: columns.map((column) => /* @__PURE__ */ jsx14(TableHead, { children: column.header }, column.key)) }) }),
|
|
2065
|
-
/* @__PURE__ */ jsx14(TableBody, { children: data.map((row) => /* @__PURE__ */ jsx14(
|
|
2066
|
-
TableRow,
|
|
2067
|
-
{
|
|
2068
|
-
onClick: () => onRowClick?.(row),
|
|
2069
|
-
className: onRowClick ? "cursor-pointer hover:bg-muted/50" : "",
|
|
2070
|
-
children: columns.map((column) => /* @__PURE__ */ jsx14(TableCell, { children: column.cell(row) }, `${row.id}-${column.key}`))
|
|
2071
|
-
},
|
|
2072
|
-
row.id
|
|
2073
|
-
)) })
|
|
2074
|
-
] }) })
|
|
2075
|
-
] });
|
|
2076
|
-
}
|
|
2077
|
-
|
|
2078
|
-
// src/components/iam/permissions.tsx
|
|
2079
|
-
import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
2080
|
-
function getTranslation(value, locale) {
|
|
2081
|
-
if (!value) {
|
|
2082
|
-
return "";
|
|
2083
|
-
}
|
|
2084
|
-
if (typeof value === "string") {
|
|
2085
|
-
return value;
|
|
2086
|
-
}
|
|
2087
|
-
if (typeof value === "object") {
|
|
2088
|
-
return value[locale] ?? value.en ?? value.am ?? "";
|
|
2089
|
-
}
|
|
2090
|
-
return "";
|
|
2091
|
-
}
|
|
2092
|
-
function Permissions() {
|
|
2093
|
-
const { hooks } = useApi();
|
|
2094
|
-
const locale = useLocale();
|
|
2095
|
-
const [page, setPage] = useState9(1);
|
|
2096
|
-
const limit = 20;
|
|
2097
|
-
const { data, isLoading, error } = hooks.useQuery("get", "/permissions", {
|
|
2098
|
-
params: {
|
|
2099
|
-
query: {
|
|
2100
|
-
page: String(page),
|
|
2101
|
-
limit: String(limit)
|
|
2102
|
-
}
|
|
2103
|
-
}
|
|
2104
|
-
});
|
|
2105
|
-
const columns = [
|
|
2106
|
-
{
|
|
2107
|
-
key: "name",
|
|
2108
|
-
header: "Permission",
|
|
2109
|
-
cell: (permission) => /* @__PURE__ */ jsxs13("div", { children: [
|
|
2110
|
-
/* @__PURE__ */ jsx15("p", { className: "font-medium", children: getTranslation(permission.name, locale) }),
|
|
2111
|
-
/* @__PURE__ */ jsx15(Badge, { variant: "outline", className: "mt-1 font-mono text-xs", children: permission.code })
|
|
2112
|
-
] })
|
|
2113
|
-
},
|
|
2114
|
-
{
|
|
2115
|
-
key: "resource",
|
|
2116
|
-
header: "Resource",
|
|
2117
|
-
cell: (permission) => /* @__PURE__ */ jsx15(Badge, { variant: "secondary", children: permission.resource })
|
|
2118
|
-
},
|
|
2119
|
-
{
|
|
2120
|
-
key: "action",
|
|
2121
|
-
header: "Action",
|
|
2122
|
-
cell: (permission) => /* @__PURE__ */ jsx15(Badge, { variant: "outline", children: permission.action })
|
|
2123
|
-
},
|
|
2124
|
-
{
|
|
2125
|
-
key: "description",
|
|
2126
|
-
header: "Description",
|
|
2127
|
-
cell: (permission) => /* @__PURE__ */ jsx15("p", { className: "text-sm text-muted-foreground max-w-xs truncate", children: getTranslation(permission.description, locale) })
|
|
2128
|
-
},
|
|
2129
|
-
{
|
|
2130
|
-
key: "actions",
|
|
2131
|
-
header: "Actions",
|
|
2132
|
-
cell: (_permission) => /* @__PURE__ */ jsx15(Button7, { variant: "outline", size: "sm", children: "Edit" })
|
|
2133
|
-
}
|
|
2134
|
-
];
|
|
2135
|
-
if (error) {
|
|
2136
|
-
return /* @__PURE__ */ jsx15("div", { className: "p-6 text-center", children: /* @__PURE__ */ jsx15("p", { className: "text-destructive", children: "Error loading permissions" }) });
|
|
2137
|
-
}
|
|
2138
|
-
return /* @__PURE__ */ jsxs13("div", { className: "w-full p-6 space-y-4", children: [
|
|
2139
|
-
/* @__PURE__ */ jsxs13("div", { className: "flex justify-between items-center", children: [
|
|
2140
|
-
/* @__PURE__ */ jsxs13("div", { children: [
|
|
2141
|
-
/* @__PURE__ */ jsx15("h1", { className: "text-3xl font-bold", children: "Permissions" }),
|
|
2142
|
-
/* @__PURE__ */ jsx15("p", { className: "text-muted-foreground", children: "Manage system permissions" })
|
|
2143
|
-
] }),
|
|
2144
|
-
/* @__PURE__ */ jsx15(Button7, { children: "Create Permission" })
|
|
2145
|
-
] }),
|
|
2146
|
-
/* @__PURE__ */ jsx15(
|
|
2147
|
-
DataTable,
|
|
2148
|
-
{
|
|
2149
|
-
data: data?.permissions || [],
|
|
2150
|
-
columns,
|
|
2151
|
-
isLoading,
|
|
2152
|
-
emptyMessage: "No permissions found"
|
|
2153
|
-
}
|
|
2154
|
-
),
|
|
2155
|
-
data && "permissions" in data && data.permissions && data.permissions.length >= limit && /* @__PURE__ */ jsxs13("div", { className: "flex justify-between items-center", children: [
|
|
2156
|
-
/* @__PURE__ */ jsx15(
|
|
2157
|
-
Button7,
|
|
2158
|
-
{
|
|
2159
|
-
variant: "outline",
|
|
2160
|
-
disabled: page === 1,
|
|
2161
|
-
onClick: () => setPage((prev) => prev - 1),
|
|
2162
|
-
children: "Previous"
|
|
2163
|
-
}
|
|
2164
|
-
),
|
|
2165
|
-
/* @__PURE__ */ jsxs13("span", { className: "text-sm text-muted-foreground", children: [
|
|
2166
|
-
"Page ",
|
|
2167
|
-
page
|
|
2168
|
-
] }),
|
|
2169
|
-
/* @__PURE__ */ jsx15(
|
|
2170
|
-
Button7,
|
|
2171
|
-
{
|
|
2172
|
-
variant: "outline",
|
|
2173
|
-
onClick: () => setPage((prev) => prev + 1),
|
|
2174
|
-
children: "Next"
|
|
2175
|
-
}
|
|
2176
|
-
)
|
|
2177
|
-
] })
|
|
2178
|
-
] });
|
|
2179
|
-
}
|
|
2180
|
-
|
|
2181
|
-
// src/components/iam/roles.tsx
|
|
2182
|
-
import { Badge as Badge2, Button as Button8 } from "@mesob/ui/components";
|
|
2183
|
-
import { useLocale as useLocale2 } from "next-intl";
|
|
2184
|
-
import { useState as useState10 } from "react";
|
|
2185
|
-
import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
2186
|
-
function getTranslation2(value, locale) {
|
|
2187
|
-
if (!value) {
|
|
2188
|
-
return "";
|
|
2189
|
-
}
|
|
2190
|
-
if (typeof value === "string") {
|
|
2191
|
-
return value;
|
|
2192
|
-
}
|
|
2193
|
-
if (typeof value === "object") {
|
|
2194
|
-
return value[locale] ?? value.en ?? value.am ?? "";
|
|
2195
|
-
}
|
|
2196
|
-
return "";
|
|
2197
|
-
}
|
|
2198
|
-
function Roles() {
|
|
2199
|
-
const { hooks } = useApi();
|
|
2200
|
-
const locale = useLocale2();
|
|
2201
|
-
const [page, setPage] = useState10(1);
|
|
2202
|
-
const limit = 20;
|
|
2203
|
-
const { data, isLoading, error } = hooks.useQuery("get", "/roles", {
|
|
2204
|
-
params: {
|
|
2205
|
-
query: {
|
|
2206
|
-
page: String(page),
|
|
2207
|
-
limit: String(limit)
|
|
2208
|
-
}
|
|
2209
|
-
}
|
|
2210
|
-
});
|
|
2211
|
-
const columns = [
|
|
2212
|
-
{
|
|
2213
|
-
key: "name",
|
|
2214
|
-
header: "Role",
|
|
2215
|
-
cell: (role) => /* @__PURE__ */ jsxs14("div", { children: [
|
|
2216
|
-
/* @__PURE__ */ jsx16("p", { className: "font-medium", children: getTranslation2(role.name, locale) }),
|
|
2217
|
-
/* @__PURE__ */ jsx16(Badge2, { variant: "outline", className: "mt-1", children: role.code })
|
|
2218
|
-
] })
|
|
2219
|
-
},
|
|
2220
|
-
{
|
|
2221
|
-
key: "description",
|
|
2222
|
-
header: "Description",
|
|
2223
|
-
cell: (role) => /* @__PURE__ */ jsx16("p", { className: "text-sm text-muted-foreground", children: getTranslation2(role.description, locale) })
|
|
2224
|
-
},
|
|
2225
|
-
{
|
|
2226
|
-
key: "createdAt",
|
|
2227
|
-
header: "Created",
|
|
2228
|
-
cell: (role) => /* @__PURE__ */ jsx16("p", { className: "text-sm", children: new Date(role.createdAt).toLocaleDateString() })
|
|
2229
|
-
},
|
|
2230
|
-
{
|
|
2231
|
-
key: "actions",
|
|
2232
|
-
header: "Actions",
|
|
2233
|
-
cell: (_role) => /* @__PURE__ */ jsxs14("div", { className: "flex gap-2", children: [
|
|
2234
|
-
/* @__PURE__ */ jsx16(Button8, { variant: "outline", size: "sm", children: "Permissions" }),
|
|
2235
|
-
/* @__PURE__ */ jsx16(Button8, { variant: "outline", size: "sm", children: "Edit" })
|
|
2236
|
-
] })
|
|
2237
|
-
}
|
|
2238
|
-
];
|
|
2239
|
-
if (error) {
|
|
2240
|
-
return /* @__PURE__ */ jsx16("div", { className: "p-6 text-center", children: /* @__PURE__ */ jsx16("p", { className: "text-destructive", children: "Error loading roles" }) });
|
|
2241
|
-
}
|
|
2242
|
-
return /* @__PURE__ */ jsxs14("div", { className: "w-full p-6 space-y-4", children: [
|
|
2243
|
-
/* @__PURE__ */ jsxs14("div", { className: "flex justify-between items-center", children: [
|
|
2244
|
-
/* @__PURE__ */ jsxs14("div", { children: [
|
|
2245
|
-
/* @__PURE__ */ jsx16("h1", { className: "text-3xl font-bold", children: "Roles" }),
|
|
2246
|
-
/* @__PURE__ */ jsx16("p", { className: "text-muted-foreground", children: "Manage user roles" })
|
|
2247
|
-
] }),
|
|
2248
|
-
/* @__PURE__ */ jsx16(Button8, { children: "Create Role" })
|
|
2249
|
-
] }),
|
|
2250
|
-
/* @__PURE__ */ jsx16(
|
|
2251
|
-
DataTable,
|
|
2252
|
-
{
|
|
2253
|
-
data: data?.roles || [],
|
|
2254
|
-
columns,
|
|
2255
|
-
isLoading,
|
|
2256
|
-
emptyMessage: "No roles found"
|
|
2257
|
-
}
|
|
2258
|
-
),
|
|
2259
|
-
data && "roles" in data && data.roles && data.roles.length >= limit && /* @__PURE__ */ jsxs14("div", { className: "flex justify-between items-center", children: [
|
|
2260
|
-
/* @__PURE__ */ jsx16(
|
|
2261
|
-
Button8,
|
|
2262
|
-
{
|
|
2263
|
-
variant: "outline",
|
|
2264
|
-
disabled: page === 1,
|
|
2265
|
-
onClick: () => setPage((prev) => prev - 1),
|
|
2266
|
-
children: "Previous"
|
|
2267
|
-
}
|
|
2268
|
-
),
|
|
2269
|
-
/* @__PURE__ */ jsxs14("span", { className: "text-sm text-muted-foreground", children: [
|
|
2270
|
-
"Page ",
|
|
2271
|
-
page
|
|
2272
|
-
] }),
|
|
2273
|
-
/* @__PURE__ */ jsx16(
|
|
2274
|
-
Button8,
|
|
2275
|
-
{
|
|
2276
|
-
variant: "outline",
|
|
2277
|
-
onClick: () => setPage((prev) => prev + 1),
|
|
2278
|
-
children: "Next"
|
|
2279
|
-
}
|
|
2280
|
-
)
|
|
2281
|
-
] })
|
|
2282
|
-
] });
|
|
2283
|
-
}
|
|
2284
|
-
|
|
2285
|
-
// src/components/iam/sessions.tsx
|
|
2286
|
-
import { Button as Button9 } from "@mesob/ui/components";
|
|
2287
|
-
import { useState as useState11 } from "react";
|
|
2288
|
-
import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2289
|
-
function Sessions() {
|
|
2290
|
-
const { hooks } = useApi();
|
|
2291
|
-
const [selectedSessionId] = useState11(null);
|
|
2292
|
-
const { data, isLoading, error, refetch } = hooks.useQuery(
|
|
2293
|
-
"get",
|
|
2294
|
-
"/sessions"
|
|
2295
|
-
);
|
|
2296
|
-
const deleteMutation = hooks.useMutation("delete", "/sessions/{id}", {
|
|
2297
|
-
onSuccess: () => {
|
|
2298
|
-
refetch();
|
|
2299
|
-
}
|
|
2300
|
-
});
|
|
2301
|
-
const handleDeleteSession = async (sessionId) => {
|
|
2302
|
-
if (confirm("Are you sure you want to revoke this session?")) {
|
|
2303
|
-
try {
|
|
2304
|
-
await deleteMutation.mutateAsync({
|
|
2305
|
-
params: {
|
|
2306
|
-
path: { id: sessionId }
|
|
2307
|
-
}
|
|
2308
|
-
});
|
|
2309
|
-
} catch (_err) {
|
|
2310
|
-
}
|
|
2311
|
-
}
|
|
2312
|
-
};
|
|
2313
|
-
const columns = [
|
|
2314
|
-
{
|
|
2315
|
-
key: "createdAt",
|
|
2316
|
-
header: "Created",
|
|
2317
|
-
cell: (session) => /* @__PURE__ */ jsxs15("div", { children: [
|
|
2318
|
-
/* @__PURE__ */ jsx17("p", { className: "text-sm font-medium", children: new Date(session.createdAt).toLocaleDateString() }),
|
|
2319
|
-
/* @__PURE__ */ jsx17("p", { className: "text-xs text-muted-foreground", children: new Date(session.createdAt).toLocaleTimeString() })
|
|
2320
|
-
] })
|
|
2321
|
-
},
|
|
2322
|
-
{
|
|
2323
|
-
key: "expiresAt",
|
|
2324
|
-
header: "Expires",
|
|
2325
|
-
cell: (session) => /* @__PURE__ */ jsx17("p", { className: "text-sm", children: new Date(session.expiresAt).toLocaleDateString() })
|
|
2326
|
-
},
|
|
2327
|
-
{
|
|
2328
|
-
key: "userAgent",
|
|
2329
|
-
header: "Device",
|
|
2330
|
-
cell: (session) => /* @__PURE__ */ jsx17("p", { className: "text-sm truncate max-w-xs", children: session.userAgent || "Unknown" })
|
|
2331
|
-
},
|
|
2332
|
-
{
|
|
2333
|
-
key: "ip",
|
|
2334
|
-
header: "IP Address",
|
|
2335
|
-
cell: (session) => /* @__PURE__ */ jsx17("p", { className: "text-sm font-mono", children: session.ip || "Unknown" })
|
|
2336
|
-
},
|
|
2337
|
-
{
|
|
2338
|
-
key: "actions",
|
|
2339
|
-
header: "Actions",
|
|
2340
|
-
cell: (session) => /* @__PURE__ */ jsx17(
|
|
2341
|
-
Button9,
|
|
2342
|
-
{
|
|
2343
|
-
variant: "destructive",
|
|
2344
|
-
size: "sm",
|
|
2345
|
-
onClick: () => handleDeleteSession(session.id),
|
|
2346
|
-
disabled: deleteMutation.isPending && selectedSessionId === session.id,
|
|
2347
|
-
children: deleteMutation.isPending && selectedSessionId === session.id ? "Revoking..." : "Revoke"
|
|
2348
|
-
}
|
|
2349
|
-
)
|
|
2350
|
-
}
|
|
2351
|
-
];
|
|
2352
|
-
if (error) {
|
|
2353
|
-
return /* @__PURE__ */ jsx17("div", { className: "p-6 text-center", children: /* @__PURE__ */ jsx17("p", { className: "text-destructive", children: "Error loading sessions" }) });
|
|
2354
|
-
}
|
|
2355
|
-
return /* @__PURE__ */ jsxs15("div", { className: "w-full p-6 space-y-4", children: [
|
|
2356
|
-
/* @__PURE__ */ jsxs15("div", { children: [
|
|
2357
|
-
/* @__PURE__ */ jsx17("h1", { className: "text-3xl font-bold", children: "Sessions" }),
|
|
2358
|
-
/* @__PURE__ */ jsx17("p", { className: "text-muted-foreground", children: "View and manage active sessions" })
|
|
2359
|
-
] }),
|
|
2360
|
-
/* @__PURE__ */ jsx17(
|
|
2361
|
-
DataTable,
|
|
2362
|
-
{
|
|
2363
|
-
data: data?.sessions || [],
|
|
2364
|
-
columns,
|
|
2365
|
-
isLoading,
|
|
2366
|
-
emptyMessage: "No active sessions"
|
|
2367
|
-
}
|
|
2368
|
-
)
|
|
2369
|
-
] });
|
|
2370
|
-
}
|
|
2371
|
-
|
|
2372
|
-
// src/components/iam/tenants.tsx
|
|
2373
|
-
import { Badge as Badge3, Button as Button10 } from "@mesob/ui/components";
|
|
2374
|
-
import { useState as useState12 } from "react";
|
|
2375
|
-
import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
2376
|
-
function Tenants() {
|
|
2377
|
-
const { hooks } = useApi();
|
|
2378
|
-
const [page, setPage] = useState12(1);
|
|
2379
|
-
const limit = 20;
|
|
2380
|
-
const { data, isLoading, error } = hooks.useQuery("get", "/tenants", {
|
|
2381
|
-
params: {
|
|
2382
|
-
query: {
|
|
2383
|
-
page: String(page),
|
|
2384
|
-
limit: String(limit)
|
|
2385
|
-
}
|
|
2386
|
-
}
|
|
2387
|
-
});
|
|
2388
|
-
const columns = [
|
|
2389
|
-
{
|
|
2390
|
-
key: "name",
|
|
2391
|
-
header: "Tenant",
|
|
2392
|
-
cell: (tenant) => /* @__PURE__ */ jsxs16("div", { children: [
|
|
2393
|
-
/* @__PURE__ */ jsx18("p", { className: "font-medium", children: tenant.name }),
|
|
2394
|
-
/* @__PURE__ */ jsxs16("p", { className: "text-sm text-muted-foreground", children: [
|
|
2395
|
-
"/",
|
|
2396
|
-
tenant.slug
|
|
2397
|
-
] })
|
|
2398
|
-
] })
|
|
2399
|
-
},
|
|
2400
|
-
{
|
|
2401
|
-
key: "status",
|
|
2402
|
-
header: "Status",
|
|
2403
|
-
cell: (tenant) => /* @__PURE__ */ jsx18(Badge3, { variant: tenant.status === "active" ? "default" : "secondary", children: tenant.status })
|
|
2404
|
-
},
|
|
2405
|
-
{
|
|
2406
|
-
key: "createdAt",
|
|
2407
|
-
header: "Created",
|
|
2408
|
-
cell: (tenant) => /* @__PURE__ */ jsx18("p", { className: "text-sm", children: new Date(tenant.createdAt).toLocaleDateString() })
|
|
2409
|
-
},
|
|
2410
|
-
{
|
|
2411
|
-
key: "actions",
|
|
2412
|
-
header: "Actions",
|
|
2413
|
-
cell: (_tenant) => /* @__PURE__ */ jsxs16("div", { className: "flex gap-2", children: [
|
|
2414
|
-
/* @__PURE__ */ jsx18(Button10, { variant: "outline", size: "sm", children: "Domains" }),
|
|
2415
|
-
/* @__PURE__ */ jsx18(Button10, { variant: "outline", size: "sm", children: "Edit" })
|
|
2416
|
-
] })
|
|
2417
|
-
}
|
|
2418
|
-
];
|
|
2419
|
-
if (error) {
|
|
2420
|
-
return /* @__PURE__ */ jsx18("div", { className: "p-6 text-center", children: /* @__PURE__ */ jsx18("p", { className: "text-destructive", children: "Error loading tenants" }) });
|
|
2421
|
-
}
|
|
2422
|
-
return /* @__PURE__ */ jsxs16("div", { className: "w-full p-6 space-y-4", children: [
|
|
2423
|
-
/* @__PURE__ */ jsxs16("div", { className: "flex justify-between items-center", children: [
|
|
2424
|
-
/* @__PURE__ */ jsxs16("div", { children: [
|
|
2425
|
-
/* @__PURE__ */ jsx18("h1", { className: "text-3xl font-bold", children: "Tenants" }),
|
|
2426
|
-
/* @__PURE__ */ jsx18("p", { className: "text-muted-foreground", children: "Manage tenant organizations" })
|
|
2427
|
-
] }),
|
|
2428
|
-
/* @__PURE__ */ jsx18(Button10, { children: "Create Tenant" })
|
|
2429
|
-
] }),
|
|
2430
|
-
/* @__PURE__ */ jsx18(
|
|
2431
|
-
DataTable,
|
|
2432
|
-
{
|
|
2433
|
-
data: data?.tenants || [],
|
|
2434
|
-
columns,
|
|
2435
|
-
isLoading,
|
|
2436
|
-
emptyMessage: "No tenants found"
|
|
2437
|
-
}
|
|
2438
|
-
),
|
|
2439
|
-
data && "tenants" in data && data.tenants && data.tenants.length >= limit && /* @__PURE__ */ jsxs16("div", { className: "flex justify-between items-center", children: [
|
|
2440
|
-
/* @__PURE__ */ jsx18(
|
|
2441
|
-
Button10,
|
|
2442
|
-
{
|
|
2443
|
-
variant: "outline",
|
|
2444
|
-
disabled: page === 1,
|
|
2445
|
-
onClick: () => setPage((prev) => prev - 1),
|
|
2446
|
-
children: "Previous"
|
|
2447
|
-
}
|
|
2448
|
-
),
|
|
2449
|
-
/* @__PURE__ */ jsxs16("span", { className: "text-sm text-muted-foreground", children: [
|
|
2450
|
-
"Page ",
|
|
2451
|
-
page
|
|
2452
|
-
] }),
|
|
2453
|
-
/* @__PURE__ */ jsx18(
|
|
2454
|
-
Button10,
|
|
2455
|
-
{
|
|
2456
|
-
variant: "outline",
|
|
2457
|
-
onClick: () => setPage((prev) => prev + 1),
|
|
2458
|
-
children: "Next"
|
|
2459
|
-
}
|
|
2460
|
-
)
|
|
2461
|
-
] })
|
|
2462
|
-
] });
|
|
2463
|
-
}
|
|
2464
|
-
|
|
2465
|
-
// src/components/iam/users.tsx
|
|
2466
|
-
import { Badge as Badge4, Button as Button11 } from "@mesob/ui/components";
|
|
2467
|
-
import { useState as useState13 } from "react";
|
|
2468
|
-
import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2469
|
-
function Users() {
|
|
2470
|
-
const { hooks } = useApi();
|
|
2471
|
-
const [page, setPage] = useState13(1);
|
|
2472
|
-
const limit = 20;
|
|
2473
|
-
const { data, isLoading, error } = hooks.useQuery("get", "/users", {
|
|
2474
|
-
params: {
|
|
2475
|
-
query: {
|
|
2476
|
-
page: String(page),
|
|
2477
|
-
limit: String(limit)
|
|
2478
|
-
}
|
|
2479
|
-
}
|
|
2480
|
-
});
|
|
2481
|
-
const columns = [
|
|
2482
|
-
{
|
|
2483
|
-
key: "fullName",
|
|
2484
|
-
header: "Name",
|
|
2485
|
-
cell: (user) => /* @__PURE__ */ jsxs17("div", { children: [
|
|
2486
|
-
/* @__PURE__ */ jsx19("p", { className: "font-medium", children: user.fullName }),
|
|
2487
|
-
/* @__PURE__ */ jsxs17("p", { className: "text-sm text-muted-foreground", children: [
|
|
2488
|
-
"@",
|
|
2489
|
-
user.handle
|
|
2490
|
-
] })
|
|
2491
|
-
] })
|
|
2492
|
-
},
|
|
2493
|
-
{
|
|
2494
|
-
key: "contact",
|
|
2495
|
-
header: "Contact",
|
|
2496
|
-
cell: (user) => /* @__PURE__ */ jsxs17("div", { className: "space-y-1", children: [
|
|
2497
|
-
user.email && /* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-2", children: [
|
|
2498
|
-
/* @__PURE__ */ jsx19("p", { className: "text-sm", children: user.email }),
|
|
2499
|
-
user.emailVerified && /* @__PURE__ */ jsx19(Badge4, { variant: "outline", className: "text-xs", children: "Verified" })
|
|
2500
|
-
] }),
|
|
2501
|
-
user.phone && /* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-2", children: [
|
|
2502
|
-
/* @__PURE__ */ jsx19("p", { className: "text-sm", children: user.phone }),
|
|
2503
|
-
user.phoneVerified && /* @__PURE__ */ jsx19(Badge4, { variant: "outline", className: "text-xs", children: "Verified" })
|
|
2504
|
-
] })
|
|
2505
|
-
] })
|
|
2506
|
-
},
|
|
2507
|
-
{
|
|
2508
|
-
key: "lastSignIn",
|
|
2509
|
-
header: "Last Sign In",
|
|
2510
|
-
cell: (user) => /* @__PURE__ */ jsx19("p", { className: "text-sm", children: user.lastSignInAt ? new Date(user.lastSignInAt).toLocaleDateString() : "Never" })
|
|
2511
|
-
},
|
|
2512
|
-
{
|
|
2513
|
-
key: "actions",
|
|
2514
|
-
header: "Actions",
|
|
2515
|
-
cell: (_user) => /* @__PURE__ */ jsxs17("div", { className: "flex gap-2", children: [
|
|
2516
|
-
/* @__PURE__ */ jsx19(Button11, { variant: "outline", size: "sm", children: "View" }),
|
|
2517
|
-
/* @__PURE__ */ jsx19(Button11, { variant: "outline", size: "sm", children: "Edit" })
|
|
2518
|
-
] })
|
|
2519
|
-
}
|
|
2520
|
-
];
|
|
2521
|
-
if (error) {
|
|
2522
|
-
return /* @__PURE__ */ jsx19("div", { className: "p-6 text-center", children: /* @__PURE__ */ jsx19("p", { className: "text-destructive", children: "Error loading users" }) });
|
|
2523
|
-
}
|
|
2524
|
-
return /* @__PURE__ */ jsxs17("div", { className: "w-full p-6 space-y-4", children: [
|
|
2525
|
-
/* @__PURE__ */ jsxs17("div", { className: "flex justify-between items-center", children: [
|
|
2526
|
-
/* @__PURE__ */ jsxs17("div", { children: [
|
|
2527
|
-
/* @__PURE__ */ jsx19("h1", { className: "text-3xl font-bold", children: "Users" }),
|
|
2528
|
-
/* @__PURE__ */ jsx19("p", { className: "text-muted-foreground", children: "Manage user accounts" })
|
|
2529
|
-
] }),
|
|
2530
|
-
/* @__PURE__ */ jsx19(Button11, { children: "Create User" })
|
|
2531
|
-
] }),
|
|
2532
|
-
/* @__PURE__ */ jsx19(
|
|
2533
|
-
DataTable,
|
|
2534
|
-
{
|
|
2535
|
-
data: data?.users || [],
|
|
2536
|
-
columns,
|
|
2537
|
-
isLoading,
|
|
2538
|
-
emptyMessage: "No users found"
|
|
2539
|
-
}
|
|
2540
|
-
),
|
|
2541
|
-
data && "users" in data && data.users && data.users.length >= limit && /* @__PURE__ */ jsxs17("div", { className: "flex justify-between items-center", children: [
|
|
2542
|
-
/* @__PURE__ */ jsx19(
|
|
2543
|
-
Button11,
|
|
2544
|
-
{
|
|
2545
|
-
variant: "outline",
|
|
2546
|
-
disabled: page === 1,
|
|
2547
|
-
onClick: () => setPage((prev) => prev - 1),
|
|
2548
|
-
children: "Previous"
|
|
2549
|
-
}
|
|
2550
|
-
),
|
|
2551
|
-
/* @__PURE__ */ jsxs17("span", { className: "text-sm text-muted-foreground", children: [
|
|
2552
|
-
"Page ",
|
|
2553
|
-
page
|
|
2554
|
-
] }),
|
|
2555
|
-
/* @__PURE__ */ jsx19(
|
|
2556
|
-
Button11,
|
|
2557
|
-
{
|
|
2558
|
-
variant: "outline",
|
|
2559
|
-
onClick: () => setPage((prev) => prev + 1),
|
|
2560
|
-
children: "Next"
|
|
2561
|
-
}
|
|
2562
|
-
)
|
|
2563
|
-
] })
|
|
2564
|
-
] });
|
|
2565
|
-
}
|
|
2566
|
-
|
|
2567
|
-
// src/components/profile/account.tsx
|
|
2568
|
-
import { Separator } from "@mesob/ui/components";
|
|
2569
|
-
import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2570
|
-
function Account() {
|
|
2571
|
-
const { user, isAuthenticated } = useSession();
|
|
2572
|
-
if (!(isAuthenticated && user)) {
|
|
2573
|
-
return /* @__PURE__ */ jsx20("div", { children: "Sign in required" });
|
|
2574
|
-
}
|
|
2575
|
-
return /* @__PURE__ */ jsxs18("div", { className: "p-6 max-w-4xl", children: [
|
|
2576
|
-
/* @__PURE__ */ jsxs18("div", { className: "mb-6", children: [
|
|
2577
|
-
/* @__PURE__ */ jsx20("h2", { className: "text-lg font-semibold mb-4", children: "Profile details" }),
|
|
2578
|
-
/* @__PURE__ */ jsx20(Separator, {})
|
|
2579
|
-
] }),
|
|
2580
|
-
/* @__PURE__ */ jsxs18("div", { className: "space-y-6 transition-all duration-300 ease-in-out", children: [
|
|
2581
|
-
/* @__PURE__ */ jsx20("div", { className: "flex flex-col md:flex-row items-start gap-4 md:gap-12 min-h-[3rem]", children: /* @__PURE__ */ jsx20("div", { className: "w-full md:w-48 mt-4 shrink-0 h-fit", children: /* @__PURE__ */ jsx20("span", { className: "font-medium text-sm", children: "Profile" }) }) }),
|
|
2582
|
-
/* @__PURE__ */ jsx20(Separator, {}),
|
|
2583
|
-
/* @__PURE__ */ jsxs18("div", { className: "flex flex-col md:flex-row gap-4 md:gap-12 py-2", children: [
|
|
2584
|
-
/* @__PURE__ */ jsx20("div", { className: "w-full md:w-48 shrink-0", children: /* @__PURE__ */ jsx20("span", { className: "font-medium text-sm", children: "Email addresses" }) }),
|
|
2585
|
-
/* @__PURE__ */ jsx20("div", { className: "flex-1 space-y-4", children: /* @__PURE__ */ jsx20("div", { className: "flex items-center justify-between group", children: user.email ? /* @__PURE__ */ jsx20("div", { className: "flex items-center gap-3", children: /* @__PURE__ */ jsx20("span", { className: "text-sm", children: user.email }) }) : /* @__PURE__ */ jsx20("span", { className: "text-sm text-muted-foreground", children: "No email address" }) }) })
|
|
2586
|
-
] }),
|
|
2587
|
-
/* @__PURE__ */ jsx20(Separator, {}),
|
|
2588
|
-
/* @__PURE__ */ jsxs18("div", { className: "flex flex-col md:flex-row gap-4 md:gap-12 py-2", children: [
|
|
2589
|
-
/* @__PURE__ */ jsx20("div", { className: "w-full md:w-48 shrink-0", children: /* @__PURE__ */ jsx20("span", { className: "font-medium text-sm", children: "Phone numbers" }) }),
|
|
2590
|
-
/* @__PURE__ */ jsx20("div", { className: "flex-1 space-y-4", children: user.phone ? /* @__PURE__ */ jsx20("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsx20("span", { className: "text-sm", children: user.phone }) }) : /* @__PURE__ */ jsx20("span", { className: "text-sm text-muted-foreground", children: "No phone number" }) })
|
|
2591
|
-
] })
|
|
2592
|
-
] })
|
|
2593
|
-
] });
|
|
2594
|
-
}
|
|
2595
|
-
|
|
2596
|
-
// src/components/profile/change-email-form.tsx
|
|
18
|
+
AuthFormSkeleton
|
|
19
|
+
} from "./chunk-5M7I7WNH.js";
|
|
2597
20
|
import {
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
CollapsibleContent,
|
|
2601
|
-
CollapsibleTrigger
|
|
2602
|
-
} from "@mesob/ui/components";
|
|
2603
|
-
import { IconChevronDown } from "@tabler/icons-react";
|
|
2604
|
-
import { useState as useState16 } from "react";
|
|
2605
|
-
|
|
2606
|
-
// src/components/profile/request-change-email-form.tsx
|
|
2607
|
-
import { zodResolver as zodResolver6 } from "@hookform/resolvers/zod";
|
|
2608
|
-
import { Button as Button12, Input as Input5, Label, Spinner as Spinner2 } from "@mesob/ui/components";
|
|
2609
|
-
import { IconEye as IconEye4, IconEyeOff as IconEyeOff4 } from "@tabler/icons-react";
|
|
2610
|
-
import { useEffect as useEffect8, useState as useState14 } from "react";
|
|
2611
|
-
import { useForm as useForm6 } from "react-hook-form";
|
|
2612
|
-
import { toast as toast7 } from "sonner";
|
|
2613
|
-
import { z as z6 } from "zod";
|
|
2614
|
-
import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
2615
|
-
var emailPasswordSchema = z6.object({
|
|
2616
|
-
email: z6.string().email("Invalid email address"),
|
|
2617
|
-
password: z6.string().min(8, "Password must be at least 8 characters").max(128, "Password too long")
|
|
2618
|
-
});
|
|
2619
|
-
function isAuthError2(error) {
|
|
2620
|
-
return typeof error === "object" && error !== null && ("code" in error || "message" in error || "name" in error);
|
|
2621
|
-
}
|
|
2622
|
-
function getErrorCode(error) {
|
|
2623
|
-
if (error.code) {
|
|
2624
|
-
return error.code;
|
|
2625
|
-
}
|
|
2626
|
-
if (error.message) {
|
|
2627
|
-
const upperMessage = error.message.toUpperCase().trim();
|
|
2628
|
-
const validCodes2 = [
|
|
2629
|
-
"USER_NOT_FOUND",
|
|
2630
|
-
"USER_EXISTS",
|
|
2631
|
-
"INVALID_PASSWORD",
|
|
2632
|
-
"VERIFICATION_EXPIRED",
|
|
2633
|
-
"VERIFICATION_MISMATCH",
|
|
2634
|
-
"VERIFICATION_NOT_FOUND",
|
|
2635
|
-
"TOO_MANY_ATTEMPTS",
|
|
2636
|
-
"UNAUTHORIZED"
|
|
2637
|
-
];
|
|
2638
|
-
if (validCodes2.includes(upperMessage)) {
|
|
2639
|
-
return upperMessage;
|
|
2640
|
-
}
|
|
2641
|
-
}
|
|
2642
|
-
return void 0;
|
|
2643
|
-
}
|
|
2644
|
-
function getErrorMessage(error) {
|
|
2645
|
-
if (isAuthError2(error)) {
|
|
2646
|
-
const errorCode = getErrorCode(error);
|
|
2647
|
-
switch (errorCode) {
|
|
2648
|
-
case "USER_EXISTS":
|
|
2649
|
-
return "This email is already taken. Please use a different email.";
|
|
2650
|
-
case "VERIFICATION_EXPIRED":
|
|
2651
|
-
return "Verification code has expired. Please request a new one.";
|
|
2652
|
-
case "VERIFICATION_MISMATCH":
|
|
2653
|
-
return "Invalid verification code. Please try again.";
|
|
2654
|
-
case "VERIFICATION_NOT_FOUND":
|
|
2655
|
-
return "Verification not found. Please request a new code.";
|
|
2656
|
-
default:
|
|
2657
|
-
return error.message || "An error occurred. Please try again.";
|
|
2658
|
-
}
|
|
2659
|
-
}
|
|
2660
|
-
if (error instanceof Error) {
|
|
2661
|
-
return error.message;
|
|
2662
|
-
}
|
|
2663
|
-
return "An error occurred. Please try again.";
|
|
2664
|
-
}
|
|
2665
|
-
function RequestChangeEmailForm({
|
|
2666
|
-
onSuccess,
|
|
2667
|
-
onCancel,
|
|
2668
|
-
buttonText
|
|
2669
|
-
}) {
|
|
2670
|
-
const { user } = useSession();
|
|
2671
|
-
const { hooks } = useApi();
|
|
2672
|
-
const [isSubmitting, setIsSubmitting] = useState14(false);
|
|
2673
|
-
const [isChecking, setIsChecking] = useState14(true);
|
|
2674
|
-
const [showPassword, setShowPassword] = useState14(false);
|
|
2675
|
-
const getPendingAccountChangeQuery = hooks.useQuery(
|
|
2676
|
-
"get",
|
|
2677
|
-
"/account-change/pending",
|
|
2678
|
-
{},
|
|
2679
|
-
{ enabled: false }
|
|
2680
|
-
);
|
|
2681
|
-
const verifyPasswordMutation = hooks.useMutation("post", "/password/verify");
|
|
2682
|
-
const checkUserMutation = hooks.useMutation("post", "/check-account");
|
|
2683
|
-
const requestEmailVerificationMutation = hooks.useMutation(
|
|
2684
|
-
"post",
|
|
2685
|
-
"/email/verification/request"
|
|
2686
|
-
);
|
|
2687
|
-
const emailPasswordForm = useForm6({
|
|
2688
|
-
resolver: zodResolver6(emailPasswordSchema),
|
|
2689
|
-
defaultValues: {
|
|
2690
|
-
email: "",
|
|
2691
|
-
password: ""
|
|
2692
|
-
}
|
|
2693
|
-
});
|
|
2694
|
-
const {
|
|
2695
|
-
register,
|
|
2696
|
-
handleSubmit,
|
|
2697
|
-
getValues,
|
|
2698
|
-
setValue,
|
|
2699
|
-
formState: { errors }
|
|
2700
|
-
} = emailPasswordForm;
|
|
2701
|
-
useEffect8(() => {
|
|
2702
|
-
let active = true;
|
|
2703
|
-
const run = async () => {
|
|
2704
|
-
try {
|
|
2705
|
-
const data = await getPendingAccountChangeQuery.refetch();
|
|
2706
|
-
if (!active) {
|
|
2707
|
-
return;
|
|
2708
|
-
}
|
|
2709
|
-
const accountChange = data.data?.accountChange;
|
|
2710
|
-
const verificationId = data.data?.verificationId;
|
|
2711
|
-
if (accountChange?.changeType !== "email") {
|
|
2712
|
-
setIsChecking(false);
|
|
2713
|
-
return;
|
|
2714
|
-
}
|
|
2715
|
-
if (!accountChange.newEmail) {
|
|
2716
|
-
setIsChecking(false);
|
|
2717
|
-
return;
|
|
2718
|
-
}
|
|
2719
|
-
if (getValues("email")) {
|
|
2720
|
-
setIsChecking(false);
|
|
2721
|
-
return;
|
|
2722
|
-
}
|
|
2723
|
-
setValue("email", accountChange.newEmail, { shouldValidate: true });
|
|
2724
|
-
if (verificationId) {
|
|
2725
|
-
toast7.message("Resuming verification\u2026");
|
|
2726
|
-
onSuccess(verificationId, accountChange.newEmail);
|
|
2727
|
-
return;
|
|
2728
|
-
}
|
|
2729
|
-
setIsChecking(false);
|
|
2730
|
-
} catch {
|
|
2731
|
-
setIsChecking(false);
|
|
2732
|
-
}
|
|
2733
|
-
};
|
|
2734
|
-
run().catch(() => void 0);
|
|
2735
|
-
return () => {
|
|
2736
|
-
active = false;
|
|
2737
|
-
};
|
|
2738
|
-
}, [getPendingAccountChangeQuery.refetch, getValues, onSuccess, setValue]);
|
|
2739
|
-
const onEmailPasswordSubmit = async (data) => {
|
|
2740
|
-
if (!user) {
|
|
2741
|
-
toast7.error("User not found");
|
|
2742
|
-
return;
|
|
2743
|
-
}
|
|
2744
|
-
try {
|
|
2745
|
-
setIsSubmitting(true);
|
|
2746
|
-
await verifyPasswordMutation.mutateAsync({
|
|
2747
|
-
body: { password: data.password }
|
|
2748
|
-
});
|
|
2749
|
-
const checkResult = await checkUserMutation.mutateAsync({
|
|
2750
|
-
body: { identifier: data.email }
|
|
2751
|
-
});
|
|
2752
|
-
if (checkResult.data?.exists) {
|
|
2753
|
-
if (user?.email?.toLowerCase() === data.email.toLowerCase()) {
|
|
2754
|
-
toast7.error("This is already your current email address.");
|
|
2755
|
-
return;
|
|
2756
|
-
}
|
|
2757
|
-
toast7.error(
|
|
2758
|
-
"This email is already taken. Please use a different email."
|
|
2759
|
-
);
|
|
2760
|
-
return;
|
|
2761
|
-
}
|
|
2762
|
-
const verification = await requestEmailVerificationMutation.mutateAsync({
|
|
2763
|
-
body: { email: data.email }
|
|
2764
|
-
});
|
|
2765
|
-
toast7.success("Verification code sent to your email");
|
|
2766
|
-
onSuccess(verification.data?.verificationId ?? "", data.email);
|
|
2767
|
-
} catch (error) {
|
|
2768
|
-
const errorMessage = getErrorMessage(error);
|
|
2769
|
-
if (isAuthError2(error)) {
|
|
2770
|
-
const errorCode = getErrorCode(error);
|
|
2771
|
-
if (errorCode === "INVALID_PASSWORD" || errorCode === "USER_NOT_FOUND") {
|
|
2772
|
-
toast7.error("Incorrect password. Please try again.");
|
|
2773
|
-
return;
|
|
2774
|
-
}
|
|
2775
|
-
}
|
|
2776
|
-
toast7.error(errorMessage);
|
|
2777
|
-
} finally {
|
|
2778
|
-
setIsSubmitting(false);
|
|
2779
|
-
}
|
|
2780
|
-
};
|
|
2781
|
-
const isLoading = isSubmitting || isChecking;
|
|
2782
|
-
return /* @__PURE__ */ jsxs19(
|
|
2783
|
-
"form",
|
|
2784
|
-
{
|
|
2785
|
-
onSubmit: handleSubmit(onEmailPasswordSubmit),
|
|
2786
|
-
className: "p-4 space-y-4 border-t",
|
|
2787
|
-
children: [
|
|
2788
|
-
/* @__PURE__ */ jsxs19("div", { className: "space-y-4 w-full md:w-1/2", children: [
|
|
2789
|
-
/* @__PURE__ */ jsxs19("div", { className: "space-y-2", children: [
|
|
2790
|
-
/* @__PURE__ */ jsx21(Label, { htmlFor: "email", children: "New Email Address" }),
|
|
2791
|
-
/* @__PURE__ */ jsx21(
|
|
2792
|
-
Input5,
|
|
2793
|
-
{
|
|
2794
|
-
id: "email",
|
|
2795
|
-
type: "email",
|
|
2796
|
-
placeholder: "Enter your new email",
|
|
2797
|
-
...register("email"),
|
|
2798
|
-
disabled: isLoading
|
|
2799
|
-
}
|
|
2800
|
-
),
|
|
2801
|
-
errors.email && /* @__PURE__ */ jsx21("p", { className: "text-sm text-destructive", children: errors.email.message })
|
|
2802
|
-
] }),
|
|
2803
|
-
/* @__PURE__ */ jsxs19("div", { className: "space-y-2", children: [
|
|
2804
|
-
/* @__PURE__ */ jsx21(Label, { htmlFor: "password", children: "Password" }),
|
|
2805
|
-
/* @__PURE__ */ jsxs19("div", { className: "relative", children: [
|
|
2806
|
-
/* @__PURE__ */ jsx21(
|
|
2807
|
-
Input5,
|
|
2808
|
-
{
|
|
2809
|
-
id: "password",
|
|
2810
|
-
type: showPassword ? "text" : "password",
|
|
2811
|
-
autoComplete: "current-password",
|
|
2812
|
-
placeholder: "Enter your password",
|
|
2813
|
-
...register("password"),
|
|
2814
|
-
disabled: isLoading
|
|
2815
|
-
}
|
|
2816
|
-
),
|
|
2817
|
-
/* @__PURE__ */ jsx21(
|
|
2818
|
-
"button",
|
|
2819
|
-
{
|
|
2820
|
-
type: "button",
|
|
2821
|
-
onClick: () => setShowPassword(!showPassword),
|
|
2822
|
-
className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground",
|
|
2823
|
-
disabled: isLoading,
|
|
2824
|
-
children: showPassword ? /* @__PURE__ */ jsx21(IconEyeOff4, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx21(IconEye4, { className: "h-4 w-4" })
|
|
2825
|
-
}
|
|
2826
|
-
)
|
|
2827
|
-
] }),
|
|
2828
|
-
errors.password && /* @__PURE__ */ jsx21("p", { className: "text-sm text-destructive", children: errors.password.message })
|
|
2829
|
-
] })
|
|
2830
|
-
] }),
|
|
2831
|
-
/* @__PURE__ */ jsxs19("div", { className: "flex justify-end gap-2", children: [
|
|
2832
|
-
/* @__PURE__ */ jsx21(
|
|
2833
|
-
Button12,
|
|
2834
|
-
{
|
|
2835
|
-
type: "button",
|
|
2836
|
-
variant: "outline",
|
|
2837
|
-
onClick: onCancel,
|
|
2838
|
-
disabled: isLoading,
|
|
2839
|
-
children: "Cancel"
|
|
2840
|
-
}
|
|
2841
|
-
),
|
|
2842
|
-
/* @__PURE__ */ jsxs19(Button12, { type: "submit", disabled: isLoading, children: [
|
|
2843
|
-
isLoading && /* @__PURE__ */ jsx21(Spinner2, { className: "mr-2 h-4 w-4" }),
|
|
2844
|
-
isChecking ? "Checking\u2026" : buttonText
|
|
2845
|
-
] })
|
|
2846
|
-
] })
|
|
2847
|
-
]
|
|
2848
|
-
}
|
|
2849
|
-
);
|
|
2850
|
-
}
|
|
2851
|
-
|
|
2852
|
-
// src/components/profile/verify-change-email-form.tsx
|
|
2853
|
-
import { useState as useState15 } from "react";
|
|
2854
|
-
import { toast as toast8 } from "sonner";
|
|
2855
|
-
|
|
2856
|
-
// src/components/profile/otp-verification-modal.tsx
|
|
21
|
+
ProfileSkeleton
|
|
22
|
+
} from "./chunk-NEO72TMH.js";
|
|
2857
23
|
import {
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
DialogHeader,
|
|
2862
|
-
DialogTitle
|
|
2863
|
-
} from "@mesob/ui/components";
|
|
2864
|
-
import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
2865
|
-
function OtpVerificationModal({
|
|
2866
|
-
open,
|
|
2867
|
-
title,
|
|
2868
|
-
description,
|
|
2869
|
-
verificationId,
|
|
2870
|
-
isLoading,
|
|
2871
|
-
onSubmit,
|
|
2872
|
-
onResend,
|
|
2873
|
-
onCancel
|
|
2874
|
-
}) {
|
|
2875
|
-
return /* @__PURE__ */ jsx22(
|
|
2876
|
-
Dialog,
|
|
2877
|
-
{
|
|
2878
|
-
open,
|
|
2879
|
-
onOpenChange: (nextOpen) => {
|
|
2880
|
-
if (!nextOpen) {
|
|
2881
|
-
onCancel?.();
|
|
2882
|
-
}
|
|
2883
|
-
},
|
|
2884
|
-
children: /* @__PURE__ */ jsxs20(DialogContent, { children: [
|
|
2885
|
-
/* @__PURE__ */ jsxs20(DialogHeader, { children: [
|
|
2886
|
-
/* @__PURE__ */ jsx22(DialogTitle, { children: title }),
|
|
2887
|
-
description && /* @__PURE__ */ jsx22(DialogDescription, { children: description })
|
|
2888
|
-
] }),
|
|
2889
|
-
/* @__PURE__ */ jsx22(
|
|
2890
|
-
VerificationForm,
|
|
2891
|
-
{
|
|
2892
|
-
verificationId,
|
|
2893
|
-
isLoading,
|
|
2894
|
-
onSubmit: async ({ code }) => onSubmit(code),
|
|
2895
|
-
onResend: onResend ?? (() => void 0)
|
|
2896
|
-
}
|
|
2897
|
-
)
|
|
2898
|
-
] })
|
|
2899
|
-
}
|
|
2900
|
-
);
|
|
2901
|
-
}
|
|
2902
|
-
|
|
2903
|
-
// src/components/profile/verify-change-email-form.tsx
|
|
2904
|
-
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
2905
|
-
function isAuthError3(error) {
|
|
2906
|
-
return typeof error === "object" && error !== null && ("code" in error || "message" in error || "name" in error);
|
|
2907
|
-
}
|
|
2908
|
-
function getErrorCode2(error) {
|
|
2909
|
-
if (error.code) {
|
|
2910
|
-
return error.code;
|
|
2911
|
-
}
|
|
2912
|
-
if (error.message) {
|
|
2913
|
-
const upperMessage = error.message.toUpperCase().trim();
|
|
2914
|
-
const validCodes2 = [
|
|
2915
|
-
"USER_NOT_FOUND",
|
|
2916
|
-
"USER_EXISTS",
|
|
2917
|
-
"INVALID_PASSWORD",
|
|
2918
|
-
"VERIFICATION_EXPIRED",
|
|
2919
|
-
"VERIFICATION_MISMATCH",
|
|
2920
|
-
"VERIFICATION_NOT_FOUND",
|
|
2921
|
-
"TOO_MANY_ATTEMPTS",
|
|
2922
|
-
"UNAUTHORIZED"
|
|
2923
|
-
];
|
|
2924
|
-
if (validCodes2.includes(upperMessage)) {
|
|
2925
|
-
return upperMessage;
|
|
2926
|
-
}
|
|
2927
|
-
}
|
|
2928
|
-
return void 0;
|
|
2929
|
-
}
|
|
2930
|
-
function getErrorMessage2(error) {
|
|
2931
|
-
if (isAuthError3(error)) {
|
|
2932
|
-
const errorCode = getErrorCode2(error);
|
|
2933
|
-
switch (errorCode) {
|
|
2934
|
-
case "USER_EXISTS":
|
|
2935
|
-
return "This email is already taken. Please use a different email.";
|
|
2936
|
-
case "VERIFICATION_EXPIRED":
|
|
2937
|
-
return "Verification code has expired. Please request a new one.";
|
|
2938
|
-
case "VERIFICATION_MISMATCH":
|
|
2939
|
-
return "Invalid verification code. Please try again.";
|
|
2940
|
-
case "VERIFICATION_NOT_FOUND":
|
|
2941
|
-
return "Verification not found. Please request a new code.";
|
|
2942
|
-
default:
|
|
2943
|
-
return error.message || "An error occurred. Please try again.";
|
|
2944
|
-
}
|
|
2945
|
-
}
|
|
2946
|
-
if (error instanceof Error) {
|
|
2947
|
-
return error.message;
|
|
2948
|
-
}
|
|
2949
|
-
return "An error occurred. Please try again.";
|
|
2950
|
-
}
|
|
2951
|
-
function VerifyChangeEmailForm({
|
|
2952
|
-
email,
|
|
2953
|
-
verificationId,
|
|
2954
|
-
onSuccess,
|
|
2955
|
-
onCancel
|
|
2956
|
-
}) {
|
|
2957
|
-
const { refresh } = useSession();
|
|
2958
|
-
const { hooks } = useApi();
|
|
2959
|
-
const [isSubmitting, setIsSubmitting] = useState15(false);
|
|
2960
|
-
const [currentVerificationId, setCurrentVerificationId] = useState15(verificationId);
|
|
2961
|
-
const verifyEmailMutation = hooks.useMutation(
|
|
2962
|
-
"post",
|
|
2963
|
-
"/email/verification/confirm"
|
|
2964
|
-
);
|
|
2965
|
-
const updateEmailMutation = hooks.useMutation("put", "/profile/email");
|
|
2966
|
-
const requestEmailVerificationMutation = hooks.useMutation(
|
|
2967
|
-
"post",
|
|
2968
|
-
"/email/verification/request"
|
|
2969
|
-
);
|
|
2970
|
-
const onOtpSubmit = async (code) => {
|
|
2971
|
-
if (!currentVerificationId) {
|
|
2972
|
-
toast8.error("Verification not found. Please request a new code.");
|
|
2973
|
-
return;
|
|
2974
|
-
}
|
|
2975
|
-
try {
|
|
2976
|
-
setIsSubmitting(true);
|
|
2977
|
-
await verifyEmailMutation.mutateAsync({
|
|
2978
|
-
body: {
|
|
2979
|
-
verificationId: currentVerificationId,
|
|
2980
|
-
code
|
|
2981
|
-
}
|
|
2982
|
-
});
|
|
2983
|
-
await updateEmailMutation.mutateAsync({
|
|
2984
|
-
body: { email }
|
|
2985
|
-
});
|
|
2986
|
-
toast8.success("Email updated successfully");
|
|
2987
|
-
await refresh();
|
|
2988
|
-
onSuccess();
|
|
2989
|
-
} catch (error) {
|
|
2990
|
-
const errorMessage = getErrorMessage2(error);
|
|
2991
|
-
toast8.error(errorMessage);
|
|
2992
|
-
} finally {
|
|
2993
|
-
setIsSubmitting(false);
|
|
2994
|
-
}
|
|
2995
|
-
};
|
|
2996
|
-
if (!currentVerificationId) {
|
|
2997
|
-
toast8.error("Verification not found. Please request a new code.");
|
|
2998
|
-
return null;
|
|
2999
|
-
}
|
|
3000
|
-
return /* @__PURE__ */ jsx23(
|
|
3001
|
-
OtpVerificationModal,
|
|
3002
|
-
{
|
|
3003
|
-
open: true,
|
|
3004
|
-
title: "Verify email",
|
|
3005
|
-
description: `Enter the verification code sent to ${email}`,
|
|
3006
|
-
verificationId: currentVerificationId,
|
|
3007
|
-
isLoading: isSubmitting,
|
|
3008
|
-
onSubmit: onOtpSubmit,
|
|
3009
|
-
onResend: async () => {
|
|
3010
|
-
try {
|
|
3011
|
-
setIsSubmitting(true);
|
|
3012
|
-
const next = await requestEmailVerificationMutation.mutateAsync({
|
|
3013
|
-
body: { email }
|
|
3014
|
-
});
|
|
3015
|
-
setCurrentVerificationId(next.data?.verificationId ?? null);
|
|
3016
|
-
toast8.success("Verification code resent");
|
|
3017
|
-
} catch (error) {
|
|
3018
|
-
toast8.error(getErrorMessage2(error));
|
|
3019
|
-
} finally {
|
|
3020
|
-
setIsSubmitting(false);
|
|
3021
|
-
}
|
|
3022
|
-
},
|
|
3023
|
-
onCancel
|
|
3024
|
-
}
|
|
3025
|
-
);
|
|
3026
|
-
}
|
|
3027
|
-
|
|
3028
|
-
// src/components/profile/change-email-form.tsx
|
|
3029
|
-
import { jsx as jsx24, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
3030
|
-
function ChangeEmailForm() {
|
|
3031
|
-
const { user } = useSession();
|
|
3032
|
-
const [isOpen, setIsOpen] = useState16(false);
|
|
3033
|
-
const [showOtp, setShowOtp] = useState16(false);
|
|
3034
|
-
const [verificationId, setVerificationId] = useState16(null);
|
|
3035
|
-
const [newEmail, setNewEmail] = useState16("");
|
|
3036
|
-
const resetForms = () => {
|
|
3037
|
-
setShowOtp(false);
|
|
3038
|
-
setVerificationId(null);
|
|
3039
|
-
setNewEmail("");
|
|
3040
|
-
};
|
|
3041
|
-
const handleRequestSuccess = (id, email) => {
|
|
3042
|
-
setVerificationId(id);
|
|
3043
|
-
setNewEmail(email);
|
|
3044
|
-
setShowOtp(true);
|
|
3045
|
-
};
|
|
3046
|
-
const handleVerifySuccess = () => {
|
|
3047
|
-
resetForms();
|
|
3048
|
-
setIsOpen(false);
|
|
3049
|
-
};
|
|
3050
|
-
const handleCancel = () => {
|
|
3051
|
-
resetForms();
|
|
3052
|
-
setIsOpen(false);
|
|
3053
|
-
};
|
|
3054
|
-
const title = user?.email ? "Change Email" : "Add Email";
|
|
3055
|
-
const description = user?.email ? "Update your email address" : "Add an email address to your account";
|
|
3056
|
-
return /* @__PURE__ */ jsx24(Collapsible, { open: isOpen, onOpenChange: setIsOpen, children: /* @__PURE__ */ jsxs21("div", { className: "border rounded-lg", children: [
|
|
3057
|
-
/* @__PURE__ */ jsxs21(
|
|
3058
|
-
CollapsibleTrigger,
|
|
3059
|
-
{
|
|
3060
|
-
render: /* @__PURE__ */ jsx24(
|
|
3061
|
-
Button13,
|
|
3062
|
-
{
|
|
3063
|
-
variant: "ghost",
|
|
3064
|
-
className: "w-full justify-between p-4 h-auto"
|
|
3065
|
-
}
|
|
3066
|
-
),
|
|
3067
|
-
children: [
|
|
3068
|
-
/* @__PURE__ */ jsxs21("div", { className: "flex flex-col items-start", children: [
|
|
3069
|
-
/* @__PURE__ */ jsx24("span", { className: "font-medium", children: title }),
|
|
3070
|
-
/* @__PURE__ */ jsx24("span", { className: "text-sm text-muted-foreground", children: description })
|
|
3071
|
-
] }),
|
|
3072
|
-
/* @__PURE__ */ jsx24(
|
|
3073
|
-
IconChevronDown,
|
|
3074
|
-
{
|
|
3075
|
-
className: `h-4 w-4 transition-transform ${isOpen ? "rotate-180" : ""}`
|
|
3076
|
-
}
|
|
3077
|
-
)
|
|
3078
|
-
]
|
|
3079
|
-
}
|
|
3080
|
-
),
|
|
3081
|
-
/* @__PURE__ */ jsx24(CollapsibleContent, { children: showOtp ? /* @__PURE__ */ jsx24(
|
|
3082
|
-
VerifyChangeEmailForm,
|
|
3083
|
-
{
|
|
3084
|
-
email: newEmail,
|
|
3085
|
-
verificationId,
|
|
3086
|
-
onSuccess: handleVerifySuccess,
|
|
3087
|
-
onCancel: handleCancel
|
|
3088
|
-
}
|
|
3089
|
-
) : /* @__PURE__ */ jsx24(
|
|
3090
|
-
RequestChangeEmailForm,
|
|
3091
|
-
{
|
|
3092
|
-
onSuccess: handleRequestSuccess,
|
|
3093
|
-
onCancel: handleCancel,
|
|
3094
|
-
buttonText: title
|
|
3095
|
-
}
|
|
3096
|
-
) })
|
|
3097
|
-
] }) });
|
|
3098
|
-
}
|
|
3099
|
-
|
|
3100
|
-
// src/components/profile/change-password-form.tsx
|
|
3101
|
-
import { zodResolver as zodResolver7 } from "@hookform/resolvers/zod";
|
|
24
|
+
ProfileLayout,
|
|
25
|
+
ProfileSidebar
|
|
26
|
+
} from "./chunk-ISNNPMF7.js";
|
|
3102
27
|
import {
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
Label as Label2,
|
|
3109
|
-
Spinner as Spinner3
|
|
3110
|
-
} from "@mesob/ui/components";
|
|
3111
|
-
import { IconChevronDown as IconChevronDown2, IconEye as IconEye5, IconEyeOff as IconEyeOff5 } from "@tabler/icons-react";
|
|
3112
|
-
import { useState as useState17 } from "react";
|
|
3113
|
-
import { useForm as useForm7 } from "react-hook-form";
|
|
3114
|
-
import { toast as toast9 } from "sonner";
|
|
3115
|
-
import { z as z7 } from "zod";
|
|
3116
|
-
import { jsx as jsx25, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
3117
|
-
var changePasswordSchema = z7.object({
|
|
3118
|
-
currentPassword: z7.string().min(8, "Password must be at least 8 characters"),
|
|
3119
|
-
newPassword: z7.string().min(8, "Password must be at least 8 characters"),
|
|
3120
|
-
confirmPassword: z7.string().min(8, "Password must be at least 8 characters")
|
|
3121
|
-
}).refine((data) => data.newPassword === data.confirmPassword, {
|
|
3122
|
-
message: "Passwords don't match",
|
|
3123
|
-
path: ["confirmPassword"]
|
|
3124
|
-
});
|
|
3125
|
-
function isAuthError4(error) {
|
|
3126
|
-
return typeof error === "object" && error !== null && ("code" in error || "message" in error || "name" in error);
|
|
3127
|
-
}
|
|
3128
|
-
function getErrorCode3(error) {
|
|
3129
|
-
if (error.code) {
|
|
3130
|
-
return error.code;
|
|
3131
|
-
}
|
|
3132
|
-
if (error.message) {
|
|
3133
|
-
const upperMessage = error.message.toUpperCase().trim();
|
|
3134
|
-
const validCodes2 = [
|
|
3135
|
-
"INVALID_PASSWORD",
|
|
3136
|
-
"UNAUTHORIZED",
|
|
3137
|
-
"HAS_NO_PASSWORD",
|
|
3138
|
-
"USER_NOT_FOUND",
|
|
3139
|
-
"USER_EXISTS",
|
|
3140
|
-
"VERIFICATION_EXPIRED",
|
|
3141
|
-
"VERIFICATION_MISMATCH",
|
|
3142
|
-
"VERIFICATION_NOT_FOUND",
|
|
3143
|
-
"TOO_MANY_ATTEMPTS",
|
|
3144
|
-
"REQUIRES_VERIFICATION",
|
|
3145
|
-
"ACCESS_DENIED"
|
|
3146
|
-
];
|
|
3147
|
-
if (validCodes2.includes(upperMessage)) {
|
|
3148
|
-
return upperMessage;
|
|
3149
|
-
}
|
|
3150
|
-
}
|
|
3151
|
-
return void 0;
|
|
3152
|
-
}
|
|
3153
|
-
function getPasswordChangeErrorMessage(error) {
|
|
3154
|
-
if (isAuthError4(error)) {
|
|
3155
|
-
const errorCode = getErrorCode3(error);
|
|
3156
|
-
switch (errorCode) {
|
|
3157
|
-
case "INVALID_PASSWORD":
|
|
3158
|
-
return "The current password you entered is incorrect. Please try again.";
|
|
3159
|
-
case "UNAUTHORIZED":
|
|
3160
|
-
return "You are not authorized to perform this action. Please sign in again.";
|
|
3161
|
-
case "HAS_NO_PASSWORD":
|
|
3162
|
-
return "Your account does not have a password set. Please use password reset instead.";
|
|
3163
|
-
default:
|
|
3164
|
-
return error.message || "Failed to change password. Please try again.";
|
|
3165
|
-
}
|
|
3166
|
-
}
|
|
3167
|
-
if (error instanceof Error) {
|
|
3168
|
-
return error.message;
|
|
3169
|
-
}
|
|
3170
|
-
return "Failed to change password. Please try again.";
|
|
3171
|
-
}
|
|
3172
|
-
function ChangePasswordForm() {
|
|
3173
|
-
const { user: _user } = useSession();
|
|
3174
|
-
const [isOpen, setIsOpen] = useState17(false);
|
|
3175
|
-
const [isSubmitting, setIsSubmitting] = useState17(false);
|
|
3176
|
-
const [showPassword, setShowPassword] = useState17(false);
|
|
3177
|
-
const [showNewPassword, setShowNewPassword] = useState17(false);
|
|
3178
|
-
const [showConfirmPassword, setShowConfirmPassword] = useState17(false);
|
|
3179
|
-
const form = useForm7({
|
|
3180
|
-
resolver: zodResolver7(changePasswordSchema),
|
|
3181
|
-
defaultValues: {
|
|
3182
|
-
currentPassword: "",
|
|
3183
|
-
newPassword: "",
|
|
3184
|
-
confirmPassword: ""
|
|
3185
|
-
}
|
|
3186
|
-
});
|
|
3187
|
-
const { register, handleSubmit, formState, reset } = form;
|
|
3188
|
-
const onSubmit = (_data) => {
|
|
3189
|
-
try {
|
|
3190
|
-
setIsSubmitting(true);
|
|
3191
|
-
toast9.error("Password change unavailable");
|
|
3192
|
-
setIsOpen(false);
|
|
3193
|
-
} catch (error) {
|
|
3194
|
-
const errorMessage = getPasswordChangeErrorMessage(error);
|
|
3195
|
-
toast9.error(errorMessage);
|
|
3196
|
-
} finally {
|
|
3197
|
-
setIsSubmitting(false);
|
|
3198
|
-
}
|
|
3199
|
-
};
|
|
3200
|
-
return /* @__PURE__ */ jsx25(Collapsible2, { open: isOpen, onOpenChange: setIsOpen, children: /* @__PURE__ */ jsxs22("div", { className: "border rounded-lg", children: [
|
|
3201
|
-
/* @__PURE__ */ jsxs22(
|
|
3202
|
-
CollapsibleTrigger2,
|
|
3203
|
-
{
|
|
3204
|
-
render: /* @__PURE__ */ jsx25(
|
|
3205
|
-
Button14,
|
|
3206
|
-
{
|
|
3207
|
-
variant: "ghost",
|
|
3208
|
-
className: "w-full justify-between p-4 h-auto"
|
|
3209
|
-
}
|
|
3210
|
-
),
|
|
3211
|
-
children: [
|
|
3212
|
-
/* @__PURE__ */ jsxs22("div", { className: "flex flex-col items-start", children: [
|
|
3213
|
-
/* @__PURE__ */ jsx25("span", { className: "font-medium", children: "Change Password" }),
|
|
3214
|
-
/* @__PURE__ */ jsx25("span", { className: "text-sm text-muted-foreground", children: "Update your account password" })
|
|
3215
|
-
] }),
|
|
3216
|
-
/* @__PURE__ */ jsx25(
|
|
3217
|
-
IconChevronDown2,
|
|
3218
|
-
{
|
|
3219
|
-
className: `h-4 w-4 transition-transform ${isOpen ? "rotate-180" : ""}`
|
|
3220
|
-
}
|
|
3221
|
-
)
|
|
3222
|
-
]
|
|
3223
|
-
}
|
|
3224
|
-
),
|
|
3225
|
-
/* @__PURE__ */ jsx25(CollapsibleContent2, { children: /* @__PURE__ */ jsxs22(
|
|
3226
|
-
"form",
|
|
3227
|
-
{
|
|
3228
|
-
onSubmit: handleSubmit(onSubmit),
|
|
3229
|
-
className: "p-4 space-y-4 border-t",
|
|
3230
|
-
children: [
|
|
3231
|
-
/* @__PURE__ */ jsxs22("div", { className: "space-y-2 w-full md:w-1/2", children: [
|
|
3232
|
-
/* @__PURE__ */ jsx25(Label2, { htmlFor: "currentPassword", children: "Old Password" }),
|
|
3233
|
-
/* @__PURE__ */ jsxs22("div", { className: "relative", children: [
|
|
3234
|
-
/* @__PURE__ */ jsx25(
|
|
3235
|
-
Input6,
|
|
3236
|
-
{
|
|
3237
|
-
id: "currentPassword",
|
|
3238
|
-
type: showPassword ? "text" : "password",
|
|
3239
|
-
autoComplete: "current-password",
|
|
3240
|
-
placeholder: "Enter your current password",
|
|
3241
|
-
...register("currentPassword")
|
|
3242
|
-
}
|
|
3243
|
-
),
|
|
3244
|
-
/* @__PURE__ */ jsx25(
|
|
3245
|
-
"button",
|
|
3246
|
-
{
|
|
3247
|
-
type: "button",
|
|
3248
|
-
onClick: () => setShowPassword(!showPassword),
|
|
3249
|
-
className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground",
|
|
3250
|
-
children: showPassword ? /* @__PURE__ */ jsx25(IconEyeOff5, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx25(IconEye5, { className: "h-4 w-4" })
|
|
3251
|
-
}
|
|
3252
|
-
)
|
|
3253
|
-
] }),
|
|
3254
|
-
formState.errors.currentPassword && /* @__PURE__ */ jsx25("p", { className: "text-sm text-destructive", children: formState.errors.currentPassword.message })
|
|
3255
|
-
] }),
|
|
3256
|
-
/* @__PURE__ */ jsxs22("div", { className: "space-y-2 w-full md:w-1/2", children: [
|
|
3257
|
-
/* @__PURE__ */ jsx25(Label2, { htmlFor: "newPassword", children: "New Password" }),
|
|
3258
|
-
/* @__PURE__ */ jsxs22("div", { className: "relative", children: [
|
|
3259
|
-
/* @__PURE__ */ jsx25(
|
|
3260
|
-
Input6,
|
|
3261
|
-
{
|
|
3262
|
-
id: "newPassword",
|
|
3263
|
-
type: showNewPassword ? "text" : "password",
|
|
3264
|
-
placeholder: "Enter your new password",
|
|
3265
|
-
autoComplete: "new-password",
|
|
3266
|
-
...register("newPassword")
|
|
3267
|
-
}
|
|
3268
|
-
),
|
|
3269
|
-
/* @__PURE__ */ jsx25(
|
|
3270
|
-
"button",
|
|
3271
|
-
{
|
|
3272
|
-
type: "button",
|
|
3273
|
-
onClick: () => setShowNewPassword(!showNewPassword),
|
|
3274
|
-
className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground",
|
|
3275
|
-
children: showNewPassword ? /* @__PURE__ */ jsx25(IconEyeOff5, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx25(IconEye5, { className: "h-4 w-4" })
|
|
3276
|
-
}
|
|
3277
|
-
)
|
|
3278
|
-
] }),
|
|
3279
|
-
formState.errors.newPassword && /* @__PURE__ */ jsx25("p", { className: "text-sm text-destructive", children: formState.errors.newPassword.message })
|
|
3280
|
-
] }),
|
|
3281
|
-
/* @__PURE__ */ jsxs22("div", { className: "space-y-2 w-full md:w-1/2", children: [
|
|
3282
|
-
/* @__PURE__ */ jsx25(Label2, { htmlFor: "confirmPassword", children: "Confirm New Password" }),
|
|
3283
|
-
/* @__PURE__ */ jsxs22("div", { className: "relative", children: [
|
|
3284
|
-
/* @__PURE__ */ jsx25(
|
|
3285
|
-
Input6,
|
|
3286
|
-
{
|
|
3287
|
-
id: "confirmPassword",
|
|
3288
|
-
type: showConfirmPassword ? "text" : "password",
|
|
3289
|
-
placeholder: "Confirm your new password",
|
|
3290
|
-
autoComplete: "new-password",
|
|
3291
|
-
...register("confirmPassword")
|
|
3292
|
-
}
|
|
3293
|
-
),
|
|
3294
|
-
/* @__PURE__ */ jsx25(
|
|
3295
|
-
"button",
|
|
3296
|
-
{
|
|
3297
|
-
type: "button",
|
|
3298
|
-
onClick: () => setShowConfirmPassword(!showConfirmPassword),
|
|
3299
|
-
className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground",
|
|
3300
|
-
children: showConfirmPassword ? /* @__PURE__ */ jsx25(IconEyeOff5, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx25(IconEye5, { className: "h-4 w-4" })
|
|
3301
|
-
}
|
|
3302
|
-
)
|
|
3303
|
-
] }),
|
|
3304
|
-
formState.errors.confirmPassword && /* @__PURE__ */ jsx25("p", { className: "text-sm text-destructive", children: formState.errors.confirmPassword.message })
|
|
3305
|
-
] }),
|
|
3306
|
-
/* @__PURE__ */ jsxs22("div", { className: "flex justify-end gap-2", children: [
|
|
3307
|
-
/* @__PURE__ */ jsx25(
|
|
3308
|
-
Button14,
|
|
3309
|
-
{
|
|
3310
|
-
type: "button",
|
|
3311
|
-
variant: "outline",
|
|
3312
|
-
onClick: () => {
|
|
3313
|
-
reset();
|
|
3314
|
-
setIsOpen(false);
|
|
3315
|
-
},
|
|
3316
|
-
disabled: isSubmitting,
|
|
3317
|
-
children: "Cancel"
|
|
3318
|
-
}
|
|
3319
|
-
),
|
|
3320
|
-
/* @__PURE__ */ jsxs22(Button14, { type: "submit", disabled: isSubmitting, children: [
|
|
3321
|
-
isSubmitting && /* @__PURE__ */ jsx25(Spinner3, { className: "mr-2 h-4 w-4" }),
|
|
3322
|
-
"Change Password"
|
|
3323
|
-
] })
|
|
3324
|
-
] })
|
|
3325
|
-
]
|
|
3326
|
-
}
|
|
3327
|
-
) })
|
|
3328
|
-
] }) });
|
|
3329
|
-
}
|
|
3330
|
-
|
|
3331
|
-
// src/components/profile/change-phone-form.tsx
|
|
28
|
+
Security
|
|
29
|
+
} from "./chunk-OYHH7HQG.js";
|
|
30
|
+
import "./chunk-5F5FZMHE.js";
|
|
31
|
+
import "./chunk-ZG6WFZHX.js";
|
|
32
|
+
import "./chunk-C26NPUPI.js";
|
|
3332
33
|
import {
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
} from "
|
|
3338
|
-
import
|
|
3339
|
-
import {
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
import {
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
import
|
|
3346
|
-
import {
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
import {
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
return;
|
|
3453
|
-
}
|
|
3454
|
-
const accountChange = data.data?.accountChange;
|
|
3455
|
-
const verificationId = data.data?.verificationId;
|
|
3456
|
-
if (accountChange?.changeType !== "phone") {
|
|
3457
|
-
setIsChecking(false);
|
|
3458
|
-
return;
|
|
3459
|
-
}
|
|
3460
|
-
if (!accountChange.newPhone) {
|
|
3461
|
-
setIsChecking(false);
|
|
3462
|
-
return;
|
|
3463
|
-
}
|
|
3464
|
-
if (getValues("phone")) {
|
|
3465
|
-
setIsChecking(false);
|
|
3466
|
-
return;
|
|
3467
|
-
}
|
|
3468
|
-
setValue("phone", accountChange.newPhone, { shouldValidate: true });
|
|
3469
|
-
if (verificationId) {
|
|
3470
|
-
toast10.message("Resuming verification\u2026");
|
|
3471
|
-
onSuccess(verificationId, accountChange.newPhone);
|
|
3472
|
-
return;
|
|
3473
|
-
}
|
|
3474
|
-
setIsChecking(false);
|
|
3475
|
-
} catch {
|
|
3476
|
-
setIsChecking(false);
|
|
3477
|
-
}
|
|
3478
|
-
};
|
|
3479
|
-
run().catch(() => void 0);
|
|
3480
|
-
return () => {
|
|
3481
|
-
active = false;
|
|
3482
|
-
};
|
|
3483
|
-
}, [getPendingAccountChangeQuery.refetch, getValues, onSuccess, setValue]);
|
|
3484
|
-
const onPhonePasswordSubmit = async (data) => {
|
|
3485
|
-
if (!user) {
|
|
3486
|
-
toast10.error("User not found");
|
|
3487
|
-
return;
|
|
3488
|
-
}
|
|
3489
|
-
try {
|
|
3490
|
-
setIsSubmitting(true);
|
|
3491
|
-
const normalizedPhone = normalizePhone(data.phone);
|
|
3492
|
-
await verifyPasswordMutation.mutateAsync({
|
|
3493
|
-
body: { password: data.password }
|
|
3494
|
-
});
|
|
3495
|
-
const checkResult = await checkUserMutation.mutateAsync({
|
|
3496
|
-
body: { identifier: normalizedPhone }
|
|
3497
|
-
});
|
|
3498
|
-
if (checkResult.data?.exists) {
|
|
3499
|
-
if (user?.phone?.replace(/\s/g, "") === normalizedPhone.replace(/\s/g, "")) {
|
|
3500
|
-
toast10.error("This is already your current phone number.");
|
|
3501
|
-
return;
|
|
3502
|
-
}
|
|
3503
|
-
toast10.error(
|
|
3504
|
-
"This phone number is already taken. Please use a different number."
|
|
3505
|
-
);
|
|
3506
|
-
return;
|
|
3507
|
-
}
|
|
3508
|
-
const verification = await requestPhoneOtpMutation.mutateAsync({
|
|
3509
|
-
body: {
|
|
3510
|
-
phone: normalizedPhone,
|
|
3511
|
-
context: "change-phone"
|
|
3512
|
-
}
|
|
3513
|
-
});
|
|
3514
|
-
toast10.success("Verification code sent to your phone");
|
|
3515
|
-
onSuccess(verification.data?.verificationId ?? "", normalizedPhone);
|
|
3516
|
-
} catch (error) {
|
|
3517
|
-
const errorMessage = getErrorMessage3(error);
|
|
3518
|
-
if (isAuthError5(error)) {
|
|
3519
|
-
const errorCode = getErrorCode4(error);
|
|
3520
|
-
if (errorCode === "INVALID_PASSWORD" || errorCode === "USER_NOT_FOUND") {
|
|
3521
|
-
toast10.error("Incorrect password. Please try again.");
|
|
3522
|
-
return;
|
|
3523
|
-
}
|
|
3524
|
-
}
|
|
3525
|
-
toast10.error(errorMessage);
|
|
3526
|
-
} finally {
|
|
3527
|
-
setIsSubmitting(false);
|
|
3528
|
-
}
|
|
3529
|
-
};
|
|
3530
|
-
const isLoading = isSubmitting || isChecking;
|
|
3531
|
-
return /* @__PURE__ */ jsxs23(
|
|
3532
|
-
"form",
|
|
3533
|
-
{
|
|
3534
|
-
onSubmit: handleSubmit(onPhonePasswordSubmit),
|
|
3535
|
-
className: "p-4 space-y-4 border-t",
|
|
3536
|
-
children: [
|
|
3537
|
-
/* @__PURE__ */ jsxs23("div", { className: "space-y-4 w-full md:w-1/2", children: [
|
|
3538
|
-
/* @__PURE__ */ jsxs23("div", { className: "space-y-2", children: [
|
|
3539
|
-
/* @__PURE__ */ jsx26(Label3, { htmlFor: "phone", children: "Phone Number" }),
|
|
3540
|
-
/* @__PURE__ */ jsx26(
|
|
3541
|
-
Input7,
|
|
3542
|
-
{
|
|
3543
|
-
id: "phone",
|
|
3544
|
-
type: "tel",
|
|
3545
|
-
placeholder: "Enter your new phone number",
|
|
3546
|
-
...register("phone"),
|
|
3547
|
-
disabled: isLoading
|
|
3548
|
-
}
|
|
3549
|
-
),
|
|
3550
|
-
errors.phone && /* @__PURE__ */ jsx26("p", { className: "text-sm text-destructive", children: errors.phone.message })
|
|
3551
|
-
] }),
|
|
3552
|
-
/* @__PURE__ */ jsxs23("div", { className: "space-y-2", children: [
|
|
3553
|
-
/* @__PURE__ */ jsx26(Label3, { htmlFor: "password", children: "Password" }),
|
|
3554
|
-
/* @__PURE__ */ jsxs23("div", { className: "relative", children: [
|
|
3555
|
-
/* @__PURE__ */ jsx26(
|
|
3556
|
-
Input7,
|
|
3557
|
-
{
|
|
3558
|
-
id: "password",
|
|
3559
|
-
type: showPassword ? "text" : "password",
|
|
3560
|
-
autoComplete: "current-password",
|
|
3561
|
-
placeholder: "Enter your password",
|
|
3562
|
-
...register("password"),
|
|
3563
|
-
disabled: isLoading
|
|
3564
|
-
}
|
|
3565
|
-
),
|
|
3566
|
-
/* @__PURE__ */ jsx26(
|
|
3567
|
-
"button",
|
|
3568
|
-
{
|
|
3569
|
-
type: "button",
|
|
3570
|
-
onClick: () => setShowPassword(!showPassword),
|
|
3571
|
-
className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground",
|
|
3572
|
-
children: showPassword ? /* @__PURE__ */ jsx26(IconEyeOff6, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx26(IconEye6, { className: "h-4 w-4" })
|
|
3573
|
-
}
|
|
3574
|
-
)
|
|
3575
|
-
] }),
|
|
3576
|
-
errors.password && /* @__PURE__ */ jsx26("p", { className: "text-sm text-destructive", children: errors.password.message })
|
|
3577
|
-
] })
|
|
3578
|
-
] }),
|
|
3579
|
-
/* @__PURE__ */ jsxs23("div", { className: "flex justify-end gap-2", children: [
|
|
3580
|
-
/* @__PURE__ */ jsx26(
|
|
3581
|
-
Button15,
|
|
3582
|
-
{
|
|
3583
|
-
type: "button",
|
|
3584
|
-
variant: "outline",
|
|
3585
|
-
onClick: onCancel,
|
|
3586
|
-
disabled: isLoading,
|
|
3587
|
-
children: "Cancel"
|
|
3588
|
-
}
|
|
3589
|
-
),
|
|
3590
|
-
/* @__PURE__ */ jsxs23(Button15, { type: "submit", disabled: isLoading, children: [
|
|
3591
|
-
isLoading && /* @__PURE__ */ jsx26(Spinner4, { className: "mr-2 h-4 w-4" }),
|
|
3592
|
-
isChecking ? "Checking\u2026" : buttonText
|
|
3593
|
-
] })
|
|
3594
|
-
] })
|
|
3595
|
-
]
|
|
3596
|
-
}
|
|
3597
|
-
);
|
|
3598
|
-
}
|
|
3599
|
-
|
|
3600
|
-
// src/components/profile/verify-change-phone-form.tsx
|
|
3601
|
-
import { useState as useState19 } from "react";
|
|
3602
|
-
import { toast as toast11 } from "sonner";
|
|
3603
|
-
import { jsx as jsx27 } from "react/jsx-runtime";
|
|
3604
|
-
function isAuthError6(error) {
|
|
3605
|
-
return typeof error === "object" && error !== null && ("code" in error || "message" in error || "name" in error);
|
|
3606
|
-
}
|
|
3607
|
-
function getErrorCode5(error) {
|
|
3608
|
-
if (error.code) {
|
|
3609
|
-
return error.code;
|
|
3610
|
-
}
|
|
3611
|
-
if (error.message) {
|
|
3612
|
-
const upperMessage = error.message.toUpperCase().trim();
|
|
3613
|
-
const validCodes2 = [
|
|
3614
|
-
"USER_NOT_FOUND",
|
|
3615
|
-
"USER_EXISTS",
|
|
3616
|
-
"INVALID_PASSWORD",
|
|
3617
|
-
"VERIFICATION_EXPIRED",
|
|
3618
|
-
"VERIFICATION_MISMATCH",
|
|
3619
|
-
"VERIFICATION_NOT_FOUND",
|
|
3620
|
-
"TOO_MANY_ATTEMPTS",
|
|
3621
|
-
"UNAUTHORIZED"
|
|
3622
|
-
];
|
|
3623
|
-
if (validCodes2.includes(upperMessage)) {
|
|
3624
|
-
return upperMessage;
|
|
3625
|
-
}
|
|
3626
|
-
}
|
|
3627
|
-
return void 0;
|
|
3628
|
-
}
|
|
3629
|
-
function getErrorMessage4(error) {
|
|
3630
|
-
if (isAuthError6(error)) {
|
|
3631
|
-
const errorCode = getErrorCode5(error);
|
|
3632
|
-
switch (errorCode) {
|
|
3633
|
-
case "USER_EXISTS":
|
|
3634
|
-
return "This phone number is already taken. Please use a different number.";
|
|
3635
|
-
case "VERIFICATION_EXPIRED":
|
|
3636
|
-
return "Verification code has expired. Please request a new one.";
|
|
3637
|
-
case "VERIFICATION_MISMATCH":
|
|
3638
|
-
return "Invalid verification code. Please try again.";
|
|
3639
|
-
case "VERIFICATION_NOT_FOUND":
|
|
3640
|
-
return "Verification not found. Please request a new code.";
|
|
3641
|
-
default:
|
|
3642
|
-
return error.message || "An error occurred. Please try again.";
|
|
3643
|
-
}
|
|
3644
|
-
}
|
|
3645
|
-
if (error instanceof Error) {
|
|
3646
|
-
return error.message;
|
|
3647
|
-
}
|
|
3648
|
-
return "An error occurred. Please try again.";
|
|
3649
|
-
}
|
|
3650
|
-
function VerifyChangePhoneForm({
|
|
3651
|
-
phone,
|
|
3652
|
-
verificationId,
|
|
3653
|
-
onSuccess,
|
|
3654
|
-
onCancel
|
|
3655
|
-
}) {
|
|
3656
|
-
const { refresh } = useSession();
|
|
3657
|
-
const { hooks } = useApi();
|
|
3658
|
-
const [isSubmitting, setIsSubmitting] = useState19(false);
|
|
3659
|
-
const [currentVerificationId, setCurrentVerificationId] = useState19(verificationId);
|
|
3660
|
-
const verifyPhoneOtpMutation = hooks.useMutation(
|
|
3661
|
-
"post",
|
|
3662
|
-
"/phone/verification/confirm"
|
|
3663
|
-
);
|
|
3664
|
-
const updatePhoneMutation = hooks.useMutation("put", "/profile/phone");
|
|
3665
|
-
const requestPhoneOtpMutation = hooks.useMutation(
|
|
3666
|
-
"post",
|
|
3667
|
-
"/phone/verification/request"
|
|
3668
|
-
);
|
|
3669
|
-
const onOtpSubmit = async (code) => {
|
|
3670
|
-
if (!currentVerificationId) {
|
|
3671
|
-
toast11.error("Verification not found. Please request a new code.");
|
|
3672
|
-
return;
|
|
3673
|
-
}
|
|
3674
|
-
try {
|
|
3675
|
-
setIsSubmitting(true);
|
|
3676
|
-
await verifyPhoneOtpMutation.mutateAsync({
|
|
3677
|
-
body: {
|
|
3678
|
-
verificationId: currentVerificationId,
|
|
3679
|
-
code,
|
|
3680
|
-
context: "change-phone"
|
|
3681
|
-
}
|
|
3682
|
-
});
|
|
3683
|
-
await updatePhoneMutation.mutateAsync({
|
|
3684
|
-
body: { phone }
|
|
3685
|
-
});
|
|
3686
|
-
toast11.success("Phone number updated successfully");
|
|
3687
|
-
await refresh();
|
|
3688
|
-
onSuccess();
|
|
3689
|
-
} catch (error) {
|
|
3690
|
-
const errorMessage = getErrorMessage4(error);
|
|
3691
|
-
toast11.error(errorMessage);
|
|
3692
|
-
} finally {
|
|
3693
|
-
setIsSubmitting(false);
|
|
3694
|
-
}
|
|
3695
|
-
};
|
|
3696
|
-
if (!currentVerificationId) {
|
|
3697
|
-
toast11.error("Verification not found. Please request a new code.");
|
|
3698
|
-
return null;
|
|
3699
|
-
}
|
|
3700
|
-
return /* @__PURE__ */ jsx27(
|
|
3701
|
-
OtpVerificationModal,
|
|
3702
|
-
{
|
|
3703
|
-
open: true,
|
|
3704
|
-
title: "Verify phone",
|
|
3705
|
-
description: `Enter the verification code sent to ${phone}`,
|
|
3706
|
-
verificationId: currentVerificationId,
|
|
3707
|
-
isLoading: isSubmitting,
|
|
3708
|
-
onSubmit: onOtpSubmit,
|
|
3709
|
-
onResend: async () => {
|
|
3710
|
-
try {
|
|
3711
|
-
setIsSubmitting(true);
|
|
3712
|
-
const next = await requestPhoneOtpMutation.mutateAsync({
|
|
3713
|
-
body: {
|
|
3714
|
-
phone,
|
|
3715
|
-
context: "change-phone"
|
|
3716
|
-
}
|
|
3717
|
-
});
|
|
3718
|
-
setCurrentVerificationId(next.data?.verificationId ?? null);
|
|
3719
|
-
toast11.success("Verification code resent");
|
|
3720
|
-
} catch (error) {
|
|
3721
|
-
toast11.error(getErrorMessage4(error));
|
|
3722
|
-
} finally {
|
|
3723
|
-
setIsSubmitting(false);
|
|
3724
|
-
}
|
|
3725
|
-
},
|
|
3726
|
-
onCancel
|
|
3727
|
-
}
|
|
3728
|
-
);
|
|
3729
|
-
}
|
|
3730
|
-
|
|
3731
|
-
// src/components/profile/change-phone-form.tsx
|
|
3732
|
-
import { jsx as jsx28, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
3733
|
-
function ChangePhoneForm() {
|
|
3734
|
-
const { user } = useSession();
|
|
3735
|
-
const [isOpen, setIsOpen] = useState20(false);
|
|
3736
|
-
const [showOtp, setShowOtp] = useState20(false);
|
|
3737
|
-
const [verificationId, setVerificationId] = useState20(null);
|
|
3738
|
-
const [newPhone, setNewPhone] = useState20("");
|
|
3739
|
-
const resetForms = () => {
|
|
3740
|
-
setShowOtp(false);
|
|
3741
|
-
setVerificationId(null);
|
|
3742
|
-
setNewPhone("");
|
|
3743
|
-
};
|
|
3744
|
-
const handleRequestSuccess = (id, phone) => {
|
|
3745
|
-
setVerificationId(id);
|
|
3746
|
-
setNewPhone(phone);
|
|
3747
|
-
setShowOtp(true);
|
|
3748
|
-
};
|
|
3749
|
-
const handleVerifySuccess = () => {
|
|
3750
|
-
resetForms();
|
|
3751
|
-
setIsOpen(false);
|
|
3752
|
-
};
|
|
3753
|
-
const handleCancel = () => {
|
|
3754
|
-
resetForms();
|
|
3755
|
-
setIsOpen(false);
|
|
3756
|
-
};
|
|
3757
|
-
const title = user?.phone ? "Change Phone" : "Add Phone";
|
|
3758
|
-
const description = user?.phone ? "Update your phone number" : "Add a phone number to your account";
|
|
3759
|
-
return /* @__PURE__ */ jsx28(Collapsible3, { open: isOpen, onOpenChange: setIsOpen, children: /* @__PURE__ */ jsxs24("div", { className: "border rounded-lg", children: [
|
|
3760
|
-
/* @__PURE__ */ jsxs24(
|
|
3761
|
-
CollapsibleTrigger3,
|
|
3762
|
-
{
|
|
3763
|
-
render: /* @__PURE__ */ jsx28(
|
|
3764
|
-
Button16,
|
|
3765
|
-
{
|
|
3766
|
-
variant: "ghost",
|
|
3767
|
-
className: "w-full justify-between p-4 h-auto"
|
|
3768
|
-
}
|
|
3769
|
-
),
|
|
3770
|
-
children: [
|
|
3771
|
-
/* @__PURE__ */ jsxs24("div", { className: "flex flex-col items-start", children: [
|
|
3772
|
-
/* @__PURE__ */ jsx28("span", { className: "font-medium", children: title }),
|
|
3773
|
-
/* @__PURE__ */ jsx28("span", { className: "text-sm text-muted-foreground", children: description })
|
|
3774
|
-
] }),
|
|
3775
|
-
/* @__PURE__ */ jsx28(
|
|
3776
|
-
IconChevronDown3,
|
|
3777
|
-
{
|
|
3778
|
-
className: `h-4 w-4 transition-transform ${isOpen ? "rotate-180" : ""}`
|
|
3779
|
-
}
|
|
3780
|
-
)
|
|
3781
|
-
]
|
|
3782
|
-
}
|
|
3783
|
-
),
|
|
3784
|
-
/* @__PURE__ */ jsx28(CollapsibleContent3, { children: showOtp ? /* @__PURE__ */ jsx28(
|
|
3785
|
-
VerifyChangePhoneForm,
|
|
3786
|
-
{
|
|
3787
|
-
phone: newPhone,
|
|
3788
|
-
verificationId,
|
|
3789
|
-
onSuccess: handleVerifySuccess,
|
|
3790
|
-
onCancel: handleCancel
|
|
3791
|
-
}
|
|
3792
|
-
) : /* @__PURE__ */ jsx28(
|
|
3793
|
-
RequestChangePhoneForm,
|
|
3794
|
-
{
|
|
3795
|
-
onSuccess: handleRequestSuccess,
|
|
3796
|
-
onCancel: handleCancel,
|
|
3797
|
-
buttonText: title
|
|
3798
|
-
}
|
|
3799
|
-
) })
|
|
3800
|
-
] }) });
|
|
3801
|
-
}
|
|
3802
|
-
|
|
3803
|
-
// src/components/profile/security.tsx
|
|
3804
|
-
import { jsx as jsx29, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
3805
|
-
function Security() {
|
|
3806
|
-
return /* @__PURE__ */ jsxs25("div", { className: "p-6 space-y-6", children: [
|
|
3807
|
-
/* @__PURE__ */ jsxs25("div", { children: [
|
|
3808
|
-
/* @__PURE__ */ jsx29("h1", { className: "text-2xl font-semibold", children: "Security" }),
|
|
3809
|
-
/* @__PURE__ */ jsx29("p", { className: "text-muted-foreground", children: "Manage your security settings" })
|
|
3810
|
-
] }),
|
|
3811
|
-
/* @__PURE__ */ jsxs25("div", { className: "space-y-4", children: [
|
|
3812
|
-
/* @__PURE__ */ jsx29(ChangePasswordForm, {}),
|
|
3813
|
-
/* @__PURE__ */ jsx29(ChangeEmailForm, {}),
|
|
3814
|
-
/* @__PURE__ */ jsx29(ChangePhoneForm, {})
|
|
3815
|
-
] })
|
|
3816
|
-
] });
|
|
3817
|
-
}
|
|
3818
|
-
|
|
3819
|
-
// src/components/skeletons/auth-form-skeleton.tsx
|
|
3820
|
-
import { Skeleton as Skeleton2 } from "@mesob/ui/components";
|
|
3821
|
-
import { jsx as jsx30, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
3822
|
-
function AuthFormSkeleton() {
|
|
3823
|
-
return /* @__PURE__ */ jsxs26("div", { className: "w-full max-w-md space-y-6 p-6", children: [
|
|
3824
|
-
/* @__PURE__ */ jsxs26("div", { className: "space-y-2 text-center", children: [
|
|
3825
|
-
/* @__PURE__ */ jsx30(Skeleton2, { className: "h-8 w-48 mx-auto" }),
|
|
3826
|
-
/* @__PURE__ */ jsx30(Skeleton2, { className: "h-4 w-64 mx-auto" })
|
|
3827
|
-
] }),
|
|
3828
|
-
/* @__PURE__ */ jsxs26("div", { className: "space-y-4", children: [
|
|
3829
|
-
/* @__PURE__ */ jsxs26("div", { className: "space-y-2", children: [
|
|
3830
|
-
/* @__PURE__ */ jsx30(Skeleton2, { className: "h-4 w-24" }),
|
|
3831
|
-
/* @__PURE__ */ jsx30(Skeleton2, { className: "h-10 w-full" })
|
|
3832
|
-
] }),
|
|
3833
|
-
/* @__PURE__ */ jsxs26("div", { className: "space-y-2", children: [
|
|
3834
|
-
/* @__PURE__ */ jsx30(Skeleton2, { className: "h-4 w-24" }),
|
|
3835
|
-
/* @__PURE__ */ jsx30(Skeleton2, { className: "h-10 w-full" })
|
|
3836
|
-
] }),
|
|
3837
|
-
/* @__PURE__ */ jsx30(Skeleton2, { className: "h-10 w-full" })
|
|
3838
|
-
] }),
|
|
3839
|
-
/* @__PURE__ */ jsxs26("div", { className: "space-y-2", children: [
|
|
3840
|
-
/* @__PURE__ */ jsx30(Skeleton2, { className: "h-px w-full" }),
|
|
3841
|
-
/* @__PURE__ */ jsx30(Skeleton2, { className: "h-4 w-32 mx-auto" })
|
|
3842
|
-
] })
|
|
3843
|
-
] });
|
|
3844
|
-
}
|
|
3845
|
-
|
|
3846
|
-
// src/components/skeletons/profile-skeleton.tsx
|
|
3847
|
-
import { Skeleton as Skeleton3 } from "@mesob/ui/components";
|
|
3848
|
-
import { jsx as jsx31, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
3849
|
-
function ProfileSkeleton() {
|
|
3850
|
-
return /* @__PURE__ */ jsxs27("div", { className: "w-full max-w-4xl space-y-8 p-6", children: [
|
|
3851
|
-
/* @__PURE__ */ jsxs27("div", { className: "flex items-center gap-6", children: [
|
|
3852
|
-
/* @__PURE__ */ jsx31(Skeleton3, { className: "h-24 w-24 rounded-full" }),
|
|
3853
|
-
/* @__PURE__ */ jsxs27("div", { className: "space-y-2 flex-1", children: [
|
|
3854
|
-
/* @__PURE__ */ jsx31(Skeleton3, { className: "h-8 w-48" }),
|
|
3855
|
-
/* @__PURE__ */ jsx31(Skeleton3, { className: "h-4 w-64" })
|
|
3856
|
-
] })
|
|
3857
|
-
] }),
|
|
3858
|
-
/* @__PURE__ */ jsx31("div", { className: "space-y-6", children: [1, 2, 3].map((i) => /* @__PURE__ */ jsxs27("div", { className: "space-y-4", children: [
|
|
3859
|
-
/* @__PURE__ */ jsx31(Skeleton3, { className: "h-6 w-32" }),
|
|
3860
|
-
/* @__PURE__ */ jsxs27("div", { className: "space-y-3", children: [
|
|
3861
|
-
/* @__PURE__ */ jsxs27("div", { className: "flex justify-between items-center", children: [
|
|
3862
|
-
/* @__PURE__ */ jsx31(Skeleton3, { className: "h-4 w-24" }),
|
|
3863
|
-
/* @__PURE__ */ jsx31(Skeleton3, { className: "h-4 w-32" })
|
|
3864
|
-
] }),
|
|
3865
|
-
/* @__PURE__ */ jsxs27("div", { className: "flex justify-between items-center", children: [
|
|
3866
|
-
/* @__PURE__ */ jsx31(Skeleton3, { className: "h-4 w-24" }),
|
|
3867
|
-
/* @__PURE__ */ jsx31(Skeleton3, { className: "h-4 w-40" })
|
|
3868
|
-
] })
|
|
3869
|
-
] })
|
|
3870
|
-
] }, i)) })
|
|
3871
|
-
] });
|
|
3872
|
-
}
|
|
34
|
+
Sessions
|
|
35
|
+
} from "./chunk-LSYKVFJA.js";
|
|
36
|
+
import {
|
|
37
|
+
TenantsPage
|
|
38
|
+
} from "./chunk-FAHN63DA.js";
|
|
39
|
+
import "./chunk-LNG736CV.js";
|
|
40
|
+
import {
|
|
41
|
+
Tenants
|
|
42
|
+
} from "./chunk-UXOZ2TME.js";
|
|
43
|
+
import {
|
|
44
|
+
UsersPage
|
|
45
|
+
} from "./chunk-BGSHXIHI.js";
|
|
46
|
+
import "./chunk-BZ42QPXE.js";
|
|
47
|
+
import {
|
|
48
|
+
Users
|
|
49
|
+
} from "./chunk-LZR4YUDV.js";
|
|
50
|
+
import {
|
|
51
|
+
Account
|
|
52
|
+
} from "./chunk-G7SCXCCM.js";
|
|
53
|
+
import "./chunk-C5ZW7FD2.js";
|
|
54
|
+
import "./chunk-MS2JUZ3N.js";
|
|
55
|
+
import "./chunk-MELNS4QH.js";
|
|
56
|
+
import "./chunk-EQ4346FE.js";
|
|
57
|
+
import "./chunk-KWG4DSB5.js";
|
|
58
|
+
import "./chunk-OQGJX37L.js";
|
|
59
|
+
import {
|
|
60
|
+
PermissionsPage
|
|
61
|
+
} from "./chunk-S3CXCCKL.js";
|
|
62
|
+
import {
|
|
63
|
+
Permissions
|
|
64
|
+
} from "./chunk-35TCGAW3.js";
|
|
65
|
+
import {
|
|
66
|
+
RoleDetailLayout
|
|
67
|
+
} from "./chunk-GXKBVCVS.js";
|
|
68
|
+
import {
|
|
69
|
+
RoleDetailPage
|
|
70
|
+
} from "./chunk-C2KFZ57H.js";
|
|
71
|
+
import {
|
|
72
|
+
RolePermissionsPage
|
|
73
|
+
} from "./chunk-YZ264S2L.js";
|
|
74
|
+
import {
|
|
75
|
+
RolesPage
|
|
76
|
+
} from "./chunk-JB6XVST4.js";
|
|
77
|
+
import "./chunk-AIMD6R6U.js";
|
|
78
|
+
import {
|
|
79
|
+
Roles
|
|
80
|
+
} from "./chunk-JZZJCBAE.js";
|
|
81
|
+
import {
|
|
82
|
+
DataTable
|
|
83
|
+
} from "./chunk-TFVBER3Y.js";
|
|
84
|
+
import {
|
|
85
|
+
TableSkeleton
|
|
86
|
+
} from "./chunk-RT5C7IAE.js";
|
|
87
|
+
import {
|
|
88
|
+
SessionsPage
|
|
89
|
+
} from "./chunk-L4CGIO2I.js";
|
|
90
|
+
import "./chunk-3BZC4VVD.js";
|
|
91
|
+
import "./chunk-T6P7UHVP.js";
|
|
92
|
+
import "./chunk-NPW7D2HZ.js";
|
|
93
|
+
import {
|
|
94
|
+
SignUp
|
|
95
|
+
} from "./chunk-OAN4EXU4.js";
|
|
96
|
+
import {
|
|
97
|
+
VerifyEmail
|
|
98
|
+
} from "./chunk-II5MLBSB.js";
|
|
99
|
+
import {
|
|
100
|
+
VerifyPhone
|
|
101
|
+
} from "./chunk-45UCLKH2.js";
|
|
102
|
+
import {
|
|
103
|
+
VerificationForm
|
|
104
|
+
} from "./chunk-FFR5UHTS.js";
|
|
105
|
+
import {
|
|
106
|
+
Deny
|
|
107
|
+
} from "./chunk-RLPZFLAS.js";
|
|
108
|
+
import {
|
|
109
|
+
Grant
|
|
110
|
+
} from "./chunk-ZESFGO3K.js";
|
|
111
|
+
import {
|
|
112
|
+
AuthErrorBoundary,
|
|
113
|
+
ErrorBoundary
|
|
114
|
+
} from "./chunk-7KXTL6NT.js";
|
|
115
|
+
import {
|
|
116
|
+
PermissionSelector
|
|
117
|
+
} from "./chunk-GRT6EBR6.js";
|
|
118
|
+
import {
|
|
119
|
+
AuthCard
|
|
120
|
+
} from "./chunk-G2AW2H36.js";
|
|
121
|
+
import "./chunk-GP7GIUI3.js";
|
|
122
|
+
import {
|
|
123
|
+
ForgotPassword
|
|
124
|
+
} from "./chunk-FHOLUOOZ.js";
|
|
125
|
+
import {
|
|
126
|
+
ResetPasswordForm
|
|
127
|
+
} from "./chunk-OHIIMUQC.js";
|
|
128
|
+
import {
|
|
129
|
+
SetPassword
|
|
130
|
+
} from "./chunk-HOO2VLNM.js";
|
|
131
|
+
import {
|
|
132
|
+
SignIn
|
|
133
|
+
} from "./chunk-FBABIA5J.js";
|
|
134
|
+
import {
|
|
135
|
+
normalizePhone
|
|
136
|
+
} from "./chunk-V2W3WPCZ.js";
|
|
137
|
+
import {
|
|
138
|
+
handleError
|
|
139
|
+
} from "./chunk-55BMNC4S.js";
|
|
140
|
+
import "./chunk-DPH2PHK3.js";
|
|
141
|
+
import {
|
|
142
|
+
useTranslator
|
|
143
|
+
} from "./chunk-QNCE2B5O.js";
|
|
144
|
+
import {
|
|
145
|
+
MesobAuthProvider,
|
|
146
|
+
getSessionCookieName,
|
|
147
|
+
hasAuthCookie,
|
|
148
|
+
useApi,
|
|
149
|
+
useConfig,
|
|
150
|
+
useHasAuthCookie,
|
|
151
|
+
useSession
|
|
152
|
+
} from "./chunk-72YRO3A7.js";
|
|
3873
153
|
|
|
3874
154
|
// src/hooks/use-session-cookie-name.ts
|
|
3875
155
|
function useSessionCookieName() {
|
|
@@ -3882,20 +162,39 @@ export {
|
|
|
3882
162
|
AuthErrorBoundary,
|
|
3883
163
|
AuthFormSkeleton,
|
|
3884
164
|
DataTable,
|
|
165
|
+
Deny,
|
|
3885
166
|
ErrorBoundary,
|
|
3886
167
|
ForgotPassword,
|
|
168
|
+
Grant,
|
|
3887
169
|
MesobAuthProvider,
|
|
170
|
+
PermissionSelector,
|
|
3888
171
|
Permissions,
|
|
172
|
+
PermissionsPage,
|
|
173
|
+
ProfileLayout,
|
|
174
|
+
ProfileSidebar,
|
|
3889
175
|
ProfileSkeleton,
|
|
3890
176
|
ResetPasswordForm,
|
|
177
|
+
RoleDetailLayout,
|
|
178
|
+
RoleDetailPage,
|
|
179
|
+
RolePermissionsPage,
|
|
180
|
+
RoleUsersPage,
|
|
3891
181
|
Roles,
|
|
182
|
+
RolesPage,
|
|
3892
183
|
Security,
|
|
3893
184
|
Sessions,
|
|
185
|
+
SessionsPage,
|
|
186
|
+
SetPassword,
|
|
3894
187
|
SignIn,
|
|
3895
188
|
SignUp,
|
|
3896
189
|
TableSkeleton,
|
|
190
|
+
TenantDetailPageContent,
|
|
3897
191
|
Tenants,
|
|
192
|
+
TenantsPage,
|
|
193
|
+
UserActivityPageContent,
|
|
194
|
+
UserDetailLayoutContent,
|
|
195
|
+
UserDetailPageContent,
|
|
3898
196
|
Users,
|
|
197
|
+
UsersPage,
|
|
3899
198
|
VerificationForm,
|
|
3900
199
|
VerifyEmail,
|
|
3901
200
|
VerifyPhone,
|