@mesob/auth-react 0.3.5 → 0.4.0

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.
Files changed (124) hide show
  1. package/dist/components/auth/forgot-password.js +5 -1
  2. package/dist/components/auth/forgot-password.js.map +1 -1
  3. package/dist/components/auth/reset-password-form.js +5 -1
  4. package/dist/components/auth/reset-password-form.js.map +1 -1
  5. package/dist/components/auth/set-password.d.ts +9 -0
  6. package/dist/components/auth/set-password.js +527 -0
  7. package/dist/components/auth/set-password.js.map +1 -0
  8. package/dist/components/auth/sign-in.js +22 -1
  9. package/dist/components/auth/sign-in.js.map +1 -1
  10. package/dist/components/auth/sign-up.js +7 -5
  11. package/dist/components/auth/sign-up.js.map +1 -1
  12. package/dist/components/auth/verify-email.js +5 -1
  13. package/dist/components/auth/verify-email.js.map +1 -1
  14. package/dist/components/auth/verify-phone.js +5 -1
  15. package/dist/components/auth/verify-phone.js.map +1 -1
  16. package/dist/components/authorization/deny.d.ts +11 -0
  17. package/dist/components/authorization/deny.js +52 -0
  18. package/dist/components/authorization/deny.js.map +1 -0
  19. package/dist/components/authorization/grant.d.ts +12 -0
  20. package/dist/components/authorization/grant.js +57 -0
  21. package/dist/components/authorization/grant.js.map +1 -0
  22. package/dist/components/error-boundary.d.ts +2 -2
  23. package/dist/components/iam/permission-selector.d.ts +19 -0
  24. package/dist/components/iam/permission-selector.js +122 -0
  25. package/dist/components/iam/permission-selector.js.map +1 -0
  26. package/dist/components/iam/permissions.js +12 -31
  27. package/dist/components/iam/permissions.js.map +1 -1
  28. package/dist/components/iam/role-detail-layout.d.ts +11 -0
  29. package/dist/components/iam/role-detail-layout.js +137 -0
  30. package/dist/components/iam/role-detail-layout.js.map +1 -0
  31. package/dist/components/iam/role-detail-page.d.ts +9 -0
  32. package/dist/components/iam/role-detail-page.js +229 -0
  33. package/dist/components/iam/role-detail-page.js.map +1 -0
  34. package/dist/components/iam/role-permissions-page.d.ts +8 -0
  35. package/dist/components/iam/role-permissions-page.js +397 -0
  36. package/dist/components/iam/role-permissions-page.js.map +1 -0
  37. package/dist/components/iam/roles.js +11 -8
  38. package/dist/components/iam/roles.js.map +1 -1
  39. package/dist/components/iam/users.js +1 -7
  40. package/dist/components/iam/users.js.map +1 -1
  41. package/dist/components/profile/account.js +110 -19
  42. package/dist/components/profile/account.js.map +1 -1
  43. package/dist/components/profile/change-profile.d.ts +2 -1
  44. package/dist/components/profile/change-profile.js +16 -8
  45. package/dist/components/profile/change-profile.js.map +1 -1
  46. package/dist/components/profile/security.js +51 -17
  47. package/dist/components/profile/security.js.map +1 -1
  48. package/dist/index.d.ts +9 -1
  49. package/dist/index.js +1813 -725
  50. package/dist/index.js.map +1 -1
  51. package/dist/pages/auth/forgot-password.d.ts +7 -0
  52. package/dist/pages/auth/forgot-password.js +784 -0
  53. package/dist/pages/auth/forgot-password.js.map +1 -0
  54. package/dist/pages/auth/layout.d.ts +8 -0
  55. package/dist/pages/auth/layout.js +562 -0
  56. package/dist/pages/auth/layout.js.map +1 -0
  57. package/dist/pages/auth/reset-password.d.ts +10 -0
  58. package/dist/pages/auth/reset-password.js +913 -0
  59. package/dist/pages/auth/reset-password.js.map +1 -0
  60. package/dist/pages/auth/set-password.d.ts +10 -0
  61. package/dist/pages/auth/set-password.js +946 -0
  62. package/dist/pages/auth/set-password.js.map +1 -0
  63. package/dist/pages/auth/sign-in.d.ts +10 -0
  64. package/dist/pages/auth/sign-in.js +984 -0
  65. package/dist/pages/auth/sign-in.js.map +1 -0
  66. package/dist/pages/auth/sign-up.d.ts +10 -0
  67. package/dist/pages/auth/sign-up.js +940 -0
  68. package/dist/pages/auth/sign-up.js.map +1 -0
  69. package/dist/pages/auth/verify-email.d.ts +10 -0
  70. package/dist/pages/auth/verify-email.js +950 -0
  71. package/dist/pages/auth/verify-email.js.map +1 -0
  72. package/dist/pages/auth/verify-phone.d.ts +10 -0
  73. package/dist/pages/auth/verify-phone.js +964 -0
  74. package/dist/pages/auth/verify-phone.js.map +1 -0
  75. package/dist/pages/iam/permissions.d.ts +5 -0
  76. package/dist/pages/iam/permissions.js +308 -0
  77. package/dist/pages/iam/permissions.js.map +1 -0
  78. package/dist/pages/iam/role-detail-layout.d.ts +12 -0
  79. package/dist/pages/iam/role-detail-layout.js +145 -0
  80. package/dist/pages/iam/role-detail-layout.js.map +1 -0
  81. package/dist/pages/iam/role-detail.d.ts +12 -0
  82. package/dist/pages/iam/role-detail.js +241 -0
  83. package/dist/pages/iam/role-detail.js.map +1 -0
  84. package/dist/pages/iam/role-permissions.d.ts +12 -0
  85. package/dist/pages/iam/role-permissions.js +409 -0
  86. package/dist/pages/iam/role-permissions.js.map +1 -0
  87. package/dist/pages/iam/role-users.d.ts +12 -0
  88. package/dist/pages/iam/role-users.js +825 -0
  89. package/dist/pages/iam/role-users.js.map +1 -0
  90. package/dist/pages/iam/roles.d.ts +5 -0
  91. package/dist/pages/iam/roles.js +684 -0
  92. package/dist/pages/iam/roles.js.map +1 -0
  93. package/dist/pages/iam/sessions.d.ts +5 -0
  94. package/dist/pages/iam/sessions.js +315 -0
  95. package/dist/pages/iam/sessions.js.map +1 -0
  96. package/dist/pages/iam/tenant-detail.d.ts +10 -0
  97. package/dist/pages/iam/tenant-detail.js +186 -0
  98. package/dist/pages/iam/tenant-detail.js.map +1 -0
  99. package/dist/pages/iam/tenants.d.ts +5 -0
  100. package/dist/pages/iam/tenants.js +610 -0
  101. package/dist/pages/iam/tenants.js.map +1 -0
  102. package/dist/pages/iam/user-activity.d.ts +10 -0
  103. package/dist/pages/iam/user-activity.js +850 -0
  104. package/dist/pages/iam/user-activity.js.map +1 -0
  105. package/dist/pages/iam/user-detail-layout.d.ts +12 -0
  106. package/dist/pages/iam/user-detail-layout.js +106 -0
  107. package/dist/pages/iam/user-detail-layout.js.map +1 -0
  108. package/dist/pages/iam/user-detail.d.ts +10 -0
  109. package/dist/pages/iam/user-detail.js +102 -0
  110. package/dist/pages/iam/user-detail.js.map +1 -0
  111. package/dist/pages/iam/users.d.ts +5 -0
  112. package/dist/pages/iam/users.js +1275 -0
  113. package/dist/pages/iam/users.js.map +1 -0
  114. package/dist/pages/profile/account.d.ts +5 -0
  115. package/dist/pages/profile/account.js +182 -0
  116. package/dist/pages/profile/account.js.map +1 -0
  117. package/dist/pages/profile/layout.d.ts +8 -0
  118. package/dist/pages/profile/layout.js +133 -0
  119. package/dist/pages/profile/layout.js.map +1 -0
  120. package/dist/pages/profile/security.d.ts +5 -0
  121. package/dist/pages/profile/security.js +1539 -0
  122. package/dist/pages/profile/security.js.map +1 -0
  123. package/dist/{types-vcfvnAzQ.d.ts → types-g9QcNRxT.d.ts} +13 -7
  124. package/package.json +102 -3
