@mesob/auth-react 0.4.3 → 0.4.5
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-XEFPJKBB.js → chunk-4ABXALRN.js} +2 -2
- package/dist/{chunk-DXTZQ2VY.js → chunk-4NUO6F3J.js} +2 -2
- package/dist/{chunk-CC3HI442.js → chunk-5AEV7RAN.js} +3 -3
- package/dist/{chunk-VA2XUED4.js → chunk-5HAABEAS.js} +2 -2
- package/dist/{chunk-EKZYBYZQ.js → chunk-5SDS2E3F.js} +2 -2
- package/dist/{chunk-ODDTS4RN.js → chunk-6IEX2RLA.js} +3 -3
- package/dist/{chunk-HM4MAF2I.js → chunk-A3GIMM2R.js} +3 -3
- package/dist/{chunk-4QMUNU5E.js → chunk-A7ORWWM5.js} +6 -4
- package/dist/{chunk-4QMUNU5E.js.map → chunk-A7ORWWM5.js.map} +1 -1
- package/dist/{chunk-XCJ3ZH7D.js → chunk-AWSAC7RT.js} +1 -1
- package/dist/{chunk-XCJ3ZH7D.js.map → chunk-AWSAC7RT.js.map} +1 -1
- package/dist/{chunk-V4VX55TT.js → chunk-CP4TTRV4.js} +2 -2
- package/dist/{chunk-GB3Q5IWT.js → chunk-CXMPZWMX.js} +4 -4
- package/dist/{chunk-AKEBT5PJ.js → chunk-DG6GRTPG.js} +2 -2
- package/dist/{chunk-KTZSXSHV.js → chunk-DY3NVBLJ.js} +2 -2
- package/dist/{chunk-OK7WPIHQ.js → chunk-EPEXIGKB.js} +2 -2
- package/dist/{chunk-F6IMR5XS.js → chunk-EQWOGD4F.js} +2 -2
- package/dist/{chunk-RZFSMM3X.js → chunk-ETOCBXDT.js} +3 -3
- package/dist/{chunk-LNG736CV.js → chunk-EWXK56WQ.js} +1 -1
- package/dist/chunk-FPYQ7XGV.js +415 -0
- package/dist/chunk-FPYQ7XGV.js.map +1 -0
- package/dist/chunk-G74DDR4O.js +153 -0
- package/dist/chunk-G74DDR4O.js.map +1 -0
- package/dist/{chunk-HH347MJI.js → chunk-GVEBIL3O.js} +2 -2
- package/dist/{chunk-M6ZUEZJT.js → chunk-HXHI4FU6.js} +3 -3
- package/dist/{chunk-VU4Z2XSQ.js → chunk-IFAVSKHE.js} +3 -3
- package/dist/{chunk-WD2COCQW.js → chunk-KOBZ34XU.js} +4 -4
- package/dist/{chunk-ZE3R37PI.js → chunk-L32Z3TPA.js} +213 -54
- package/dist/chunk-L32Z3TPA.js.map +1 -0
- package/dist/{chunk-CDECLPL4.js → chunk-LHZ4EEN6.js} +3 -3
- package/dist/{chunk-REHGRIUT.js → chunk-MQI6Q2S4.js} +7 -25
- package/dist/chunk-MQI6Q2S4.js.map +1 -0
- package/dist/{chunk-6F5LEXYI.js → chunk-MVVAPYUD.js} +2 -2
- package/dist/chunk-NUWAI3FE.js +350 -0
- package/dist/chunk-NUWAI3FE.js.map +1 -0
- package/dist/{chunk-S3KIMVDE.js → chunk-OQUUS5ZX.js} +4 -4
- package/dist/chunk-OW75JENQ.js +19 -0
- package/dist/chunk-OW75JENQ.js.map +1 -0
- package/dist/{chunk-KM5GOJ75.js → chunk-PG65ZD7A.js} +4 -4
- package/dist/{chunk-NFBOIG3D.js → chunk-RBXITSE2.js} +5 -5
- package/dist/{chunk-BMZTYXGO.js → chunk-RMJNENJB.js} +2 -2
- package/dist/{chunk-5NKPFZ2Q.js → chunk-SGDXNT7M.js} +3 -3
- package/dist/{chunk-SJHJ63HK.js → chunk-SW7WD64K.js} +15 -6
- package/dist/chunk-SW7WD64K.js.map +1 -0
- package/dist/{chunk-ABF34UFW.js → chunk-SXVTYYUT.js} +3 -3
- package/dist/{chunk-ABF34UFW.js.map → chunk-SXVTYYUT.js.map} +1 -1
- package/dist/{chunk-GIGXCAGH.js → chunk-TB2ZPGLW.js} +3 -3
- package/dist/{chunk-RJBNA7OH.js → chunk-TLQMK2QF.js} +4 -4
- package/dist/{chunk-RXHL7LUV.js → chunk-UAKGEJUN.js} +3 -3
- package/dist/{chunk-3HV5KQFZ.js → chunk-UGQP733V.js} +2 -2
- package/dist/{chunk-YHZLPAYD.js → chunk-UY55LEIG.js} +2 -2
- package/dist/{chunk-QJVZHT27.js → chunk-W3D4HG5W.js} +3 -3
- package/dist/{chunk-YLWCA2WK.js → chunk-WQ3UUUKF.js} +10 -3
- package/dist/chunk-WQ3UUUKF.js.map +1 -0
- package/dist/{chunk-JRHJNMG3.js → chunk-WY2JJNZW.js} +2 -2
- package/dist/{chunk-4BFHC4JI.js → chunk-X2BHF4KC.js} +2 -2
- package/dist/{chunk-SYT5Z7EF.js → chunk-YFQNNSSC.js} +2 -2
- package/dist/{chunk-JED4SG3W.js → chunk-YN7OEQI7.js} +4 -4
- package/dist/{chunk-JED4SG3W.js.map → chunk-YN7OEQI7.js.map} +1 -1
- package/dist/{chunk-PS2KBGDB.js → chunk-Z34NJZRL.js} +3 -3
- package/dist/{chunk-EGZYJMSA.js → chunk-ZXKEG3X5.js} +2 -2
- package/dist/{chunk-L2W6FXSZ.js → chunk-ZZ6D4KE4.js} +2 -2
- package/dist/components/auth/countdown.js +3 -3
- package/dist/components/auth/forgot-password.js +3 -3
- package/dist/components/auth/reset-password-form.js +3 -3
- package/dist/components/auth/set-password.js +3 -3
- package/dist/components/auth/sign-in.js +3 -3
- package/dist/components/auth/sign-up.js +3 -3
- package/dist/components/auth/verification-form.js +4 -4
- package/dist/components/auth/verify-email.js +5 -5
- package/dist/components/auth/verify-phone.js +5 -5
- package/dist/components/authorization/deny.js +2 -2
- package/dist/components/authorization/grant.js +2 -2
- package/dist/components/iam/permission-selector.js +2 -2
- package/dist/components/iam/permissions-page.js +2 -2
- package/dist/components/iam/permissions.js +2 -2
- package/dist/components/iam/role-detail-layout.js +2 -2
- package/dist/components/iam/role-detail-page.js +2 -2
- package/dist/components/iam/role-permissions-page.js +3 -3
- package/dist/components/iam/roles-page.js +6 -5
- package/dist/components/iam/roles.js +2 -2
- package/dist/components/iam/sessions-page.js +4 -4
- package/dist/components/iam/sessions.js +2 -2
- package/dist/components/iam/tenants-page.js +5 -5
- package/dist/components/iam/tenants.js +2 -2
- package/dist/components/iam/users-page.js +6 -5
- package/dist/components/iam/users.js +2 -2
- package/dist/components/profile/account.js +2 -2
- package/dist/components/profile/change-email-form.js +8 -8
- package/dist/components/profile/change-password-form.js +2 -2
- package/dist/components/profile/change-phone-form.js +8 -8
- package/dist/components/profile/otp-verification-modal.js +5 -5
- package/dist/components/profile/profile-layout.js +3 -3
- package/dist/components/profile/request-change-email-form.js +2 -2
- package/dist/components/profile/request-change-phone-form.js +2 -2
- package/dist/components/profile/security.js +13 -13
- package/dist/components/profile/verify-change-email-form.js +6 -6
- package/dist/components/profile/verify-change-phone-form.js +6 -6
- package/dist/index.js +50 -48
- package/dist/index.js.map +1 -1
- package/dist/pages/auth/forgot-password.js +3 -3
- package/dist/pages/auth/layout.js +1 -1
- package/dist/pages/auth/reset-password.js +3 -3
- package/dist/pages/auth/set-password.js +3 -3
- package/dist/pages/auth/sign-in.js +3 -3
- package/dist/pages/auth/sign-up.js +3 -3
- package/dist/pages/auth/verify-email.js +5 -5
- package/dist/pages/auth/verify-phone.js +5 -5
- package/dist/pages/iam/permissions.js +2 -2
- package/dist/pages/iam/role-detail-layout.js +2 -2
- package/dist/pages/iam/role-detail.js +2 -2
- package/dist/pages/iam/role-permissions.js +3 -3
- package/dist/pages/iam/role-users.js +7 -5
- package/dist/pages/iam/role-users.js.map +1 -1
- package/dist/pages/iam/roles.js +6 -5
- package/dist/pages/iam/sessions.js +4 -4
- package/dist/pages/iam/tenant-detail.js +3 -3
- package/dist/pages/iam/tenants/tenant-selector.js +150 -0
- package/dist/pages/iam/tenants/tenant-selector.js.map +1 -0
- package/dist/pages/iam/tenants/tenants-data.js +7 -0
- package/dist/pages/iam/tenants/tenants-data.js.map +1 -0
- package/dist/pages/iam/tenants.js +5 -5
- package/dist/pages/iam/user-activity.js +6 -5
- package/dist/pages/iam/user-activity.js.map +1 -1
- package/dist/pages/iam/user-detail-layout.js +2 -2
- package/dist/pages/iam/user-detail.js +2 -2
- package/dist/pages/iam/users/_components/users-data.d.ts +4 -4
- package/dist/pages/iam/users/user-selector.js +14 -0
- package/dist/pages/iam/users/user-selector.js.map +1 -0
- package/dist/pages/iam/users/users-data.js +1 -0
- package/dist/pages/iam/users/users-data.js.map +1 -0
- package/dist/pages/iam/users.js +6 -5
- package/dist/pages/profile/account.js +2 -2
- package/dist/pages/profile/layout.js +3 -3
- package/dist/pages/profile/security.js +13 -13
- package/dist/types.d.ts +2 -0
- package/package.json +20 -3
- package/dist/chunk-GYFHM72X.js +0 -486
- package/dist/chunk-GYFHM72X.js.map +0 -1
- package/dist/chunk-REHGRIUT.js.map +0 -1
- package/dist/chunk-SJHJ63HK.js.map +0 -1
- package/dist/chunk-UCNNUST6.js +0 -271
- package/dist/chunk-UCNNUST6.js.map +0 -1
- package/dist/chunk-YLWCA2WK.js.map +0 -1
- package/dist/chunk-ZE3R37PI.js.map +0 -1
- /package/dist/{chunk-XEFPJKBB.js.map → chunk-4ABXALRN.js.map} +0 -0
- /package/dist/{chunk-DXTZQ2VY.js.map → chunk-4NUO6F3J.js.map} +0 -0
- /package/dist/{chunk-CC3HI442.js.map → chunk-5AEV7RAN.js.map} +0 -0
- /package/dist/{chunk-VA2XUED4.js.map → chunk-5HAABEAS.js.map} +0 -0
- /package/dist/{chunk-EKZYBYZQ.js.map → chunk-5SDS2E3F.js.map} +0 -0
- /package/dist/{chunk-ODDTS4RN.js.map → chunk-6IEX2RLA.js.map} +0 -0
- /package/dist/{chunk-HM4MAF2I.js.map → chunk-A3GIMM2R.js.map} +0 -0
- /package/dist/{chunk-V4VX55TT.js.map → chunk-CP4TTRV4.js.map} +0 -0
- /package/dist/{chunk-GB3Q5IWT.js.map → chunk-CXMPZWMX.js.map} +0 -0
- /package/dist/{chunk-AKEBT5PJ.js.map → chunk-DG6GRTPG.js.map} +0 -0
- /package/dist/{chunk-KTZSXSHV.js.map → chunk-DY3NVBLJ.js.map} +0 -0
- /package/dist/{chunk-OK7WPIHQ.js.map → chunk-EPEXIGKB.js.map} +0 -0
- /package/dist/{chunk-F6IMR5XS.js.map → chunk-EQWOGD4F.js.map} +0 -0
- /package/dist/{chunk-RZFSMM3X.js.map → chunk-ETOCBXDT.js.map} +0 -0
- /package/dist/{chunk-LNG736CV.js.map → chunk-EWXK56WQ.js.map} +0 -0
- /package/dist/{chunk-HH347MJI.js.map → chunk-GVEBIL3O.js.map} +0 -0
- /package/dist/{chunk-M6ZUEZJT.js.map → chunk-HXHI4FU6.js.map} +0 -0
- /package/dist/{chunk-VU4Z2XSQ.js.map → chunk-IFAVSKHE.js.map} +0 -0
- /package/dist/{chunk-WD2COCQW.js.map → chunk-KOBZ34XU.js.map} +0 -0
- /package/dist/{chunk-CDECLPL4.js.map → chunk-LHZ4EEN6.js.map} +0 -0
- /package/dist/{chunk-6F5LEXYI.js.map → chunk-MVVAPYUD.js.map} +0 -0
- /package/dist/{chunk-S3KIMVDE.js.map → chunk-OQUUS5ZX.js.map} +0 -0
- /package/dist/{chunk-KM5GOJ75.js.map → chunk-PG65ZD7A.js.map} +0 -0
- /package/dist/{chunk-NFBOIG3D.js.map → chunk-RBXITSE2.js.map} +0 -0
- /package/dist/{chunk-BMZTYXGO.js.map → chunk-RMJNENJB.js.map} +0 -0
- /package/dist/{chunk-5NKPFZ2Q.js.map → chunk-SGDXNT7M.js.map} +0 -0
- /package/dist/{chunk-GIGXCAGH.js.map → chunk-TB2ZPGLW.js.map} +0 -0
- /package/dist/{chunk-RJBNA7OH.js.map → chunk-TLQMK2QF.js.map} +0 -0
- /package/dist/{chunk-RXHL7LUV.js.map → chunk-UAKGEJUN.js.map} +0 -0
- /package/dist/{chunk-3HV5KQFZ.js.map → chunk-UGQP733V.js.map} +0 -0
- /package/dist/{chunk-YHZLPAYD.js.map → chunk-UY55LEIG.js.map} +0 -0
- /package/dist/{chunk-QJVZHT27.js.map → chunk-W3D4HG5W.js.map} +0 -0
- /package/dist/{chunk-JRHJNMG3.js.map → chunk-WY2JJNZW.js.map} +0 -0
- /package/dist/{chunk-4BFHC4JI.js.map → chunk-X2BHF4KC.js.map} +0 -0
- /package/dist/{chunk-SYT5Z7EF.js.map → chunk-YFQNNSSC.js.map} +0 -0
- /package/dist/{chunk-PS2KBGDB.js.map → chunk-Z34NJZRL.js.map} +0 -0
- /package/dist/{chunk-EGZYJMSA.js.map → chunk-ZXKEG3X5.js.map} +0 -0
- /package/dist/{chunk-L2W6FXSZ.js.map → chunk-ZZ6D4KE4.js.map} +0 -0
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-C5ZW7FD2.js";
|
|
4
4
|
import {
|
|
5
5
|
useSession
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-AWSAC7RT.js";
|
|
7
7
|
|
|
8
8
|
// src/components/profile/account.tsx
|
|
9
9
|
import { Badge, Card, CardContent, Separator } from "@mesob/ui/components";
|
|
@@ -86,4 +86,4 @@ function Account() {
|
|
|
86
86
|
export {
|
|
87
87
|
Account
|
|
88
88
|
};
|
|
89
|
-
//# sourceMappingURL=chunk-
|
|
89
|
+
//# sourceMappingURL=chunk-4ABXALRN.js.map
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-TFVBER3Y.js";
|
|
4
4
|
import {
|
|
5
5
|
useApi
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-AWSAC7RT.js";
|
|
7
7
|
|
|
8
8
|
// src/components/iam/roles.tsx
|
|
9
9
|
import { Badge, Button } from "@mesob/ui/components";
|
|
@@ -115,4 +115,4 @@ function Roles() {
|
|
|
115
115
|
export {
|
|
116
116
|
Roles
|
|
117
117
|
};
|
|
118
|
-
//# sourceMappingURL=chunk-
|
|
118
|
+
//# sourceMappingURL=chunk-4NUO6F3J.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
OtpVerificationModal
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-UGQP733V.js";
|
|
4
4
|
import {
|
|
5
5
|
useApi,
|
|
6
6
|
useSession
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-AWSAC7RT.js";
|
|
8
8
|
|
|
9
9
|
// src/components/profile/verify-change-email-form.tsx
|
|
10
10
|
import { useState } from "react";
|
|
@@ -136,4 +136,4 @@ function VerifyChangeEmailForm({
|
|
|
136
136
|
export {
|
|
137
137
|
VerifyChangeEmailForm
|
|
138
138
|
};
|
|
139
|
-
//# sourceMappingURL=chunk-
|
|
139
|
+
//# sourceMappingURL=chunk-5AEV7RAN.js.map
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-TFVBER3Y.js";
|
|
4
4
|
import {
|
|
5
5
|
useApi
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-AWSAC7RT.js";
|
|
7
7
|
|
|
8
8
|
// src/components/iam/users.tsx
|
|
9
9
|
import { Badge, Button } from "@mesob/ui/components";
|
|
@@ -104,4 +104,4 @@ function Users() {
|
|
|
104
104
|
export {
|
|
105
105
|
Users
|
|
106
106
|
};
|
|
107
|
-
//# sourceMappingURL=chunk-
|
|
107
|
+
//# sourceMappingURL=chunk-5HAABEAS.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
useSession
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-AWSAC7RT.js";
|
|
4
4
|
|
|
5
5
|
// src/components/authorization/grant.tsx
|
|
6
6
|
import { grant as canGrant } from "@mesob/common";
|
|
@@ -25,4 +25,4 @@ function Grant({
|
|
|
25
25
|
export {
|
|
26
26
|
Grant
|
|
27
27
|
};
|
|
28
|
-
//# sourceMappingURL=chunk-
|
|
28
|
+
//# sourceMappingURL=chunk-5SDS2E3F.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
OtpVerificationModal
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-UGQP733V.js";
|
|
4
4
|
import {
|
|
5
5
|
useApi,
|
|
6
6
|
useSession
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-AWSAC7RT.js";
|
|
8
8
|
|
|
9
9
|
// src/components/profile/verify-change-phone-form.tsx
|
|
10
10
|
import { useState } from "react";
|
|
@@ -140,4 +140,4 @@ function VerifyChangePhoneForm({
|
|
|
140
140
|
export {
|
|
141
141
|
VerifyChangePhoneForm
|
|
142
142
|
};
|
|
143
|
-
//# sourceMappingURL=chunk-
|
|
143
|
+
//# sourceMappingURL=chunk-6IEX2RLA.js.map
|
|
@@ -6,11 +6,11 @@ import {
|
|
|
6
6
|
} from "./chunk-DPH2PHK3.js";
|
|
7
7
|
import {
|
|
8
8
|
useTranslator
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-EPEXIGKB.js";
|
|
10
10
|
import {
|
|
11
11
|
useApi,
|
|
12
12
|
useConfig
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-AWSAC7RT.js";
|
|
14
14
|
|
|
15
15
|
// src/components/auth/reset-password-form.tsx
|
|
16
16
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
@@ -283,4 +283,4 @@ var ResetPasswordForm = ({
|
|
|
283
283
|
export {
|
|
284
284
|
ResetPasswordForm
|
|
285
285
|
};
|
|
286
|
-
//# sourceMappingURL=chunk-
|
|
286
|
+
//# sourceMappingURL=chunk-A3GIMM2R.js.map
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
RoleCard,
|
|
3
|
-
RolesList
|
|
3
|
+
RolesList
|
|
4
|
+
} from "./chunk-MQI6Q2S4.js";
|
|
5
|
+
import {
|
|
4
6
|
str
|
|
5
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-OW75JENQ.js";
|
|
6
8
|
import {
|
|
7
9
|
authApi$
|
|
8
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-W3D4HG5W.js";
|
|
9
11
|
import {
|
|
10
12
|
defaultEntityQueryOptions
|
|
11
13
|
} from "./chunk-NPW7D2HZ.js";
|
|
@@ -300,4 +302,4 @@ function UserActivityPageContent({
|
|
|
300
302
|
export {
|
|
301
303
|
UserActivityPageContent
|
|
302
304
|
};
|
|
303
|
-
//# sourceMappingURL=chunk-
|
|
305
|
+
//# sourceMappingURL=chunk-A7ORWWM5.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/pages/iam/users/activity/user-activity-page-content.tsx","../src/pages/iam/users/activity/_components/role-section.tsx","../src/pages/iam/roles/_components/role-selector.tsx"],"sourcesContent":["'use client';\n\nimport {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Section,\n} from '@mesob/ui/components';\nimport { IconCalendar } from '@tabler/icons-react';\nimport { RoleSection } from './_components/role-section';\n\ntype UserActivityPageContentProps = {\n userId: string;\n};\n\nexport function UserActivityPageContent({\n userId,\n}: UserActivityPageContentProps) {\n if (!userId) {\n return null;\n }\n\n return (\n <div className=\"space-y-4\">\n <Card>\n <CardHeader>\n <CardTitle>Activity</CardTitle>\n </CardHeader>\n <CardContent className=\"flex items-center gap-2 text-muted-foreground text-sm\">\n <IconCalendar className=\"h-4 w-4\" />\n Activity (placeholder)\n </CardContent>\n </Card>\n <RoleSection userId={userId} />\n <Section title=\"Permissions\">test</Section>\n <Section title=\"Groups\">test</Section>\n </div>\n );\n}\n","'use client';\n\nimport {\n Button,\n EntityEmptyState,\n EntityLoadingState,\n EntitySection,\n useEntitySectionState,\n} from '@mesob/ui/components';\nimport { IconPlus, IconShield } from '@tabler/icons-react';\nimport { useMemo, useState } from 'react';\nimport { RoleSelector } from '../../../roles/_components/role-selector';\nimport type { Role } from '../../../roles/_components/roles-data';\nimport { str } from '../../../roles/_components/roles-data';\nimport { RolesList } from '../../../roles/_components/roles-list';\nimport {\n authApi$,\n defaultEntityQueryOptions,\n} from '../../../shared/page-helpers';\n\nconst LIMIT = 100;\nconst TABLE_COLUMN_COUNT = 4;\n\nfunction filterAndSort(\n roles: Role[],\n search: string,\n sort: string,\n order: 'asc' | 'desc',\n) {\n let out = roles;\n if (search.trim()) {\n const q = search.trim().toLowerCase();\n out = out.filter(\n (r) =>\n str(r.name).toLowerCase().includes(q) ||\n r.code.toLowerCase().includes(q),\n );\n }\n const mult = order === 'asc' ? 1 : -1;\n const by = sort === 'code' ? 'code' : 'createdAt';\n out = [...out].sort((a, b) =>\n by === 'code'\n ? mult * a.code.localeCompare(b.code)\n : mult *\n (new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()),\n );\n return out;\n}\n\nexport function RoleSection({ userId }: { userId: string }) {\n const [open, setOpen] = useState(false);\n const sectionState = useEntitySectionState({\n defaultSort: 'createdAt',\n defaultOrder: 'desc',\n defaultPageSize: 10,\n filterOptions: [\n { label: 'All', value: '' },\n { label: 'By Code', value: 'code' },\n ],\n sortOptions: [\n { label: 'Created', value: 'createdAt' },\n { label: 'Updated', value: 'updatedAt' },\n { label: 'Code', value: 'code' },\n ],\n views: ['table', 'card'],\n });\n\n const { data, isPending, isFetching } = authApi$.useQuery(\n 'get',\n '/roles',\n { params: { query: { limit: LIMIT } } },\n { ...defaultEntityQueryOptions, enabled: open },\n );\n const isLoading = isPending || isFetching;\n const roles = data?.roles ?? [];\n\n const filtered = useMemo(\n () =>\n filterAndSort(\n roles,\n sectionState.search,\n sectionState.sort,\n sectionState.order,\n ),\n [roles, sectionState.search, sectionState.sort, sectionState.order],\n );\n const pageCount = Math.ceil(filtered.length / sectionState.pageSize) || 1;\n const pageIndex = Math.min(sectionState.page - 1, Math.max(0, pageCount - 1));\n const paginated = useMemo(\n () =>\n filtered.slice(\n pageIndex * sectionState.pageSize,\n pageIndex * sectionState.pageSize + sectionState.pageSize,\n ),\n [filtered, pageIndex, sectionState.pageSize],\n );\n\n return (\n <EntitySection\n title=\"Role\"\n state={sectionState}\n onOpenChange={setOpen}\n actions={\n <RoleSelector\n trigger={\n <Button variant=\"outline\" size=\"sm\">\n <IconPlus className=\"h-4 w-4\" />\n Add role\n </Button>\n }\n multiple\n onSelect={(roles) => {\n // TODO: assign roles to user; logging for now\n // biome-ignore lint/suspicious/noConsole: intentional for now\n console.log('Selected roles:', userId, roles);\n }}\n />\n }\n config={{\n searchPlaceholder: 'Search roles...',\n filterOptions: sectionState.filterOptions,\n sortOptions: sectionState.sortOptions,\n views: sectionState.views,\n }}\n >\n {(state) => (\n <>\n {isLoading && (\n <EntityLoadingState\n view={state.view as 'table' | 'card'}\n rowCount={state.pageSize}\n columnCount={TABLE_COLUMN_COUNT}\n cardCount={state.pageSize}\n />\n )}\n {!isLoading && filtered.length === 0 && (\n <EntityEmptyState\n icon={IconShield}\n entityName=\"role\"\n title=\"No roles\"\n description={\n roles.length === 0 ? 'No roles in tenant.' : 'No matches.'\n }\n />\n )}\n {!isLoading && filtered.length > 0 && (\n <RolesList\n data={paginated}\n view={state.view as 'table' | 'card'}\n pageIndex={pageIndex}\n pageSize={state.pageSize}\n pageCount={pageCount}\n totalRows={filtered.length}\n onPageChange={(p) => state.setPage(p + 1)}\n onPageSizeChange={(size) => {\n state.setPageSize(size);\n state.setPage(1);\n }}\n />\n )}\n </>\n )}\n </EntitySection>\n );\n}\n","'use client';\n\nimport {\n EntitySelector,\n type EntitySelectorColumn,\n type EntitySelectorConfig,\n useEntitySectionState,\n} from '@mesob/ui/components';\nimport { cn } from '@mesob/ui/lib/utils';\nimport { IconCalendar, IconShield } from '@tabler/icons-react';\nimport type { ReactNode } from 'react';\nimport type { paths } from '../../../../data/openapi';\nimport { authApi$, defaultEntityQueryOptions } from '../../shared/page-helpers';\nimport { RoleCard } from './role-card';\nimport type { Role } from './roles-data';\nimport { str } from './roles-data';\n\nfunction SelectableRoleCard({\n role,\n selected,\n onToggle,\n}: {\n role: Role;\n selected: boolean;\n onToggle: () => void;\n}) {\n return (\n // biome-ignore lint/a11y/useSemanticElements: div to avoid nested buttons from RoleCard\n <div\n role=\"button\"\n tabIndex={0}\n onClick={onToggle}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n onToggle();\n }\n }}\n className={cn(\n 'cursor-pointer rounded-lg transition-shadow focus:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n selected && 'ring-primary ring-2',\n )}\n >\n <RoleCard role={role} mode=\"static\" />\n </div>\n );\n}\n\nconst roleColumns: EntitySelectorColumn<Role>[] = [\n {\n key: 'role',\n header: 'Role',\n cell: (role) => (\n <>\n <p className=\"font-medium\">{str(role.name) || role.code}</p>\n <p className=\"text-sm text-muted-foreground\">{role.code}</p>\n </>\n ),\n },\n {\n key: 'description',\n header: 'Description',\n cell: (role) => (\n <span className=\"text-muted-foreground line-clamp-1 max-w-[200px]\">\n {str(role.description) || '—'}\n </span>\n ),\n },\n {\n key: 'created',\n header: 'Created',\n cell: (role) => (\n <div className=\"flex items-center gap-1 text-muted-foreground\">\n <IconCalendar className=\"h-4 w-4\" />\n {new Date(role.createdAt).toLocaleDateString()}\n </div>\n ),\n },\n];\n\ntype RoleSelectorProps = {\n trigger: ReactNode;\n multiple?: boolean;\n onSelect: (roles: Role[]) => void;\n modalSize?: 'sm' | 'md' | 'lg' | 'xl' | 'full';\n contentClassName?: string;\n};\n\nexport function RoleSelector({\n trigger,\n multiple = true,\n onSelect,\n modalSize = 'xl',\n contentClassName,\n}: RoleSelectorProps) {\n const state = useEntitySectionState({\n defaultSort: 'createdAt',\n defaultOrder: 'desc',\n defaultPageSize: 10,\n searchParamName: 'search',\n });\n const rolesQuery = state.queryConfig as {\n params: {\n query: NonNullable<paths['/roles']['get']['parameters']['query']>;\n };\n };\n\n const { data, isPending, isFetching } = authApi$.useQuery(\n 'get',\n '/roles',\n rolesQuery,\n defaultEntityQueryOptions,\n );\n\n const roles = data?.roles ?? [];\n\n const config: EntitySelectorConfig<Role> = {\n title: 'Select role(s)',\n modalSize,\n contentClassName,\n multiple,\n entityName: 'role',\n entityIcon: IconShield,\n columns: roleColumns,\n columnCount: 3,\n getItemLabel: (role) => str(role.name) || role.code,\n searchPlaceholder: 'Search roles...',\n wrapHeaderInCard: false,\n filterOptions: [\n { label: 'All', value: '' },\n { label: 'By Code', value: 'code' },\n ],\n sortOptions: [\n { label: 'Created', value: 'createdAt' },\n { label: 'Updated', value: 'updatedAt' },\n { label: 'Code', value: 'code' },\n ],\n showViewToggle: false,\n renderCard: (role, selected, onToggle) => (\n <SelectableRoleCard role={role} selected={selected} onToggle={onToggle} />\n ),\n };\n\n return (\n <EntitySelector<Role>\n trigger={trigger}\n config={config}\n onSelect={onSelect}\n items={roles}\n total={data?.total}\n isLoading={isPending || isFetching}\n state={state}\n />\n );\n}\n"],"mappings":"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","names":["IconCalendar","useEntitySectionState","IconShield","Fragment","jsx","jsxs","useEntitySectionState","roles","IconShield","jsx","jsxs","IconCalendar"]}
|
|
1
|
+
{"version":3,"sources":["../src/pages/iam/users/activity/user-activity-page-content.tsx","../src/pages/iam/users/activity/_components/role-section.tsx","../src/pages/iam/roles/_components/role-selector.tsx"],"sourcesContent":["'use client';\n\nimport {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Section,\n} from '@mesob/ui/components';\nimport { IconCalendar } from '@tabler/icons-react';\nimport { RoleSection } from './_components/role-section';\n\ntype UserActivityPageContentProps = {\n userId: string;\n};\n\nexport function UserActivityPageContent({\n userId,\n}: UserActivityPageContentProps) {\n if (!userId) {\n return null;\n }\n\n return (\n <div className=\"space-y-4\">\n <Card>\n <CardHeader>\n <CardTitle>Activity</CardTitle>\n </CardHeader>\n <CardContent className=\"flex items-center gap-2 text-muted-foreground text-sm\">\n <IconCalendar className=\"h-4 w-4\" />\n Activity (placeholder)\n </CardContent>\n </Card>\n <RoleSection userId={userId} />\n <Section title=\"Permissions\">test</Section>\n <Section title=\"Groups\">test</Section>\n </div>\n );\n}\n","'use client';\n\nimport {\n Button,\n EntityEmptyState,\n EntityLoadingState,\n EntitySection,\n useEntitySectionState,\n} from '@mesob/ui/components';\nimport { IconPlus, IconShield } from '@tabler/icons-react';\nimport { useMemo, useState } from 'react';\nimport { RoleSelector } from '../../../roles/_components/role-selector';\nimport type { Role } from '../../../roles/_components/roles-data';\nimport { str } from '../../../roles/_components/roles-data';\nimport { RolesList } from '../../../roles/_components/roles-list';\nimport {\n authApi$,\n defaultEntityQueryOptions,\n} from '../../../shared/page-helpers';\n\nconst LIMIT = 100;\nconst TABLE_COLUMN_COUNT = 4;\n\nfunction filterAndSort(\n roles: Role[],\n search: string,\n sort: string,\n order: 'asc' | 'desc',\n) {\n let out = roles;\n if (search.trim()) {\n const q = search.trim().toLowerCase();\n out = out.filter(\n (r) =>\n str(r.name).toLowerCase().includes(q) ||\n r.code.toLowerCase().includes(q),\n );\n }\n const mult = order === 'asc' ? 1 : -1;\n const by = sort === 'code' ? 'code' : 'createdAt';\n out = [...out].sort((a, b) =>\n by === 'code'\n ? mult * a.code.localeCompare(b.code)\n : mult *\n (new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()),\n );\n return out;\n}\n\nexport function RoleSection({ userId }: { userId: string }) {\n const [open, setOpen] = useState(false);\n const sectionState = useEntitySectionState({\n defaultSort: 'createdAt',\n defaultOrder: 'desc',\n defaultPageSize: 10,\n filterOptions: [\n { label: 'All', value: '' },\n { label: 'By Code', value: 'code' },\n ],\n sortOptions: [\n { label: 'Created', value: 'createdAt' },\n { label: 'Updated', value: 'updatedAt' },\n { label: 'Code', value: 'code' },\n ],\n views: ['table', 'card'],\n });\n\n const { data, isPending, isFetching } = authApi$.useQuery(\n 'get',\n '/roles',\n { params: { query: { limit: LIMIT } } },\n { ...defaultEntityQueryOptions, enabled: open },\n );\n const isLoading = isPending || isFetching;\n const roles = data?.roles ?? [];\n\n const filtered = useMemo(\n () =>\n filterAndSort(\n roles,\n sectionState.search,\n sectionState.sort,\n sectionState.order,\n ),\n [roles, sectionState.search, sectionState.sort, sectionState.order],\n );\n const pageCount = Math.ceil(filtered.length / sectionState.pageSize) || 1;\n const pageIndex = Math.min(sectionState.page - 1, Math.max(0, pageCount - 1));\n const paginated = useMemo(\n () =>\n filtered.slice(\n pageIndex * sectionState.pageSize,\n pageIndex * sectionState.pageSize + sectionState.pageSize,\n ),\n [filtered, pageIndex, sectionState.pageSize],\n );\n\n return (\n <EntitySection\n title=\"Role\"\n state={sectionState}\n onOpenChange={setOpen}\n actions={\n <RoleSelector\n trigger={\n <Button variant=\"outline\" size=\"sm\">\n <IconPlus className=\"h-4 w-4\" />\n Add role\n </Button>\n }\n multiple\n onSelect={(roles) => {\n // TODO: assign roles to user; logging for now\n // biome-ignore lint/suspicious/noConsole: intentional for now\n console.log('Selected roles:', userId, roles);\n }}\n />\n }\n config={{\n searchPlaceholder: 'Search roles...',\n filterOptions: sectionState.filterOptions,\n sortOptions: sectionState.sortOptions,\n views: sectionState.views,\n }}\n >\n {(state) => (\n <>\n {isLoading && (\n <EntityLoadingState\n view={state.view as 'table' | 'card'}\n rowCount={state.pageSize}\n columnCount={TABLE_COLUMN_COUNT}\n cardCount={state.pageSize}\n />\n )}\n {!isLoading && filtered.length === 0 && (\n <EntityEmptyState\n icon={IconShield}\n entityName=\"role\"\n title=\"No roles\"\n description={\n roles.length === 0 ? 'No roles in tenant.' : 'No matches.'\n }\n />\n )}\n {!isLoading && filtered.length > 0 && (\n <RolesList\n data={paginated}\n view={state.view as 'table' | 'card'}\n pageIndex={pageIndex}\n pageSize={state.pageSize}\n pageCount={pageCount}\n totalRows={filtered.length}\n onPageChange={(p) => state.setPage(p + 1)}\n onPageSizeChange={(size) => {\n state.setPageSize(size);\n state.setPage(1);\n }}\n />\n )}\n </>\n )}\n </EntitySection>\n );\n}\n","'use client';\n\nimport {\n EntitySelector,\n type EntitySelectorColumn,\n type EntitySelectorConfig,\n useEntitySectionState,\n} from '@mesob/ui/components';\nimport { cn } from '@mesob/ui/lib/utils';\nimport { IconCalendar, IconShield } from '@tabler/icons-react';\nimport type { ReactNode } from 'react';\nimport type { paths } from '../../../../data/openapi';\nimport { authApi$, defaultEntityQueryOptions } from '../../shared/page-helpers';\nimport { RoleCard } from './role-card';\nimport type { Role } from './roles-data';\nimport { str } from './roles-data';\n\nfunction SelectableRoleCard({\n role,\n selected,\n onToggle,\n}: {\n role: Role;\n selected: boolean;\n onToggle: () => void;\n}) {\n return (\n // biome-ignore lint/a11y/useSemanticElements: div to avoid nested buttons from RoleCard\n <div\n role=\"button\"\n tabIndex={0}\n onClick={onToggle}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n onToggle();\n }\n }}\n className={cn(\n 'cursor-pointer rounded-lg transition-shadow focus:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n selected && 'ring-primary ring-2',\n )}\n >\n <RoleCard role={role} mode=\"static\" />\n </div>\n );\n}\n\nconst roleColumns: EntitySelectorColumn<Role>[] = [\n {\n key: 'role',\n header: 'Role',\n cell: (role) => (\n <>\n <p className=\"font-medium\">{str(role.name) || role.code}</p>\n <p className=\"text-sm text-muted-foreground\">{role.code}</p>\n </>\n ),\n },\n {\n key: 'description',\n header: 'Description',\n cell: (role) => (\n <span className=\"text-muted-foreground line-clamp-1 max-w-[200px]\">\n {str(role.description) || '—'}\n </span>\n ),\n },\n {\n key: 'created',\n header: 'Created',\n cell: (role) => (\n <div className=\"flex items-center gap-1 text-muted-foreground\">\n <IconCalendar className=\"h-4 w-4\" />\n {new Date(role.createdAt).toLocaleDateString()}\n </div>\n ),\n },\n];\n\ntype RoleSelectorProps = {\n trigger: ReactNode;\n multiple?: boolean;\n onSelect: (roles: Role[]) => void;\n modalSize?: 'sm' | 'md' | 'lg' | 'xl' | 'full';\n contentClassName?: string;\n};\n\nexport function RoleSelector({\n trigger,\n multiple = true,\n onSelect,\n modalSize = 'xl',\n contentClassName,\n}: RoleSelectorProps) {\n const state = useEntitySectionState({\n defaultSort: 'createdAt',\n defaultOrder: 'desc',\n defaultPageSize: 10,\n searchParamName: 'search',\n });\n const rolesQuery = state.queryConfig as {\n params: {\n query: NonNullable<paths['/roles']['get']['parameters']['query']>;\n };\n };\n\n const { data, isPending, isFetching } = authApi$.useQuery(\n 'get',\n '/roles',\n rolesQuery,\n defaultEntityQueryOptions,\n );\n\n const roles = data?.roles ?? [];\n\n const config: EntitySelectorConfig<Role> = {\n title: 'Select role(s)',\n modalSize,\n contentClassName,\n multiple,\n entityName: 'role',\n entityIcon: IconShield,\n columns: roleColumns,\n columnCount: 3,\n getItemLabel: (role) => str(role.name) || role.code,\n searchPlaceholder: 'Search roles...',\n wrapHeaderInCard: false,\n filterOptions: [\n { label: 'All', value: '' },\n { label: 'By Code', value: 'code' },\n ],\n sortOptions: [\n { label: 'Created', value: 'createdAt' },\n { label: 'Updated', value: 'updatedAt' },\n { label: 'Code', value: 'code' },\n ],\n showViewToggle: false,\n renderCard: (role, selected, onToggle) => (\n <SelectableRoleCard role={role} selected={selected} onToggle={onToggle} />\n ),\n };\n\n return (\n <EntitySelector<Role>\n trigger={trigger}\n config={config}\n onSelect={onSelect}\n items={roles}\n total={data?.total}\n isLoading={isPending || isFetching}\n state={state}\n />\n );\n}\n"],"mappings":"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","names":["IconCalendar","useEntitySectionState","IconShield","Fragment","jsx","jsxs","useEntitySectionState","roles","IconShield","jsx","jsxs","IconCalendar"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/cookie.ts","../src/provider.tsx","../src/lib/translations.ts","../src/types.ts","../src/utils/custom-fetch.ts"],"sourcesContent":["import type { AuthClientConfig } from '../types';\n\nconst isProduction =\n typeof process !== 'undefined' && process.env.NODE_ENV === 'production';\n\nexport const getSessionCookieName = (config: AuthClientConfig): string => {\n const prefix = config.cookiePrefix || '';\n const baseName = 'session_token';\n if (prefix) {\n return `${prefix}_${baseName}`;\n }\n return isProduction ? '__Host-session_token' : baseName;\n};\n","'use client';\n\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\nimport { deepmerge } from 'deepmerge-ts';\nimport createFetchClient from 'openapi-fetch';\nimport createClient from 'openapi-react-query';\nimport type { ReactNode } from 'react';\nimport { createContext, useContext, useMemo, useState } from 'react';\nimport type { paths } from './data/openapi';\nimport { createTranslator } from './lib/translations';\nimport {\n type AuthClientConfig,\n type AuthResponse,\n defaultAuthClientConfig,\n type Session,\n type User,\n} from './types';\nimport { getSessionCookieName } from './utils/cookie';\nimport { createCustomFetch } from './utils/custom-fetch';\n\n// biome-ignore lint/suspicious/noExplicitAny: OpenAPI hooks type\ntype OpenApiHooks = any;\n\n// --- Utility: Check if running on server ---\nfunction isServer(): boolean {\n return typeof document === 'undefined';\n}\n\n/**\n * @deprecated Cookie is httpOnly and cannot be read client-side.\n * Use `useSession().isAuthenticated` instead.\n * This function always returns false on client.\n */\nexport function hasAuthCookie(_cookieName: string): boolean {\n // Cookie is httpOnly, can't check client-side\n // Always return false - use useSession() for auth status\n return false;\n}\n\n// --- Types ---\nexport type AuthStatus = 'loading' | 'authenticated' | 'unauthenticated';\n\ntype AuthState = {\n user: User | null;\n session: Session | null;\n status: AuthStatus;\n error: Error | null;\n};\n\ntype SessionContextValue = AuthState & {\n isLoading: boolean;\n isAuthenticated: boolean;\n refresh: () => Promise<void>;\n signOut: () => Promise<void>;\n};\n\ntype ApiContextValue = {\n hooks: OpenApiHooks;\n setAuth: (auth: AuthResponse) => void;\n clearAuth: () => void;\n refresh: () => Promise<void>;\n};\n\ntype ConfigContextValue = {\n config: AuthClientConfig;\n cookieName: string;\n t: (key: string, params?: Record<string, string | number>) => string;\n};\n\nconst SessionContext = createContext<SessionContextValue | null>(null);\nconst ApiContext = createContext<ApiContextValue | null>(null);\nconst ConfigContext = createContext<ConfigContextValue | null>(null);\n\nconst queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n refetchOnWindowFocus: false,\n },\n },\n});\n\n// --- Hooks ---\n\n/**\n * Get session state including user, session, and auth status.\n * - `status`: 'loading' | 'authenticated' | 'unauthenticated'\n * - `isLoading`: true while fetching session\n * - `isAuthenticated`: true if user and session exist\n */\nexport function useSession(): SessionContextValue {\n const context = useContext(SessionContext);\n if (!context) {\n throw new Error('useSession must be used within MesobAuthProvider');\n }\n return context;\n}\n\nexport function useApi(): ApiContextValue {\n const context = useContext(ApiContext);\n if (!context) {\n throw new Error('useApi must be used within MesobAuthProvider');\n }\n return context;\n}\n\nexport function useConfig(): ConfigContextValue {\n const context = useContext(ConfigContext);\n if (!context) {\n throw new Error('useConfig must be used within MesobAuthProvider');\n }\n return context;\n}\n\n/**\n * @deprecated Cookie is httpOnly, can't be checked client-side.\n * Use `useSession().isAuthenticated` instead.\n */\nexport function useHasAuthCookie(): boolean {\n const { status } = useSession();\n return status === 'authenticated' || status === 'loading';\n}\n\n// --- Provider ---\n\ntype MesobAuthProviderProps = {\n config: AuthClientConfig;\n children: ReactNode;\n};\n\nexport function MesobAuthProvider({\n config,\n children,\n}: MesobAuthProviderProps) {\n const mergedConfig = useMemo(\n () =>\n deepmerge(\n { ...defaultAuthClientConfig } as Partial<AuthClientConfig>,\n config,\n ) as AuthClientConfig,\n [config],\n );\n\n const api = useMemo(\n () =>\n createFetchClient<paths>({\n baseUrl: mergedConfig.baseURL,\n fetch: createCustomFetch(mergedConfig),\n }),\n [mergedConfig],\n );\n\n const hooks = useMemo(() => createClient(api), [api]);\n const cookieName = useMemo(\n () => getSessionCookieName(mergedConfig),\n [mergedConfig],\n );\n\n return (\n <QueryClientProvider client={queryClient}>\n <AuthStateProvider\n config={mergedConfig}\n hooks={hooks}\n cookieName={cookieName}\n >\n {children}\n </AuthStateProvider>\n </QueryClientProvider>\n );\n}\n\ntype AuthStateProviderProps = {\n config: AuthClientConfig;\n hooks: OpenApiHooks;\n cookieName: string;\n children: ReactNode;\n};\n\nfunction AuthStateProvider({\n config,\n hooks,\n cookieName,\n children,\n}: AuthStateProviderProps) {\n // Manual override for sign-out / sign-in\n const [override, setOverride] = useState<AuthState | null>(null);\n\n // Always fetch session - cookie is httpOnly, can't check client-side\n // Server will read the cookie and return user/session if valid\n const {\n data: sessionData,\n isLoading,\n isFetched,\n error: sessionError,\n refetch,\n } = hooks.useQuery(\n 'get',\n '/session',\n {},\n {\n enabled: !(override || isServer()),\n refetchOnMount: false,\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n retry: false,\n gcTime: 0,\n staleTime: 0,\n },\n );\n\n // Derive state directly - no useEffect\n const user = override?.user ?? sessionData?.user ?? null;\n const session = override?.session ?? sessionData?.session ?? null;\n const error = override?.error ?? (sessionError as Error | null);\n\n // Check error status code\n const errorStatus = (() => {\n if (!sessionError) {\n return null;\n }\n const err = sessionError as { status?: number };\n return err.status ?? null;\n })();\n\n // Check if error is a network/connection error\n const isNetworkError = (() => {\n if (!sessionError) {\n return false;\n }\n const error = sessionError as Error & { cause?: unknown; data?: unknown };\n const errorMessage =\n error.message || String(error) || JSON.stringify(error);\n // Network errors: TypeError, DOMException, or fetch failures\n if (\n error instanceof TypeError ||\n error instanceof DOMException ||\n error.name === 'TypeError' ||\n errorMessage.includes('Failed to fetch') ||\n errorMessage.includes('ERR_CONNECTION_REFUSED') ||\n errorMessage.includes('NetworkError') ||\n errorMessage.includes('Network request failed') ||\n errorMessage.includes('fetch failed')\n ) {\n return true;\n }\n // Check error cause\n if (error.cause) {\n const causeStr = String(error.cause);\n if (\n causeStr.includes('Failed to fetch') ||\n causeStr.includes('ERR_CONNECTION_REFUSED') ||\n causeStr.includes('NetworkError')\n ) {\n return true;\n }\n }\n return false;\n })();\n\n // Compute status\n // biome-ignore lint: Status determination requires multiple checks\n const status: AuthStatus = (() => {\n if (override) {\n return override.status;\n }\n if (isServer()) {\n return 'loading';\n }\n if (user && session) {\n return 'authenticated';\n }\n // Check for network errors or auth errors first - allow auth page to show\n if (isNetworkError || errorStatus === 401) {\n return 'unauthenticated';\n }\n // If we have an error but it's not a network error, still check loading state\n if (sessionError && !isNetworkError && errorStatus !== 401) {\n if (errorStatus && errorStatus >= 500) {\n return 'authenticated';\n }\n // Other errors mean unauthenticated\n if (isFetched) {\n return 'unauthenticated';\n }\n }\n if (isLoading || !isFetched) {\n return 'loading';\n }\n if (isFetched && !user && !session) {\n return 'unauthenticated';\n }\n return 'unauthenticated';\n })();\n\n const signOutMutation = hooks.useMutation('post', '/sign-out');\n const t = createTranslator(config.messages || {});\n\n const setAuth = (auth: AuthResponse) => {\n setOverride({\n user: auth.user,\n session: auth.session,\n status: 'authenticated',\n error: null,\n });\n };\n\n const clearAuth = () => {\n setOverride({\n user: null,\n session: null,\n status: 'unauthenticated',\n error: null,\n });\n };\n\n const refresh = async () => {\n setOverride(null);\n await refetch();\n };\n\n const signOut = async () => {\n await signOutMutation.mutateAsync({});\n clearAuth();\n\n const redirectUrl = config.navigation?.defaultRedirectUrl || '/';\n\n if (config.navigation?.onNavigate) {\n config.navigation.onNavigate(redirectUrl);\n } else if (typeof window !== 'undefined') {\n window.location.href = redirectUrl;\n }\n };\n\n return (\n <ConfigContext.Provider value={{ config, cookieName, t }}>\n <ApiContext.Provider value={{ hooks, setAuth, clearAuth, refresh }}>\n <SessionContext.Provider\n value={{\n user,\n session,\n status,\n error,\n isLoading: status === 'loading',\n isAuthenticated: status === 'authenticated',\n refresh,\n signOut,\n }}\n >\n {children}\n </SessionContext.Provider>\n </ApiContext.Provider>\n </ConfigContext.Provider>\n );\n}\n","type Messages = Record<string, unknown>;\n\nexport function createTranslator(messages: Messages, namespace?: string) {\n return (key: string, params?: Record<string, string | number>): string => {\n const fullKey = namespace ? `${namespace}.${key}` : key;\n const keys = fullKey.split('.');\n\n let value: unknown = messages;\n for (const k of keys) {\n if (value && typeof value === 'object' && value !== null) {\n value = (value as Record<string, unknown>)[k];\n } else {\n return fullKey;\n }\n }\n\n if (typeof value !== 'string') {\n return fullKey;\n }\n\n // Simple parameter replacement\n if (params) {\n return value.replace(/\\{(\\w+)\\}/g, (_, param) =>\n String(params[param] ?? `{${param}}`),\n );\n }\n\n return value;\n };\n}\n","import type { PermissionTree } from '@mesob/common';\n\nexport type UIConfig = {\n logo: React.ReactNode;\n name: React.ReactNode;\n logoImage?: string;\n};\n\nexport type FeaturesConfig = {\n enableSignup?: boolean;\n enablePasswordReset?: boolean;\n enableEmailSignup?: boolean;\n enablePhoneSignup?: boolean;\n enableSocialSignup?: boolean;\n socialProviders?: string[];\n};\n\nexport type TenantConfig = {\n enabled: boolean;\n tenantId: string;\n};\n\nexport type NavigationConfig = {\n locale?: string;\n defaultRedirectUrl?: string;\n onNavigate?: (path: string) => void;\n linkComponent?: React.ComponentType<\n React.ComponentProps<'a'> & { href: string }\n >;\n links?: {\n signIn?: string;\n signUp?: string;\n forgotPassword?: string;\n setPassword?: string;\n };\n};\n\nexport type AuthClientConfig = {\n baseURL: string;\n ui: UIConfig;\n features?: FeaturesConfig;\n tenant?: TenantConfig;\n permissions?: PermissionTree;\n navigation?: NavigationConfig;\n messages?: Record<string, unknown>;\n cookiePrefix?: string;\n phoneRegex?: RegExp | string;\n};\n\ntype DefaultAuthClientConfig = {\n readonly features: {\n readonly enableSignup: true;\n readonly enablePasswordReset: true;\n readonly enableEmailSignup: true;\n readonly enablePhoneSignup: true;\n readonly enableSocialSignup: false;\n readonly socialProviders: [];\n };\n readonly navigation: {\n readonly locale: 'en';\n };\n readonly cookiePrefix: 'msb';\n readonly phoneRegex: RegExp;\n};\n\nexport const defaultAuthClientConfig: DefaultAuthClientConfig = {\n features: {\n enableSignup: true,\n enablePasswordReset: true,\n enableEmailSignup: true,\n enablePhoneSignup: true,\n enableSocialSignup: false,\n socialProviders: [],\n },\n navigation: {\n locale: 'en',\n },\n cookiePrefix: 'msb',\n phoneRegex: /^(\\+2519|\\+2517|2519|2517|09|07)\\d{8}$/,\n} as const;\n\nexport type User = {\n id: string;\n tenantId: string;\n fullName: string;\n email: string | null;\n phone: string | null;\n handle?: string;\n image: string | null;\n emailVerified: boolean;\n phoneVerified: boolean;\n lastSignInAt?: string | null;\n /** Role IDs */\n roles?: string[] | null;\n roleCodes?: string[] | null;\n permissions?: string[] | null;\n};\n\nexport type Session = {\n id?: string;\n expiresAt: string;\n createdAt?: string;\n userAgent?: string | null;\n ip?: string | null;\n};\n\nexport type AuthResponse = {\n user: User;\n session: Session;\n sessionToken?: string;\n sessionExpiresAt?: string;\n};\n\nexport type AuthErrorCode =\n | 'USER_NOT_FOUND'\n | 'INVALID_PASSWORD'\n | 'USER_EXISTS'\n | 'VERIFICATION_EXPIRED'\n | 'VERIFICATION_MISMATCH'\n | 'VERIFICATION_NOT_FOUND'\n | 'TOO_MANY_ATTEMPTS'\n | 'REQUIRES_VERIFICATION'\n | 'UNAUTHORIZED'\n | 'ACCESS_DENIED'\n | 'HAS_NO_PASSWORD'\n | 'PASSWORD_ALREADY_SET';\n\nexport type AuthError = {\n message: string;\n code?: AuthErrorCode;\n status?: number;\n details?: Record<string, unknown>;\n};\n","import type { AuthClientConfig } from '../types';\n\nexport const createCustomFetch = (_config: AuthClientConfig) => {\n return (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\n if (input instanceof Request) {\n return fetch(input, { ...init, credentials: 'include' });\n }\n return fetch(input, { ...init, credentials: 'include' });\n };\n};\n"],"mappings":"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","names":["error"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils/cookie.ts","../src/provider.tsx","../src/lib/translations.ts","../src/types.ts","../src/utils/custom-fetch.ts"],"sourcesContent":["import type { AuthClientConfig } from '../types';\n\nconst isProduction =\n typeof process !== 'undefined' && process.env.NODE_ENV === 'production';\n\nexport const getSessionCookieName = (config: AuthClientConfig): string => {\n const prefix = config.cookiePrefix || '';\n const baseName = 'session_token';\n if (prefix) {\n return `${prefix}_${baseName}`;\n }\n return isProduction ? '__Host-session_token' : baseName;\n};\n","'use client';\n\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\nimport { deepmerge } from 'deepmerge-ts';\nimport createFetchClient from 'openapi-fetch';\nimport createClient from 'openapi-react-query';\nimport type { ReactNode } from 'react';\nimport { createContext, useContext, useMemo, useState } from 'react';\nimport type { paths } from './data/openapi';\nimport { createTranslator } from './lib/translations';\nimport {\n type AuthClientConfig,\n type AuthResponse,\n defaultAuthClientConfig,\n type Session,\n type User,\n} from './types';\nimport { getSessionCookieName } from './utils/cookie';\nimport { createCustomFetch } from './utils/custom-fetch';\n\n// biome-ignore lint/suspicious/noExplicitAny: OpenAPI hooks type\ntype OpenApiHooks = any;\n\n// --- Utility: Check if running on server ---\nfunction isServer(): boolean {\n return typeof document === 'undefined';\n}\n\n/**\n * @deprecated Cookie is httpOnly and cannot be read client-side.\n * Use `useSession().isAuthenticated` instead.\n * This function always returns false on client.\n */\nexport function hasAuthCookie(_cookieName: string): boolean {\n // Cookie is httpOnly, can't check client-side\n // Always return false - use useSession() for auth status\n return false;\n}\n\n// --- Types ---\nexport type AuthStatus = 'loading' | 'authenticated' | 'unauthenticated';\n\ntype AuthState = {\n user: User | null;\n session: Session | null;\n status: AuthStatus;\n error: Error | null;\n};\n\ntype SessionContextValue = AuthState & {\n isLoading: boolean;\n isAuthenticated: boolean;\n refresh: () => Promise<void>;\n signOut: () => Promise<void>;\n};\n\ntype ApiContextValue = {\n hooks: OpenApiHooks;\n setAuth: (auth: AuthResponse) => void;\n clearAuth: () => void;\n refresh: () => Promise<void>;\n};\n\ntype ConfigContextValue = {\n config: AuthClientConfig;\n cookieName: string;\n t: (key: string, params?: Record<string, string | number>) => string;\n};\n\nconst SessionContext = createContext<SessionContextValue | null>(null);\nconst ApiContext = createContext<ApiContextValue | null>(null);\nconst ConfigContext = createContext<ConfigContextValue | null>(null);\n\nconst queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n refetchOnWindowFocus: false,\n },\n },\n});\n\n// --- Hooks ---\n\n/**\n * Get session state including user, session, and auth status.\n * - `status`: 'loading' | 'authenticated' | 'unauthenticated'\n * - `isLoading`: true while fetching session\n * - `isAuthenticated`: true if user and session exist\n */\nexport function useSession(): SessionContextValue {\n const context = useContext(SessionContext);\n if (!context) {\n throw new Error('useSession must be used within MesobAuthProvider');\n }\n return context;\n}\n\nexport function useApi(): ApiContextValue {\n const context = useContext(ApiContext);\n if (!context) {\n throw new Error('useApi must be used within MesobAuthProvider');\n }\n return context;\n}\n\nexport function useConfig(): ConfigContextValue {\n const context = useContext(ConfigContext);\n if (!context) {\n throw new Error('useConfig must be used within MesobAuthProvider');\n }\n return context;\n}\n\n/**\n * @deprecated Cookie is httpOnly, can't be checked client-side.\n * Use `useSession().isAuthenticated` instead.\n */\nexport function useHasAuthCookie(): boolean {\n const { status } = useSession();\n return status === 'authenticated' || status === 'loading';\n}\n\n// --- Provider ---\n\ntype MesobAuthProviderProps = {\n config: AuthClientConfig;\n children: ReactNode;\n};\n\nexport function MesobAuthProvider({\n config,\n children,\n}: MesobAuthProviderProps) {\n const mergedConfig = useMemo(\n () =>\n deepmerge(\n { ...defaultAuthClientConfig } as Partial<AuthClientConfig>,\n config,\n ) as AuthClientConfig,\n [config],\n );\n\n const api = useMemo(\n () =>\n createFetchClient<paths>({\n baseUrl: mergedConfig.baseURL,\n fetch: createCustomFetch(mergedConfig),\n }),\n [mergedConfig],\n );\n\n const hooks = useMemo(() => createClient(api), [api]);\n const cookieName = useMemo(\n () => getSessionCookieName(mergedConfig),\n [mergedConfig],\n );\n\n return (\n <QueryClientProvider client={queryClient}>\n <AuthStateProvider\n config={mergedConfig}\n hooks={hooks}\n cookieName={cookieName}\n >\n {children}\n </AuthStateProvider>\n </QueryClientProvider>\n );\n}\n\ntype AuthStateProviderProps = {\n config: AuthClientConfig;\n hooks: OpenApiHooks;\n cookieName: string;\n children: ReactNode;\n};\n\nfunction AuthStateProvider({\n config,\n hooks,\n cookieName,\n children,\n}: AuthStateProviderProps) {\n // Manual override for sign-out / sign-in\n const [override, setOverride] = useState<AuthState | null>(null);\n\n // Always fetch session - cookie is httpOnly, can't check client-side\n // Server will read the cookie and return user/session if valid\n const {\n data: sessionData,\n isLoading,\n isFetched,\n error: sessionError,\n refetch,\n } = hooks.useQuery(\n 'get',\n '/session',\n {},\n {\n enabled: !(override || isServer()),\n refetchOnMount: false,\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n retry: false,\n gcTime: 0,\n staleTime: 0,\n },\n );\n\n // Derive state directly - no useEffect\n const user = override?.user ?? sessionData?.user ?? null;\n const session = override?.session ?? sessionData?.session ?? null;\n const error = override?.error ?? (sessionError as Error | null);\n\n // Check error status code\n const errorStatus = (() => {\n if (!sessionError) {\n return null;\n }\n const err = sessionError as { status?: number };\n return err.status ?? null;\n })();\n\n // Check if error is a network/connection error\n const isNetworkError = (() => {\n if (!sessionError) {\n return false;\n }\n const error = sessionError as Error & { cause?: unknown; data?: unknown };\n const errorMessage =\n error.message || String(error) || JSON.stringify(error);\n // Network errors: TypeError, DOMException, or fetch failures\n if (\n error instanceof TypeError ||\n error instanceof DOMException ||\n error.name === 'TypeError' ||\n errorMessage.includes('Failed to fetch') ||\n errorMessage.includes('ERR_CONNECTION_REFUSED') ||\n errorMessage.includes('NetworkError') ||\n errorMessage.includes('Network request failed') ||\n errorMessage.includes('fetch failed')\n ) {\n return true;\n }\n // Check error cause\n if (error.cause) {\n const causeStr = String(error.cause);\n if (\n causeStr.includes('Failed to fetch') ||\n causeStr.includes('ERR_CONNECTION_REFUSED') ||\n causeStr.includes('NetworkError')\n ) {\n return true;\n }\n }\n return false;\n })();\n\n // Compute status\n // biome-ignore lint: Status determination requires multiple checks\n const status: AuthStatus = (() => {\n if (override) {\n return override.status;\n }\n if (isServer()) {\n return 'loading';\n }\n if (user && session) {\n return 'authenticated';\n }\n // Check for network errors or auth errors first - allow auth page to show\n if (isNetworkError || errorStatus === 401) {\n return 'unauthenticated';\n }\n // If we have an error but it's not a network error, still check loading state\n if (sessionError && !isNetworkError && errorStatus !== 401) {\n if (errorStatus && errorStatus >= 500) {\n return 'authenticated';\n }\n // Other errors mean unauthenticated\n if (isFetched) {\n return 'unauthenticated';\n }\n }\n if (isLoading || !isFetched) {\n return 'loading';\n }\n if (isFetched && !user && !session) {\n return 'unauthenticated';\n }\n return 'unauthenticated';\n })();\n\n const signOutMutation = hooks.useMutation('post', '/sign-out');\n const t = createTranslator(config.messages || {});\n\n const setAuth = (auth: AuthResponse) => {\n setOverride({\n user: auth.user,\n session: auth.session,\n status: 'authenticated',\n error: null,\n });\n };\n\n const clearAuth = () => {\n setOverride({\n user: null,\n session: null,\n status: 'unauthenticated',\n error: null,\n });\n };\n\n const refresh = async () => {\n setOverride(null);\n await refetch();\n };\n\n const signOut = async () => {\n await signOutMutation.mutateAsync({});\n clearAuth();\n\n const redirectUrl = config.navigation?.defaultRedirectUrl || '/';\n\n if (config.navigation?.onNavigate) {\n config.navigation.onNavigate(redirectUrl);\n } else if (typeof window !== 'undefined') {\n window.location.href = redirectUrl;\n }\n };\n\n return (\n <ConfigContext.Provider value={{ config, cookieName, t }}>\n <ApiContext.Provider value={{ hooks, setAuth, clearAuth, refresh }}>\n <SessionContext.Provider\n value={{\n user,\n session,\n status,\n error,\n isLoading: status === 'loading',\n isAuthenticated: status === 'authenticated',\n refresh,\n signOut,\n }}\n >\n {children}\n </SessionContext.Provider>\n </ApiContext.Provider>\n </ConfigContext.Provider>\n );\n}\n","type Messages = Record<string, unknown>;\n\nexport function createTranslator(messages: Messages, namespace?: string) {\n return (key: string, params?: Record<string, string | number>): string => {\n const fullKey = namespace ? `${namespace}.${key}` : key;\n const keys = fullKey.split('.');\n\n let value: unknown = messages;\n for (const k of keys) {\n if (value && typeof value === 'object' && value !== null) {\n value = (value as Record<string, unknown>)[k];\n } else {\n return fullKey;\n }\n }\n\n if (typeof value !== 'string') {\n return fullKey;\n }\n\n // Simple parameter replacement\n if (params) {\n return value.replace(/\\{(\\w+)\\}/g, (_, param) =>\n String(params[param] ?? `{${param}}`),\n );\n }\n\n return value;\n };\n}\n","import type { PermissionTree } from '@mesob/common';\n\nexport type UIConfig = {\n logo: React.ReactNode;\n name: React.ReactNode;\n logoImage?: string;\n};\n\nexport type FeaturesConfig = {\n enableSignup?: boolean;\n enablePasswordReset?: boolean;\n enableEmailSignup?: boolean;\n enablePhoneSignup?: boolean;\n enableSocialSignup?: boolean;\n socialProviders?: string[];\n};\n\nexport type TenantConfig = {\n enabled: boolean;\n tenantId: string;\n};\n\nexport type NavigationConfig = {\n locale?: string;\n defaultRedirectUrl?: string;\n onNavigate?: (path: string) => void;\n linkComponent?: React.ComponentType<\n React.ComponentProps<'a'> & { href: string }\n >;\n links?: {\n signIn?: string;\n signUp?: string;\n forgotPassword?: string;\n setPassword?: string;\n };\n};\n\nexport type AuthClientConfig = {\n baseURL: string;\n ui: UIConfig;\n features?: FeaturesConfig;\n tenant?: TenantConfig;\n permissions?: PermissionTree;\n navigation?: NavigationConfig;\n messages?: Record<string, unknown>;\n cookiePrefix?: string;\n phoneRegex?: RegExp | string;\n /** Default userType filter for users list (e.g. 'employee'). Omit or 'all' to show all. */\n defaultUserType?: string;\n};\n\ntype DefaultAuthClientConfig = {\n readonly features: {\n readonly enableSignup: true;\n readonly enablePasswordReset: true;\n readonly enableEmailSignup: true;\n readonly enablePhoneSignup: true;\n readonly enableSocialSignup: false;\n readonly socialProviders: [];\n };\n readonly navigation: {\n readonly locale: 'en';\n };\n readonly cookiePrefix: 'msb';\n readonly phoneRegex: RegExp;\n};\n\nexport const defaultAuthClientConfig: DefaultAuthClientConfig = {\n features: {\n enableSignup: true,\n enablePasswordReset: true,\n enableEmailSignup: true,\n enablePhoneSignup: true,\n enableSocialSignup: false,\n socialProviders: [],\n },\n navigation: {\n locale: 'en',\n },\n cookiePrefix: 'msb',\n phoneRegex: /^(\\+2519|\\+2517|2519|2517|09|07)\\d{8}$/,\n} as const;\n\nexport type User = {\n id: string;\n tenantId: string;\n fullName: string;\n email: string | null;\n phone: string | null;\n handle?: string;\n image: string | null;\n emailVerified: boolean;\n phoneVerified: boolean;\n lastSignInAt?: string | null;\n /** Role IDs */\n roles?: string[] | null;\n roleCodes?: string[] | null;\n permissions?: string[] | null;\n};\n\nexport type Session = {\n id?: string;\n expiresAt: string;\n createdAt?: string;\n userAgent?: string | null;\n ip?: string | null;\n};\n\nexport type AuthResponse = {\n user: User;\n session: Session;\n sessionToken?: string;\n sessionExpiresAt?: string;\n};\n\nexport type AuthErrorCode =\n | 'USER_NOT_FOUND'\n | 'INVALID_PASSWORD'\n | 'USER_EXISTS'\n | 'VERIFICATION_EXPIRED'\n | 'VERIFICATION_MISMATCH'\n | 'VERIFICATION_NOT_FOUND'\n | 'TOO_MANY_ATTEMPTS'\n | 'REQUIRES_VERIFICATION'\n | 'UNAUTHORIZED'\n | 'ACCESS_DENIED'\n | 'HAS_NO_PASSWORD'\n | 'PASSWORD_ALREADY_SET';\n\nexport type AuthError = {\n message: string;\n code?: AuthErrorCode;\n status?: number;\n details?: Record<string, unknown>;\n};\n","import type { AuthClientConfig } from '../types';\n\nexport const createCustomFetch = (_config: AuthClientConfig) => {\n return (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\n if (input instanceof Request) {\n return fetch(input, { ...init, credentials: 'include' });\n }\n return fetch(input, { ...init, credentials: 'include' });\n };\n};\n"],"mappings":"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","names":["error"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
useSession
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-AWSAC7RT.js";
|
|
4
4
|
|
|
5
5
|
// src/components/authorization/deny.tsx
|
|
6
6
|
import { deny as canDeny } from "@mesob/common";
|
|
@@ -20,4 +20,4 @@ function Deny({ permissions, userPermissions, children }) {
|
|
|
20
20
|
export {
|
|
21
21
|
Deny
|
|
22
22
|
};
|
|
23
|
-
//# sourceMappingURL=chunk-
|
|
23
|
+
//# sourceMappingURL=chunk-CP4TTRV4.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
VerificationForm
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-Z34NJZRL.js";
|
|
4
4
|
import {
|
|
5
5
|
handleError
|
|
6
6
|
} from "./chunk-55BMNC4S.js";
|
|
@@ -9,11 +9,11 @@ import {
|
|
|
9
9
|
} from "./chunk-DPH2PHK3.js";
|
|
10
10
|
import {
|
|
11
11
|
useTranslator
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-EPEXIGKB.js";
|
|
13
13
|
import {
|
|
14
14
|
useApi,
|
|
15
15
|
useConfig
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-AWSAC7RT.js";
|
|
17
17
|
|
|
18
18
|
// src/components/auth/verify-email.tsx
|
|
19
19
|
import { Alert, AlertDescription, AlertTitle } from "@mesob/ui/components";
|
|
@@ -180,4 +180,4 @@ var VerifyEmail = ({
|
|
|
180
180
|
export {
|
|
181
181
|
VerifyEmail
|
|
182
182
|
};
|
|
183
|
-
//# sourceMappingURL=chunk-
|
|
183
|
+
//# sourceMappingURL=chunk-CXMPZWMX.js.map
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
useApi,
|
|
6
6
|
useConfig,
|
|
7
7
|
useSession
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-AWSAC7RT.js";
|
|
9
9
|
|
|
10
10
|
// src/components/profile/request-change-phone-form.tsx
|
|
11
11
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
@@ -269,4 +269,4 @@ function RequestChangePhoneForm({
|
|
|
269
269
|
export {
|
|
270
270
|
RequestChangePhoneForm
|
|
271
271
|
};
|
|
272
|
-
//# sourceMappingURL=chunk-
|
|
272
|
+
//# sourceMappingURL=chunk-DG6GRTPG.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
useApi,
|
|
3
3
|
useConfig
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-AWSAC7RT.js";
|
|
5
5
|
|
|
6
6
|
// src/components/iam/role-detail-page.tsx
|
|
7
7
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
@@ -191,4 +191,4 @@ function RoleDetailSkeleton() {
|
|
|
191
191
|
export {
|
|
192
192
|
RoleDetailPage
|
|
193
193
|
};
|
|
194
|
-
//# sourceMappingURL=chunk-
|
|
194
|
+
//# sourceMappingURL=chunk-DY3NVBLJ.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createTranslator,
|
|
3
3
|
useConfig
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-AWSAC7RT.js";
|
|
5
5
|
|
|
6
6
|
// src/hooks/use-translator.ts
|
|
7
7
|
import { useMesob } from "@mesob/ui/providers";
|
|
@@ -20,4 +20,4 @@ function useTranslator(namespace) {
|
|
|
20
20
|
export {
|
|
21
21
|
useTranslator
|
|
22
22
|
};
|
|
23
|
-
//# sourceMappingURL=chunk-
|
|
23
|
+
//# sourceMappingURL=chunk-EPEXIGKB.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
useApi,
|
|
3
3
|
useConfig
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-AWSAC7RT.js";
|
|
5
5
|
|
|
6
6
|
// src/components/iam/role-detail-layout.tsx
|
|
7
7
|
import {
|
|
@@ -100,4 +100,4 @@ function RoleDetailLayout({
|
|
|
100
100
|
export {
|
|
101
101
|
RoleDetailLayout
|
|
102
102
|
};
|
|
103
|
-
//# sourceMappingURL=chunk-
|
|
103
|
+
//# sourceMappingURL=chunk-EQWOGD4F.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
str
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-EWXK56WQ.js";
|
|
4
4
|
import {
|
|
5
5
|
useApi,
|
|
6
6
|
useConfig
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-AWSAC7RT.js";
|
|
8
8
|
|
|
9
9
|
// src/pages/iam/tenants/tenant-detail-page-content.tsx
|
|
10
10
|
import {
|
|
@@ -138,4 +138,4 @@ function TenantDetailPageContent({
|
|
|
138
138
|
export {
|
|
139
139
|
TenantDetailPageContent
|
|
140
140
|
};
|
|
141
|
-
//# sourceMappingURL=chunk-
|
|
141
|
+
//# sourceMappingURL=chunk-ETOCBXDT.js.map
|