@@ -0,0 +1,984 @@
1
+ // src/components/auth/auth-card.tsx
2
+ import { Card } from "@mesob/ui/components";
3
+ import { jsx } from "react/jsx-runtime";
4
+
5
+ // src/components/auth/forgot-password.tsx
6
+ import { zodResolver } from "@hookform/resolvers/zod";
7
+ import {
8
+ Alert,
9
+ AlertDescription,
10
+ AlertTitle,
11
+ Button,
12
+ Form,
13
+ FormControl,
14
+ FormField,
15
+ FormItem,
16
+ FormLabel,
17
+ FormMessage,
18
+ Input
19
+ } from "@mesob/ui/components";
20
+ import { useMesob as useMesob2 } from "@mesob/ui/providers";
21
+ import { IconAlertCircle } from "@tabler/icons-react";
22
+ import { useEffect, useState as useState2 } from "react";
23
+ import { useForm } from "react-hook-form";
24
+ import { toast } from "sonner";
25
+ import { z } from "zod";
26
+
27
+ // src/hooks/use-translator.ts
28
+ import { useMesob } from "@mesob/ui/providers";
29
+
30
+ // src/lib/translations.ts
31
+ function createTranslator(messages, namespace) {
32
+ return (key, params) => {
33
+ const fullKey = namespace ? `${namespace}.${key}` : key;
34
+ const keys = fullKey.split(".");
35
+ let value = messages;
36
+ for (const k of keys) {
37
+ if (value && typeof value === "object" && value !== null) {
38
+ value = value[k];
39
+ } else {
40
+ return fullKey;
41
+ }
42
+ }
43
+ if (typeof value !== "string") {
44
+ return fullKey;
45
+ }
46
+ if (params) {
47
+ return value.replace(
48
+ /\{(\w+)\}/g,
49
+ (_, param) => String(params[param] ?? `{${param}}`)
50
+ );
51
+ }
52
+ return value;
53
+ };
54
+ }
55
+
56
+ // src/provider.tsx
57
+ import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
58
+ import { deepmerge } from "deepmerge-ts";
59
+ import createFetchClient from "openapi-fetch";
60
+ import createClient from "openapi-react-query";
61
+ import { createContext, useContext, useMemo, useState } from "react";
62
+
63
+ // src/utils/cookie.ts
64
+ var isProduction = typeof process !== "undefined" && process.env.NODE_ENV === "production";
65
+
66
+ // src/provider.tsx
67
+ import { jsx as jsx2 } from "react/jsx-runtime";
68
+ var SessionContext = createContext(null);
69
+ var ApiContext = createContext(null);
70
+ var ConfigContext = createContext(null);
71
+ var queryClient = new QueryClient({
72
+ defaultOptions: {
73
+ queries: {
74
+ refetchOnWindowFocus: false
75
+ }
76
+ }
77
+ });
78
+ function useApi() {
79
+ const context = useContext(ApiContext);
80
+ if (!context) {
81
+ throw new Error("useApi must be used within MesobAuthProvider");
82
+ }
83
+ return context;
84
+ }
85
+ function useConfig() {
86
+ const context = useContext(ConfigContext);
87
+ if (!context) {
88
+ throw new Error("useConfig must be used within MesobAuthProvider");
89
+ }
90
+ return context;
91
+ }
92
+
93
+ // src/hooks/use-translator.ts
94
+ function useTranslator(namespace) {
95
+ const mesob = useMesob();
96
+ const { config } = useConfig();
97
+ if (mesob?.t) {
98
+ return (key, params) => {
99
+ const fullKey = namespace ? `${namespace}.${key}` : key;
100
+ return mesob.t?.(fullKey, params) ?? fullKey;
101
+ };
102
+ }
103
+ return createTranslator(config.messages || {}, namespace);
104
+ }
105
+
106
+ // src/constants/auth.error.codes.ts
107
+ var AUTH_ERROR_MAPPING = {
108
+ USER_NOT_FOUND: {
109
+ title: "Account Not Found",
110
+ description: "We could not find an account with that identifier. Please check your spelling or sign up."
111
+ },
112
+ INVALID_PASSWORD: {
113
+ title: "Invalid Password",
114
+ description: "The password you entered is incorrect. Please try again."
115
+ },
116
+ USER_EXISTS: {
117
+ title: "Account Already Exists",
118
+ description: "An account with this identifier already exists. Please sign in instead."
119
+ },
120
+ VERIFICATION_EXPIRED: {
121
+ title: "Verification Expired",
122
+ description: "The verification code or link has expired. Please request a new one."
123
+ },
124
+ VERIFICATION_MISMATCH: {
125
+ title: "Invalid Code",
126
+ description: "The verification code you entered is invalid. Please double-check and try again."
127
+ },
128
+ VERIFICATION_NOT_FOUND: {
129
+ title: "Verification Not Found",
130
+ description: "We could not find a pending verification request. Please restart the process."
131
+ },
132
+ TOO_MANY_ATTEMPTS: {
133
+ title: "Too Many Attempts",
134
+ description: "You have made too many requests recently. Please wait a moment before trying again."
135
+ },
136
+ REQUIRES_VERIFICATION: {
137
+ title: "Verification Required",
138
+ description: "You need to verify your account before you can continue. Please check your email or phone."
139
+ },
140
+ UNAUTHORIZED: {
141
+ title: "Unauthorized",
142
+ description: "You are not authorized to perform this action. Please sign in again."
143
+ },
144
+ ACCESS_DENIED: {
145
+ title: "Access Denied",
146
+ description: "You do not have permission to access this resource. Please contact support if you believe this is an error."
147
+ },
148
+ HAS_NO_PASSWORD: {
149
+ title: "No Password Set",
150
+ description: "Your account does not have a password yet. Continue to set a password before signing in."
151
+ },
152
+ PASSWORD_ALREADY_SET: {
153
+ title: "Password Already Set",
154
+ description: "This account already has a password. Use the normal sign-in form instead."
155
+ }
156
+ };
157
+ var validCodes = Object.keys(AUTH_ERROR_MAPPING);
158
+
159
+ // src/utils/handle-error.ts
160
+ function isAuthError(err) {
161
+ return typeof err === "object" && err !== null && "message" in err && typeof err.message === "string";
162
+ }
163
+ function extractErrorCode(err) {
164
+ if (err.code && validCodes.includes(err.code)) {
165
+ return err.code;
166
+ }
167
+ if (err.message) {
168
+ const messageUpper = err.message.toUpperCase().trim();
169
+ if (validCodes.includes(messageUpper)) {
170
+ return messageUpper;
171
+ }
172
+ }
173
+ return "";
174
+ }
175
+ function sanitizeErrorMessage(message) {
176
+ const lowerMessage = message.toLowerCase();
177
+ 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");
178
+ if (isDatabaseError) {
179
+ return "An error occurred while processing your request";
180
+ }
181
+ return message;
182
+ }
183
+ function handleAuthError(err, setError, t) {
184
+ const errorCode = extractErrorCode(err);
185
+ if (errorCode && AUTH_ERROR_MAPPING[errorCode]) {
186
+ const mapping = AUTH_ERROR_MAPPING[errorCode];
187
+ setError({
188
+ title: mapping.title,
189
+ description: mapping.description
190
+ });
191
+ return;
192
+ }
193
+ const sanitizedMessage = sanitizeErrorMessage(
194
+ err.message || t("errors.fallback")
195
+ );
196
+ setError({
197
+ title: t("errors.fallback"),
198
+ description: sanitizedMessage
199
+ });
200
+ }
201
+ function handleGenericError(err, setError, t) {
202
+ const rawMessage = err instanceof Error ? err.message : t("errors.fallback");
203
+ const sanitizedMessage = sanitizeErrorMessage(rawMessage);
204
+ setError({
205
+ title: "Error",
206
+ description: sanitizedMessage
207
+ });
208
+ }
209
+ var handleError = (err, setError, t) => {
210
+ if (isAuthError(err)) {
211
+ handleAuthError(err, setError, t);
212
+ } else {
213
+ handleGenericError(err, setError, t);
214
+ }
215
+ };
216
+
217
+ // src/components/auth/auth-layout.tsx
218
+ import { jsx as jsx3, jsxs } from "react/jsx-runtime";
219
+ var AuthLayout = ({
220
+ title,
221
+ description,
222
+ children,
223
+ footer,
224
+ logoImage
225
+ }) => {
226
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
227
+ /* @__PURE__ */ jsx3("div", { className: "flex size-8 mb-6 w-full items-center justify-center rounded-md", children: /* @__PURE__ */ jsx3(
228
+ "img",
229
+ {
230
+ src: logoImage || "",
231
+ alt: title,
232
+ width: 42,
233
+ height: 42
234
+ }
235
+ ) }),
236
+ /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
237
+ /* @__PURE__ */ jsx3("h1", { className: "text-2xl font-bold tracking-tight", children: title }),
238
+ description && /* @__PURE__ */ jsx3("p", { className: "mt-2 text-sm text-muted-foreground", children: description })
239
+ ] }),
240
+ children,
241
+ 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 }) })
242
+ ] });
243
+ };
244
+
245
+ // src/components/auth/forgot-password.tsx
246
+ import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
247
+
248
+ // src/components/auth/reset-password-form.tsx
249
+ import { zodResolver as zodResolver2 } from "@hookform/resolvers/zod";
250
+ import {
251
+ Alert as Alert2,
252
+ AlertDescription as AlertDescription2,
253
+ AlertTitle as AlertTitle2,
254
+ Button as Button2,
255
+ Form as Form2,
256
+ FormControl as FormControl2,
257
+ FormField as FormField2,
258
+ FormItem as FormItem2,
259
+ FormLabel as FormLabel2,
260
+ FormMessage as FormMessage2,
261
+ Input as Input2,
262
+ InputOTP,
263
+ InputOTPGroup,
264
+ InputOTPSlot,
265
+ useFormField
266
+ } from "@mesob/ui/components";
267
+ import { useMesob as useMesob3 } from "@mesob/ui/providers";
268
+ import { IconAlertCircle as IconAlertCircle2, IconEye, IconEyeOff } from "@tabler/icons-react";
269
+ import { useEffect as useEffect2, useState as useState3 } from "react";
270
+ import { useForm as useForm2 } from "react-hook-form";
271
+ import { toast as toast2 } from "sonner";
272
+ import { z as z2 } from "zod";
273
+ import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
274
+
275
+ // src/components/auth/set-password.tsx
276
+ import { zodResolver as zodResolver3 } from "@hookform/resolvers/zod";
277
+ import {
278
+ Alert as Alert3,
279
+ AlertDescription as AlertDescription3,
280
+ AlertTitle as AlertTitle3,
281
+ Button as Button3,
282
+ Form as Form3,
283
+ FormControl as FormControl3,
284
+ FormField as FormField3,
285
+ FormItem as FormItem3,
286
+ FormLabel as FormLabel3,
287
+ FormMessage as FormMessage3,
288
+ Input as Input3,
289
+ useFormField as useFormField2
290
+ } from "@mesob/ui/components";
291
+ import { useMesob as useMesob4 } from "@mesob/ui/providers";
292
+ import { IconAlertCircle as IconAlertCircle3, IconEye as IconEye2, IconEyeOff as IconEyeOff2 } from "@tabler/icons-react";
293
+ import { useEffect as useEffect3, useEffectEvent, useState as useState4 } from "react";
294
+ import { useForm as useForm3 } from "react-hook-form";
295
+ import { toast as toast3 } from "sonner";
296
+ import { z as z3 } from "zod";
297
+
298
+ // src/utils/normalize-phone.ts
299
+ function normalizePhone(phone) {
300
+ const cleaned = phone.trim().replace(/\s/g, "");
301
+ if (cleaned.startsWith("+2519") || cleaned.startsWith("+2517")) {
302
+ return cleaned;
303
+ }
304
+ if (cleaned.startsWith("2519") || cleaned.startsWith("2517")) {
305
+ return `+${cleaned}`;
306
+ }
307
+ if (cleaned.startsWith("09") || cleaned.startsWith("07")) {
308
+ return `+251${cleaned.slice(1)}`;
309
+ }
310
+ if ((cleaned.startsWith("9") || cleaned.startsWith("7")) && cleaned.length === 9) {
311
+ return `+251${cleaned}`;
312
+ }
313
+ return cleaned;
314
+ }
315
+
316
+ // src/components/auth/set-password.tsx
317
+ import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
318
+
319
+ // src/components/auth/sign-in.tsx
320
+ import { zodResolver as zodResolver4 } from "@hookform/resolvers/zod";
321
+ import {
322
+ Alert as Alert4,
323
+ AlertDescription as AlertDescription4,
324
+ AlertTitle as AlertTitle4,
325
+ Button as Button4,
326
+ Form as Form4,
327
+ FormControl as FormControl4,
328
+ FormField as FormField4,
329
+ FormItem as FormItem4,
330
+ FormLabel as FormLabel4,
331
+ FormMessage as FormMessage4,
332
+ Input as Input4,
333
+ useFormField as useFormField3
334
+ } from "@mesob/ui/components";
335
+ import { useMesob as useMesob5 } from "@mesob/ui/providers";
336
+ import { IconAlertCircle as IconAlertCircle4, IconEye as IconEye3, IconEyeOff as IconEyeOff3 } from "@tabler/icons-react";
337
+ import { useEffect as useEffect4, useState as useState5 } from "react";
338
+ import { useForm as useForm4 } from "react-hook-form";
339
+ import { toast as toast4 } from "sonner";
340
+ import { z as z4 } from "zod";
341
+ import { Fragment, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
342
+ var isPhone = (s) => /^\+?[0-9()[\]\s-]{6,}$/.test(s);
343
+ function PasswordInput({ field, show, onToggle }) {
344
+ const { formItemId, error } = useFormField3();
345
+ return /* @__PURE__ */ jsxs5("div", { className: "relative", children: [
346
+ /* @__PURE__ */ jsx7(
347
+ Input4,
348
+ {
349
+ ...field,
350
+ id: formItemId,
351
+ type: show ? "text" : "password",
352
+ autoComplete: "current-password",
353
+ "aria-invalid": !!error,
354
+ className: "pr-10"
355
+ }
356
+ ),
357
+ /* @__PURE__ */ jsx7(
358
+ Button4,
359
+ {
360
+ type: "button",
361
+ variant: "ghost",
362
+ size: "icon",
363
+ className: "absolute right-0 top-0 h-full px-3 text-muted-foreground hover:text-foreground",
364
+ onClick: onToggle,
365
+ "aria-label": show ? "Hide password" : "Show password",
366
+ children: show ? /* @__PURE__ */ jsx7(IconEyeOff3, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx7(IconEye3, { className: "h-4 w-4" })
367
+ }
368
+ )
369
+ ] });
370
+ }
371
+ var signInSchema = (t, phoneRegex) => z4.object({
372
+ username: z4.string().trim().min(1, { message: t("errors.requiredField") }).refine(
373
+ (val) => {
374
+ const isEmail = z4.email().safeParse(val).success;
375
+ const isPhone2 = phoneRegex.test(val);
376
+ return isEmail || isPhone2;
377
+ },
378
+ { message: t("errors.invalidEmailOrPhone") }
379
+ ),
380
+ password: z4.union([
381
+ z4.literal(""),
382
+ z4.string().min(8, t("errors.passwordLength")).max(128, t("errors.longPasswordError"))
383
+ ]).optional()
384
+ });
385
+ var SignIn = ({ redirectUrl } = {}) => {
386
+ const { hooks, setAuth } = useApi();
387
+ const { config } = useConfig();
388
+ const mesob = useMesob5();
389
+ const t = useTranslator("Auth.signIn");
390
+ const Link = mesob?.navigation?.Link;
391
+ const [isLoading, setIsLoading] = useState5(false);
392
+ const [error, setError] = useState5(null);
393
+ const [showPasswordField, setShowPasswordField] = useState5(false);
394
+ const [showPassword, setShowPassword] = useState5(false);
395
+ const [username, setUsername] = useState5("");
396
+ const [isChecking, setIsChecking] = useState5(false);
397
+ const checkUserMutation = hooks.useMutation("post", "/check-account");
398
+ const signInMutation = hooks.useMutation("post", "/sign-in");
399
+ const phoneRegex = typeof config.phoneRegex === "string" ? new RegExp(config.phoneRegex) : config.phoneRegex || /^(\+2519|\+2517|2519|2517|09|07)\d{8}$/;
400
+ const defaultRedirect = redirectUrl || config.navigation?.defaultRedirectUrl || "/dashboard";
401
+ const forgotPasswordLink = config.navigation?.links?.forgotPassword || "/auth/forgot-password";
402
+ const signUpLink = config.navigation?.links?.signUp || "/auth/sign-up";
403
+ const setPasswordLink = config.navigation?.links?.setPassword || "/auth/set-password";
404
+ const onNavigate = config.navigation?.onNavigate || ((path) => {
405
+ if (typeof window !== "undefined") {
406
+ window.location.href = path;
407
+ }
408
+ });
409
+ const logoImage = config.ui.logoImage;
410
+ const form = useForm4({
411
+ resolver: zodResolver4(signInSchema(t, phoneRegex)),
412
+ defaultValues: { username: "", password: "" },
413
+ mode: "onBlur"
414
+ });
415
+ useEffect4(() => {
416
+ if (error) {
417
+ toast4.error(error.title || "Error", {
418
+ description: error.description
419
+ });
420
+ }
421
+ }, [error]);
422
+ const handleCheckAccount = async (usernameValue) => {
423
+ setIsChecking(true);
424
+ try {
425
+ const normalizedUsername = phoneRegex.test(usernameValue) ? normalizePhone(usernameValue) : usernameValue;
426
+ const result = await checkUserMutation.mutateAsync({
427
+ body: {
428
+ username: normalizedUsername
429
+ }
430
+ });
431
+ if (result.exists) {
432
+ if (result.requiresPasswordSetup) {
433
+ const redirectParam = defaultRedirect ? `&redirect=${encodeURIComponent(defaultRedirect)}` : "";
434
+ onNavigate(
435
+ `${setPasswordLink}?identifier=${encodeURIComponent(normalizedUsername)}${redirectParam}`
436
+ );
437
+ return;
438
+ }
439
+ setUsername(normalizedUsername);
440
+ form.setValue("username", normalizedUsername);
441
+ setShowPasswordField(true);
442
+ } else {
443
+ const email = isPhone(normalizedUsername) ? "" : normalizedUsername;
444
+ const redirectParam = defaultRedirect ? `&redirect=${encodeURIComponent(defaultRedirect)}` : "";
445
+ if (email) {
446
+ onNavigate(
447
+ `${signUpLink}?email=${encodeURIComponent(email)}${redirectParam}`
448
+ );
449
+ } else {
450
+ onNavigate(
451
+ `${signUpLink}?phone=${encodeURIComponent(normalizedUsername)}${redirectParam}`
452
+ );
453
+ }
454
+ }
455
+ } catch {
456
+ form.setError("username", { message: t("errors.checkAccountFailed") });
457
+ } finally {
458
+ setIsChecking(false);
459
+ }
460
+ };
461
+ const onSubmit = async (values) => {
462
+ if (showPasswordField) {
463
+ const pwd = values.password;
464
+ if (!pwd || pwd.length < 8) {
465
+ form.setError("password", { message: t("errors.passwordLength") });
466
+ return;
467
+ }
468
+ await handlePasswordSubmit({ password: pwd });
469
+ } else {
470
+ await handleCheckAccount(values.username);
471
+ }
472
+ };
473
+ const handlePasswordSubmit = async (values) => {
474
+ setIsLoading(true);
475
+ setError(null);
476
+ try {
477
+ const res = await signInMutation.mutateAsync({
478
+ body: {
479
+ identifier: username,
480
+ password: values.password
481
+ }
482
+ });
483
+ if ("verificationId" in res && res.verificationId) {
484
+ const redirectParam = defaultRedirect ? `&redirect=${encodeURIComponent(defaultRedirect)}` : "";
485
+ const verifyPath = isPhone(username) ? `/auth/verify-phone?context=sign-in&verificationId=${res.verificationId}&identifier=${encodeURIComponent(username)}${redirectParam}` : `/auth/verify-email?verificationId=${res.verificationId}${redirectParam}`;
486
+ onNavigate(verifyPath);
487
+ return;
488
+ }
489
+ if ("user" in res && "session" in res) {
490
+ setAuth(res);
491
+ }
492
+ onNavigate(defaultRedirect);
493
+ } catch (err) {
494
+ const authError = err;
495
+ const errorCode = authError.code || authError.message;
496
+ if (errorCode === "HAS_NO_PASSWORD") {
497
+ const redirectParam = defaultRedirect ? `&redirect=${encodeURIComponent(defaultRedirect)}` : "";
498
+ onNavigate(
499
+ `${setPasswordLink}?identifier=${encodeURIComponent(username)}${redirectParam}`
500
+ );
501
+ return;
502
+ }
503
+ handleError(err, setError, t);
504
+ } finally {
505
+ setIsLoading(false);
506
+ }
507
+ };
508
+ const handleBack = () => {
509
+ setShowPasswordField(false);
510
+ setUsername("");
511
+ form.setValue("password", "");
512
+ };
513
+ const isSubmitting = isLoading || checkUserMutation.isPending || signInMutation.isPending || isChecking;
514
+ let submitLabel = t("form.continue");
515
+ if (isSubmitting) {
516
+ submitLabel = showPasswordField ? t("form.submitting") : t("form.checking");
517
+ } else if (showPasswordField) {
518
+ submitLabel = t("form.submit");
519
+ }
520
+ let errorContent = null;
521
+ if (error) {
522
+ if (typeof error === "string") {
523
+ errorContent = { title: "Error", description: error };
524
+ } else {
525
+ errorContent = error;
526
+ }
527
+ }
528
+ const formContent = /* @__PURE__ */ jsx7(Form4, { ...form, children: /* @__PURE__ */ jsxs5(
529
+ "form",
530
+ {
531
+ id: "sign-in-form",
532
+ onSubmit: form.handleSubmit(onSubmit),
533
+ className: "space-y-4",
534
+ children: [
535
+ showPasswordField ? /* @__PURE__ */ jsxs5(Fragment, { children: [
536
+ /* @__PURE__ */ jsxs5(FormItem4, { children: [
537
+ /* @__PURE__ */ jsxs5(FormLabel4, { className: "flex justify-between items-center", children: [
538
+ t("form.accountLabel"),
539
+ /* @__PURE__ */ jsx7(
540
+ Button4,
541
+ {
542
+ type: "button",
543
+ variant: "link",
544
+ size: "sm",
545
+ className: "p-0 m-0 h-auto",
546
+ onClick: handleBack,
547
+ children: t("changeAccount")
548
+ }
549
+ )
550
+ ] }),
551
+ /* @__PURE__ */ jsx7(
552
+ Input4,
553
+ {
554
+ id: "sign-in-username",
555
+ type: "text",
556
+ value: username,
557
+ autoComplete: "username",
558
+ disabled: true
559
+ }
560
+ )
561
+ ] }),
562
+ /* @__PURE__ */ jsx7(
563
+ FormField4,
564
+ {
565
+ control: form.control,
566
+ name: "password",
567
+ render: ({ field }) => /* @__PURE__ */ jsxs5(FormItem4, { children: [
568
+ /* @__PURE__ */ jsx7(FormLabel4, { children: t("form.passwordLabel") }),
569
+ /* @__PURE__ */ jsx7(
570
+ PasswordInput,
571
+ {
572
+ field: { ...field, value: field.value ?? "" },
573
+ show: showPassword,
574
+ onToggle: () => setShowPassword(!showPassword)
575
+ }
576
+ ),
577
+ /* @__PURE__ */ jsx7(FormMessage4, {})
578
+ ] })
579
+ }
580
+ )
581
+ ] }) : /* @__PURE__ */ jsx7(
582
+ FormField4,
583
+ {
584
+ control: form.control,
585
+ name: "username",
586
+ render: ({ field }) => /* @__PURE__ */ jsxs5(FormItem4, { children: [
587
+ /* @__PURE__ */ jsx7(FormLabel4, { children: t("form.accountLabel") }),
588
+ /* @__PURE__ */ jsx7(FormControl4, { children: /* @__PURE__ */ jsx7(Input4, { ...field, type: "text", autoComplete: "username" }) }),
589
+ /* @__PURE__ */ jsx7(FormMessage4, {})
590
+ ] })
591
+ }
592
+ ),
593
+ /* @__PURE__ */ jsx7(
594
+ Button4,
595
+ {
596
+ type: "submit",
597
+ className: "w-full",
598
+ disabled: isSubmitting,
599
+ loading: isSubmitting,
600
+ children: submitLabel
601
+ }
602
+ )
603
+ ]
604
+ }
605
+ ) });
606
+ return /* @__PURE__ */ jsx7("div", { className: "space-y-4", children: /* @__PURE__ */ jsxs5(
607
+ AuthLayout,
608
+ {
609
+ title: config.ui.name,
610
+ description: t("description"),
611
+ logoImage,
612
+ footer: showPasswordField ? /* @__PURE__ */ jsx7("div", { className: "flex items-center justify-center w-full", children: Link ? /* @__PURE__ */ jsx7(
613
+ Link,
614
+ {
615
+ href: forgotPasswordLink,
616
+ className: "text-primary inline-block hover:underline",
617
+ children: t("footer.forgotPassword")
618
+ }
619
+ ) : /* @__PURE__ */ jsx7(
620
+ "a",
621
+ {
622
+ href: forgotPasswordLink,
623
+ onClick: (e) => {
624
+ e.preventDefault();
625
+ onNavigate(forgotPasswordLink);
626
+ },
627
+ className: "text-primary inline-block hover:underline",
628
+ children: t("footer.forgotPassword")
629
+ }
630
+ ) }) : void 0,
631
+ children: [
632
+ formContent,
633
+ errorContent && /* @__PURE__ */ jsxs5(Alert4, { variant: "destructive", className: "mt-4", children: [
634
+ /* @__PURE__ */ jsx7(IconAlertCircle4, { className: "h-4 w-4" }),
635
+ /* @__PURE__ */ jsx7(AlertTitle4, { children: errorContent.title }),
636
+ /* @__PURE__ */ jsx7(AlertDescription4, { children: errorContent.description })
637
+ ] })
638
+ ]
639
+ }
640
+ ) });
641
+ };
642
+
643
+ // src/components/auth/sign-up.tsx
644
+ import { zodResolver as zodResolver5 } from "@hookform/resolvers/zod";
645
+ import {
646
+ Alert as Alert5,
647
+ AlertDescription as AlertDescription5,
648
+ AlertTitle as AlertTitle5,
649
+ Button as Button5,
650
+ Form as Form5,
651
+ FormControl as FormControl5,
652
+ FormField as FormField5,
653
+ FormItem as FormItem5,
654
+ FormLabel as FormLabel5,
655
+ FormMessage as FormMessage5,
656
+ Input as Input5,
657
+ useFormField as useFormField4
658
+ } from "@mesob/ui/components";
659
+ import { useMesob as useMesob6 } from "@mesob/ui/providers";
660
+ import { IconAlertCircle as IconAlertCircle5, IconEye as IconEye4, IconEyeOff as IconEyeOff4 } from "@tabler/icons-react";
661
+ import { useEffect as useEffect5, useState as useState6 } from "react";
662
+ import { useForm as useForm5 } from "react-hook-form";
663
+ import { toast as toast5 } from "sonner";
664
+ import { z as z5 } from "zod";
665
+ import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
666
+
667
+ // src/components/auth/verification-form.tsx
668
+ import { zodResolver as zodResolver6 } from "@hookform/resolvers/zod";
669
+ import {
670
+ Button as Button6,
671
+ Form as Form6,
672
+ FormControl as FormControl6,
673
+ FormField as FormField6,
674
+ FormItem as FormItem6,
675
+ FormLabel as FormLabel6,
676
+ FormMessage as FormMessage6,
677
+ InputOTP as InputOTP2,
678
+ InputOTPGroup as InputOTPGroup2,
679
+ InputOTPSlot as InputOTPSlot2
680
+ } from "@mesob/ui/components";
681
+ import { useForm as useForm6 } from "react-hook-form";
682
+ import { z as z6 } from "zod";
683
+
684
+ // src/components/auth/countdown.tsx
685
+ import { Spinner } from "@mesob/ui/components";
686
+ import { useEffect as useEffect6, useState as useState7 } from "react";
687
+ import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
688
+
689
+ // src/components/auth/verification-form.tsx
690
+ import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
691
+
692
+ // src/components/auth/verify-email.tsx
693
+ import { Alert as Alert6, AlertDescription as AlertDescription6, AlertTitle as AlertTitle6 } from "@mesob/ui/components";
694
+ import { useMesob as useMesob7 } from "@mesob/ui/providers";
695
+ import { IconAlertCircle as IconAlertCircle6 } from "@tabler/icons-react";
696
+ import { useEffect as useEffect7, useState as useState8 } from "react";
697
+ import { toast as toast6 } from "sonner";
698
+ import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
699
+
700
+ // src/components/auth/verify-phone.tsx
701
+ import { Alert as Alert7, AlertDescription as AlertDescription7, AlertTitle as AlertTitle7 } from "@mesob/ui/components";
702
+ import { useMesob as useMesob8 } from "@mesob/ui/providers";
703
+ import { IconAlertCircle as IconAlertCircle7 } from "@tabler/icons-react";
704
+ import { useEffect as useEffect8, useState as useState9 } from "react";
705
+ import { toast as toast7 } from "sonner";
706
+ import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
707
+
708
+ // src/components/authorization/deny.tsx
709
+ import { deny as canDeny } from "@mesob/common";
710
+ import { Fragment as Fragment2, jsx as jsx13 } from "react/jsx-runtime";
711
+
712
+ // src/components/authorization/grant.tsx
713
+ import { grant as canGrant } from "@mesob/common";
714
+ import { Fragment as Fragment3, jsx as jsx14 } from "react/jsx-runtime";
715
+
716
+ // src/components/error-boundary.tsx
717
+ import { Button as Button7 } from "@mesob/ui/components";
718
+ import { Component } from "react";
719
+ import { jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
720
+
721
+ // src/components/iam/permission-selector.tsx
722
+ import {
723
+ Badge,
724
+ EntitySelector,
725
+ useEntitySectionState
726
+ } from "@mesob/ui/components";
727
+ import { IconKey } from "@tabler/icons-react";
728
+ import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
729
+
730
+ // src/components/iam/permissions.tsx
731
+ import { Badge as Badge2, Button as Button8 } from "@mesob/ui/components";
732
+ import { useState as useState10 } from "react";
733
+
734
+ // src/components/shared/data-table.tsx
735
+ import {
736
+ Table,
737
+ TableBody,
738
+ TableCell,
739
+ TableHead,
740
+ TableHeader,
741
+ TableRow
742
+ } from "@mesob/ui/components";
743
+
744
+ // src/components/skeletons/table-skeleton.tsx
745
+ import { Skeleton } from "@mesob/ui/components";
746
+ import { jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
747
+
748
+ // src/components/shared/data-table.tsx
749
+ import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
750
+
751
+ // src/components/iam/permissions.tsx
752
+ import { jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
753
+
754
+ // src/components/iam/role-detail-layout.tsx
755
+ import {
756
+ EntityDetailHeader,
757
+ EntityEmptyState,
758
+ PageContainer,
759
+ useBreadcrumbs
760
+ } from "@mesob/ui/components";
761
+ import { IconShield } from "@tabler/icons-react";
762
+ import { useMemo as useMemo2 } from "react";
763
+ import { jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
764
+
765
+ // src/components/iam/role-detail-page.tsx
766
+ import { zodResolver as zodResolver7 } from "@hookform/resolvers/zod";
767
+ import {
768
+ EntityFormActions,
769
+ Form as Form7,
770
+ FormControl as FormControl7,
771
+ FormField as FormField7,
772
+ FormItem as FormItem7,
773
+ FormLabel as FormLabel7,
774
+ FormMessage as FormMessage7,
775
+ Input as Input6,
776
+ LocaleInputText,
777
+ LocaleInputTextarea,
778
+ Section,
779
+ Skeleton as Skeleton2
780
+ } from "@mesob/ui/components";
781
+ import { useLocaleSchemas } from "@mesob/ui/providers";
782
+ import { useQueryClient } from "@tanstack/react-query";
783
+ import { useEffect as useEffect9, useMemo as useMemo3 } from "react";
784
+ import { useForm as useForm7 } from "react-hook-form";
785
+ import { toast as toast8 } from "sonner";
786
+ import { z as z7 } from "zod";
787
+ import { jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
788
+
789
+ // src/components/iam/role-permissions-page.tsx
790
+ import {
791
+ Badge as Badge3,
792
+ Button as Button9,
793
+ DataTablePagination,
794
+ DeleteConfirmButton,
795
+ DisplayTable,
796
+ EntityEmptyState as EntityEmptyState2,
797
+ EntityFilter,
798
+ EntityHeader,
799
+ EntityLoadingState,
800
+ EntitySearch,
801
+ EntitySort,
802
+ EntityViewToggle,
803
+ PageBody,
804
+ Tbody,
805
+ Td,
806
+ Th,
807
+ Thead,
808
+ Tr,
809
+ useEntityPagination,
810
+ useEntityParams
811
+ } from "@mesob/ui/components";
812
+ import { IconKey as IconKey2, IconPlus, IconTrash } from "@tabler/icons-react";
813
+ import { useQueryClient as useQueryClient2 } from "@tanstack/react-query";
814
+ import { useMemo as useMemo4 } from "react";
815
+ import { toast as toast9 } from "sonner";
816
+ import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
817
+
818
+ // src/components/iam/roles.tsx
819
+ import { Badge as Badge4, Button as Button10 } from "@mesob/ui/components";
820
+ import { useLocale } from "next-intl";
821
+ import { useState as useState11 } from "react";
822
+ import { jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
823
+
824
+ // src/components/iam/sessions.tsx
825
+ import { Button as Button11 } from "@mesob/ui/components";
826
+ import { useState as useState12 } from "react";
827
+ import { jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
828
+
829
+ // src/components/iam/tenants.tsx
830
+ import { Badge as Badge5, Button as Button12 } from "@mesob/ui/components";
831
+ import { useState as useState13 } from "react";
832
+ import { jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
833
+
834
+ // src/components/iam/users.tsx
835
+ import { Badge as Badge6, Button as Button13 } from "@mesob/ui/components";
836
+ import { useState as useState14 } from "react";
837
+ import { jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
838
+
839
+ // src/components/profile/account.tsx
840
+ import { Badge as Badge8, Card as Card2, CardContent, Separator } from "@mesob/ui/components";
841
+
842
+ // src/components/profile/change-profile.tsx
843
+ import {
844
+ Avatar,
845
+ AvatarFallback,
846
+ AvatarImage,
847
+ Badge as Badge7,
848
+ Button as Button14
849
+ } from "@mesob/ui/components";
850
+ import { useState as useState15 } from "react";
851
+ import { jsx as jsx27, jsxs as jsxs23 } from "react/jsx-runtime";
852
+
853
+ // src/components/profile/account.tsx
854
+ import { jsx as jsx28, jsxs as jsxs24 } from "react/jsx-runtime";
855
+
856
+ // src/components/profile/security.tsx
857
+ import { Badge as Badge9, Card as Card3, CardContent as CardContent2, Separator as Separator2 } from "@mesob/ui/components";
858
+
859
+ // src/components/profile/change-email-form.tsx
860
+ import {
861
+ Button as Button16,
862
+ Collapsible,
863
+ CollapsibleContent,
864
+ CollapsibleTrigger
865
+ } from "@mesob/ui/components";
866
+ import { IconChevronDown } from "@tabler/icons-react";
867
+ import { useState as useState18 } from "react";
868
+
869
+ // src/components/profile/request-change-email-form.tsx
870
+ import { zodResolver as zodResolver8 } from "@hookform/resolvers/zod";
871
+ import { Button as Button15, Input as Input7, Label, Spinner as Spinner2 } from "@mesob/ui/components";
872
+ import { IconEye as IconEye5, IconEyeOff as IconEyeOff5 } from "@tabler/icons-react";
873
+ import { useEffect as useEffect10, useState as useState16 } from "react";
874
+ import { useForm as useForm8 } from "react-hook-form";
875
+ import { toast as toast10 } from "sonner";
876
+ import { z as z8 } from "zod";
877
+ import { jsx as jsx29, jsxs as jsxs25 } from "react/jsx-runtime";
878
+ var emailPasswordSchema = z8.object({
879
+ email: z8.string().email("Invalid email address"),
880
+ password: z8.string().min(8, "Password must be at least 8 characters").max(128, "Password too long")
881
+ });
882
+
883
+ // src/components/profile/verify-change-email-form.tsx
884
+ import { useState as useState17 } from "react";
885
+ import { toast as toast11 } from "sonner";
886
+
887
+ // src/components/profile/otp-verification-modal.tsx
888
+ import {
889
+ Dialog,
890
+ DialogContent,
891
+ DialogDescription,
892
+ DialogHeader,
893
+ DialogTitle
894
+ } from "@mesob/ui/components";
895
+ import { jsx as jsx30, jsxs as jsxs26 } from "react/jsx-runtime";
896
+
897
+ // src/components/profile/verify-change-email-form.tsx
898
+ import { jsx as jsx31 } from "react/jsx-runtime";
899
+
900
+ // src/components/profile/change-email-form.tsx
901
+ import { jsx as jsx32, jsxs as jsxs27 } from "react/jsx-runtime";
902
+
903
+ // src/components/profile/change-password-form.tsx
904
+ import { zodResolver as zodResolver9 } from "@hookform/resolvers/zod";
905
+ import {
906
+ Button as Button17,
907
+ Collapsible as Collapsible2,
908
+ CollapsibleContent as CollapsibleContent2,
909
+ CollapsibleTrigger as CollapsibleTrigger2,
910
+ Input as Input8,
911
+ Label as Label2,
912
+ Spinner as Spinner3
913
+ } from "@mesob/ui/components";
914
+ import { IconChevronDown as IconChevronDown2, IconEye as IconEye6, IconEyeOff as IconEyeOff6 } from "@tabler/icons-react";
915
+ import { useState as useState19 } from "react";
916
+ import { useForm as useForm9 } from "react-hook-form";
917
+ import { toast as toast12 } from "sonner";
918
+ import { z as z9 } from "zod";
919
+ import { jsx as jsx33, jsxs as jsxs28 } from "react/jsx-runtime";
920
+ var changePasswordSchema = z9.object({
921
+ currentPassword: z9.string().min(8, "Password must be at least 8 characters"),
922
+ newPassword: z9.string().min(8, "Password must be at least 8 characters"),
923
+ confirmPassword: z9.string().min(8, "Password must be at least 8 characters")
924
+ }).refine((data) => data.newPassword === data.confirmPassword, {
925
+ message: "Passwords don't match",
926
+ path: ["confirmPassword"]
927
+ });
928
+
929
+ // src/components/profile/change-phone-form.tsx
930
+ import {
931
+ Button as Button19,
932
+ Collapsible as Collapsible3,
933
+ CollapsibleContent as CollapsibleContent3,
934
+ CollapsibleTrigger as CollapsibleTrigger3
935
+ } from "@mesob/ui/components";
936
+ import { IconChevronDown as IconChevronDown3 } from "@tabler/icons-react";
937
+ import { useState as useState22 } from "react";
938
+
939
+ // src/components/profile/request-change-phone-form.tsx
940
+ import { zodResolver as zodResolver10 } from "@hookform/resolvers/zod";
941
+ import { Button as Button18, Input as Input9, Label as Label3, Spinner as Spinner4 } from "@mesob/ui/components";
942
+ import { IconEye as IconEye7, IconEyeOff as IconEyeOff7 } from "@tabler/icons-react";
943
+ import { useEffect as useEffect11, useState as useState20 } from "react";
944
+ import { useForm as useForm10 } from "react-hook-form";
945
+ import { toast as toast13 } from "sonner";
946
+ import { z as z10 } from "zod";
947
+ import { jsx as jsx34, jsxs as jsxs29 } from "react/jsx-runtime";
948
+
949
+ // src/components/profile/verify-change-phone-form.tsx
950
+ import { useState as useState21 } from "react";
951
+ import { toast as toast14 } from "sonner";
952
+ import { jsx as jsx35 } from "react/jsx-runtime";
953
+
954
+ // src/components/profile/change-phone-form.tsx
955
+ import { jsx as jsx36, jsxs as jsxs30 } from "react/jsx-runtime";
956
+
957
+ // src/components/profile/security.tsx
958
+ import { jsx as jsx37, jsxs as jsxs31 } from "react/jsx-runtime";
959
+
960
+ // src/components/skeletons/auth-form-skeleton.tsx
961
+ import { Skeleton as Skeleton3 } from "@mesob/ui/components";
962
+ import { jsx as jsx38, jsxs as jsxs32 } from "react/jsx-runtime";
963
+
964
+ // src/components/skeletons/profile-skeleton.tsx
965
+ import { Skeleton as Skeleton4 } from "@mesob/ui/components";
966
+ import { jsx as jsx39, jsxs as jsxs33 } from "react/jsx-runtime";
967
+
968
+ // src/pages/auth/sign-in.tsx
969
+ import { jsx as jsx40 } from "react/jsx-runtime";
970
+ var metadata = {
971
+ title: "Sign in",
972
+ description: "Sign in to your account."
973
+ };
974
+ async function SignInPage({ searchParams }) {
975
+ const params = searchParams ? await searchParams : {};
976
+ const redirectParam = params.redirect;
977
+ const redirectUrl = typeof redirectParam === "string" ? redirectParam : void 0;
978
+ return /* @__PURE__ */ jsx40(SignIn, { redirectUrl });
979
+ }
980
+ export {
981
+ SignInPage as default,
982
+ metadata
983
+ };
984
+ //# sourceMappingURL=sign-in.js.map