@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
package/dist/index.js CHANGED
@@ -366,7 +366,11 @@ var AUTH_ERROR_MAPPING = {
366
366
  },
367
367
  HAS_NO_PASSWORD: {
368
368
  title: "No Password Set",
369
- description: "Your account does not have a password set (e.g. social login). Please sign in with your provider or reset your password."
369
+ description: "Your account does not have a password yet. Continue to set a password before signing in."
370
+ },
371
+ PASSWORD_ALREADY_SET: {
372
+ title: "Password Already Set",
373
+ description: "This account already has a password. Use the normal sign-in form instead."
370
374
  }
371
375
  };
372
376
  var validCodes = Object.keys(AUTH_ERROR_MAPPING);
@@ -851,7 +855,7 @@ var ResetPasswordForm = ({
851
855
  );
852
856
  };
853
857
 
854
- // src/components/auth/sign-in.tsx
858
+ // src/components/auth/set-password.tsx
855
859
  import { zodResolver as zodResolver3 } from "@hookform/resolvers/zod";
856
860
  import {
857
861
  Alert as Alert3,
@@ -869,7 +873,7 @@ import {
869
873
  } from "@mesob/ui/components";
870
874
  import { useMesob as useMesob4 } from "@mesob/ui/providers";
871
875
  import { IconAlertCircle as IconAlertCircle3, IconEye as IconEye2, IconEyeOff as IconEyeOff2 } from "@tabler/icons-react";
872
- import { useEffect as useEffect3, useState as useState4 } from "react";
876
+ import { useEffect as useEffect3, useEffectEvent, useState as useState4 } from "react";
873
877
  import { useForm as useForm3 } from "react-hook-form";
874
878
  import { toast as toast3 } from "sonner";
875
879
  import { z as z3 } from "zod";
@@ -892,9 +896,8 @@ function normalizePhone(phone) {
892
896
  return cleaned;
893
897
  }
894
898
 
895
- // src/components/auth/sign-in.tsx
896
- import { Fragment, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
897
- var isPhone = (s) => /^\+?[0-9()[\]\s-]{6,}$/.test(s);
899
+ // src/components/auth/set-password.tsx
900
+ import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
898
901
  function PasswordInput2({ field, show, onToggle }) {
899
902
  const { formItemId, error } = useFormField2();
900
903
  return /* @__PURE__ */ jsxs4("div", { className: "relative", children: [
@@ -904,7 +907,6 @@ function PasswordInput2({ field, show, onToggle }) {
904
907
  ...field,
905
908
  id: formItemId,
906
909
  type: show ? "text" : "password",
907
- autoComplete: "current-password",
908
910
  "aria-invalid": !!error,
909
911
  className: "pr-10"
910
912
  }
@@ -923,52 +925,339 @@ function PasswordInput2({ field, show, onToggle }) {
923
925
  )
924
926
  ] });
925
927
  }
926
- var signInSchema = (t, phoneRegex) => z3.object({
927
- username: z3.string().trim().min(1, { message: t("errors.requiredField") }).refine(
928
+ var setPasswordSchema = (t) => z3.object({
929
+ password: z3.string().min(8, t("errors.passwordLength")).max(128, t("errors.longPasswordError")),
930
+ confirmPassword: z3.string()
931
+ }).refine((data) => data.password === data.confirmPassword, {
932
+ message: t("errors.passwordsMismatch"),
933
+ path: ["confirmPassword"]
934
+ });
935
+ var getPhoneRegex = (phoneRegex) => {
936
+ if (typeof phoneRegex === "string") {
937
+ return new RegExp(phoneRegex);
938
+ }
939
+ return phoneRegex || /^(\+2519|\+2517|2519|2517|09|07)\d{8}$/;
940
+ };
941
+ var normalizeIdentifier = (identifier, phoneRegex) => {
942
+ const resolvedPhoneRegex = getPhoneRegex(phoneRegex);
943
+ return resolvedPhoneRegex.test(identifier) ? normalizePhone(identifier) : identifier;
944
+ };
945
+ var SetPassword = function SetPassword2({
946
+ identifier,
947
+ redirectUrl
948
+ } = {}) {
949
+ const { hooks, setAuth } = useApi();
950
+ const { config } = useConfig();
951
+ const mesob = useMesob4();
952
+ const t = useTranslator("Auth.setPassword");
953
+ const Link = mesob?.navigation?.Link;
954
+ const [error, setError] = useState4(null);
955
+ const [isLoading, setIsLoading] = useState4(false);
956
+ const [isChecking, setIsChecking] = useState4(true);
957
+ const [showPassword, setShowPassword] = useState4(false);
958
+ const [showConfirmPassword, setShowConfirmPassword] = useState4(false);
959
+ const [account, setAccount] = useState4(null);
960
+ const checkAccountMutation = hooks.useMutation("post", "/check-account");
961
+ const setPasswordMutation = hooks.useMutation("post", "/password/set");
962
+ const onNavigate = config.navigation?.onNavigate || ((path) => {
963
+ if (typeof window !== "undefined") {
964
+ window.location.href = path;
965
+ }
966
+ });
967
+ const signInLink = config.navigation?.links?.signIn || "/auth/sign-in";
968
+ const logoImage = config.ui.logoImage;
969
+ const defaultRedirect = redirectUrl || config.navigation?.defaultRedirectUrl || "/";
970
+ const form = useForm3({
971
+ resolver: zodResolver3(setPasswordSchema(t)),
972
+ defaultValues: {
973
+ password: "",
974
+ confirmPassword: ""
975
+ }
976
+ });
977
+ useEffect3(() => {
978
+ if (error) {
979
+ toast3.error(error.title || "Error", {
980
+ description: error.description
981
+ });
982
+ }
983
+ }, [error]);
984
+ const loadAccount = useEffectEvent(async () => {
985
+ if (!identifier) {
986
+ setError({
987
+ title: t("errors.fallback"),
988
+ description: t("errors.missingIdentifier")
989
+ });
990
+ setIsChecking(false);
991
+ return;
992
+ }
993
+ try {
994
+ const normalizedIdentifier = normalizeIdentifier(
995
+ identifier,
996
+ config.phoneRegex
997
+ );
998
+ const res = await checkAccountMutation.mutateAsync({
999
+ body: { username: normalizedIdentifier }
1000
+ });
1001
+ if (!(res.exists && res.account && res.requiresPasswordSetup)) {
1002
+ setError({
1003
+ title: t("errors.fallback"),
1004
+ description: t("errors.accountNotEligible")
1005
+ });
1006
+ setIsChecking(false);
1007
+ return;
1008
+ }
1009
+ setAccount({
1010
+ fullName: res.account.fullName,
1011
+ email: res.account.email,
1012
+ phone: res.account.phone
1013
+ });
1014
+ } catch {
1015
+ setError({
1016
+ title: t("errors.fallback"),
1017
+ description: t("errors.accountLookupFailed")
1018
+ });
1019
+ } finally {
1020
+ setIsChecking(false);
1021
+ }
1022
+ });
1023
+ useEffect3(() => {
1024
+ loadAccount().catch(() => {
1025
+ setIsChecking(false);
1026
+ });
1027
+ }, [identifier]);
1028
+ const handleSubmit = form.handleSubmit(async (values) => {
1029
+ if (!identifier) {
1030
+ return;
1031
+ }
1032
+ setIsLoading(true);
1033
+ setError(null);
1034
+ try {
1035
+ const normalizedIdentifier = normalizeIdentifier(
1036
+ identifier,
1037
+ config.phoneRegex
1038
+ );
1039
+ const res = await setPasswordMutation.mutateAsync({
1040
+ body: {
1041
+ identifier: normalizedIdentifier,
1042
+ password: values.password
1043
+ }
1044
+ });
1045
+ if ("user" in res && "session" in res) {
1046
+ setAuth(res);
1047
+ }
1048
+ onNavigate(defaultRedirect);
1049
+ } catch (err) {
1050
+ handleError(err, setError, t);
1051
+ } finally {
1052
+ setIsLoading(false);
1053
+ }
1054
+ });
1055
+ const accountLabel = account?.email ? t("form.emailLabel") : t("form.phoneLabel");
1056
+ const accountValue = account?.email || account?.phone || identifier || "";
1057
+ let errorContent = null;
1058
+ if (error) {
1059
+ errorContent = typeof error === "string" ? { title: "Error", description: error } : error;
1060
+ }
1061
+ const showError = !isChecking && !!errorContent;
1062
+ const errorAlert = showError && errorContent && /* @__PURE__ */ jsxs4(Alert3, { variant: "destructive", className: "mt-4", children: [
1063
+ /* @__PURE__ */ jsx6(IconAlertCircle3, { className: "h-4 w-4" }),
1064
+ /* @__PURE__ */ jsx6(AlertTitle3, { children: errorContent.title }),
1065
+ /* @__PURE__ */ jsx6(AlertDescription3, { children: errorContent.description })
1066
+ ] });
1067
+ return /* @__PURE__ */ jsxs4(
1068
+ AuthLayout,
1069
+ {
1070
+ title: config.ui.name,
1071
+ description: t("description"),
1072
+ logoImage,
1073
+ footer: /* @__PURE__ */ jsxs4("p", { children: [
1074
+ t("footer.hasPassword"),
1075
+ " ",
1076
+ Link ? /* @__PURE__ */ jsx6(Link, { href: signInLink, className: "text-primary hover:underline", children: t("footer.signInCta") }) : /* @__PURE__ */ jsx6(
1077
+ "a",
1078
+ {
1079
+ href: signInLink,
1080
+ onClick: (e) => {
1081
+ e.preventDefault();
1082
+ onNavigate(signInLink);
1083
+ },
1084
+ className: "text-primary hover:underline",
1085
+ children: t("footer.signInCta")
1086
+ }
1087
+ )
1088
+ ] }),
1089
+ children: [
1090
+ /* @__PURE__ */ jsx6(Form3, { ...form, children: /* @__PURE__ */ jsxs4(
1091
+ "form",
1092
+ {
1093
+ id: "set-password-form",
1094
+ onSubmit: handleSubmit,
1095
+ className: "space-y-4",
1096
+ children: [
1097
+ /* @__PURE__ */ jsxs4(FormItem3, { children: [
1098
+ /* @__PURE__ */ jsx6(FormLabel3, { children: t("form.fullNameLabel") }),
1099
+ /* @__PURE__ */ jsx6(FormControl3, { children: /* @__PURE__ */ jsx6(Input3, { value: account?.fullName || "", disabled: true }) })
1100
+ ] }),
1101
+ /* @__PURE__ */ jsxs4(FormItem3, { children: [
1102
+ /* @__PURE__ */ jsx6(FormLabel3, { children: accountLabel }),
1103
+ /* @__PURE__ */ jsx6(FormControl3, { children: /* @__PURE__ */ jsx6(Input3, { value: accountValue, disabled: true }) })
1104
+ ] }),
1105
+ /* @__PURE__ */ jsx6(
1106
+ FormField3,
1107
+ {
1108
+ control: form.control,
1109
+ name: "password",
1110
+ render: ({ field }) => /* @__PURE__ */ jsxs4(FormItem3, { children: [
1111
+ /* @__PURE__ */ jsx6(FormLabel3, { children: t("form.passwordLabel") }),
1112
+ /* @__PURE__ */ jsx6(
1113
+ PasswordInput2,
1114
+ {
1115
+ field,
1116
+ show: showPassword,
1117
+ onToggle: () => setShowPassword(!showPassword)
1118
+ }
1119
+ ),
1120
+ /* @__PURE__ */ jsx6(FormMessage3, {})
1121
+ ] })
1122
+ }
1123
+ ),
1124
+ /* @__PURE__ */ jsx6(
1125
+ FormField3,
1126
+ {
1127
+ control: form.control,
1128
+ name: "confirmPassword",
1129
+ render: ({ field }) => /* @__PURE__ */ jsxs4(FormItem3, { children: [
1130
+ /* @__PURE__ */ jsx6(FormLabel3, { children: t("form.confirmPasswordLabel") }),
1131
+ /* @__PURE__ */ jsx6(
1132
+ PasswordInput2,
1133
+ {
1134
+ field,
1135
+ show: showConfirmPassword,
1136
+ onToggle: () => setShowConfirmPassword(!showConfirmPassword)
1137
+ }
1138
+ ),
1139
+ /* @__PURE__ */ jsx6(FormMessage3, {})
1140
+ ] })
1141
+ }
1142
+ ),
1143
+ /* @__PURE__ */ jsx6(
1144
+ Button3,
1145
+ {
1146
+ type: "submit",
1147
+ form: "set-password-form",
1148
+ className: "w-full",
1149
+ disabled: isChecking || !account || isLoading || setPasswordMutation.isPending,
1150
+ children: isLoading || setPasswordMutation.isPending ? t("form.submitting") : t("form.submit")
1151
+ }
1152
+ )
1153
+ ]
1154
+ }
1155
+ ) }),
1156
+ errorAlert
1157
+ ]
1158
+ }
1159
+ );
1160
+ };
1161
+
1162
+ // src/components/auth/sign-in.tsx
1163
+ import { zodResolver as zodResolver4 } from "@hookform/resolvers/zod";
1164
+ import {
1165
+ Alert as Alert4,
1166
+ AlertDescription as AlertDescription4,
1167
+ AlertTitle as AlertTitle4,
1168
+ Button as Button4,
1169
+ Form as Form4,
1170
+ FormControl as FormControl4,
1171
+ FormField as FormField4,
1172
+ FormItem as FormItem4,
1173
+ FormLabel as FormLabel4,
1174
+ FormMessage as FormMessage4,
1175
+ Input as Input4,
1176
+ useFormField as useFormField3
1177
+ } from "@mesob/ui/components";
1178
+ import { useMesob as useMesob5 } from "@mesob/ui/providers";
1179
+ import { IconAlertCircle as IconAlertCircle4, IconEye as IconEye3, IconEyeOff as IconEyeOff3 } from "@tabler/icons-react";
1180
+ import { useEffect as useEffect4, useState as useState5 } from "react";
1181
+ import { useForm as useForm4 } from "react-hook-form";
1182
+ import { toast as toast4 } from "sonner";
1183
+ import { z as z4 } from "zod";
1184
+ import { Fragment, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
1185
+ var isPhone = (s) => /^\+?[0-9()[\]\s-]{6,}$/.test(s);
1186
+ function PasswordInput3({ field, show, onToggle }) {
1187
+ const { formItemId, error } = useFormField3();
1188
+ return /* @__PURE__ */ jsxs5("div", { className: "relative", children: [
1189
+ /* @__PURE__ */ jsx7(
1190
+ Input4,
1191
+ {
1192
+ ...field,
1193
+ id: formItemId,
1194
+ type: show ? "text" : "password",
1195
+ autoComplete: "current-password",
1196
+ "aria-invalid": !!error,
1197
+ className: "pr-10"
1198
+ }
1199
+ ),
1200
+ /* @__PURE__ */ jsx7(
1201
+ Button4,
1202
+ {
1203
+ type: "button",
1204
+ variant: "ghost",
1205
+ size: "icon",
1206
+ className: "absolute right-0 top-0 h-full px-3 text-muted-foreground hover:text-foreground",
1207
+ onClick: onToggle,
1208
+ "aria-label": show ? "Hide password" : "Show password",
1209
+ children: show ? /* @__PURE__ */ jsx7(IconEyeOff3, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx7(IconEye3, { className: "h-4 w-4" })
1210
+ }
1211
+ )
1212
+ ] });
1213
+ }
1214
+ var signInSchema = (t, phoneRegex) => z4.object({
1215
+ username: z4.string().trim().min(1, { message: t("errors.requiredField") }).refine(
928
1216
  (val) => {
929
- const isEmail = z3.email().safeParse(val).success;
1217
+ const isEmail = z4.email().safeParse(val).success;
930
1218
  const isPhone3 = phoneRegex.test(val);
931
1219
  return isEmail || isPhone3;
932
1220
  },
933
1221
  { message: t("errors.invalidEmailOrPhone") }
934
1222
  ),
935
- password: z3.union([
936
- z3.literal(""),
937
- z3.string().min(8, t("errors.passwordLength")).max(128, t("errors.longPasswordError"))
1223
+ password: z4.union([
1224
+ z4.literal(""),
1225
+ z4.string().min(8, t("errors.passwordLength")).max(128, t("errors.longPasswordError"))
938
1226
  ]).optional()
939
1227
  });
940
1228
  var SignIn = ({ redirectUrl } = {}) => {
941
1229
  const { hooks, setAuth } = useApi();
942
1230
  const { config } = useConfig();
943
- const mesob = useMesob4();
1231
+ const mesob = useMesob5();
944
1232
  const t = useTranslator("Auth.signIn");
945
1233
  const Link = mesob?.navigation?.Link;
946
- const [isLoading, setIsLoading] = useState4(false);
947
- const [error, setError] = useState4(null);
948
- const [showPasswordField, setShowPasswordField] = useState4(false);
949
- const [showPassword, setShowPassword] = useState4(false);
950
- const [username, setUsername] = useState4("");
951
- const [isChecking, setIsChecking] = useState4(false);
1234
+ const [isLoading, setIsLoading] = useState5(false);
1235
+ const [error, setError] = useState5(null);
1236
+ const [showPasswordField, setShowPasswordField] = useState5(false);
1237
+ const [showPassword, setShowPassword] = useState5(false);
1238
+ const [username, setUsername] = useState5("");
1239
+ const [isChecking, setIsChecking] = useState5(false);
952
1240
  const checkUserMutation = hooks.useMutation("post", "/check-account");
953
1241
  const signInMutation = hooks.useMutation("post", "/sign-in");
954
1242
  const phoneRegex = typeof config.phoneRegex === "string" ? new RegExp(config.phoneRegex) : config.phoneRegex || /^(\+2519|\+2517|2519|2517|09|07)\d{8}$/;
955
1243
  const defaultRedirect = redirectUrl || config.navigation?.defaultRedirectUrl || "/dashboard";
956
1244
  const forgotPasswordLink = config.navigation?.links?.forgotPassword || "/auth/forgot-password";
957
1245
  const signUpLink = config.navigation?.links?.signUp || "/auth/sign-up";
1246
+ const setPasswordLink = config.navigation?.links?.setPassword || "/auth/set-password";
958
1247
  const onNavigate = config.navigation?.onNavigate || ((path) => {
959
1248
  if (typeof window !== "undefined") {
960
1249
  window.location.href = path;
961
1250
  }
962
1251
  });
963
1252
  const logoImage = config.ui.logoImage;
964
- const form = useForm3({
965
- resolver: zodResolver3(signInSchema(t, phoneRegex)),
1253
+ const form = useForm4({
1254
+ resolver: zodResolver4(signInSchema(t, phoneRegex)),
966
1255
  defaultValues: { username: "", password: "" },
967
1256
  mode: "onBlur"
968
1257
  });
969
- useEffect3(() => {
1258
+ useEffect4(() => {
970
1259
  if (error) {
971
- toast3.error(error.title || "Error", {
1260
+ toast4.error(error.title || "Error", {
972
1261
  description: error.description
973
1262
  });
974
1263
  }
@@ -983,6 +1272,13 @@ var SignIn = ({ redirectUrl } = {}) => {
983
1272
  }
984
1273
  });
985
1274
  if (result.exists) {
1275
+ if (result.requiresPasswordSetup) {
1276
+ const redirectParam = defaultRedirect ? `&redirect=${encodeURIComponent(defaultRedirect)}` : "";
1277
+ onNavigate(
1278
+ `${setPasswordLink}?identifier=${encodeURIComponent(normalizedUsername)}${redirectParam}`
1279
+ );
1280
+ return;
1281
+ }
986
1282
  setUsername(normalizedUsername);
987
1283
  form.setValue("username", normalizedUsername);
988
1284
  setShowPasswordField(true);
@@ -1038,6 +1334,15 @@ var SignIn = ({ redirectUrl } = {}) => {
1038
1334
  }
1039
1335
  onNavigate(defaultRedirect);
1040
1336
  } catch (err) {
1337
+ const authError = err;
1338
+ const errorCode = authError.code || authError.message;
1339
+ if (errorCode === "HAS_NO_PASSWORD") {
1340
+ const redirectParam = defaultRedirect ? `&redirect=${encodeURIComponent(defaultRedirect)}` : "";
1341
+ onNavigate(
1342
+ `${setPasswordLink}?identifier=${encodeURIComponent(username)}${redirectParam}`
1343
+ );
1344
+ return;
1345
+ }
1041
1346
  handleError(err, setError, t);
1042
1347
  } finally {
1043
1348
  setIsLoading(false);
@@ -1063,19 +1368,19 @@ var SignIn = ({ redirectUrl } = {}) => {
1063
1368
  errorContent = error;
1064
1369
  }
1065
1370
  }
1066
- const formContent = /* @__PURE__ */ jsx6(Form3, { ...form, children: /* @__PURE__ */ jsxs4(
1371
+ const formContent = /* @__PURE__ */ jsx7(Form4, { ...form, children: /* @__PURE__ */ jsxs5(
1067
1372
  "form",
1068
1373
  {
1069
1374
  id: "sign-in-form",
1070
1375
  onSubmit: form.handleSubmit(onSubmit),
1071
1376
  className: "space-y-4",
1072
1377
  children: [
1073
- showPasswordField ? /* @__PURE__ */ jsxs4(Fragment, { children: [
1074
- /* @__PURE__ */ jsxs4(FormItem3, { children: [
1075
- /* @__PURE__ */ jsxs4(FormLabel3, { className: "flex justify-between items-center", children: [
1378
+ showPasswordField ? /* @__PURE__ */ jsxs5(Fragment, { children: [
1379
+ /* @__PURE__ */ jsxs5(FormItem4, { children: [
1380
+ /* @__PURE__ */ jsxs5(FormLabel4, { className: "flex justify-between items-center", children: [
1076
1381
  t("form.accountLabel"),
1077
- /* @__PURE__ */ jsx6(
1078
- Button3,
1382
+ /* @__PURE__ */ jsx7(
1383
+ Button4,
1079
1384
  {
1080
1385
  type: "button",
1081
1386
  variant: "link",
@@ -1086,8 +1391,8 @@ var SignIn = ({ redirectUrl } = {}) => {
1086
1391
  }
1087
1392
  )
1088
1393
  ] }),
1089
- /* @__PURE__ */ jsx6(
1090
- Input3,
1394
+ /* @__PURE__ */ jsx7(
1395
+ Input4,
1091
1396
  {
1092
1397
  id: "sign-in-username",
1093
1398
  type: "text",
@@ -1097,39 +1402,39 @@ var SignIn = ({ redirectUrl } = {}) => {
1097
1402
  }
1098
1403
  )
1099
1404
  ] }),
1100
- /* @__PURE__ */ jsx6(
1101
- FormField3,
1405
+ /* @__PURE__ */ jsx7(
1406
+ FormField4,
1102
1407
  {
1103
1408
  control: form.control,
1104
1409
  name: "password",
1105
- render: ({ field }) => /* @__PURE__ */ jsxs4(FormItem3, { children: [
1106
- /* @__PURE__ */ jsx6(FormLabel3, { children: t("form.passwordLabel") }),
1107
- /* @__PURE__ */ jsx6(
1108
- PasswordInput2,
1410
+ render: ({ field }) => /* @__PURE__ */ jsxs5(FormItem4, { children: [
1411
+ /* @__PURE__ */ jsx7(FormLabel4, { children: t("form.passwordLabel") }),
1412
+ /* @__PURE__ */ jsx7(
1413
+ PasswordInput3,
1109
1414
  {
1110
1415
  field: { ...field, value: field.value ?? "" },
1111
1416
  show: showPassword,
1112
1417
  onToggle: () => setShowPassword(!showPassword)
1113
1418
  }
1114
1419
  ),
1115
- /* @__PURE__ */ jsx6(FormMessage3, {})
1420
+ /* @__PURE__ */ jsx7(FormMessage4, {})
1116
1421
  ] })
1117
1422
  }
1118
1423
  )
1119
- ] }) : /* @__PURE__ */ jsx6(
1120
- FormField3,
1424
+ ] }) : /* @__PURE__ */ jsx7(
1425
+ FormField4,
1121
1426
  {
1122
1427
  control: form.control,
1123
1428
  name: "username",
1124
- render: ({ field }) => /* @__PURE__ */ jsxs4(FormItem3, { children: [
1125
- /* @__PURE__ */ jsx6(FormLabel3, { children: t("form.accountLabel") }),
1126
- /* @__PURE__ */ jsx6(FormControl3, { children: /* @__PURE__ */ jsx6(Input3, { ...field, type: "text", autoComplete: "username" }) }),
1127
- /* @__PURE__ */ jsx6(FormMessage3, {})
1429
+ render: ({ field }) => /* @__PURE__ */ jsxs5(FormItem4, { children: [
1430
+ /* @__PURE__ */ jsx7(FormLabel4, { children: t("form.accountLabel") }),
1431
+ /* @__PURE__ */ jsx7(FormControl4, { children: /* @__PURE__ */ jsx7(Input4, { ...field, type: "text", autoComplete: "username" }) }),
1432
+ /* @__PURE__ */ jsx7(FormMessage4, {})
1128
1433
  ] })
1129
1434
  }
1130
1435
  ),
1131
- /* @__PURE__ */ jsx6(
1132
- Button3,
1436
+ /* @__PURE__ */ jsx7(
1437
+ Button4,
1133
1438
  {
1134
1439
  type: "submit",
1135
1440
  className: "w-full",
@@ -1141,20 +1446,20 @@ var SignIn = ({ redirectUrl } = {}) => {
1141
1446
  ]
1142
1447
  }
1143
1448
  ) });
1144
- return /* @__PURE__ */ jsx6("div", { className: "space-y-4", children: /* @__PURE__ */ jsxs4(
1449
+ return /* @__PURE__ */ jsx7("div", { className: "space-y-4", children: /* @__PURE__ */ jsxs5(
1145
1450
  AuthLayout,
1146
1451
  {
1147
1452
  title: config.ui.name,
1148
1453
  description: t("description"),
1149
1454
  logoImage,
1150
- footer: showPasswordField ? /* @__PURE__ */ jsx6("div", { className: "flex items-center justify-center w-full", children: Link ? /* @__PURE__ */ jsx6(
1455
+ footer: showPasswordField ? /* @__PURE__ */ jsx7("div", { className: "flex items-center justify-center w-full", children: Link ? /* @__PURE__ */ jsx7(
1151
1456
  Link,
1152
1457
  {
1153
1458
  href: forgotPasswordLink,
1154
1459
  className: "text-primary inline-block hover:underline",
1155
1460
  children: t("footer.forgotPassword")
1156
1461
  }
1157
- ) : /* @__PURE__ */ jsx6(
1462
+ ) : /* @__PURE__ */ jsx7(
1158
1463
  "a",
1159
1464
  {
1160
1465
  href: forgotPasswordLink,
@@ -1168,10 +1473,10 @@ var SignIn = ({ redirectUrl } = {}) => {
1168
1473
  ) }) : void 0,
1169
1474
  children: [
1170
1475
  formContent,
1171
- errorContent && /* @__PURE__ */ jsxs4(Alert3, { variant: "destructive", className: "mt-4", children: [
1172
- /* @__PURE__ */ jsx6(IconAlertCircle3, { className: "h-4 w-4" }),
1173
- /* @__PURE__ */ jsx6(AlertTitle3, { children: errorContent.title }),
1174
- /* @__PURE__ */ jsx6(AlertDescription3, { children: errorContent.description })
1476
+ errorContent && /* @__PURE__ */ jsxs5(Alert4, { variant: "destructive", className: "mt-4", children: [
1477
+ /* @__PURE__ */ jsx7(IconAlertCircle4, { className: "h-4 w-4" }),
1478
+ /* @__PURE__ */ jsx7(AlertTitle4, { children: errorContent.title }),
1479
+ /* @__PURE__ */ jsx7(AlertDescription4, { children: errorContent.description })
1175
1480
  ] })
1176
1481
  ]
1177
1482
  }
@@ -1179,34 +1484,34 @@ var SignIn = ({ redirectUrl } = {}) => {
1179
1484
  };
1180
1485
 
1181
1486
  // src/components/auth/sign-up.tsx
1182
- import { zodResolver as zodResolver4 } from "@hookform/resolvers/zod";
1487
+ import { zodResolver as zodResolver5 } from "@hookform/resolvers/zod";
1183
1488
  import {
1184
- Alert as Alert4,
1185
- AlertDescription as AlertDescription4,
1186
- AlertTitle as AlertTitle4,
1187
- Button as Button4,
1188
- Form as Form4,
1189
- FormControl as FormControl4,
1190
- FormField as FormField4,
1191
- FormItem as FormItem4,
1192
- FormLabel as FormLabel4,
1193
- FormMessage as FormMessage4,
1194
- Input as Input4,
1195
- useFormField as useFormField3
1489
+ Alert as Alert5,
1490
+ AlertDescription as AlertDescription5,
1491
+ AlertTitle as AlertTitle5,
1492
+ Button as Button5,
1493
+ Form as Form5,
1494
+ FormControl as FormControl5,
1495
+ FormField as FormField5,
1496
+ FormItem as FormItem5,
1497
+ FormLabel as FormLabel5,
1498
+ FormMessage as FormMessage5,
1499
+ Input as Input5,
1500
+ useFormField as useFormField4
1196
1501
  } from "@mesob/ui/components";
1197
- import { useMesob as useMesob5 } from "@mesob/ui/providers";
1198
- import { IconAlertCircle as IconAlertCircle4, IconEye as IconEye3, IconEyeOff as IconEyeOff3 } from "@tabler/icons-react";
1199
- import { useEffect as useEffect4, useState as useState5 } from "react";
1200
- import { useForm as useForm4 } from "react-hook-form";
1201
- import { toast as toast4 } from "sonner";
1202
- import { z as z4 } from "zod";
1203
- import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
1502
+ import { useMesob as useMesob6 } from "@mesob/ui/providers";
1503
+ import { IconAlertCircle as IconAlertCircle5, IconEye as IconEye4, IconEyeOff as IconEyeOff4 } from "@tabler/icons-react";
1504
+ import { useEffect as useEffect5, useState as useState6 } from "react";
1505
+ import { useForm as useForm5 } from "react-hook-form";
1506
+ import { toast as toast5 } from "sonner";
1507
+ import { z as z5 } from "zod";
1508
+ import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
1204
1509
  var isPhone2 = (s) => /^\+?[0-9()[\]\s-]{6,}$/.test(s);
1205
- function PasswordInput3({ field, show, onToggle }) {
1206
- const { formItemId, error } = useFormField3();
1207
- return /* @__PURE__ */ jsxs5("div", { className: "relative", children: [
1208
- /* @__PURE__ */ jsx7(
1209
- Input4,
1510
+ function PasswordInput4({ field, show, onToggle }) {
1511
+ const { formItemId, error } = useFormField4();
1512
+ return /* @__PURE__ */ jsxs6("div", { className: "relative", children: [
1513
+ /* @__PURE__ */ jsx8(
1514
+ Input5,
1210
1515
  {
1211
1516
  ...field,
1212
1517
  id: formItemId,
@@ -1215,8 +1520,8 @@ function PasswordInput3({ field, show, onToggle }) {
1215
1520
  className: "pr-10"
1216
1521
  }
1217
1522
  ),
1218
- /* @__PURE__ */ jsx7(
1219
- Button4,
1523
+ /* @__PURE__ */ jsx8(
1524
+ Button5,
1220
1525
  {
1221
1526
  type: "button",
1222
1527
  variant: "ghost",
@@ -1224,14 +1529,14 @@ function PasswordInput3({ field, show, onToggle }) {
1224
1529
  className: "absolute right-0 top-0 h-full px-3 text-muted-foreground hover:text-foreground",
1225
1530
  onClick: onToggle,
1226
1531
  "aria-label": show ? "Hide password" : "Show password",
1227
- children: show ? /* @__PURE__ */ jsx7(IconEyeOff3, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx7(IconEye3, { className: "h-4 w-4" })
1532
+ children: show ? /* @__PURE__ */ jsx8(IconEyeOff4, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx8(IconEye4, { className: "h-4 w-4" })
1228
1533
  }
1229
1534
  )
1230
1535
  ] });
1231
1536
  }
1232
- var signUpSchema = (t) => z4.object({
1233
- fullName: z4.string().min(1, t("errors.fullNameRequired")),
1234
- identifier: z4.string().min(1, t("errors.contactRequired")).refine(
1537
+ var signUpSchema = (t) => z5.object({
1538
+ fullName: z5.string().min(1, t("errors.fullNameRequired")),
1539
+ identifier: z5.string().min(1, t("errors.contactRequired")).refine(
1235
1540
  (val) => {
1236
1541
  if (!val) {
1237
1542
  return false;
@@ -1242,8 +1547,8 @@ var signUpSchema = (t) => z4.object({
1242
1547
  message: t("errors.invalidEmailOrPhone")
1243
1548
  }
1244
1549
  ),
1245
- password: z4.string().min(8, t("errors.passwordLength")).max(128, t("errors.longPasswordError")),
1246
- confirmPassword: z4.string()
1550
+ password: z5.string().min(8, t("errors.passwordLength")).max(128, t("errors.longPasswordError")),
1551
+ confirmPassword: z5.string()
1247
1552
  }).refine((data) => data.password === data.confirmPassword, {
1248
1553
  message: t("errors.passwordsMismatch"),
1249
1554
  path: ["confirmPassword"]
@@ -1254,13 +1559,13 @@ var SignUp = ({
1254
1559
  } = {}) => {
1255
1560
  const { hooks, setAuth } = useApi();
1256
1561
  const { config } = useConfig();
1257
- const mesob = useMesob5();
1562
+ const mesob = useMesob6();
1258
1563
  const t = useTranslator("Auth.signUp");
1259
1564
  const Link = mesob?.navigation?.Link;
1260
- const [isLoading, setIsLoading] = useState5(false);
1261
- const [error, setError] = useState5(null);
1262
- const [showPassword, setShowPassword] = useState5(false);
1263
- const [showConfirmPassword, setShowConfirmPassword] = useState5(false);
1565
+ const [isLoading, setIsLoading] = useState6(false);
1566
+ const [error, setError] = useState6(null);
1567
+ const [showPassword, setShowPassword] = useState6(false);
1568
+ const [showConfirmPassword, setShowConfirmPassword] = useState6(false);
1264
1569
  const signUpMutation = hooks.useMutation("post", "/sign-up");
1265
1570
  const signInLink = config.navigation?.links?.signIn || "/auth/sign-in";
1266
1571
  const onNavigate = config.navigation?.onNavigate || ((path) => {
@@ -1271,8 +1576,8 @@ var SignUp = ({
1271
1576
  const logoImage = config.ui.logoImage;
1272
1577
  const defaultRedirect = redirectUrl || config.navigation?.defaultRedirectUrl || "/";
1273
1578
  const hasInitialIdentifier = !!initialIdentifier;
1274
- const form = useForm4({
1275
- resolver: zodResolver4(signUpSchema(t)),
1579
+ const form = useForm5({
1580
+ resolver: zodResolver5(signUpSchema(t)),
1276
1581
  defaultValues: {
1277
1582
  fullName: "",
1278
1583
  identifier: initialIdentifier || "",
@@ -1280,14 +1585,14 @@ var SignUp = ({
1280
1585
  confirmPassword: ""
1281
1586
  }
1282
1587
  });
1283
- useEffect4(() => {
1588
+ useEffect5(() => {
1284
1589
  if (initialIdentifier) {
1285
1590
  form.setValue("identifier", initialIdentifier);
1286
1591
  }
1287
1592
  }, [initialIdentifier, form]);
1288
- useEffect4(() => {
1593
+ useEffect5(() => {
1289
1594
  if (error) {
1290
- toast4.error(error.title || "Error", {
1595
+ toast5.error(error.title || "Error", {
1291
1596
  description: error.description
1292
1597
  });
1293
1598
  }
@@ -1302,13 +1607,11 @@ var SignUp = ({
1302
1607
  body: usingPhone ? {
1303
1608
  phone: identifier,
1304
1609
  password: values.password,
1305
- fullName: values.fullName,
1306
- handle: values.handle
1610
+ fullName: values.fullName
1307
1611
  } : {
1308
1612
  email: identifier,
1309
1613
  password: values.password,
1310
- fullName: values.fullName,
1311
- handle: values.handle
1614
+ fullName: values.fullName
1312
1615
  }
1313
1616
  });
1314
1617
  if ("verificationId" in res && res.verificationId) {
@@ -1352,16 +1655,16 @@ var SignUp = ({
1352
1655
  errorContent = error;
1353
1656
  }
1354
1657
  }
1355
- return /* @__PURE__ */ jsxs5(
1658
+ return /* @__PURE__ */ jsxs6(
1356
1659
  AuthLayout,
1357
1660
  {
1358
1661
  title: config.ui.name,
1359
1662
  description: t("description"),
1360
1663
  logoImage,
1361
- footer: /* @__PURE__ */ jsxs5("p", { children: [
1664
+ footer: /* @__PURE__ */ jsxs6("p", { children: [
1362
1665
  t("footer.hasAccount"),
1363
1666
  " ",
1364
- Link ? /* @__PURE__ */ jsx7(Link, { href: signInLink, className: "text-primary hover:underline", children: t("footer.signInCta") }) : /* @__PURE__ */ jsx7(
1667
+ Link ? /* @__PURE__ */ jsx8(Link, { href: signInLink, className: "text-primary hover:underline", children: t("footer.signInCta") }) : /* @__PURE__ */ jsx8(
1365
1668
  "a",
1366
1669
  {
1367
1670
  href: signInLink,
@@ -1375,84 +1678,84 @@ var SignUp = ({
1375
1678
  )
1376
1679
  ] }),
1377
1680
  children: [
1378
- /* @__PURE__ */ jsx7(Form4, { ...form, children: /* @__PURE__ */ jsxs5("form", { id: "sign-up-form", onSubmit: handleSubmit, className: "space-y-4", children: [
1379
- /* @__PURE__ */ jsx7(
1380
- FormField4,
1681
+ /* @__PURE__ */ jsx8(Form5, { ...form, children: /* @__PURE__ */ jsxs6("form", { id: "sign-up-form", onSubmit: handleSubmit, className: "space-y-4", children: [
1682
+ /* @__PURE__ */ jsx8(
1683
+ FormField5,
1381
1684
  {
1382
1685
  control: form.control,
1383
1686
  name: "fullName",
1384
- render: ({ field }) => /* @__PURE__ */ jsxs5(FormItem4, { children: [
1385
- /* @__PURE__ */ jsx7(FormLabel4, { children: t("form.fullNameLabel") }),
1386
- /* @__PURE__ */ jsx7(FormControl4, { children: /* @__PURE__ */ jsx7(Input4, { ...field }) }),
1387
- /* @__PURE__ */ jsx7(FormMessage4, {})
1687
+ render: ({ field }) => /* @__PURE__ */ jsxs6(FormItem5, { children: [
1688
+ /* @__PURE__ */ jsx8(FormLabel5, { children: t("form.fullNameLabel") }),
1689
+ /* @__PURE__ */ jsx8(FormControl5, { children: /* @__PURE__ */ jsx8(Input5, { ...field }) }),
1690
+ /* @__PURE__ */ jsx8(FormMessage5, {})
1388
1691
  ] })
1389
1692
  }
1390
1693
  ),
1391
- /* @__PURE__ */ jsx7(
1392
- FormField4,
1694
+ /* @__PURE__ */ jsx8(
1695
+ FormField5,
1393
1696
  {
1394
1697
  control: form.control,
1395
1698
  name: "identifier",
1396
- render: ({ field }) => /* @__PURE__ */ jsxs5(FormItem4, { children: [
1397
- /* @__PURE__ */ jsx7(
1398
- FormLabel4,
1699
+ render: ({ field }) => /* @__PURE__ */ jsxs6(FormItem5, { children: [
1700
+ /* @__PURE__ */ jsx8(
1701
+ FormLabel5,
1399
1702
  {
1400
1703
  className: hasInitialIdentifier ? "block" : void 0,
1401
1704
  children: identifierLabel
1402
1705
  }
1403
1706
  ),
1404
- /* @__PURE__ */ jsx7(FormControl4, { children: /* @__PURE__ */ jsx7(
1405
- Input4,
1707
+ /* @__PURE__ */ jsx8(FormControl5, { children: /* @__PURE__ */ jsx8(
1708
+ Input5,
1406
1709
  {
1407
1710
  ...field,
1408
1711
  type: field.value.includes("@") ? "email" : "tel",
1409
1712
  disabled: hasInitialIdentifier
1410
1713
  }
1411
1714
  ) }),
1412
- /* @__PURE__ */ jsx7(FormMessage4, {})
1715
+ /* @__PURE__ */ jsx8(FormMessage5, {})
1413
1716
  ] })
1414
1717
  }
1415
1718
  ),
1416
- /* @__PURE__ */ jsx7(
1417
- FormField4,
1719
+ /* @__PURE__ */ jsx8(
1720
+ FormField5,
1418
1721
  {
1419
1722
  control: form.control,
1420
1723
  name: "password",
1421
- render: ({ field }) => /* @__PURE__ */ jsxs5(FormItem4, { children: [
1422
- /* @__PURE__ */ jsx7(FormLabel4, { children: t("form.passwordLabel") }),
1423
- /* @__PURE__ */ jsx7(
1424
- PasswordInput3,
1724
+ render: ({ field }) => /* @__PURE__ */ jsxs6(FormItem5, { children: [
1725
+ /* @__PURE__ */ jsx8(FormLabel5, { children: t("form.passwordLabel") }),
1726
+ /* @__PURE__ */ jsx8(
1727
+ PasswordInput4,
1425
1728
  {
1426
1729
  field,
1427
1730
  show: showPassword,
1428
1731
  onToggle: () => setShowPassword(!showPassword)
1429
1732
  }
1430
1733
  ),
1431
- /* @__PURE__ */ jsx7(FormMessage4, {})
1734
+ /* @__PURE__ */ jsx8(FormMessage5, {})
1432
1735
  ] })
1433
1736
  }
1434
1737
  ),
1435
- /* @__PURE__ */ jsx7(
1436
- FormField4,
1738
+ /* @__PURE__ */ jsx8(
1739
+ FormField5,
1437
1740
  {
1438
1741
  control: form.control,
1439
1742
  name: "confirmPassword",
1440
- render: ({ field }) => /* @__PURE__ */ jsxs5(FormItem4, { children: [
1441
- /* @__PURE__ */ jsx7(FormLabel4, { children: t("form.confirmPasswordLabel") }),
1442
- /* @__PURE__ */ jsx7(
1443
- PasswordInput3,
1743
+ render: ({ field }) => /* @__PURE__ */ jsxs6(FormItem5, { children: [
1744
+ /* @__PURE__ */ jsx8(FormLabel5, { children: t("form.confirmPasswordLabel") }),
1745
+ /* @__PURE__ */ jsx8(
1746
+ PasswordInput4,
1444
1747
  {
1445
1748
  field,
1446
1749
  show: showConfirmPassword,
1447
1750
  onToggle: () => setShowConfirmPassword(!showConfirmPassword)
1448
1751
  }
1449
1752
  ),
1450
- /* @__PURE__ */ jsx7(FormMessage4, {})
1753
+ /* @__PURE__ */ jsx8(FormMessage5, {})
1451
1754
  ] })
1452
1755
  }
1453
1756
  ),
1454
- /* @__PURE__ */ jsx7(
1455
- Button4,
1757
+ /* @__PURE__ */ jsx8(
1758
+ Button5,
1456
1759
  {
1457
1760
  type: "submit",
1458
1761
  form: "sign-up-form",
@@ -1462,10 +1765,10 @@ var SignUp = ({
1462
1765
  }
1463
1766
  )
1464
1767
  ] }) }),
1465
- errorContent && /* @__PURE__ */ jsxs5(Alert4, { variant: "destructive", className: "mt-4", children: [
1466
- /* @__PURE__ */ jsx7(IconAlertCircle4, { className: "h-4 w-4" }),
1467
- /* @__PURE__ */ jsx7(AlertTitle4, { children: errorContent.title }),
1468
- /* @__PURE__ */ jsx7(AlertDescription4, { children: errorContent.description })
1768
+ errorContent && /* @__PURE__ */ jsxs6(Alert5, { variant: "destructive", className: "mt-4", children: [
1769
+ /* @__PURE__ */ jsx8(IconAlertCircle5, { className: "h-4 w-4" }),
1770
+ /* @__PURE__ */ jsx8(AlertTitle5, { children: errorContent.title }),
1771
+ /* @__PURE__ */ jsx8(AlertDescription5, { children: errorContent.description })
1469
1772
  ] })
1470
1773
  ]
1471
1774
  }
@@ -1473,35 +1776,35 @@ var SignUp = ({
1473
1776
  };
1474
1777
 
1475
1778
  // src/components/auth/verification-form.tsx
1476
- import { zodResolver as zodResolver5 } from "@hookform/resolvers/zod";
1779
+ import { zodResolver as zodResolver6 } from "@hookform/resolvers/zod";
1477
1780
  import {
1478
- Button as Button5,
1479
- Form as Form5,
1480
- FormControl as FormControl5,
1481
- FormField as FormField5,
1482
- FormItem as FormItem5,
1483
- FormLabel as FormLabel5,
1484
- FormMessage as FormMessage5,
1781
+ Button as Button6,
1782
+ Form as Form6,
1783
+ FormControl as FormControl6,
1784
+ FormField as FormField6,
1785
+ FormItem as FormItem6,
1786
+ FormLabel as FormLabel6,
1787
+ FormMessage as FormMessage6,
1485
1788
  InputOTP as InputOTP2,
1486
1789
  InputOTPGroup as InputOTPGroup2,
1487
1790
  InputOTPSlot as InputOTPSlot2
1488
1791
  } from "@mesob/ui/components";
1489
- import { useForm as useForm5 } from "react-hook-form";
1490
- import { z as z5 } from "zod";
1792
+ import { useForm as useForm6 } from "react-hook-form";
1793
+ import { z as z6 } from "zod";
1491
1794
 
1492
1795
  // src/components/auth/countdown.tsx
1493
1796
  import { Spinner } from "@mesob/ui/components";
1494
- import { useEffect as useEffect5, useState as useState6 } from "react";
1495
- import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
1797
+ import { useEffect as useEffect6, useState as useState7 } from "react";
1798
+ import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
1496
1799
  var Countdown = ({
1497
1800
  initialSeconds = 60,
1498
1801
  onResend,
1499
1802
  resending = false
1500
1803
  }) => {
1501
1804
  const t = useTranslator("Common");
1502
- const [seconds, setSeconds] = useState6(initialSeconds);
1503
- const [isResending, setIsResending] = useState6(false);
1504
- useEffect5(() => {
1805
+ const [seconds, setSeconds] = useState7(initialSeconds);
1806
+ const [isResending, setIsResending] = useState7(false);
1807
+ useEffect6(() => {
1505
1808
  if (seconds <= 0) {
1506
1809
  return;
1507
1810
  }
@@ -1528,9 +1831,9 @@ var Countdown = ({
1528
1831
  };
1529
1832
  const busy = isResending || resending;
1530
1833
  if (seconds > 0) {
1531
- return /* @__PURE__ */ jsx8("p", { className: "text-sm text-muted-foreground", children: t("resendIn", { seconds }) });
1834
+ return /* @__PURE__ */ jsx9("p", { className: "text-sm text-muted-foreground", children: t("resendIn", { seconds }) });
1532
1835
  }
1533
- return /* @__PURE__ */ jsxs6(
1836
+ return /* @__PURE__ */ jsxs7(
1534
1837
  "button",
1535
1838
  {
1536
1839
  type: "button",
@@ -1538,7 +1841,7 @@ var Countdown = ({
1538
1841
  disabled: busy,
1539
1842
  className: "text-sm text-primary hover:underline disabled:opacity-50 flex items-center gap-1",
1540
1843
  children: [
1541
- busy && /* @__PURE__ */ jsx8(Spinner, { className: "h-3 w-3" }),
1844
+ busy && /* @__PURE__ */ jsx9(Spinner, { className: "h-3 w-3" }),
1542
1845
  t("resend")
1543
1846
  ]
1544
1847
  }
@@ -1546,9 +1849,9 @@ var Countdown = ({
1546
1849
  };
1547
1850
 
1548
1851
  // src/components/auth/verification-form.tsx
1549
- import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
1550
- var verificationSchema = (t) => z5.object({
1551
- code: z5.string().length(6, t("form.codeLength"))
1852
+ import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
1853
+ var verificationSchema = (t) => z6.object({
1854
+ code: z6.string().length(6, t("form.codeLength"))
1552
1855
  });
1553
1856
  var VerificationForm = ({
1554
1857
  onSubmit,
@@ -1556,29 +1859,29 @@ var VerificationForm = ({
1556
1859
  isLoading = false
1557
1860
  }) => {
1558
1861
  const t = useTranslator("Auth.verification");
1559
- const form = useForm5({
1560
- resolver: zodResolver5(verificationSchema(t)),
1862
+ const form = useForm6({
1863
+ resolver: zodResolver6(verificationSchema(t)),
1561
1864
  defaultValues: { code: "" }
1562
1865
  });
1563
1866
  const handleSubmit = form.handleSubmit(async (values) => {
1564
1867
  await onSubmit(values);
1565
1868
  });
1566
1869
  const codeLength = form.watch("code").length;
1567
- return /* @__PURE__ */ jsx9(Form5, { ...form, children: /* @__PURE__ */ jsxs7(
1870
+ return /* @__PURE__ */ jsx10(Form6, { ...form, children: /* @__PURE__ */ jsxs8(
1568
1871
  "form",
1569
1872
  {
1570
1873
  id: "verification-form",
1571
1874
  onSubmit: handleSubmit,
1572
1875
  className: "space-y-4",
1573
1876
  children: [
1574
- /* @__PURE__ */ jsx9(
1575
- FormField5,
1877
+ /* @__PURE__ */ jsx10(
1878
+ FormField6,
1576
1879
  {
1577
1880
  control: form.control,
1578
1881
  name: "code",
1579
- render: ({ field }) => /* @__PURE__ */ jsxs7(FormItem5, { children: [
1580
- /* @__PURE__ */ jsx9("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx9(FormLabel5, { children: t("form.codeLabel") }) }),
1581
- /* @__PURE__ */ jsx9(FormControl5, { children: /* @__PURE__ */ jsx9(
1882
+ render: ({ field }) => /* @__PURE__ */ jsxs8(FormItem6, { children: [
1883
+ /* @__PURE__ */ jsx10("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx10(FormLabel6, { children: t("form.codeLabel") }) }),
1884
+ /* @__PURE__ */ jsx10(FormControl6, { children: /* @__PURE__ */ jsx10(
1582
1885
  InputOTP2,
1583
1886
  {
1584
1887
  maxLength: 6,
@@ -1587,22 +1890,22 @@ var VerificationForm = ({
1587
1890
  onChange: field.onChange,
1588
1891
  onBlur: field.onBlur,
1589
1892
  containerClassName: "gap-4 justify-center mb-2 flex items-center",
1590
- children: /* @__PURE__ */ jsxs7(InputOTPGroup2, { className: "gap-3 *:data-[slot=input-otp-slot]:h-12 *:data-[slot=input-otp-slot]:w-12 *:data-[slot=input-otp-slot]:rounded-md *:data-[slot=input-otp-slot]:border *:data-[slot=input-otp-slot]:text-xl", children: [
1591
- /* @__PURE__ */ jsx9(InputOTPSlot2, { className: "h-12", index: 0 }),
1592
- /* @__PURE__ */ jsx9(InputOTPSlot2, { className: "h-12", index: 1 }),
1593
- /* @__PURE__ */ jsx9(InputOTPSlot2, { className: "h-12", index: 2 }),
1594
- /* @__PURE__ */ jsx9(InputOTPSlot2, { className: "h-12", index: 3 }),
1595
- /* @__PURE__ */ jsx9(InputOTPSlot2, { className: "h-12", index: 4 }),
1596
- /* @__PURE__ */ jsx9(InputOTPSlot2, { className: "h-12", index: 5 })
1893
+ children: /* @__PURE__ */ jsxs8(InputOTPGroup2, { className: "gap-3 *:data-[slot=input-otp-slot]:h-12 *:data-[slot=input-otp-slot]:w-12 *:data-[slot=input-otp-slot]:rounded-md *:data-[slot=input-otp-slot]:border *:data-[slot=input-otp-slot]:text-xl", children: [
1894
+ /* @__PURE__ */ jsx10(InputOTPSlot2, { className: "h-12", index: 0 }),
1895
+ /* @__PURE__ */ jsx10(InputOTPSlot2, { className: "h-12", index: 1 }),
1896
+ /* @__PURE__ */ jsx10(InputOTPSlot2, { className: "h-12", index: 2 }),
1897
+ /* @__PURE__ */ jsx10(InputOTPSlot2, { className: "h-12", index: 3 }),
1898
+ /* @__PURE__ */ jsx10(InputOTPSlot2, { className: "h-12", index: 4 }),
1899
+ /* @__PURE__ */ jsx10(InputOTPSlot2, { className: "h-12", index: 5 })
1597
1900
  ] })
1598
1901
  }
1599
1902
  ) }),
1600
- /* @__PURE__ */ jsx9(FormMessage5, {})
1903
+ /* @__PURE__ */ jsx10(FormMessage6, {})
1601
1904
  ] })
1602
1905
  }
1603
1906
  ),
1604
- /* @__PURE__ */ jsx9(
1605
- Button5,
1907
+ /* @__PURE__ */ jsx10(
1908
+ Button6,
1606
1909
  {
1607
1910
  type: "submit",
1608
1911
  form: "verification-form",
@@ -1612,19 +1915,19 @@ var VerificationForm = ({
1612
1915
  children: t("form.confirm")
1613
1916
  }
1614
1917
  ),
1615
- /* @__PURE__ */ jsx9("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx9(Countdown, { onResend, resending: isLoading }) })
1918
+ /* @__PURE__ */ jsx10("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx10(Countdown, { onResend, resending: isLoading }) })
1616
1919
  ]
1617
1920
  }
1618
1921
  ) });
1619
1922
  };
1620
1923
 
1621
1924
  // src/components/auth/verify-email.tsx
1622
- import { Alert as Alert5, AlertDescription as AlertDescription5, AlertTitle as AlertTitle5 } from "@mesob/ui/components";
1623
- import { useMesob as useMesob6 } from "@mesob/ui/providers";
1624
- import { IconAlertCircle as IconAlertCircle5 } from "@tabler/icons-react";
1625
- import { useEffect as useEffect6, useState as useState7 } from "react";
1626
- import { toast as toast5 } from "sonner";
1627
- import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
1925
+ import { Alert as Alert6, AlertDescription as AlertDescription6, AlertTitle as AlertTitle6 } from "@mesob/ui/components";
1926
+ import { useMesob as useMesob7 } from "@mesob/ui/providers";
1927
+ import { IconAlertCircle as IconAlertCircle6 } from "@tabler/icons-react";
1928
+ import { useEffect as useEffect7, useState as useState8 } from "react";
1929
+ import { toast as toast6 } from "sonner";
1930
+ import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
1628
1931
  var VerifyEmail = ({
1629
1932
  verificationId,
1630
1933
  email,
@@ -1632,13 +1935,13 @@ var VerifyEmail = ({
1632
1935
  }) => {
1633
1936
  const { hooks, setAuth } = useApi();
1634
1937
  const { config } = useConfig();
1635
- const mesob = useMesob6();
1938
+ const mesob = useMesob7();
1636
1939
  const t = useTranslator("Auth.verification");
1637
1940
  const common = useTranslator("Common");
1638
1941
  const footer = useTranslator("Auth.forgotPassword.footer");
1639
1942
  const Link = mesob?.navigation?.Link;
1640
- const [isLoading, setIsLoading] = useState7(false);
1641
- const [error, setError] = useState7(null);
1943
+ const [isLoading, setIsLoading] = useState8(false);
1944
+ const [error, setError] = useState8(null);
1642
1945
  const verifyEmailMutation = hooks.useMutation(
1643
1946
  "post",
1644
1947
  "/email/verification/confirm"
@@ -1655,9 +1958,9 @@ var VerifyEmail = ({
1655
1958
  });
1656
1959
  const logoImage = config.ui.logoImage;
1657
1960
  const defaultRedirect = redirectUrl || config.navigation?.defaultRedirectUrl || "/";
1658
- useEffect6(() => {
1961
+ useEffect7(() => {
1659
1962
  if (error) {
1660
- toast5.error(error.title || "Error", {
1963
+ toast6.error(error.title || "Error", {
1661
1964
  description: error.description
1662
1965
  });
1663
1966
  }
@@ -1712,12 +2015,12 @@ var VerifyEmail = ({
1712
2015
  }
1713
2016
  };
1714
2017
  if (!verificationId) {
1715
- return /* @__PURE__ */ jsx10(
2018
+ return /* @__PURE__ */ jsx11(
1716
2019
  AuthLayout,
1717
2020
  {
1718
2021
  title: common("invalidLinkTitle"),
1719
2022
  description: common("invalidLinkDescription"),
1720
- footer: Link ? /* @__PURE__ */ jsx10(Link, { href: signInLink, className: "text-primary hover:underline", children: footer("backToSignIn") }) : /* @__PURE__ */ jsx10(
2023
+ footer: Link ? /* @__PURE__ */ jsx11(Link, { href: signInLink, className: "text-primary hover:underline", children: footer("backToSignIn") }) : /* @__PURE__ */ jsx11(
1721
2024
  "a",
1722
2025
  {
1723
2026
  href: signInLink,
@@ -1729,7 +2032,7 @@ var VerifyEmail = ({
1729
2032
  children: footer("backToSignIn")
1730
2033
  }
1731
2034
  ),
1732
- children: /* @__PURE__ */ jsx10("div", {})
2035
+ children: /* @__PURE__ */ jsx11("div", {})
1733
2036
  }
1734
2037
  );
1735
2038
  }
@@ -1741,13 +2044,13 @@ var VerifyEmail = ({
1741
2044
  errorContent = error;
1742
2045
  }
1743
2046
  }
1744
- return /* @__PURE__ */ jsxs8(
2047
+ return /* @__PURE__ */ jsxs9(
1745
2048
  AuthLayout,
1746
2049
  {
1747
2050
  title: config.ui.name,
1748
2051
  description: t("email.description"),
1749
2052
  logoImage,
1750
- footer: Link ? /* @__PURE__ */ jsx10(Link, { href: signInLink, className: "text-primary hover:underline", children: footer("backToSignIn") }) : /* @__PURE__ */ jsx10(
2053
+ footer: Link ? /* @__PURE__ */ jsx11(Link, { href: signInLink, className: "text-primary hover:underline", children: footer("backToSignIn") }) : /* @__PURE__ */ jsx11(
1751
2054
  "a",
1752
2055
  {
1753
2056
  href: signInLink,
@@ -1760,7 +2063,7 @@ var VerifyEmail = ({
1760
2063
  }
1761
2064
  ),
1762
2065
  children: [
1763
- /* @__PURE__ */ jsx10(
2066
+ /* @__PURE__ */ jsx11(
1764
2067
  VerificationForm,
1765
2068
  {
1766
2069
  verificationId,
@@ -1770,10 +2073,10 @@ var VerifyEmail = ({
1770
2073
  error
1771
2074
  }
1772
2075
  ),
1773
- errorContent && /* @__PURE__ */ jsxs8(Alert5, { variant: "destructive", className: "mt-4", children: [
1774
- /* @__PURE__ */ jsx10(IconAlertCircle5, { className: "h-4 w-4" }),
1775
- /* @__PURE__ */ jsx10(AlertTitle5, { children: errorContent.title }),
1776
- /* @__PURE__ */ jsx10(AlertDescription5, { children: errorContent.description })
2076
+ errorContent && /* @__PURE__ */ jsxs9(Alert6, { variant: "destructive", className: "mt-4", children: [
2077
+ /* @__PURE__ */ jsx11(IconAlertCircle6, { className: "h-4 w-4" }),
2078
+ /* @__PURE__ */ jsx11(AlertTitle6, { children: errorContent.title }),
2079
+ /* @__PURE__ */ jsx11(AlertDescription6, { children: errorContent.description })
1777
2080
  ] })
1778
2081
  ]
1779
2082
  }
@@ -1781,12 +2084,12 @@ var VerifyEmail = ({
1781
2084
  };
1782
2085
 
1783
2086
  // src/components/auth/verify-phone.tsx
1784
- import { Alert as Alert6, AlertDescription as AlertDescription6, AlertTitle as AlertTitle6 } from "@mesob/ui/components";
1785
- import { useMesob as useMesob7 } from "@mesob/ui/providers";
1786
- import { IconAlertCircle as IconAlertCircle6 } from "@tabler/icons-react";
1787
- import { useEffect as useEffect7, useState as useState8 } from "react";
1788
- import { toast as toast6 } from "sonner";
1789
- import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
2087
+ import { Alert as Alert7, AlertDescription as AlertDescription7, AlertTitle as AlertTitle7 } from "@mesob/ui/components";
2088
+ import { useMesob as useMesob8 } from "@mesob/ui/providers";
2089
+ import { IconAlertCircle as IconAlertCircle7 } from "@tabler/icons-react";
2090
+ import { useEffect as useEffect8, useState as useState9 } from "react";
2091
+ import { toast as toast7 } from "sonner";
2092
+ import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
1790
2093
  var VerifyPhone = ({
1791
2094
  verificationId,
1792
2095
  context,
@@ -1795,13 +2098,13 @@ var VerifyPhone = ({
1795
2098
  }) => {
1796
2099
  const { hooks, refresh, setAuth } = useApi();
1797
2100
  const { config } = useConfig();
1798
- const mesob = useMesob7();
2101
+ const mesob = useMesob8();
1799
2102
  const Link = mesob?.navigation?.Link;
1800
2103
  const t = useTranslator("Auth.verification");
1801
2104
  const common = useTranslator("Common");
1802
2105
  const footer = useTranslator("Auth.forgotPassword.footer");
1803
- const [isLoading, setIsLoading] = useState8(false);
1804
- const [error, setError] = useState8(null);
2106
+ const [isLoading, setIsLoading] = useState9(false);
2107
+ const [error, setError] = useState9(null);
1805
2108
  const verifyPhoneMutation = hooks.useMutation(
1806
2109
  "post",
1807
2110
  "/phone/verification/confirm"
@@ -1818,9 +2121,9 @@ var VerifyPhone = ({
1818
2121
  });
1819
2122
  const logoImage = config.ui.logoImage;
1820
2123
  const defaultRedirect = redirectUrl || config.navigation?.defaultRedirectUrl || "/";
1821
- useEffect7(() => {
2124
+ useEffect8(() => {
1822
2125
  if (error) {
1823
- toast6.error(error.title || "Error", {
2126
+ toast7.error(error.title || "Error", {
1824
2127
  description: error.description
1825
2128
  });
1826
2129
  }
@@ -1888,13 +2191,13 @@ var VerifyPhone = ({
1888
2191
  }
1889
2192
  };
1890
2193
  if (!verificationId) {
1891
- return /* @__PURE__ */ jsx11(
2194
+ return /* @__PURE__ */ jsx12(
1892
2195
  AuthLayout,
1893
2196
  {
1894
2197
  title: common("invalidLinkTitle"),
1895
2198
  description: common("invalidLinkDescription"),
1896
- footer: /* @__PURE__ */ jsx11(Link, { href: signInLink, className: "text-primary hover:underline", children: footer("backToSignIn") }),
1897
- children: /* @__PURE__ */ jsx11("div", {})
2199
+ footer: /* @__PURE__ */ jsx12(Link, { href: signInLink, className: "text-primary hover:underline", children: footer("backToSignIn") }),
2200
+ children: /* @__PURE__ */ jsx12("div", {})
1898
2201
  }
1899
2202
  );
1900
2203
  }
@@ -1906,7 +2209,7 @@ var VerifyPhone = ({
1906
2209
  errorContent = error;
1907
2210
  }
1908
2211
  }
1909
- return /* @__PURE__ */ jsxs9(
2212
+ return /* @__PURE__ */ jsxs10(
1910
2213
  AuthLayout,
1911
2214
  {
1912
2215
  title: config.ui.name,
@@ -1914,7 +2217,7 @@ var VerifyPhone = ({
1914
2217
  target: phone || t("phone.missingPhone")
1915
2218
  }),
1916
2219
  logoImage,
1917
- footer: Link ? /* @__PURE__ */ jsx11(Link, { href: signInLink, className: "text-primary hover:underline", children: footer("backToSignIn") }) : /* @__PURE__ */ jsx11(
2220
+ footer: Link ? /* @__PURE__ */ jsx12(Link, { href: signInLink, className: "text-primary hover:underline", children: footer("backToSignIn") }) : /* @__PURE__ */ jsx12(
1918
2221
  "a",
1919
2222
  {
1920
2223
  href: signInLink,
@@ -1927,7 +2230,7 @@ var VerifyPhone = ({
1927
2230
  }
1928
2231
  ),
1929
2232
  children: [
1930
- /* @__PURE__ */ jsx11(
2233
+ /* @__PURE__ */ jsx12(
1931
2234
  VerificationForm,
1932
2235
  {
1933
2236
  verificationId,
@@ -1937,20 +2240,55 @@ var VerifyPhone = ({
1937
2240
  error
1938
2241
  }
1939
2242
  ),
1940
- errorContent && /* @__PURE__ */ jsxs9(Alert6, { variant: "destructive", className: "mt-4", children: [
1941
- /* @__PURE__ */ jsx11(IconAlertCircle6, { className: "h-4 w-4" }),
1942
- /* @__PURE__ */ jsx11(AlertTitle6, { children: errorContent.title }),
1943
- /* @__PURE__ */ jsx11(AlertDescription6, { children: errorContent.description })
2243
+ errorContent && /* @__PURE__ */ jsxs10(Alert7, { variant: "destructive", className: "mt-4", children: [
2244
+ /* @__PURE__ */ jsx12(IconAlertCircle7, { className: "h-4 w-4" }),
2245
+ /* @__PURE__ */ jsx12(AlertTitle7, { children: errorContent.title }),
2246
+ /* @__PURE__ */ jsx12(AlertDescription7, { children: errorContent.description })
1944
2247
  ] })
1945
2248
  ]
1946
2249
  }
1947
2250
  );
1948
2251
  };
1949
2252
 
2253
+ // src/components/authorization/deny.tsx
2254
+ import { deny as canDeny } from "@mesob/common";
2255
+ import { Fragment as Fragment2, jsx as jsx13 } from "react/jsx-runtime";
2256
+ function Deny({ permissions, userPermissions, children }) {
2257
+ const { isLoading, user } = useSession();
2258
+ if (userPermissions === void 0 && isLoading) {
2259
+ return null;
2260
+ }
2261
+ const resolvedPermissions = userPermissions ?? user?.permissions ?? [];
2262
+ if (canDeny(permissions, resolvedPermissions)) {
2263
+ return /* @__PURE__ */ jsx13(Fragment2, { children });
2264
+ }
2265
+ return null;
2266
+ }
2267
+
2268
+ // src/components/authorization/grant.tsx
2269
+ import { grant as canGrant } from "@mesob/common";
2270
+ import { Fragment as Fragment3, jsx as jsx14 } from "react/jsx-runtime";
2271
+ function Grant({
2272
+ permissions,
2273
+ userPermissions,
2274
+ fallback = null,
2275
+ children
2276
+ }) {
2277
+ const { isLoading, user } = useSession();
2278
+ if (userPermissions === void 0 && isLoading) {
2279
+ return null;
2280
+ }
2281
+ const resolvedPermissions = userPermissions ?? user?.permissions ?? [];
2282
+ if (canGrant(permissions, resolvedPermissions)) {
2283
+ return /* @__PURE__ */ jsx14(Fragment3, { children });
2284
+ }
2285
+ return /* @__PURE__ */ jsx14(Fragment3, { children: fallback });
2286
+ }
2287
+
1950
2288
  // src/components/error-boundary.tsx
1951
- import { Button as Button6 } from "@mesob/ui/components";
2289
+ import { Button as Button7 } from "@mesob/ui/components";
1952
2290
  import { Component } from "react";
1953
- import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
2291
+ import { jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
1954
2292
  var ErrorBoundary = class extends Component {
1955
2293
  constructor(props) {
1956
2294
  super(props);
@@ -1972,28 +2310,112 @@ var ErrorBoundary = class extends Component {
1972
2310
  reset: this.reset
1973
2311
  });
1974
2312
  }
1975
- return /* @__PURE__ */ jsx12(ErrorFallback, { error: this.state.error, reset: this.reset });
2313
+ return /* @__PURE__ */ jsx15(ErrorFallback, { error: this.state.error, reset: this.reset });
1976
2314
  }
1977
2315
  return this.props.children;
1978
2316
  }
1979
2317
  };
1980
2318
  function ErrorFallback({ error, reset }) {
1981
- return /* @__PURE__ */ jsx12("div", { className: "flex flex-col items-center justify-center min-h-[400px] p-6", children: /* @__PURE__ */ jsxs10("div", { className: "max-w-md w-full space-y-4 text-center", children: [
1982
- /* @__PURE__ */ jsxs10("div", { className: "space-y-2", children: [
1983
- /* @__PURE__ */ jsx12("h2", { className: "text-2xl font-bold text-destructive", children: "Something went wrong" }),
1984
- /* @__PURE__ */ jsx12("p", { className: "text-muted-foreground", children: error.message || "An unexpected error occurred" })
2319
+ return /* @__PURE__ */ jsx15("div", { className: "flex flex-col items-center justify-center min-h-[400px] p-6", children: /* @__PURE__ */ jsxs11("div", { className: "max-w-md w-full space-y-4 text-center", children: [
2320
+ /* @__PURE__ */ jsxs11("div", { className: "space-y-2", children: [
2321
+ /* @__PURE__ */ jsx15("h2", { className: "text-2xl font-bold text-destructive", children: "Something went wrong" }),
2322
+ /* @__PURE__ */ jsx15("p", { className: "text-muted-foreground", children: error.message || "An unexpected error occurred" })
1985
2323
  ] }),
1986
- /* @__PURE__ */ jsx12(Button6, { onClick: reset, variant: "outline", children: "Try again" })
2324
+ /* @__PURE__ */ jsx15(Button7, { onClick: reset, variant: "outline", children: "Try again" })
1987
2325
  ] }) });
1988
2326
  }
1989
2327
  function AuthErrorBoundary({ children }) {
1990
- return /* @__PURE__ */ jsx12(ErrorBoundary, { children });
2328
+ return /* @__PURE__ */ jsx15(ErrorBoundary, { children });
2329
+ }
2330
+
2331
+ // src/components/iam/permission-selector.tsx
2332
+ import {
2333
+ Badge,
2334
+ EntitySelector,
2335
+ useEntitySectionState
2336
+ } from "@mesob/ui/components";
2337
+ import { IconKey } from "@tabler/icons-react";
2338
+ import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
2339
+ var permissionColumns = [
2340
+ {
2341
+ key: "permission",
2342
+ header: "Permission",
2343
+ cell: (permission) => /* @__PURE__ */ jsxs12("div", { className: "space-y-1", children: [
2344
+ /* @__PURE__ */ jsx16("p", { className: "font-medium", children: permission.activity }),
2345
+ /* @__PURE__ */ jsx16("p", { className: "font-mono text-xs text-muted-foreground", children: permission.id })
2346
+ ] })
2347
+ },
2348
+ {
2349
+ key: "scope",
2350
+ header: "Scope",
2351
+ cell: (permission) => /* @__PURE__ */ jsxs12("div", { className: "flex flex-wrap gap-2", children: [
2352
+ /* @__PURE__ */ jsx16(Badge, { variant: "secondary", children: permission.application }),
2353
+ /* @__PURE__ */ jsx16(Badge, { variant: "outline", children: permission.feature })
2354
+ ] })
2355
+ }
2356
+ ];
2357
+ function PermissionSelector({
2358
+ trigger,
2359
+ multiple = true,
2360
+ onSelect,
2361
+ excludeIds = []
2362
+ }) {
2363
+ const { hooks } = useApi();
2364
+ const state = useEntitySectionState({
2365
+ defaultSort: "id",
2366
+ defaultOrder: "asc",
2367
+ defaultPageSize: 10,
2368
+ searchParamName: "search"
2369
+ });
2370
+ const permissionsQuery = state.queryConfig;
2371
+ const { data, isPending, isFetching } = hooks.useQuery(
2372
+ "get",
2373
+ "/permissions",
2374
+ permissionsQuery
2375
+ );
2376
+ const items = (data?.permissions ?? []).filter(
2377
+ (permission) => !excludeIds.includes(permission.id)
2378
+ );
2379
+ const config = {
2380
+ title: "Select permission(s)",
2381
+ multiple,
2382
+ entityName: "permission",
2383
+ entityIcon: IconKey,
2384
+ columns: permissionColumns,
2385
+ getItemLabel: (permission) => permission.id,
2386
+ searchPlaceholder: "Search permissions...",
2387
+ filterOptions: [
2388
+ { label: "All", value: "" },
2389
+ { label: "Application", value: "application" },
2390
+ { label: "Feature", value: "feature" },
2391
+ { label: "Activity", value: "activity" }
2392
+ ],
2393
+ sortOptions: [
2394
+ { label: "ID", value: "id" },
2395
+ { label: "Application", value: "application" },
2396
+ { label: "Feature", value: "feature" },
2397
+ { label: "Activity", value: "activity" }
2398
+ ],
2399
+ showViewToggle: false,
2400
+ wrapHeaderInCard: false
2401
+ };
2402
+ return /* @__PURE__ */ jsx16(
2403
+ EntitySelector,
2404
+ {
2405
+ trigger,
2406
+ config,
2407
+ onSelect,
2408
+ items,
2409
+ total: items.length,
2410
+ isLoading: isPending || isFetching,
2411
+ state
2412
+ }
2413
+ );
1991
2414
  }
1992
2415
 
1993
2416
  // src/components/iam/permissions.tsx
1994
- import { Badge, Button as Button7 } from "@mesob/ui/components";
1995
- import { useLocale } from "next-intl";
1996
- import { useState as useState9 } from "react";
2417
+ import { Badge as Badge2, Button as Button8 } from "@mesob/ui/components";
2418
+ import { useState as useState10 } from "react";
1997
2419
 
1998
2420
  // src/components/shared/data-table.tsx
1999
2421
  import {
@@ -2007,7 +2429,7 @@ import {
2007
2429
 
2008
2430
  // src/components/skeletons/table-skeleton.tsx
2009
2431
  import { Skeleton } from "@mesob/ui/components";
2010
- import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
2432
+ import { jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
2011
2433
  function TableSkeleton({ columns = 5, rows = 10 }) {
2012
2434
  const headerKeys = Array.from({ length: columns }, (_, i) => `header-${i}`);
2013
2435
  const rowKeys = Array.from({ length: rows }, (_, i) => `row-${i}`);
@@ -2015,32 +2437,32 @@ function TableSkeleton({ columns = 5, rows = 10 }) {
2015
2437
  { length: rows },
2016
2438
  (_, rowIdx) => Array.from({ length: columns }, (_2, colIdx) => `cell-${rowIdx}-${colIdx}`)
2017
2439
  );
2018
- return /* @__PURE__ */ jsxs11("div", { className: "w-full space-y-4", children: [
2019
- /* @__PURE__ */ jsxs11("div", { className: "flex justify-between items-center", children: [
2020
- /* @__PURE__ */ jsx13(Skeleton, { className: "h-8 w-48" }),
2021
- /* @__PURE__ */ jsx13(Skeleton, { className: "h-10 w-32" })
2440
+ return /* @__PURE__ */ jsxs13("div", { className: "w-full space-y-4", children: [
2441
+ /* @__PURE__ */ jsxs13("div", { className: "flex justify-between items-center", children: [
2442
+ /* @__PURE__ */ jsx17(Skeleton, { className: "h-8 w-48" }),
2443
+ /* @__PURE__ */ jsx17(Skeleton, { className: "h-10 w-32" })
2022
2444
  ] }),
2023
- /* @__PURE__ */ jsxs11("div", { className: "flex gap-4", children: [
2024
- /* @__PURE__ */ jsx13(Skeleton, { className: "h-10 flex-1 max-w-sm" }),
2025
- /* @__PURE__ */ jsx13(Skeleton, { className: "h-10 w-24" }),
2026
- /* @__PURE__ */ jsx13(Skeleton, { className: "h-10 w-24" })
2445
+ /* @__PURE__ */ jsxs13("div", { className: "flex gap-4", children: [
2446
+ /* @__PURE__ */ jsx17(Skeleton, { className: "h-10 flex-1 max-w-sm" }),
2447
+ /* @__PURE__ */ jsx17(Skeleton, { className: "h-10 w-24" }),
2448
+ /* @__PURE__ */ jsx17(Skeleton, { className: "h-10 w-24" })
2027
2449
  ] }),
2028
- /* @__PURE__ */ jsxs11("div", { className: "border rounded-lg overflow-hidden", children: [
2029
- /* @__PURE__ */ jsx13("div", { className: "flex gap-4 p-4 bg-muted", children: headerKeys.map((key) => /* @__PURE__ */ jsx13(Skeleton, { className: "h-4 flex-1" }, key)) }),
2030
- rowKeys.map((rowKey, rowIdx) => /* @__PURE__ */ jsx13("div", { className: "flex gap-4 p-4 border-t", children: cellKeys[rowIdx]?.map((cellKey) => /* @__PURE__ */ jsx13(Skeleton, { className: "h-4 flex-1" }, cellKey)) }, rowKey))
2450
+ /* @__PURE__ */ jsxs13("div", { className: "border rounded-lg overflow-hidden", children: [
2451
+ /* @__PURE__ */ jsx17("div", { className: "flex gap-4 p-4 bg-muted", children: headerKeys.map((key) => /* @__PURE__ */ jsx17(Skeleton, { className: "h-4 flex-1" }, key)) }),
2452
+ rowKeys.map((rowKey, rowIdx) => /* @__PURE__ */ jsx17("div", { className: "flex gap-4 p-4 border-t", children: cellKeys[rowIdx]?.map((cellKey) => /* @__PURE__ */ jsx17(Skeleton, { className: "h-4 flex-1" }, cellKey)) }, rowKey))
2031
2453
  ] }),
2032
- /* @__PURE__ */ jsxs11("div", { className: "flex justify-between items-center", children: [
2033
- /* @__PURE__ */ jsx13(Skeleton, { className: "h-4 w-32" }),
2034
- /* @__PURE__ */ jsxs11("div", { className: "flex gap-2", children: [
2035
- /* @__PURE__ */ jsx13(Skeleton, { className: "h-10 w-20" }),
2036
- /* @__PURE__ */ jsx13(Skeleton, { className: "h-10 w-20" })
2454
+ /* @__PURE__ */ jsxs13("div", { className: "flex justify-between items-center", children: [
2455
+ /* @__PURE__ */ jsx17(Skeleton, { className: "h-4 w-32" }),
2456
+ /* @__PURE__ */ jsxs13("div", { className: "flex gap-2", children: [
2457
+ /* @__PURE__ */ jsx17(Skeleton, { className: "h-10 w-20" }),
2458
+ /* @__PURE__ */ jsx17(Skeleton, { className: "h-10 w-20" })
2037
2459
  ] })
2038
2460
  ] })
2039
2461
  ] });
2040
2462
  }
2041
2463
 
2042
2464
  // src/components/shared/data-table.tsx
2043
- import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
2465
+ import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
2044
2466
  function DataTable({
2045
2467
  data,
2046
2468
  columns,
@@ -2050,24 +2472,24 @@ function DataTable({
2050
2472
  actions
2051
2473
  }) {
2052
2474
  if (isLoading) {
2053
- return /* @__PURE__ */ jsx14(TableSkeleton, { columns: columns.length, rows: 5 });
2475
+ return /* @__PURE__ */ jsx18(TableSkeleton, { columns: columns.length, rows: 5 });
2054
2476
  }
2055
2477
  if (data.length === 0) {
2056
- return /* @__PURE__ */ jsxs12("div", { className: "flex flex-col items-center justify-center min-h-[400px] p-6", children: [
2057
- /* @__PURE__ */ jsx14("p", { className: "text-muted-foreground", children: emptyMessage }),
2058
- actions && /* @__PURE__ */ jsx14("div", { className: "mt-4", children: actions })
2478
+ return /* @__PURE__ */ jsxs14("div", { className: "flex flex-col items-center justify-center min-h-[400px] p-6", children: [
2479
+ /* @__PURE__ */ jsx18("p", { className: "text-muted-foreground", children: emptyMessage }),
2480
+ actions && /* @__PURE__ */ jsx18("div", { className: "mt-4", children: actions })
2059
2481
  ] });
2060
2482
  }
2061
- return /* @__PURE__ */ jsxs12("div", { className: "w-full space-y-4", children: [
2062
- actions && /* @__PURE__ */ jsx14("div", { className: "flex justify-end", children: actions }),
2063
- /* @__PURE__ */ jsx14("div", { className: "border rounded-lg overflow-hidden", children: /* @__PURE__ */ jsxs12(Table, { children: [
2064
- /* @__PURE__ */ jsx14(TableHeader, { children: /* @__PURE__ */ jsx14(TableRow, { children: columns.map((column) => /* @__PURE__ */ jsx14(TableHead, { children: column.header }, column.key)) }) }),
2065
- /* @__PURE__ */ jsx14(TableBody, { children: data.map((row) => /* @__PURE__ */ jsx14(
2483
+ return /* @__PURE__ */ jsxs14("div", { className: "w-full space-y-4", children: [
2484
+ actions && /* @__PURE__ */ jsx18("div", { className: "flex justify-end", children: actions }),
2485
+ /* @__PURE__ */ jsx18("div", { className: "border rounded-lg overflow-hidden", children: /* @__PURE__ */ jsxs14(Table, { children: [
2486
+ /* @__PURE__ */ jsx18(TableHeader, { children: /* @__PURE__ */ jsx18(TableRow, { children: columns.map((column) => /* @__PURE__ */ jsx18(TableHead, { children: column.header }, column.key)) }) }),
2487
+ /* @__PURE__ */ jsx18(TableBody, { children: data.map((row) => /* @__PURE__ */ jsx18(
2066
2488
  TableRow,
2067
2489
  {
2068
2490
  onClick: () => onRowClick?.(row),
2069
2491
  className: onRowClick ? "cursor-pointer hover:bg-muted/50" : "",
2070
- children: columns.map((column) => /* @__PURE__ */ jsx14(TableCell, { children: column.cell(row) }, `${row.id}-${column.key}`))
2492
+ children: columns.map((column) => /* @__PURE__ */ jsx18(TableCell, { children: column.cell(row) }, `${row.id}-${column.key}`))
2071
2493
  },
2072
2494
  row.id
2073
2495
  )) })
@@ -2076,23 +2498,10 @@ function DataTable({
2076
2498
  }
2077
2499
 
2078
2500
  // src/components/iam/permissions.tsx
2079
- import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
2080
- function getTranslation(value, locale) {
2081
- if (!value) {
2082
- return "";
2083
- }
2084
- if (typeof value === "string") {
2085
- return value;
2086
- }
2087
- if (typeof value === "object") {
2088
- return value[locale] ?? value.en ?? value.am ?? "";
2089
- }
2090
- return "";
2091
- }
2501
+ import { jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
2092
2502
  function Permissions() {
2093
2503
  const { hooks } = useApi();
2094
- const locale = useLocale();
2095
- const [page, setPage] = useState9(1);
2504
+ const [page, setPage] = useState10(1);
2096
2505
  const limit = 20;
2097
2506
  const { data, isLoading, error } = hooks.useQuery("get", "/permissions", {
2098
2507
  params: {
@@ -2102,88 +2511,636 @@ function Permissions() {
2102
2511
  }
2103
2512
  }
2104
2513
  });
2105
- const columns = [
2106
- {
2107
- key: "name",
2108
- header: "Permission",
2109
- cell: (permission) => /* @__PURE__ */ jsxs13("div", { children: [
2110
- /* @__PURE__ */ jsx15("p", { className: "font-medium", children: getTranslation(permission.name, locale) }),
2111
- /* @__PURE__ */ jsx15(Badge, { variant: "outline", className: "mt-1 font-mono text-xs", children: permission.code })
2112
- ] })
2113
- },
2114
- {
2115
- key: "resource",
2116
- header: "Resource",
2117
- cell: (permission) => /* @__PURE__ */ jsx15(Badge, { variant: "secondary", children: permission.resource })
2118
- },
2119
- {
2120
- key: "action",
2121
- header: "Action",
2122
- cell: (permission) => /* @__PURE__ */ jsx15(Badge, { variant: "outline", children: permission.action })
2123
- },
2514
+ const columns = [
2515
+ {
2516
+ key: "activity",
2517
+ header: "Permission",
2518
+ cell: (permission) => /* @__PURE__ */ jsxs15("div", { children: [
2519
+ /* @__PURE__ */ jsx19("p", { className: "font-medium", children: permission.activity }),
2520
+ /* @__PURE__ */ jsx19(Badge2, { variant: "outline", className: "mt-1 font-mono text-xs", children: permission.id })
2521
+ ] })
2522
+ },
2523
+ {
2524
+ key: "application",
2525
+ header: "Application",
2526
+ cell: (permission) => /* @__PURE__ */ jsx19(Badge2, { variant: "secondary", children: permission.application })
2527
+ },
2528
+ {
2529
+ key: "feature",
2530
+ header: "Feature",
2531
+ cell: (permission) => /* @__PURE__ */ jsx19(Badge2, { variant: "outline", children: permission.feature })
2532
+ },
2533
+ {
2534
+ key: "description",
2535
+ header: "Description",
2536
+ cell: (permission) => /* @__PURE__ */ jsx19("p", { className: "text-sm text-muted-foreground max-w-xs truncate", children: String(permission.description ?? "\u2014") })
2537
+ }
2538
+ ];
2539
+ if (error) {
2540
+ return /* @__PURE__ */ jsx19("div", { className: "p-6 text-center", children: /* @__PURE__ */ jsx19("p", { className: "text-destructive", children: "Error loading permissions" }) });
2541
+ }
2542
+ return /* @__PURE__ */ jsxs15("div", { className: "w-full p-6 space-y-4", children: [
2543
+ /* @__PURE__ */ jsxs15("div", { className: "flex justify-between items-center", children: [
2544
+ /* @__PURE__ */ jsxs15("div", { children: [
2545
+ /* @__PURE__ */ jsx19("h1", { className: "text-3xl font-bold", children: "Permissions" }),
2546
+ /* @__PURE__ */ jsx19("p", { className: "text-muted-foreground", children: "View the permission catalog for this tenant" })
2547
+ ] }),
2548
+ /* @__PURE__ */ jsx19(Button8, { variant: "outline", children: "Seed Permissions" })
2549
+ ] }),
2550
+ /* @__PURE__ */ jsx19(
2551
+ DataTable,
2552
+ {
2553
+ data: data?.permissions || [],
2554
+ columns,
2555
+ isLoading,
2556
+ emptyMessage: "No permissions found"
2557
+ }
2558
+ ),
2559
+ data && "permissions" in data && data.permissions && data.permissions.length >= limit && /* @__PURE__ */ jsxs15("div", { className: "flex justify-between items-center", children: [
2560
+ /* @__PURE__ */ jsx19(
2561
+ Button8,
2562
+ {
2563
+ variant: "outline",
2564
+ disabled: page === 1,
2565
+ onClick: () => setPage((prev) => prev - 1),
2566
+ children: "Previous"
2567
+ }
2568
+ ),
2569
+ /* @__PURE__ */ jsxs15("span", { className: "text-sm text-muted-foreground", children: [
2570
+ "Page ",
2571
+ page
2572
+ ] }),
2573
+ /* @__PURE__ */ jsx19(
2574
+ Button8,
2575
+ {
2576
+ variant: "outline",
2577
+ onClick: () => setPage((prev) => prev + 1),
2578
+ children: "Next"
2579
+ }
2580
+ )
2581
+ ] })
2582
+ ] });
2583
+ }
2584
+
2585
+ // src/components/iam/role-detail-layout.tsx
2586
+ import {
2587
+ EntityDetailHeader,
2588
+ EntityEmptyState,
2589
+ PageContainer,
2590
+ useBreadcrumbs
2591
+ } from "@mesob/ui/components";
2592
+ import { IconShield } from "@tabler/icons-react";
2593
+ import { useMemo as useMemo2 } from "react";
2594
+ import { jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
2595
+ function str(value) {
2596
+ if (value == null) {
2597
+ return "";
2598
+ }
2599
+ if (typeof value === "string") {
2600
+ return value;
2601
+ }
2602
+ if (typeof value === "object" && value !== null && "en" in value) {
2603
+ const localized = value;
2604
+ return localized.en ?? localized.am ?? "";
2605
+ }
2606
+ return String(value);
2607
+ }
2608
+ function RoleDetailLayout({
2609
+ roleId,
2610
+ basePath = "/iam/roles",
2611
+ children
2612
+ }) {
2613
+ const { hooks } = useApi();
2614
+ const { config } = useConfig();
2615
+ const { data, isLoading, isFetching, isError } = hooks.useQuery(
2616
+ "get",
2617
+ "/roles/{id}",
2618
+ { params: { path: { id: roleId } } },
2619
+ { enabled: !!roleId }
2620
+ );
2621
+ const role = data?.role;
2622
+ const title = role ? str(role.name) || role.code : roleId ?? "Role";
2623
+ useBreadcrumbs({
2624
+ items: [
2625
+ { label: "Home", href: "/dashboard" },
2626
+ { label: "IAM", href: "/iam" },
2627
+ { label: "Roles", href: basePath },
2628
+ { label: title }
2629
+ ]
2630
+ });
2631
+ const tabs = useMemo2(
2632
+ () => [
2633
+ { value: "detail", name: "Detail", href: `${basePath}/${roleId}` },
2634
+ {
2635
+ value: "permissions",
2636
+ name: "Permissions",
2637
+ href: `${basePath}/${roleId}/permissions`
2638
+ },
2639
+ {
2640
+ value: "users",
2641
+ name: "Users",
2642
+ href: `${basePath}/${roleId}/users`
2643
+ }
2644
+ ],
2645
+ [basePath, roleId]
2646
+ );
2647
+ if (!roleId) {
2648
+ return null;
2649
+ }
2650
+ const loading = isLoading || isFetching;
2651
+ if (!(loading || role)) {
2652
+ return /* @__PURE__ */ jsx20(PageContainer, { className: "flex flex-1 flex-col gap-4 p-4 pt-0", children: /* @__PURE__ */ jsx20(
2653
+ EntityEmptyState,
2654
+ {
2655
+ icon: IconShield,
2656
+ entityName: "role",
2657
+ title: isError ? "Role unavailable" : "Role not found",
2658
+ description: isError ? "Failed to load this role." : "This role no longer exists.",
2659
+ actionLabel: "Back to roles",
2660
+ onAction: () => config.navigation?.onNavigate?.(basePath) ?? window.history.back()
2661
+ }
2662
+ ) });
2663
+ }
2664
+ return /* @__PURE__ */ jsxs16(PageContainer, { className: "flex flex-1 flex-col gap-4 p-4 pt-0", children: [
2665
+ /* @__PURE__ */ jsx20(
2666
+ EntityDetailHeader,
2667
+ {
2668
+ title,
2669
+ icon: /* @__PURE__ */ jsx20(IconShield, { className: "h-5 w-5" }),
2670
+ loading,
2671
+ tabs
2672
+ }
2673
+ ),
2674
+ children
2675
+ ] });
2676
+ }
2677
+
2678
+ // src/components/iam/role-detail-page.tsx
2679
+ import { zodResolver as zodResolver7 } from "@hookform/resolvers/zod";
2680
+ import {
2681
+ EntityFormActions,
2682
+ Form as Form7,
2683
+ FormControl as FormControl7,
2684
+ FormField as FormField7,
2685
+ FormItem as FormItem7,
2686
+ FormLabel as FormLabel7,
2687
+ FormMessage as FormMessage7,
2688
+ Input as Input6,
2689
+ LocaleInputText,
2690
+ LocaleInputTextarea,
2691
+ Section,
2692
+ Skeleton as Skeleton2
2693
+ } from "@mesob/ui/components";
2694
+ import { useLocaleSchemas } from "@mesob/ui/providers";
2695
+ import { useQueryClient } from "@tanstack/react-query";
2696
+ import { useEffect as useEffect9, useMemo as useMemo3 } from "react";
2697
+ import { useForm as useForm7 } from "react-hook-form";
2698
+ import { toast as toast8 } from "sonner";
2699
+ import { z as z7 } from "zod";
2700
+ import { jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
2701
+ function RoleDetailPage({
2702
+ roleId,
2703
+ basePath = "/iam/roles"
2704
+ }) {
2705
+ const { hooks } = useApi();
2706
+ const { config } = useConfig();
2707
+ const qc = useQueryClient();
2708
+ const { localeInputDefault, requiredSchema, optionalSchema } = useLocaleSchemas();
2709
+ const schema = useMemo3(
2710
+ () => z7.object({
2711
+ name: requiredSchema,
2712
+ code: z7.string().min(1, "Code is required"),
2713
+ description: optionalSchema
2714
+ }),
2715
+ [requiredSchema, optionalSchema]
2716
+ );
2717
+ const defaults = useMemo3(
2718
+ () => ({
2719
+ name: { ...localeInputDefault },
2720
+ code: "",
2721
+ description: { ...localeInputDefault }
2722
+ }),
2723
+ [localeInputDefault]
2724
+ );
2725
+ const { data, isLoading } = hooks.useQuery(
2726
+ "get",
2727
+ "/roles/{id}",
2728
+ { params: { path: { id: roleId } } },
2729
+ { enabled: !!roleId }
2730
+ );
2731
+ const update = hooks.useMutation("put", "/roles/{id}", {
2732
+ onSuccess: () => {
2733
+ qc.invalidateQueries({ queryKey: ["get", "/roles"] });
2734
+ qc.invalidateQueries({ queryKey: ["get", "/roles/{id}"] });
2735
+ toast8.success("Role updated");
2736
+ },
2737
+ onError: () => {
2738
+ toast8.error("Failed to update role");
2739
+ }
2740
+ });
2741
+ const remove = hooks.useMutation("delete", "/roles/{id}", {
2742
+ onSuccess: () => {
2743
+ qc.invalidateQueries({ queryKey: ["get", "/roles"] });
2744
+ toast8.success("Role deleted");
2745
+ config.navigation?.onNavigate?.(basePath);
2746
+ },
2747
+ onError: () => {
2748
+ toast8.error("Failed to delete role");
2749
+ }
2750
+ });
2751
+ const form = useForm7({
2752
+ resolver: zodResolver7(schema),
2753
+ defaultValues: defaults
2754
+ });
2755
+ const { reset, formState, control, register } = form;
2756
+ useEffect9(() => {
2757
+ if (!data?.role) {
2758
+ return;
2759
+ }
2760
+ const r = data.role;
2761
+ reset({
2762
+ name: r.name ?? {},
2763
+ code: r.code,
2764
+ description: r.description ?? {}
2765
+ });
2766
+ }, [data?.role, reset]);
2767
+ if (!roleId) {
2768
+ return null;
2769
+ }
2770
+ const role = data?.role;
2771
+ const editable = role?.isEditable !== false;
2772
+ const deletable = role?.isDeletable !== false;
2773
+ const onSubmit = form.handleSubmit(async (d) => {
2774
+ await update.mutateAsync({
2775
+ params: { path: { id: roleId } },
2776
+ body: {
2777
+ name: d.name,
2778
+ code: d.code,
2779
+ description: d.description ?? void 0
2780
+ }
2781
+ });
2782
+ });
2783
+ const footer = role ? /* @__PURE__ */ jsx21(
2784
+ EntityFormActions,
2785
+ {
2786
+ mode: "edit",
2787
+ onSubmit,
2788
+ onDelete: deletable ? () => remove.mutate({
2789
+ params: { path: { id: roleId } }
2790
+ }) : void 0,
2791
+ isSubmitting: update.isPending,
2792
+ isDeleting: remove.isPending,
2793
+ disabled: !editable,
2794
+ itemName: "role"
2795
+ }
2796
+ ) : null;
2797
+ return /* @__PURE__ */ jsx21(Section, { title: "Role details", footer, defaultOpen: true, children: isLoading || !role ? /* @__PURE__ */ jsx21(RoleDetailSkeleton, {}) : /* @__PURE__ */ jsx21(Form7, { ...form, children: /* @__PURE__ */ jsxs17("form", { onSubmit, className: "space-y-4", children: [
2798
+ /* @__PURE__ */ jsx21(
2799
+ LocaleInputText,
2800
+ {
2801
+ label: "Name",
2802
+ field: "name",
2803
+ required: true,
2804
+ register,
2805
+ errors: formState.errors,
2806
+ placeholder: "e.g. Administrator",
2807
+ disabled: !editable
2808
+ }
2809
+ ),
2810
+ /* @__PURE__ */ jsx21(
2811
+ FormField7,
2812
+ {
2813
+ control,
2814
+ name: "code",
2815
+ render: ({ field }) => /* @__PURE__ */ jsxs17(FormItem7, { children: [
2816
+ /* @__PURE__ */ jsxs17(FormLabel7, { children: [
2817
+ "Code ",
2818
+ /* @__PURE__ */ jsx21("span", { className: "text-destructive", children: "*" })
2819
+ ] }),
2820
+ /* @__PURE__ */ jsx21(FormControl7, { children: /* @__PURE__ */ jsx21(
2821
+ Input6,
2822
+ {
2823
+ placeholder: "e.g. admin",
2824
+ disabled: !editable,
2825
+ ...field
2826
+ }
2827
+ ) }),
2828
+ /* @__PURE__ */ jsx21(FormMessage7, {})
2829
+ ] })
2830
+ }
2831
+ ),
2832
+ /* @__PURE__ */ jsx21(
2833
+ LocaleInputTextarea,
2834
+ {
2835
+ label: "Description",
2836
+ field: "description",
2837
+ register,
2838
+ errors: formState.errors,
2839
+ placeholder: "Description",
2840
+ rows: 3,
2841
+ disabled: !editable
2842
+ }
2843
+ )
2844
+ ] }) }) });
2845
+ }
2846
+ function RoleDetailSkeleton() {
2847
+ return /* @__PURE__ */ jsxs17("div", { className: "space-y-4", children: [
2848
+ /* @__PURE__ */ jsxs17("div", { className: "space-y-2", children: [
2849
+ /* @__PURE__ */ jsx21(Skeleton2, { className: "h-4 w-16" }),
2850
+ /* @__PURE__ */ jsx21(Skeleton2, { className: "h-10 w-full" })
2851
+ ] }),
2852
+ /* @__PURE__ */ jsxs17("div", { className: "space-y-2", children: [
2853
+ /* @__PURE__ */ jsx21(Skeleton2, { className: "h-4 w-14" }),
2854
+ /* @__PURE__ */ jsx21(Skeleton2, { className: "h-10 w-full" })
2855
+ ] }),
2856
+ /* @__PURE__ */ jsxs17("div", { className: "space-y-2", children: [
2857
+ /* @__PURE__ */ jsx21(Skeleton2, { className: "h-4 w-24" }),
2858
+ /* @__PURE__ */ jsx21(Skeleton2, { className: "h-20 w-full" })
2859
+ ] })
2860
+ ] });
2861
+ }
2862
+
2863
+ // src/components/iam/role-permissions-page.tsx
2864
+ import {
2865
+ Badge as Badge3,
2866
+ Button as Button9,
2867
+ DataTablePagination,
2868
+ DeleteConfirmButton,
2869
+ DisplayTable,
2870
+ EntityEmptyState as EntityEmptyState2,
2871
+ EntityFilter,
2872
+ EntityHeader,
2873
+ EntityLoadingState,
2874
+ EntitySearch,
2875
+ EntitySort,
2876
+ EntityViewToggle,
2877
+ PageBody,
2878
+ Tbody,
2879
+ Td,
2880
+ Th,
2881
+ Thead,
2882
+ Tr,
2883
+ useEntityPagination,
2884
+ useEntityParams
2885
+ } from "@mesob/ui/components";
2886
+ import { IconKey as IconKey2, IconPlus, IconTrash } from "@tabler/icons-react";
2887
+ import { useQueryClient as useQueryClient2 } from "@tanstack/react-query";
2888
+ import { useMemo as useMemo4 } from "react";
2889
+ import { toast as toast9 } from "sonner";
2890
+ import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
2891
+ var TABLE_COLUMN_COUNT = 4;
2892
+ function RolePermissionsPage({ roleId }) {
2893
+ const { hooks } = useApi();
2894
+ const qc = useQueryClient2();
2895
+ const { queryConfig, params, setParams } = useEntityParams({
2896
+ searchKey: "search",
2897
+ defaultSort: "application",
2898
+ defaultOrder: "asc"
2899
+ });
2900
+ const permissionsQuery = useMemo4(
2901
+ () => ({
2902
+ params: {
2903
+ path: { id: roleId },
2904
+ query: queryConfig.params.query
2905
+ }
2906
+ }),
2907
+ [queryConfig, roleId]
2908
+ );
2909
+ const { data, isPending, isFetching } = hooks.useQuery(
2910
+ "get",
2911
+ "/roles/{id}/permissions",
2912
+ permissionsQuery,
2913
+ { enabled: !!roleId }
2914
+ );
2915
+ const assignPermissions = hooks.useMutation(
2916
+ "post",
2917
+ "/roles/{id}/permissions",
2124
2918
  {
2125
- key: "description",
2126
- header: "Description",
2127
- cell: (permission) => /* @__PURE__ */ jsx15("p", { className: "text-sm text-muted-foreground max-w-xs truncate", children: getTranslation(permission.description, locale) })
2128
- },
2919
+ onSuccess: (result) => {
2920
+ qc.invalidateQueries({ queryKey: ["get", "/roles"] });
2921
+ qc.invalidateQueries({ queryKey: ["get", "/roles/{id}"] });
2922
+ qc.invalidateQueries({ queryKey: ["get", "/roles/{id}/permissions"] });
2923
+ toast9.success(
2924
+ result?.created ? `${result.created} permission(s) added` : "No changes"
2925
+ );
2926
+ },
2927
+ onError: () => {
2928
+ toast9.error("Failed to assign permissions");
2929
+ }
2930
+ }
2931
+ );
2932
+ const revokePermission = hooks.useMutation(
2933
+ "delete",
2934
+ "/roles/{id}/permissions/{permissionId}",
2129
2935
  {
2130
- key: "actions",
2131
- header: "Actions",
2132
- cell: (_permission) => /* @__PURE__ */ jsx15(Button7, { variant: "outline", size: "sm", children: "Edit" })
2936
+ onSuccess: () => {
2937
+ qc.invalidateQueries({ queryKey: ["get", "/roles"] });
2938
+ qc.invalidateQueries({ queryKey: ["get", "/roles/{id}"] });
2939
+ qc.invalidateQueries({
2940
+ queryKey: ["get", "/roles/{id}/permissions"]
2941
+ });
2942
+ toast9.success("Permission removed");
2943
+ },
2944
+ onError: () => {
2945
+ toast9.error("Failed to remove permission");
2946
+ }
2133
2947
  }
2134
- ];
2135
- if (error) {
2136
- return /* @__PURE__ */ jsx15("div", { className: "p-6 text-center", children: /* @__PURE__ */ jsx15("p", { className: "text-destructive", children: "Error loading permissions" }) });
2948
+ );
2949
+ const permissions = data?.permissions ?? [];
2950
+ const { total, pageCount } = useEntityPagination({
2951
+ items: permissions,
2952
+ total: data?.total,
2953
+ pageSize: params.pageSize
2954
+ });
2955
+ const isLoading = isPending || isFetching;
2956
+ const currentView = params.view || "table";
2957
+ if (!roleId) {
2958
+ return null;
2137
2959
  }
2138
- return /* @__PURE__ */ jsxs13("div", { className: "w-full p-6 space-y-4", children: [
2139
- /* @__PURE__ */ jsxs13("div", { className: "flex justify-between items-center", children: [
2140
- /* @__PURE__ */ jsxs13("div", { children: [
2141
- /* @__PURE__ */ jsx15("h1", { className: "text-3xl font-bold", children: "Permissions" }),
2142
- /* @__PURE__ */ jsx15("p", { className: "text-muted-foreground", children: "Manage system permissions" })
2143
- ] }),
2144
- /* @__PURE__ */ jsx15(Button7, { children: "Create Permission" })
2145
- ] }),
2146
- /* @__PURE__ */ jsx15(
2147
- DataTable,
2960
+ let content;
2961
+ if (isLoading) {
2962
+ content = /* @__PURE__ */ jsx22(
2963
+ EntityLoadingState,
2148
2964
  {
2149
- data: data?.permissions || [],
2150
- columns,
2151
- isLoading,
2152
- emptyMessage: "No permissions found"
2965
+ view: currentView,
2966
+ rowCount: params.pageSize,
2967
+ columnCount: TABLE_COLUMN_COUNT,
2968
+ cardCount: params.pageSize
2153
2969
  }
2154
- ),
2155
- data && "permissions" in data && data.permissions && data.permissions.length >= limit && /* @__PURE__ */ jsxs13("div", { className: "flex justify-between items-center", children: [
2156
- /* @__PURE__ */ jsx15(
2157
- Button7,
2970
+ );
2971
+ } else if (total === 0) {
2972
+ content = /* @__PURE__ */ jsx22(
2973
+ EntityEmptyState2,
2974
+ {
2975
+ icon: IconKey2,
2976
+ entityName: "permission",
2977
+ title: "No permissions assigned",
2978
+ description: "Assign permissions from the selector to grant access to this role."
2979
+ }
2980
+ );
2981
+ } else if (currentView === "table") {
2982
+ content = /* @__PURE__ */ jsxs18("div", { className: "space-y-4", children: [
2983
+ /* @__PURE__ */ jsxs18(DisplayTable, { withTableBorder: true, children: [
2984
+ /* @__PURE__ */ jsx22(Thead, { children: /* @__PURE__ */ jsxs18(Tr, { children: [
2985
+ /* @__PURE__ */ jsx22(Th, { children: "Permission" }),
2986
+ /* @__PURE__ */ jsx22(Th, { children: "Application" }),
2987
+ /* @__PURE__ */ jsx22(Th, { children: "Feature" }),
2988
+ /* @__PURE__ */ jsx22(Th, { className: "w-[60px]" })
2989
+ ] }) }),
2990
+ /* @__PURE__ */ jsx22(Tbody, { children: permissions.map((permission) => /* @__PURE__ */ jsxs18(Tr, { children: [
2991
+ /* @__PURE__ */ jsx22(Td, { children: /* @__PURE__ */ jsxs18("div", { className: "space-y-1", children: [
2992
+ /* @__PURE__ */ jsx22("p", { className: "font-medium", children: permission.activity }),
2993
+ /* @__PURE__ */ jsx22("p", { className: "font-mono text-xs text-muted-foreground", children: permission.id })
2994
+ ] }) }),
2995
+ /* @__PURE__ */ jsx22(Td, { children: /* @__PURE__ */ jsx22(Badge3, { variant: "secondary", children: permission.application }) }),
2996
+ /* @__PURE__ */ jsx22(Td, { children: /* @__PURE__ */ jsx22(Badge3, { variant: "outline", children: permission.feature }) }),
2997
+ /* @__PURE__ */ jsx22(Td, { children: /* @__PURE__ */ jsx22(
2998
+ DeleteConfirmButton,
2999
+ {
3000
+ entityName: "permission",
3001
+ onConfirm: () => revokePermission.mutate({
3002
+ params: {
3003
+ path: { id: roleId, permissionId: permission.id }
3004
+ }
3005
+ }),
3006
+ triggerClassName: "size-8 text-destructive hover:text-destructive"
3007
+ }
3008
+ ) })
3009
+ ] }, permission.id)) })
3010
+ ] }),
3011
+ /* @__PURE__ */ jsx22(
3012
+ DataTablePagination,
2158
3013
  {
2159
- variant: "outline",
2160
- disabled: page === 1,
2161
- onClick: () => setPage((prev) => prev - 1),
2162
- children: "Previous"
3014
+ pageIndex: params.page - 1,
3015
+ pageSize: params.pageSize,
3016
+ pageCount,
3017
+ totalRows: total,
3018
+ onPageChange: (page) => setParams({ page: page + 1 }),
3019
+ onPageSizeChange: (pageSize) => setParams({ pageSize, page: 1 })
2163
3020
  }
2164
- ),
2165
- /* @__PURE__ */ jsxs13("span", { className: "text-sm text-muted-foreground", children: [
2166
- "Page ",
2167
- page
2168
- ] }),
2169
- /* @__PURE__ */ jsx15(
2170
- Button7,
3021
+ )
3022
+ ] });
3023
+ } else {
3024
+ content = /* @__PURE__ */ jsxs18("div", { className: "space-y-4", children: [
3025
+ /* @__PURE__ */ jsx22("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-3", children: permissions.map((permission) => /* @__PURE__ */ jsx22(
3026
+ "div",
2171
3027
  {
2172
- variant: "outline",
2173
- onClick: () => setPage((prev) => prev + 1),
2174
- children: "Next"
3028
+ className: "rounded-xl border border-border/60 bg-card p-4 shadow-sm",
3029
+ children: /* @__PURE__ */ jsxs18("div", { className: "flex items-start justify-between gap-3", children: [
3030
+ /* @__PURE__ */ jsxs18("div", { className: "space-y-2", children: [
3031
+ /* @__PURE__ */ jsx22("p", { className: "font-semibold", children: permission.activity }),
3032
+ /* @__PURE__ */ jsxs18("div", { className: "flex flex-wrap gap-2", children: [
3033
+ /* @__PURE__ */ jsx22(Badge3, { variant: "secondary", children: permission.application }),
3034
+ /* @__PURE__ */ jsx22(Badge3, { variant: "outline", children: permission.feature })
3035
+ ] }),
3036
+ /* @__PURE__ */ jsx22("p", { className: "font-mono text-xs text-muted-foreground", children: permission.id })
3037
+ ] }),
3038
+ /* @__PURE__ */ jsx22(
3039
+ Button9,
3040
+ {
3041
+ type: "button",
3042
+ variant: "ghost",
3043
+ size: "icon",
3044
+ onClick: () => revokePermission.mutate({
3045
+ params: {
3046
+ path: { id: roleId, permissionId: permission.id }
3047
+ }
3048
+ }),
3049
+ disabled: revokePermission.isPending,
3050
+ children: /* @__PURE__ */ jsx22(IconTrash, { className: "h-4 w-4" })
3051
+ }
3052
+ )
3053
+ ] })
3054
+ },
3055
+ permission.id
3056
+ )) }),
3057
+ /* @__PURE__ */ jsx22(
3058
+ DataTablePagination,
3059
+ {
3060
+ pageIndex: params.page - 1,
3061
+ pageSize: params.pageSize,
3062
+ pageCount,
3063
+ totalRows: total,
3064
+ onPageChange: (page) => setParams({ page: page + 1 }),
3065
+ onPageSizeChange: (pageSize) => setParams({ pageSize, page: 1 })
2175
3066
  }
2176
3067
  )
2177
- ] })
3068
+ ] });
3069
+ }
3070
+ return /* @__PURE__ */ jsxs18(PageBody, { className: "px-0 pb-6", children: [
3071
+ /* @__PURE__ */ jsx22(
3072
+ EntityHeader,
3073
+ {
3074
+ icon: /* @__PURE__ */ jsx22(IconKey2, { className: "h-5 w-5" }),
3075
+ title: "Role permissions",
3076
+ actions: /* @__PURE__ */ jsx22(
3077
+ PermissionSelector,
3078
+ {
3079
+ trigger: /* @__PURE__ */ jsxs18(Button9, { size: "sm", loading: assignPermissions.isPending, children: [
3080
+ /* @__PURE__ */ jsx22(IconPlus, { className: "h-4 w-4" }),
3081
+ "Add permissions"
3082
+ ] }),
3083
+ onSelect: (selectedPermissions) => {
3084
+ if (!selectedPermissions.length) {
3085
+ return;
3086
+ }
3087
+ assignPermissions.mutate({
3088
+ params: { path: { id: roleId } },
3089
+ body: {
3090
+ permissionIds: selectedPermissions.map(
3091
+ (permission) => permission.id
3092
+ )
3093
+ }
3094
+ });
3095
+ },
3096
+ excludeIds: permissions.map((permission) => permission.id)
3097
+ }
3098
+ ),
3099
+ search: /* @__PURE__ */ jsx22(
3100
+ EntitySearch,
3101
+ {
3102
+ paramKey: "search",
3103
+ placeholder: "Search assigned permissions..."
3104
+ }
3105
+ ),
3106
+ filter: /* @__PURE__ */ jsx22(
3107
+ EntityFilter,
3108
+ {
3109
+ options: [
3110
+ { label: "All", value: "" },
3111
+ { label: "Application", value: "application" },
3112
+ { label: "Feature", value: "feature" },
3113
+ { label: "Activity", value: "activity" }
3114
+ ],
3115
+ placeholder: "Search field"
3116
+ }
3117
+ ),
3118
+ sort: /* @__PURE__ */ jsx22(
3119
+ EntitySort,
3120
+ {
3121
+ defaultSort: "application",
3122
+ defaultOrder: "asc",
3123
+ options: [
3124
+ { label: "ID", value: "id" },
3125
+ { label: "Application", value: "application" },
3126
+ { label: "Feature", value: "feature" },
3127
+ { label: "Activity", value: "activity" }
3128
+ ]
3129
+ }
3130
+ ),
3131
+ view: /* @__PURE__ */ jsx22(EntityViewToggle, { views: ["table", "card"] })
3132
+ }
3133
+ ),
3134
+ content
2178
3135
  ] });
2179
3136
  }
2180
3137
 
2181
3138
  // src/components/iam/roles.tsx
2182
- import { Badge as Badge2, Button as Button8 } from "@mesob/ui/components";
2183
- import { useLocale as useLocale2 } from "next-intl";
2184
- import { useState as useState10 } from "react";
2185
- import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
2186
- function getTranslation2(value, locale) {
3139
+ import { Badge as Badge4, Button as Button10 } from "@mesob/ui/components";
3140
+ import { useLocale } from "next-intl";
3141
+ import { useState as useState11 } from "react";
3142
+ import { jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
3143
+ function getTranslation(value, locale) {
2187
3144
  if (!value) {
2188
3145
  return "";
2189
3146
  }
@@ -2197,8 +3154,8 @@ function getTranslation2(value, locale) {
2197
3154
  }
2198
3155
  function Roles() {
2199
3156
  const { hooks } = useApi();
2200
- const locale = useLocale2();
2201
- const [page, setPage] = useState10(1);
3157
+ const locale = useLocale();
3158
+ const [page, setPage] = useState11(1);
2202
3159
  const limit = 20;
2203
3160
  const { data, isLoading, error } = hooks.useQuery("get", "/roles", {
2204
3161
  params: {
@@ -2212,42 +3169,45 @@ function Roles() {
2212
3169
  {
2213
3170
  key: "name",
2214
3171
  header: "Role",
2215
- cell: (role) => /* @__PURE__ */ jsxs14("div", { children: [
2216
- /* @__PURE__ */ jsx16("p", { className: "font-medium", children: getTranslation2(role.name, locale) }),
2217
- /* @__PURE__ */ jsx16(Badge2, { variant: "outline", className: "mt-1", children: role.code })
3172
+ cell: (role) => /* @__PURE__ */ jsxs19("div", { children: [
3173
+ /* @__PURE__ */ jsx23("p", { className: "font-medium", children: getTranslation(role.name, locale) }),
3174
+ /* @__PURE__ */ jsx23(Badge4, { variant: "outline", className: "mt-1", children: role.code })
2218
3175
  ] })
2219
3176
  },
2220
3177
  {
2221
- key: "description",
2222
- header: "Description",
2223
- cell: (role) => /* @__PURE__ */ jsx16("p", { className: "text-sm text-muted-foreground", children: getTranslation2(role.description, locale) })
3178
+ key: "access",
3179
+ header: "Access",
3180
+ cell: (role) => /* @__PURE__ */ jsxs19("div", { className: "flex flex-wrap gap-2", children: [
3181
+ role.isSystem ? /* @__PURE__ */ jsx23(Badge4, { children: "System" }) : null,
3182
+ /* @__PURE__ */ jsxs19(Badge4, { variant: "secondary", children: [
3183
+ role.permissionCount ?? 0,
3184
+ " permissions"
3185
+ ] })
3186
+ ] })
2224
3187
  },
2225
3188
  {
2226
3189
  key: "createdAt",
2227
3190
  header: "Created",
2228
- cell: (role) => /* @__PURE__ */ jsx16("p", { className: "text-sm", children: new Date(role.createdAt).toLocaleDateString() })
3191
+ cell: (role) => /* @__PURE__ */ jsx23("p", { className: "text-sm", children: new Date(role.createdAt).toLocaleDateString() })
2229
3192
  },
2230
3193
  {
2231
3194
  key: "actions",
2232
3195
  header: "Actions",
2233
- cell: (_role) => /* @__PURE__ */ jsxs14("div", { className: "flex gap-2", children: [
2234
- /* @__PURE__ */ jsx16(Button8, { variant: "outline", size: "sm", children: "Permissions" }),
2235
- /* @__PURE__ */ jsx16(Button8, { variant: "outline", size: "sm", children: "Edit" })
2236
- ] })
3196
+ cell: (_role) => /* @__PURE__ */ jsx23("div", { className: "flex gap-2", children: /* @__PURE__ */ jsx23(Button10, { variant: "outline", size: "sm", children: "Edit" }) })
2237
3197
  }
2238
3198
  ];
2239
3199
  if (error) {
2240
- return /* @__PURE__ */ jsx16("div", { className: "p-6 text-center", children: /* @__PURE__ */ jsx16("p", { className: "text-destructive", children: "Error loading roles" }) });
3200
+ return /* @__PURE__ */ jsx23("div", { className: "p-6 text-center", children: /* @__PURE__ */ jsx23("p", { className: "text-destructive", children: "Error loading roles" }) });
2241
3201
  }
2242
- return /* @__PURE__ */ jsxs14("div", { className: "w-full p-6 space-y-4", children: [
2243
- /* @__PURE__ */ jsxs14("div", { className: "flex justify-between items-center", children: [
2244
- /* @__PURE__ */ jsxs14("div", { children: [
2245
- /* @__PURE__ */ jsx16("h1", { className: "text-3xl font-bold", children: "Roles" }),
2246
- /* @__PURE__ */ jsx16("p", { className: "text-muted-foreground", children: "Manage user roles" })
3202
+ return /* @__PURE__ */ jsxs19("div", { className: "w-full p-6 space-y-4", children: [
3203
+ /* @__PURE__ */ jsxs19("div", { className: "flex justify-between items-center", children: [
3204
+ /* @__PURE__ */ jsxs19("div", { children: [
3205
+ /* @__PURE__ */ jsx23("h1", { className: "text-3xl font-bold", children: "Roles" }),
3206
+ /* @__PURE__ */ jsx23("p", { className: "text-muted-foreground", children: "Manage roles and assigned permissions" })
2247
3207
  ] }),
2248
- /* @__PURE__ */ jsx16(Button8, { children: "Create Role" })
3208
+ /* @__PURE__ */ jsx23(Button10, { children: "Create Role" })
2249
3209
  ] }),
2250
- /* @__PURE__ */ jsx16(
3210
+ /* @__PURE__ */ jsx23(
2251
3211
  DataTable,
2252
3212
  {
2253
3213
  data: data?.roles || [],
@@ -2256,9 +3216,9 @@ function Roles() {
2256
3216
  emptyMessage: "No roles found"
2257
3217
  }
2258
3218
  ),
2259
- data && "roles" in data && data.roles && data.roles.length >= limit && /* @__PURE__ */ jsxs14("div", { className: "flex justify-between items-center", children: [
2260
- /* @__PURE__ */ jsx16(
2261
- Button8,
3219
+ data && "roles" in data && data.roles && data.roles.length >= limit && /* @__PURE__ */ jsxs19("div", { className: "flex justify-between items-center", children: [
3220
+ /* @__PURE__ */ jsx23(
3221
+ Button10,
2262
3222
  {
2263
3223
  variant: "outline",
2264
3224
  disabled: page === 1,
@@ -2266,12 +3226,12 @@ function Roles() {
2266
3226
  children: "Previous"
2267
3227
  }
2268
3228
  ),
2269
- /* @__PURE__ */ jsxs14("span", { className: "text-sm text-muted-foreground", children: [
3229
+ /* @__PURE__ */ jsxs19("span", { className: "text-sm text-muted-foreground", children: [
2270
3230
  "Page ",
2271
3231
  page
2272
3232
  ] }),
2273
- /* @__PURE__ */ jsx16(
2274
- Button8,
3233
+ /* @__PURE__ */ jsx23(
3234
+ Button10,
2275
3235
  {
2276
3236
  variant: "outline",
2277
3237
  onClick: () => setPage((prev) => prev + 1),
@@ -2283,12 +3243,12 @@ function Roles() {
2283
3243
  }
2284
3244
 
2285
3245
  // src/components/iam/sessions.tsx
2286
- import { Button as Button9 } from "@mesob/ui/components";
2287
- import { useState as useState11 } from "react";
2288
- import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
3246
+ import { Button as Button11 } from "@mesob/ui/components";
3247
+ import { useState as useState12 } from "react";
3248
+ import { jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
2289
3249
  function Sessions() {
2290
3250
  const { hooks } = useApi();
2291
- const [selectedSessionId] = useState11(null);
3251
+ const [selectedSessionId] = useState12(null);
2292
3252
  const { data, isLoading, error, refetch } = hooks.useQuery(
2293
3253
  "get",
2294
3254
  "/sessions"
@@ -2314,31 +3274,31 @@ function Sessions() {
2314
3274
  {
2315
3275
  key: "createdAt",
2316
3276
  header: "Created",
2317
- cell: (session) => /* @__PURE__ */ jsxs15("div", { children: [
2318
- /* @__PURE__ */ jsx17("p", { className: "text-sm font-medium", children: new Date(session.createdAt).toLocaleDateString() }),
2319
- /* @__PURE__ */ jsx17("p", { className: "text-xs text-muted-foreground", children: new Date(session.createdAt).toLocaleTimeString() })
3277
+ cell: (session) => /* @__PURE__ */ jsxs20("div", { children: [
3278
+ /* @__PURE__ */ jsx24("p", { className: "text-sm font-medium", children: new Date(session.createdAt).toLocaleDateString() }),
3279
+ /* @__PURE__ */ jsx24("p", { className: "text-xs text-muted-foreground", children: new Date(session.createdAt).toLocaleTimeString() })
2320
3280
  ] })
2321
3281
  },
2322
3282
  {
2323
3283
  key: "expiresAt",
2324
3284
  header: "Expires",
2325
- cell: (session) => /* @__PURE__ */ jsx17("p", { className: "text-sm", children: new Date(session.expiresAt).toLocaleDateString() })
3285
+ cell: (session) => /* @__PURE__ */ jsx24("p", { className: "text-sm", children: new Date(session.expiresAt).toLocaleDateString() })
2326
3286
  },
2327
3287
  {
2328
3288
  key: "userAgent",
2329
3289
  header: "Device",
2330
- cell: (session) => /* @__PURE__ */ jsx17("p", { className: "text-sm truncate max-w-xs", children: session.userAgent || "Unknown" })
3290
+ cell: (session) => /* @__PURE__ */ jsx24("p", { className: "text-sm truncate max-w-xs", children: session.userAgent || "Unknown" })
2331
3291
  },
2332
3292
  {
2333
3293
  key: "ip",
2334
3294
  header: "IP Address",
2335
- cell: (session) => /* @__PURE__ */ jsx17("p", { className: "text-sm font-mono", children: session.ip || "Unknown" })
3295
+ cell: (session) => /* @__PURE__ */ jsx24("p", { className: "text-sm font-mono", children: session.ip || "Unknown" })
2336
3296
  },
2337
3297
  {
2338
3298
  key: "actions",
2339
3299
  header: "Actions",
2340
- cell: (session) => /* @__PURE__ */ jsx17(
2341
- Button9,
3300
+ cell: (session) => /* @__PURE__ */ jsx24(
3301
+ Button11,
2342
3302
  {
2343
3303
  variant: "destructive",
2344
3304
  size: "sm",
@@ -2350,14 +3310,14 @@ function Sessions() {
2350
3310
  }
2351
3311
  ];
2352
3312
  if (error) {
2353
- return /* @__PURE__ */ jsx17("div", { className: "p-6 text-center", children: /* @__PURE__ */ jsx17("p", { className: "text-destructive", children: "Error loading sessions" }) });
3313
+ return /* @__PURE__ */ jsx24("div", { className: "p-6 text-center", children: /* @__PURE__ */ jsx24("p", { className: "text-destructive", children: "Error loading sessions" }) });
2354
3314
  }
2355
- return /* @__PURE__ */ jsxs15("div", { className: "w-full p-6 space-y-4", children: [
2356
- /* @__PURE__ */ jsxs15("div", { children: [
2357
- /* @__PURE__ */ jsx17("h1", { className: "text-3xl font-bold", children: "Sessions" }),
2358
- /* @__PURE__ */ jsx17("p", { className: "text-muted-foreground", children: "View and manage active sessions" })
3315
+ return /* @__PURE__ */ jsxs20("div", { className: "w-full p-6 space-y-4", children: [
3316
+ /* @__PURE__ */ jsxs20("div", { children: [
3317
+ /* @__PURE__ */ jsx24("h1", { className: "text-3xl font-bold", children: "Sessions" }),
3318
+ /* @__PURE__ */ jsx24("p", { className: "text-muted-foreground", children: "View and manage active sessions" })
2359
3319
  ] }),
2360
- /* @__PURE__ */ jsx17(
3320
+ /* @__PURE__ */ jsx24(
2361
3321
  DataTable,
2362
3322
  {
2363
3323
  data: data?.sessions || [],
@@ -2370,12 +3330,12 @@ function Sessions() {
2370
3330
  }
2371
3331
 
2372
3332
  // src/components/iam/tenants.tsx
2373
- import { Badge as Badge3, Button as Button10 } from "@mesob/ui/components";
2374
- import { useState as useState12 } from "react";
2375
- import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
3333
+ import { Badge as Badge5, Button as Button12 } from "@mesob/ui/components";
3334
+ import { useState as useState13 } from "react";
3335
+ import { jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
2376
3336
  function Tenants() {
2377
3337
  const { hooks } = useApi();
2378
- const [page, setPage] = useState12(1);
3338
+ const [page, setPage] = useState13(1);
2379
3339
  const limit = 20;
2380
3340
  const { data, isLoading, error } = hooks.useQuery("get", "/tenants", {
2381
3341
  params: {
@@ -2389,9 +3349,9 @@ function Tenants() {
2389
3349
  {
2390
3350
  key: "name",
2391
3351
  header: "Tenant",
2392
- cell: (tenant) => /* @__PURE__ */ jsxs16("div", { children: [
2393
- /* @__PURE__ */ jsx18("p", { className: "font-medium", children: tenant.name }),
2394
- /* @__PURE__ */ jsxs16("p", { className: "text-sm text-muted-foreground", children: [
3352
+ cell: (tenant) => /* @__PURE__ */ jsxs21("div", { children: [
3353
+ /* @__PURE__ */ jsx25("p", { className: "font-medium", children: tenant.name }),
3354
+ /* @__PURE__ */ jsxs21("p", { className: "text-sm text-muted-foreground", children: [
2395
3355
  "/",
2396
3356
  tenant.slug
2397
3357
  ] })
@@ -2400,34 +3360,34 @@ function Tenants() {
2400
3360
  {
2401
3361
  key: "status",
2402
3362
  header: "Status",
2403
- cell: (tenant) => /* @__PURE__ */ jsx18(Badge3, { variant: tenant.status === "active" ? "default" : "secondary", children: tenant.status })
3363
+ cell: (tenant) => /* @__PURE__ */ jsx25(Badge5, { variant: tenant.status === "active" ? "default" : "secondary", children: tenant.status })
2404
3364
  },
2405
3365
  {
2406
3366
  key: "createdAt",
2407
3367
  header: "Created",
2408
- cell: (tenant) => /* @__PURE__ */ jsx18("p", { className: "text-sm", children: new Date(tenant.createdAt).toLocaleDateString() })
3368
+ cell: (tenant) => /* @__PURE__ */ jsx25("p", { className: "text-sm", children: new Date(tenant.createdAt).toLocaleDateString() })
2409
3369
  },
2410
3370
  {
2411
3371
  key: "actions",
2412
3372
  header: "Actions",
2413
- cell: (_tenant) => /* @__PURE__ */ jsxs16("div", { className: "flex gap-2", children: [
2414
- /* @__PURE__ */ jsx18(Button10, { variant: "outline", size: "sm", children: "Domains" }),
2415
- /* @__PURE__ */ jsx18(Button10, { variant: "outline", size: "sm", children: "Edit" })
3373
+ cell: (_tenant) => /* @__PURE__ */ jsxs21("div", { className: "flex gap-2", children: [
3374
+ /* @__PURE__ */ jsx25(Button12, { variant: "outline", size: "sm", children: "Domains" }),
3375
+ /* @__PURE__ */ jsx25(Button12, { variant: "outline", size: "sm", children: "Edit" })
2416
3376
  ] })
2417
3377
  }
2418
3378
  ];
2419
3379
  if (error) {
2420
- return /* @__PURE__ */ jsx18("div", { className: "p-6 text-center", children: /* @__PURE__ */ jsx18("p", { className: "text-destructive", children: "Error loading tenants" }) });
3380
+ return /* @__PURE__ */ jsx25("div", { className: "p-6 text-center", children: /* @__PURE__ */ jsx25("p", { className: "text-destructive", children: "Error loading tenants" }) });
2421
3381
  }
2422
- return /* @__PURE__ */ jsxs16("div", { className: "w-full p-6 space-y-4", children: [
2423
- /* @__PURE__ */ jsxs16("div", { className: "flex justify-between items-center", children: [
2424
- /* @__PURE__ */ jsxs16("div", { children: [
2425
- /* @__PURE__ */ jsx18("h1", { className: "text-3xl font-bold", children: "Tenants" }),
2426
- /* @__PURE__ */ jsx18("p", { className: "text-muted-foreground", children: "Manage tenant organizations" })
3382
+ return /* @__PURE__ */ jsxs21("div", { className: "w-full p-6 space-y-4", children: [
3383
+ /* @__PURE__ */ jsxs21("div", { className: "flex justify-between items-center", children: [
3384
+ /* @__PURE__ */ jsxs21("div", { children: [
3385
+ /* @__PURE__ */ jsx25("h1", { className: "text-3xl font-bold", children: "Tenants" }),
3386
+ /* @__PURE__ */ jsx25("p", { className: "text-muted-foreground", children: "Manage tenant organizations" })
2427
3387
  ] }),
2428
- /* @__PURE__ */ jsx18(Button10, { children: "Create Tenant" })
3388
+ /* @__PURE__ */ jsx25(Button12, { children: "Create Tenant" })
2429
3389
  ] }),
2430
- /* @__PURE__ */ jsx18(
3390
+ /* @__PURE__ */ jsx25(
2431
3391
  DataTable,
2432
3392
  {
2433
3393
  data: data?.tenants || [],
@@ -2436,9 +3396,9 @@ function Tenants() {
2436
3396
  emptyMessage: "No tenants found"
2437
3397
  }
2438
3398
  ),
2439
- data && "tenants" in data && data.tenants && data.tenants.length >= limit && /* @__PURE__ */ jsxs16("div", { className: "flex justify-between items-center", children: [
2440
- /* @__PURE__ */ jsx18(
2441
- Button10,
3399
+ data && "tenants" in data && data.tenants && data.tenants.length >= limit && /* @__PURE__ */ jsxs21("div", { className: "flex justify-between items-center", children: [
3400
+ /* @__PURE__ */ jsx25(
3401
+ Button12,
2442
3402
  {
2443
3403
  variant: "outline",
2444
3404
  disabled: page === 1,
@@ -2446,12 +3406,12 @@ function Tenants() {
2446
3406
  children: "Previous"
2447
3407
  }
2448
3408
  ),
2449
- /* @__PURE__ */ jsxs16("span", { className: "text-sm text-muted-foreground", children: [
3409
+ /* @__PURE__ */ jsxs21("span", { className: "text-sm text-muted-foreground", children: [
2450
3410
  "Page ",
2451
3411
  page
2452
3412
  ] }),
2453
- /* @__PURE__ */ jsx18(
2454
- Button10,
3413
+ /* @__PURE__ */ jsx25(
3414
+ Button12,
2455
3415
  {
2456
3416
  variant: "outline",
2457
3417
  onClick: () => setPage((prev) => prev + 1),
@@ -2463,12 +3423,12 @@ function Tenants() {
2463
3423
  }
2464
3424
 
2465
3425
  // src/components/iam/users.tsx
2466
- import { Badge as Badge4, Button as Button11 } from "@mesob/ui/components";
2467
- import { useState as useState13 } from "react";
2468
- import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
3426
+ import { Badge as Badge6, Button as Button13 } from "@mesob/ui/components";
3427
+ import { useState as useState14 } from "react";
3428
+ import { jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
2469
3429
  function Users() {
2470
3430
  const { hooks } = useApi();
2471
- const [page, setPage] = useState13(1);
3431
+ const [page, setPage] = useState14(1);
2472
3432
  const limit = 20;
2473
3433
  const { data, isLoading, error } = hooks.useQuery("get", "/users", {
2474
3434
  params: {
@@ -2482,54 +3442,48 @@ function Users() {
2482
3442
  {
2483
3443
  key: "fullName",
2484
3444
  header: "Name",
2485
- cell: (user) => /* @__PURE__ */ jsxs17("div", { children: [
2486
- /* @__PURE__ */ jsx19("p", { className: "font-medium", children: user.fullName }),
2487
- /* @__PURE__ */ jsxs17("p", { className: "text-sm text-muted-foreground", children: [
2488
- "@",
2489
- user.handle
2490
- ] })
2491
- ] })
3445
+ cell: (user) => /* @__PURE__ */ jsx26("div", { children: /* @__PURE__ */ jsx26("p", { className: "font-medium", children: user.fullName }) })
2492
3446
  },
2493
3447
  {
2494
3448
  key: "contact",
2495
3449
  header: "Contact",
2496
- cell: (user) => /* @__PURE__ */ jsxs17("div", { className: "space-y-1", children: [
2497
- user.email && /* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-2", children: [
2498
- /* @__PURE__ */ jsx19("p", { className: "text-sm", children: user.email }),
2499
- user.emailVerified && /* @__PURE__ */ jsx19(Badge4, { variant: "outline", className: "text-xs", children: "Verified" })
3450
+ cell: (user) => /* @__PURE__ */ jsxs22("div", { className: "space-y-1", children: [
3451
+ user.email && /* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-2", children: [
3452
+ /* @__PURE__ */ jsx26("p", { className: "text-sm", children: user.email }),
3453
+ user.emailVerified && /* @__PURE__ */ jsx26(Badge6, { variant: "outline", className: "text-xs", children: "Verified" })
2500
3454
  ] }),
2501
- user.phone && /* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-2", children: [
2502
- /* @__PURE__ */ jsx19("p", { className: "text-sm", children: user.phone }),
2503
- user.phoneVerified && /* @__PURE__ */ jsx19(Badge4, { variant: "outline", className: "text-xs", children: "Verified" })
3455
+ user.phone && /* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-2", children: [
3456
+ /* @__PURE__ */ jsx26("p", { className: "text-sm", children: user.phone }),
3457
+ user.phoneVerified && /* @__PURE__ */ jsx26(Badge6, { variant: "outline", className: "text-xs", children: "Verified" })
2504
3458
  ] })
2505
3459
  ] })
2506
3460
  },
2507
3461
  {
2508
3462
  key: "lastSignIn",
2509
3463
  header: "Last Sign In",
2510
- cell: (user) => /* @__PURE__ */ jsx19("p", { className: "text-sm", children: user.lastSignInAt ? new Date(user.lastSignInAt).toLocaleDateString() : "Never" })
3464
+ cell: (user) => /* @__PURE__ */ jsx26("p", { className: "text-sm", children: user.lastSignInAt ? new Date(user.lastSignInAt).toLocaleDateString() : "Never" })
2511
3465
  },
2512
3466
  {
2513
3467
  key: "actions",
2514
3468
  header: "Actions",
2515
- cell: (_user) => /* @__PURE__ */ jsxs17("div", { className: "flex gap-2", children: [
2516
- /* @__PURE__ */ jsx19(Button11, { variant: "outline", size: "sm", children: "View" }),
2517
- /* @__PURE__ */ jsx19(Button11, { variant: "outline", size: "sm", children: "Edit" })
3469
+ cell: (_user) => /* @__PURE__ */ jsxs22("div", { className: "flex gap-2", children: [
3470
+ /* @__PURE__ */ jsx26(Button13, { variant: "outline", size: "sm", children: "View" }),
3471
+ /* @__PURE__ */ jsx26(Button13, { variant: "outline", size: "sm", children: "Edit" })
2518
3472
  ] })
2519
3473
  }
2520
3474
  ];
2521
3475
  if (error) {
2522
- return /* @__PURE__ */ jsx19("div", { className: "p-6 text-center", children: /* @__PURE__ */ jsx19("p", { className: "text-destructive", children: "Error loading users" }) });
3476
+ return /* @__PURE__ */ jsx26("div", { className: "p-6 text-center", children: /* @__PURE__ */ jsx26("p", { className: "text-destructive", children: "Error loading users" }) });
2523
3477
  }
2524
- return /* @__PURE__ */ jsxs17("div", { className: "w-full p-6 space-y-4", children: [
2525
- /* @__PURE__ */ jsxs17("div", { className: "flex justify-between items-center", children: [
2526
- /* @__PURE__ */ jsxs17("div", { children: [
2527
- /* @__PURE__ */ jsx19("h1", { className: "text-3xl font-bold", children: "Users" }),
2528
- /* @__PURE__ */ jsx19("p", { className: "text-muted-foreground", children: "Manage user accounts" })
3478
+ return /* @__PURE__ */ jsxs22("div", { className: "w-full p-6 space-y-4", children: [
3479
+ /* @__PURE__ */ jsxs22("div", { className: "flex justify-between items-center", children: [
3480
+ /* @__PURE__ */ jsxs22("div", { children: [
3481
+ /* @__PURE__ */ jsx26("h1", { className: "text-3xl font-bold", children: "Users" }),
3482
+ /* @__PURE__ */ jsx26("p", { className: "text-muted-foreground", children: "Manage user accounts" })
2529
3483
  ] }),
2530
- /* @__PURE__ */ jsx19(Button11, { children: "Create User" })
3484
+ /* @__PURE__ */ jsx26(Button13, { children: "Create User" })
2531
3485
  ] }),
2532
- /* @__PURE__ */ jsx19(
3486
+ /* @__PURE__ */ jsx26(
2533
3487
  DataTable,
2534
3488
  {
2535
3489
  data: data?.users || [],
@@ -2538,9 +3492,9 @@ function Users() {
2538
3492
  emptyMessage: "No users found"
2539
3493
  }
2540
3494
  ),
2541
- data && "users" in data && data.users && data.users.length >= limit && /* @__PURE__ */ jsxs17("div", { className: "flex justify-between items-center", children: [
2542
- /* @__PURE__ */ jsx19(
2543
- Button11,
3495
+ data && "users" in data && data.users && data.users.length >= limit && /* @__PURE__ */ jsxs22("div", { className: "flex justify-between items-center", children: [
3496
+ /* @__PURE__ */ jsx26(
3497
+ Button13,
2544
3498
  {
2545
3499
  variant: "outline",
2546
3500
  disabled: page === 1,
@@ -2548,12 +3502,12 @@ function Users() {
2548
3502
  children: "Previous"
2549
3503
  }
2550
3504
  ),
2551
- /* @__PURE__ */ jsxs17("span", { className: "text-sm text-muted-foreground", children: [
3505
+ /* @__PURE__ */ jsxs22("span", { className: "text-sm text-muted-foreground", children: [
2552
3506
  "Page ",
2553
3507
  page
2554
3508
  ] }),
2555
- /* @__PURE__ */ jsx19(
2556
- Button11,
3509
+ /* @__PURE__ */ jsx26(
3510
+ Button13,
2557
3511
  {
2558
3512
  variant: "outline",
2559
3513
  onClick: () => setPage((prev) => prev + 1),
@@ -2565,56 +3519,152 @@ function Users() {
2565
3519
  }
2566
3520
 
2567
3521
  // src/components/profile/account.tsx
2568
- import { Separator } from "@mesob/ui/components";
2569
- import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
3522
+ import { Badge as Badge8, Card as Card2, CardContent, Separator } from "@mesob/ui/components";
3523
+
3524
+ // src/components/profile/change-profile.tsx
3525
+ import {
3526
+ Avatar,
3527
+ AvatarFallback,
3528
+ AvatarImage,
3529
+ Badge as Badge7,
3530
+ Button as Button14
3531
+ } from "@mesob/ui/components";
3532
+ import { useState as useState15 } from "react";
3533
+ import { jsx as jsx27, jsxs as jsxs23 } from "react/jsx-runtime";
3534
+ var ChangeProfile = ({ user }) => {
3535
+ const [isEditing, setIsEditing] = useState15(false);
3536
+ const initials = user.fullName?.split(" ").map((part) => part[0]).join("").toUpperCase().slice(0, 2) || "U";
3537
+ return /* @__PURE__ */ jsxs23("div", { className: "w-full rounded-[1.5rem] border border-border/60 bg-background/80 p-5 shadow-sm backdrop-blur", children: [
3538
+ /* @__PURE__ */ jsxs23("div", { className: "flex flex-col gap-4 md:flex-row md:items-center md:justify-between", children: [
3539
+ /* @__PURE__ */ jsxs23("div", { className: "flex items-center gap-4", children: [
3540
+ /* @__PURE__ */ jsxs23(Avatar, { className: "h-14 w-14 ring-4 ring-primary/10", children: [
3541
+ /* @__PURE__ */ jsx27(AvatarImage, { src: user.image || "", alt: user.fullName || "" }),
3542
+ /* @__PURE__ */ jsx27(AvatarFallback, { children: initials })
3543
+ ] }),
3544
+ /* @__PURE__ */ jsxs23("div", { className: "space-y-1", children: [
3545
+ /* @__PURE__ */ jsx27("div", { className: "text-base font-semibold", children: user.fullName }),
3546
+ /* @__PURE__ */ jsxs23("div", { className: "flex flex-wrap gap-2 text-xs text-muted-foreground", children: [
3547
+ /* @__PURE__ */ jsx27(Badge7, { variant: "outline", children: user.emailVerified ? "Email verified" : "Email unverified" }),
3548
+ /* @__PURE__ */ jsx27(Badge7, { variant: "outline", children: user.phoneVerified ? "Phone verified" : "Phone unverified" })
3549
+ ] })
3550
+ ] })
3551
+ ] }),
3552
+ /* @__PURE__ */ jsx27(
3553
+ Button14,
3554
+ {
3555
+ variant: "secondary",
3556
+ className: "rounded-full px-5 text-primary hover:text-primary/80",
3557
+ onClick: () => setIsEditing((v) => !v),
3558
+ children: isEditing ? "Hide editor" : "Update profile"
3559
+ }
3560
+ )
3561
+ ] }),
3562
+ isEditing && /* @__PURE__ */ jsx27("div", { className: "mt-4 rounded-2xl border border-dashed border-border bg-muted/30 px-4 py-3 text-sm text-muted-foreground", children: "Profile editing is not wired yet. Contact and password flows below are live." })
3563
+ ] });
3564
+ };
3565
+
3566
+ // src/components/profile/account.tsx
3567
+ import { jsx as jsx28, jsxs as jsxs24 } from "react/jsx-runtime";
2570
3568
  function Account() {
2571
3569
  const { user, isAuthenticated } = useSession();
2572
3570
  if (!(isAuthenticated && user)) {
2573
- return /* @__PURE__ */ jsx20("div", { children: "Sign in required" });
3571
+ return /* @__PURE__ */ jsx28("div", { className: "rounded-[1.75rem] border border-dashed border-border bg-muted/30 p-8 text-sm text-muted-foreground", children: "Sign in required." });
2574
3572
  }
2575
- return /* @__PURE__ */ jsxs18("div", { className: "p-6 max-w-4xl", children: [
2576
- /* @__PURE__ */ jsxs18("div", { className: "mb-6", children: [
2577
- /* @__PURE__ */ jsx20("h2", { className: "text-lg font-semibold mb-4", children: "Profile details" }),
2578
- /* @__PURE__ */ jsx20(Separator, {})
2579
- ] }),
2580
- /* @__PURE__ */ jsxs18("div", { className: "space-y-6 transition-all duration-300 ease-in-out", children: [
2581
- /* @__PURE__ */ jsx20("div", { className: "flex flex-col md:flex-row items-start gap-4 md:gap-12 min-h-[3rem]", children: /* @__PURE__ */ jsx20("div", { className: "w-full md:w-48 mt-4 shrink-0 h-fit", children: /* @__PURE__ */ jsx20("span", { className: "font-medium text-sm", children: "Profile" }) }) }),
2582
- /* @__PURE__ */ jsx20(Separator, {}),
2583
- /* @__PURE__ */ jsxs18("div", { className: "flex flex-col md:flex-row gap-4 md:gap-12 py-2", children: [
2584
- /* @__PURE__ */ jsx20("div", { className: "w-full md:w-48 shrink-0", children: /* @__PURE__ */ jsx20("span", { className: "font-medium text-sm", children: "Email addresses" }) }),
2585
- /* @__PURE__ */ jsx20("div", { className: "flex-1 space-y-4", children: /* @__PURE__ */ jsx20("div", { className: "flex items-center justify-between group", children: user.email ? /* @__PURE__ */ jsx20("div", { className: "flex items-center gap-3", children: /* @__PURE__ */ jsx20("span", { className: "text-sm", children: user.email }) }) : /* @__PURE__ */ jsx20("span", { className: "text-sm text-muted-foreground", children: "No email address" }) }) })
2586
- ] }),
2587
- /* @__PURE__ */ jsx20(Separator, {}),
2588
- /* @__PURE__ */ jsxs18("div", { className: "flex flex-col md:flex-row gap-4 md:gap-12 py-2", children: [
2589
- /* @__PURE__ */ jsx20("div", { className: "w-full md:w-48 shrink-0", children: /* @__PURE__ */ jsx20("span", { className: "font-medium text-sm", children: "Phone numbers" }) }),
2590
- /* @__PURE__ */ jsx20("div", { className: "flex-1 space-y-4", children: user.phone ? /* @__PURE__ */ jsx20("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsx20("span", { className: "text-sm", children: user.phone }) }) : /* @__PURE__ */ jsx20("span", { className: "text-sm text-muted-foreground", children: "No phone number" }) })
3573
+ const contactItems = [
3574
+ {
3575
+ label: "Email",
3576
+ value: user.email ?? "No email address",
3577
+ status: user.emailVerified ? "Verified" : "Needs verification"
3578
+ },
3579
+ {
3580
+ label: "Phone",
3581
+ value: user.phone ?? "No phone number",
3582
+ status: user.phoneVerified ? "Verified" : "Needs verification"
3583
+ }
3584
+ ];
3585
+ return /* @__PURE__ */ jsxs24("div", { className: "mx-auto flex w-full max-w-6xl flex-col gap-6", children: [
3586
+ /* @__PURE__ */ jsxs24("div", { className: "relative overflow-hidden rounded-[2rem] border border-border/60 bg-gradient-to-br from-background via-background to-primary/5 p-6 shadow-sm", children: [
3587
+ /* @__PURE__ */ jsx28("div", { className: "absolute inset-y-0 right-0 w-1/3 bg-[radial-gradient(circle_at_top,_hsl(var(--primary)/0.16),_transparent_60%)]" }),
3588
+ /* @__PURE__ */ jsxs24("div", { className: "relative flex flex-col gap-5", children: [
3589
+ /* @__PURE__ */ jsxs24("div", { className: "flex flex-wrap items-center gap-2", children: [
3590
+ /* @__PURE__ */ jsx28(Badge8, { variant: "outline", children: "Profile console" }),
3591
+ /* @__PURE__ */ jsx28(Badge8, { variant: "secondary", children: "Live session data" })
3592
+ ] }),
3593
+ /* @__PURE__ */ jsxs24("div", { className: "max-w-2xl space-y-2", children: [
3594
+ /* @__PURE__ */ jsx28("h2", { className: "text-2xl font-semibold tracking-tight", children: "Account details, contact state, and verification status." }),
3595
+ /* @__PURE__ */ jsx28("p", { className: "text-sm text-muted-foreground", children: "Keep the identity surface minimal here. Contact updates and sensitive changes stay in security." })
3596
+ ] }),
3597
+ /* @__PURE__ */ jsx28(ChangeProfile, { user })
2591
3598
  ] })
3599
+ ] }),
3600
+ /* @__PURE__ */ jsxs24("div", { className: "grid gap-4 lg:grid-cols-[1.5fr_0.9fr]", children: [
3601
+ /* @__PURE__ */ jsx28(Card2, { className: "rounded-[1.75rem] border-border/60 shadow-sm", children: /* @__PURE__ */ jsxs24(CardContent, { className: "space-y-5 p-6", children: [
3602
+ /* @__PURE__ */ jsxs24("div", { className: "space-y-1", children: [
3603
+ /* @__PURE__ */ jsx28("div", { className: "text-sm font-medium text-muted-foreground", children: "Contact channels" }),
3604
+ /* @__PURE__ */ jsx28("div", { className: "text-lg font-semibold", children: "Primary profile data" })
3605
+ ] }),
3606
+ /* @__PURE__ */ jsx28(Separator, {}),
3607
+ /* @__PURE__ */ jsx28("div", { className: "space-y-4", children: contactItems.map((item) => /* @__PURE__ */ jsxs24(
3608
+ "div",
3609
+ {
3610
+ className: "flex flex-col gap-3 rounded-2xl border border-border/60 bg-muted/20 p-4 md:flex-row md:items-center md:justify-between",
3611
+ children: [
3612
+ /* @__PURE__ */ jsxs24("div", { className: "space-y-1", children: [
3613
+ /* @__PURE__ */ jsx28("div", { className: "text-sm font-medium", children: item.label }),
3614
+ /* @__PURE__ */ jsx28("div", { className: "text-sm text-muted-foreground", children: item.value })
3615
+ ] }),
3616
+ /* @__PURE__ */ jsx28(Badge8, { variant: "outline", children: item.status })
3617
+ ]
3618
+ },
3619
+ item.label
3620
+ )) })
3621
+ ] }) }),
3622
+ /* @__PURE__ */ jsx28(Card2, { className: "rounded-[1.75rem] border-border/60 shadow-sm", children: /* @__PURE__ */ jsxs24(CardContent, { className: "space-y-5 p-6", children: [
3623
+ /* @__PURE__ */ jsxs24("div", { className: "space-y-1", children: [
3624
+ /* @__PURE__ */ jsx28("div", { className: "text-sm font-medium text-muted-foreground", children: "Snapshot" }),
3625
+ /* @__PURE__ */ jsx28("div", { className: "text-lg font-semibold", children: "Session-facing identity" })
3626
+ ] }),
3627
+ /* @__PURE__ */ jsx28(Separator, {}),
3628
+ /* @__PURE__ */ jsxs24("div", { className: "grid gap-3", children: [
3629
+ /* @__PURE__ */ jsxs24("div", { className: "rounded-2xl bg-primary/[0.06] p-4", children: [
3630
+ /* @__PURE__ */ jsx28("div", { className: "text-xs uppercase tracking-[0.18em] text-muted-foreground", children: "Full name" }),
3631
+ /* @__PURE__ */ jsx28("div", { className: "mt-2 text-base font-semibold", children: user.fullName })
3632
+ ] }),
3633
+ /* @__PURE__ */ jsxs24("div", { className: "rounded-2xl bg-muted/25 p-4", children: [
3634
+ /* @__PURE__ */ jsx28("div", { className: "text-xs uppercase tracking-[0.18em] text-muted-foreground", children: "Last sign in" }),
3635
+ /* @__PURE__ */ jsx28("div", { className: "mt-2 text-base font-semibold", children: user.lastSignInAt ? new Date(user.lastSignInAt).toLocaleString() : "No activity recorded" })
3636
+ ] })
3637
+ ] })
3638
+ ] }) })
2592
3639
  ] })
2593
3640
  ] });
2594
3641
  }
2595
3642
 
3643
+ // src/components/profile/security.tsx
3644
+ import { Badge as Badge9, Card as Card3, CardContent as CardContent2, Separator as Separator2 } from "@mesob/ui/components";
3645
+
2596
3646
  // src/components/profile/change-email-form.tsx
2597
3647
  import {
2598
- Button as Button13,
3648
+ Button as Button16,
2599
3649
  Collapsible,
2600
3650
  CollapsibleContent,
2601
3651
  CollapsibleTrigger
2602
3652
  } from "@mesob/ui/components";
2603
3653
  import { IconChevronDown } from "@tabler/icons-react";
2604
- import { useState as useState16 } from "react";
3654
+ import { useState as useState18 } from "react";
2605
3655
 
2606
3656
  // src/components/profile/request-change-email-form.tsx
2607
- import { zodResolver as zodResolver6 } from "@hookform/resolvers/zod";
2608
- import { Button as Button12, Input as Input5, Label, Spinner as Spinner2 } from "@mesob/ui/components";
2609
- import { IconEye as IconEye4, IconEyeOff as IconEyeOff4 } from "@tabler/icons-react";
2610
- import { useEffect as useEffect8, useState as useState14 } from "react";
2611
- import { useForm as useForm6 } from "react-hook-form";
2612
- import { toast as toast7 } from "sonner";
2613
- import { z as z6 } from "zod";
2614
- import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
2615
- var emailPasswordSchema = z6.object({
2616
- email: z6.string().email("Invalid email address"),
2617
- password: z6.string().min(8, "Password must be at least 8 characters").max(128, "Password too long")
3657
+ import { zodResolver as zodResolver8 } from "@hookform/resolvers/zod";
3658
+ import { Button as Button15, Input as Input7, Label, Spinner as Spinner2 } from "@mesob/ui/components";
3659
+ import { IconEye as IconEye5, IconEyeOff as IconEyeOff5 } from "@tabler/icons-react";
3660
+ import { useEffect as useEffect10, useState as useState16 } from "react";
3661
+ import { useForm as useForm8 } from "react-hook-form";
3662
+ import { toast as toast10 } from "sonner";
3663
+ import { z as z8 } from "zod";
3664
+ import { jsx as jsx29, jsxs as jsxs25 } from "react/jsx-runtime";
3665
+ var emailPasswordSchema = z8.object({
3666
+ email: z8.string().email("Invalid email address"),
3667
+ password: z8.string().min(8, "Password must be at least 8 characters").max(128, "Password too long")
2618
3668
  });
2619
3669
  function isAuthError2(error) {
2620
3670
  return typeof error === "object" && error !== null && ("code" in error || "message" in error || "name" in error);
@@ -2669,9 +3719,9 @@ function RequestChangeEmailForm({
2669
3719
  }) {
2670
3720
  const { user } = useSession();
2671
3721
  const { hooks } = useApi();
2672
- const [isSubmitting, setIsSubmitting] = useState14(false);
2673
- const [isChecking, setIsChecking] = useState14(true);
2674
- const [showPassword, setShowPassword] = useState14(false);
3722
+ const [isSubmitting, setIsSubmitting] = useState16(false);
3723
+ const [isChecking, setIsChecking] = useState16(true);
3724
+ const [showPassword, setShowPassword] = useState16(false);
2675
3725
  const getPendingAccountChangeQuery = hooks.useQuery(
2676
3726
  "get",
2677
3727
  "/account-change/pending",
@@ -2684,8 +3734,8 @@ function RequestChangeEmailForm({
2684
3734
  "post",
2685
3735
  "/email/verification/request"
2686
3736
  );
2687
- const emailPasswordForm = useForm6({
2688
- resolver: zodResolver6(emailPasswordSchema),
3737
+ const emailPasswordForm = useForm8({
3738
+ resolver: zodResolver8(emailPasswordSchema),
2689
3739
  defaultValues: {
2690
3740
  email: "",
2691
3741
  password: ""
@@ -2698,7 +3748,7 @@ function RequestChangeEmailForm({
2698
3748
  setValue,
2699
3749
  formState: { errors }
2700
3750
  } = emailPasswordForm;
2701
- useEffect8(() => {
3751
+ useEffect10(() => {
2702
3752
  let active = true;
2703
3753
  const run = async () => {
2704
3754
  try {
@@ -2722,7 +3772,7 @@ function RequestChangeEmailForm({
2722
3772
  }
2723
3773
  setValue("email", accountChange.newEmail, { shouldValidate: true });
2724
3774
  if (verificationId) {
2725
- toast7.message("Resuming verification\u2026");
3775
+ toast10.message("Resuming verification\u2026");
2726
3776
  onSuccess(verificationId, accountChange.newEmail);
2727
3777
  return;
2728
3778
  }
@@ -2738,7 +3788,7 @@ function RequestChangeEmailForm({
2738
3788
  }, [getPendingAccountChangeQuery.refetch, getValues, onSuccess, setValue]);
2739
3789
  const onEmailPasswordSubmit = async (data) => {
2740
3790
  if (!user) {
2741
- toast7.error("User not found");
3791
+ toast10.error("User not found");
2742
3792
  return;
2743
3793
  }
2744
3794
  try {
@@ -2751,10 +3801,10 @@ function RequestChangeEmailForm({
2751
3801
  });
2752
3802
  if (checkResult.data?.exists) {
2753
3803
  if (user?.email?.toLowerCase() === data.email.toLowerCase()) {
2754
- toast7.error("This is already your current email address.");
3804
+ toast10.error("This is already your current email address.");
2755
3805
  return;
2756
3806
  }
2757
- toast7.error(
3807
+ toast10.error(
2758
3808
  "This email is already taken. Please use a different email."
2759
3809
  );
2760
3810
  return;
@@ -2762,34 +3812,34 @@ function RequestChangeEmailForm({
2762
3812
  const verification = await requestEmailVerificationMutation.mutateAsync({
2763
3813
  body: { email: data.email }
2764
3814
  });
2765
- toast7.success("Verification code sent to your email");
3815
+ toast10.success("Verification code sent to your email");
2766
3816
  onSuccess(verification.data?.verificationId ?? "", data.email);
2767
3817
  } catch (error) {
2768
3818
  const errorMessage = getErrorMessage(error);
2769
3819
  if (isAuthError2(error)) {
2770
3820
  const errorCode = getErrorCode(error);
2771
3821
  if (errorCode === "INVALID_PASSWORD" || errorCode === "USER_NOT_FOUND") {
2772
- toast7.error("Incorrect password. Please try again.");
3822
+ toast10.error("Incorrect password. Please try again.");
2773
3823
  return;
2774
3824
  }
2775
3825
  }
2776
- toast7.error(errorMessage);
3826
+ toast10.error(errorMessage);
2777
3827
  } finally {
2778
3828
  setIsSubmitting(false);
2779
3829
  }
2780
3830
  };
2781
3831
  const isLoading = isSubmitting || isChecking;
2782
- return /* @__PURE__ */ jsxs19(
3832
+ return /* @__PURE__ */ jsxs25(
2783
3833
  "form",
2784
3834
  {
2785
3835
  onSubmit: handleSubmit(onEmailPasswordSubmit),
2786
3836
  className: "p-4 space-y-4 border-t",
2787
3837
  children: [
2788
- /* @__PURE__ */ jsxs19("div", { className: "space-y-4 w-full md:w-1/2", children: [
2789
- /* @__PURE__ */ jsxs19("div", { className: "space-y-2", children: [
2790
- /* @__PURE__ */ jsx21(Label, { htmlFor: "email", children: "New Email Address" }),
2791
- /* @__PURE__ */ jsx21(
2792
- Input5,
3838
+ /* @__PURE__ */ jsxs25("div", { className: "space-y-4 w-full md:w-1/2", children: [
3839
+ /* @__PURE__ */ jsxs25("div", { className: "space-y-2", children: [
3840
+ /* @__PURE__ */ jsx29(Label, { htmlFor: "email", children: "New Email Address" }),
3841
+ /* @__PURE__ */ jsx29(
3842
+ Input7,
2793
3843
  {
2794
3844
  id: "email",
2795
3845
  type: "email",
@@ -2798,13 +3848,13 @@ function RequestChangeEmailForm({
2798
3848
  disabled: isLoading
2799
3849
  }
2800
3850
  ),
2801
- errors.email && /* @__PURE__ */ jsx21("p", { className: "text-sm text-destructive", children: errors.email.message })
3851
+ errors.email && /* @__PURE__ */ jsx29("p", { className: "text-sm text-destructive", children: errors.email.message })
2802
3852
  ] }),
2803
- /* @__PURE__ */ jsxs19("div", { className: "space-y-2", children: [
2804
- /* @__PURE__ */ jsx21(Label, { htmlFor: "password", children: "Password" }),
2805
- /* @__PURE__ */ jsxs19("div", { className: "relative", children: [
2806
- /* @__PURE__ */ jsx21(
2807
- Input5,
3853
+ /* @__PURE__ */ jsxs25("div", { className: "space-y-2", children: [
3854
+ /* @__PURE__ */ jsx29(Label, { htmlFor: "password", children: "Password" }),
3855
+ /* @__PURE__ */ jsxs25("div", { className: "relative", children: [
3856
+ /* @__PURE__ */ jsx29(
3857
+ Input7,
2808
3858
  {
2809
3859
  id: "password",
2810
3860
  type: showPassword ? "text" : "password",
@@ -2814,23 +3864,23 @@ function RequestChangeEmailForm({
2814
3864
  disabled: isLoading
2815
3865
  }
2816
3866
  ),
2817
- /* @__PURE__ */ jsx21(
3867
+ /* @__PURE__ */ jsx29(
2818
3868
  "button",
2819
3869
  {
2820
3870
  type: "button",
2821
3871
  onClick: () => setShowPassword(!showPassword),
2822
3872
  className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground",
2823
3873
  disabled: isLoading,
2824
- children: showPassword ? /* @__PURE__ */ jsx21(IconEyeOff4, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx21(IconEye4, { className: "h-4 w-4" })
3874
+ children: showPassword ? /* @__PURE__ */ jsx29(IconEyeOff5, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx29(IconEye5, { className: "h-4 w-4" })
2825
3875
  }
2826
3876
  )
2827
3877
  ] }),
2828
- errors.password && /* @__PURE__ */ jsx21("p", { className: "text-sm text-destructive", children: errors.password.message })
3878
+ errors.password && /* @__PURE__ */ jsx29("p", { className: "text-sm text-destructive", children: errors.password.message })
2829
3879
  ] })
2830
3880
  ] }),
2831
- /* @__PURE__ */ jsxs19("div", { className: "flex justify-end gap-2", children: [
2832
- /* @__PURE__ */ jsx21(
2833
- Button12,
3881
+ /* @__PURE__ */ jsxs25("div", { className: "flex justify-end gap-2", children: [
3882
+ /* @__PURE__ */ jsx29(
3883
+ Button15,
2834
3884
  {
2835
3885
  type: "button",
2836
3886
  variant: "outline",
@@ -2839,8 +3889,8 @@ function RequestChangeEmailForm({
2839
3889
  children: "Cancel"
2840
3890
  }
2841
3891
  ),
2842
- /* @__PURE__ */ jsxs19(Button12, { type: "submit", disabled: isLoading, children: [
2843
- isLoading && /* @__PURE__ */ jsx21(Spinner2, { className: "mr-2 h-4 w-4" }),
3892
+ /* @__PURE__ */ jsxs25(Button15, { type: "submit", disabled: isLoading, children: [
3893
+ isLoading && /* @__PURE__ */ jsx29(Spinner2, { className: "mr-2 h-4 w-4" }),
2844
3894
  isChecking ? "Checking\u2026" : buttonText
2845
3895
  ] })
2846
3896
  ] })
@@ -2850,8 +3900,8 @@ function RequestChangeEmailForm({
2850
3900
  }
2851
3901
 
2852
3902
  // src/components/profile/verify-change-email-form.tsx
2853
- import { useState as useState15 } from "react";
2854
- import { toast as toast8 } from "sonner";
3903
+ import { useState as useState17 } from "react";
3904
+ import { toast as toast11 } from "sonner";
2855
3905
 
2856
3906
  // src/components/profile/otp-verification-modal.tsx
2857
3907
  import {
@@ -2861,7 +3911,7 @@ import {
2861
3911
  DialogHeader,
2862
3912
  DialogTitle
2863
3913
  } from "@mesob/ui/components";
2864
- import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
3914
+ import { jsx as jsx30, jsxs as jsxs26 } from "react/jsx-runtime";
2865
3915
  function OtpVerificationModal({
2866
3916
  open,
2867
3917
  title,
@@ -2872,7 +3922,7 @@ function OtpVerificationModal({
2872
3922
  onResend,
2873
3923
  onCancel
2874
3924
  }) {
2875
- return /* @__PURE__ */ jsx22(
3925
+ return /* @__PURE__ */ jsx30(
2876
3926
  Dialog,
2877
3927
  {
2878
3928
  open,
@@ -2881,12 +3931,12 @@ function OtpVerificationModal({
2881
3931
  onCancel?.();
2882
3932
  }
2883
3933
  },
2884
- children: /* @__PURE__ */ jsxs20(DialogContent, { children: [
2885
- /* @__PURE__ */ jsxs20(DialogHeader, { children: [
2886
- /* @__PURE__ */ jsx22(DialogTitle, { children: title }),
2887
- description && /* @__PURE__ */ jsx22(DialogDescription, { children: description })
3934
+ children: /* @__PURE__ */ jsxs26(DialogContent, { children: [
3935
+ /* @__PURE__ */ jsxs26(DialogHeader, { children: [
3936
+ /* @__PURE__ */ jsx30(DialogTitle, { children: title }),
3937
+ description && /* @__PURE__ */ jsx30(DialogDescription, { children: description })
2888
3938
  ] }),
2889
- /* @__PURE__ */ jsx22(
3939
+ /* @__PURE__ */ jsx30(
2890
3940
  VerificationForm,
2891
3941
  {
2892
3942
  verificationId,
@@ -2901,7 +3951,7 @@ function OtpVerificationModal({
2901
3951
  }
2902
3952
 
2903
3953
  // src/components/profile/verify-change-email-form.tsx
2904
- import { jsx as jsx23 } from "react/jsx-runtime";
3954
+ import { jsx as jsx31 } from "react/jsx-runtime";
2905
3955
  function isAuthError3(error) {
2906
3956
  return typeof error === "object" && error !== null && ("code" in error || "message" in error || "name" in error);
2907
3957
  }
@@ -2956,8 +4006,8 @@ function VerifyChangeEmailForm({
2956
4006
  }) {
2957
4007
  const { refresh } = useSession();
2958
4008
  const { hooks } = useApi();
2959
- const [isSubmitting, setIsSubmitting] = useState15(false);
2960
- const [currentVerificationId, setCurrentVerificationId] = useState15(verificationId);
4009
+ const [isSubmitting, setIsSubmitting] = useState17(false);
4010
+ const [currentVerificationId, setCurrentVerificationId] = useState17(verificationId);
2961
4011
  const verifyEmailMutation = hooks.useMutation(
2962
4012
  "post",
2963
4013
  "/email/verification/confirm"
@@ -2969,7 +4019,7 @@ function VerifyChangeEmailForm({
2969
4019
  );
2970
4020
  const onOtpSubmit = async (code) => {
2971
4021
  if (!currentVerificationId) {
2972
- toast8.error("Verification not found. Please request a new code.");
4022
+ toast11.error("Verification not found. Please request a new code.");
2973
4023
  return;
2974
4024
  }
2975
4025
  try {
@@ -2983,21 +4033,21 @@ function VerifyChangeEmailForm({
2983
4033
  await updateEmailMutation.mutateAsync({
2984
4034
  body: { email }
2985
4035
  });
2986
- toast8.success("Email updated successfully");
4036
+ toast11.success("Email updated successfully");
2987
4037
  await refresh();
2988
4038
  onSuccess();
2989
4039
  } catch (error) {
2990
4040
  const errorMessage = getErrorMessage2(error);
2991
- toast8.error(errorMessage);
4041
+ toast11.error(errorMessage);
2992
4042
  } finally {
2993
4043
  setIsSubmitting(false);
2994
4044
  }
2995
4045
  };
2996
4046
  if (!currentVerificationId) {
2997
- toast8.error("Verification not found. Please request a new code.");
4047
+ toast11.error("Verification not found. Please request a new code.");
2998
4048
  return null;
2999
4049
  }
3000
- return /* @__PURE__ */ jsx23(
4050
+ return /* @__PURE__ */ jsx31(
3001
4051
  OtpVerificationModal,
3002
4052
  {
3003
4053
  open: true,
@@ -3013,9 +4063,9 @@ function VerifyChangeEmailForm({
3013
4063
  body: { email }
3014
4064
  });
3015
4065
  setCurrentVerificationId(next.data?.verificationId ?? null);
3016
- toast8.success("Verification code resent");
4066
+ toast11.success("Verification code resent");
3017
4067
  } catch (error) {
3018
- toast8.error(getErrorMessage2(error));
4068
+ toast11.error(getErrorMessage2(error));
3019
4069
  } finally {
3020
4070
  setIsSubmitting(false);
3021
4071
  }
@@ -3026,13 +4076,13 @@ function VerifyChangeEmailForm({
3026
4076
  }
3027
4077
 
3028
4078
  // src/components/profile/change-email-form.tsx
3029
- import { jsx as jsx24, jsxs as jsxs21 } from "react/jsx-runtime";
4079
+ import { jsx as jsx32, jsxs as jsxs27 } from "react/jsx-runtime";
3030
4080
  function ChangeEmailForm() {
3031
4081
  const { user } = useSession();
3032
- const [isOpen, setIsOpen] = useState16(false);
3033
- const [showOtp, setShowOtp] = useState16(false);
3034
- const [verificationId, setVerificationId] = useState16(null);
3035
- const [newEmail, setNewEmail] = useState16("");
4082
+ const [isOpen, setIsOpen] = useState18(false);
4083
+ const [showOtp, setShowOtp] = useState18(false);
4084
+ const [verificationId, setVerificationId] = useState18(null);
4085
+ const [newEmail, setNewEmail] = useState18("");
3036
4086
  const resetForms = () => {
3037
4087
  setShowOtp(false);
3038
4088
  setVerificationId(null);
@@ -3053,23 +4103,23 @@ function ChangeEmailForm() {
3053
4103
  };
3054
4104
  const title = user?.email ? "Change Email" : "Add Email";
3055
4105
  const description = user?.email ? "Update your email address" : "Add an email address to your account";
3056
- return /* @__PURE__ */ jsx24(Collapsible, { open: isOpen, onOpenChange: setIsOpen, children: /* @__PURE__ */ jsxs21("div", { className: "border rounded-lg", children: [
3057
- /* @__PURE__ */ jsxs21(
4106
+ return /* @__PURE__ */ jsx32(Collapsible, { open: isOpen, onOpenChange: setIsOpen, children: /* @__PURE__ */ jsxs27("div", { className: "border rounded-lg", children: [
4107
+ /* @__PURE__ */ jsxs27(
3058
4108
  CollapsibleTrigger,
3059
4109
  {
3060
- render: /* @__PURE__ */ jsx24(
3061
- Button13,
4110
+ render: /* @__PURE__ */ jsx32(
4111
+ Button16,
3062
4112
  {
3063
4113
  variant: "ghost",
3064
4114
  className: "w-full justify-between p-4 h-auto"
3065
4115
  }
3066
4116
  ),
3067
4117
  children: [
3068
- /* @__PURE__ */ jsxs21("div", { className: "flex flex-col items-start", children: [
3069
- /* @__PURE__ */ jsx24("span", { className: "font-medium", children: title }),
3070
- /* @__PURE__ */ jsx24("span", { className: "text-sm text-muted-foreground", children: description })
4118
+ /* @__PURE__ */ jsxs27("div", { className: "flex flex-col items-start", children: [
4119
+ /* @__PURE__ */ jsx32("span", { className: "font-medium", children: title }),
4120
+ /* @__PURE__ */ jsx32("span", { className: "text-sm text-muted-foreground", children: description })
3071
4121
  ] }),
3072
- /* @__PURE__ */ jsx24(
4122
+ /* @__PURE__ */ jsx32(
3073
4123
  IconChevronDown,
3074
4124
  {
3075
4125
  className: `h-4 w-4 transition-transform ${isOpen ? "rotate-180" : ""}`
@@ -3078,7 +4128,7 @@ function ChangeEmailForm() {
3078
4128
  ]
3079
4129
  }
3080
4130
  ),
3081
- /* @__PURE__ */ jsx24(CollapsibleContent, { children: showOtp ? /* @__PURE__ */ jsx24(
4131
+ /* @__PURE__ */ jsx32(CollapsibleContent, { children: showOtp ? /* @__PURE__ */ jsx32(
3082
4132
  VerifyChangeEmailForm,
3083
4133
  {
3084
4134
  email: newEmail,
@@ -3086,7 +4136,7 @@ function ChangeEmailForm() {
3086
4136
  onSuccess: handleVerifySuccess,
3087
4137
  onCancel: handleCancel
3088
4138
  }
3089
- ) : /* @__PURE__ */ jsx24(
4139
+ ) : /* @__PURE__ */ jsx32(
3090
4140
  RequestChangeEmailForm,
3091
4141
  {
3092
4142
  onSuccess: handleRequestSuccess,
@@ -3098,26 +4148,26 @@ function ChangeEmailForm() {
3098
4148
  }
3099
4149
 
3100
4150
  // src/components/profile/change-password-form.tsx
3101
- import { zodResolver as zodResolver7 } from "@hookform/resolvers/zod";
4151
+ import { zodResolver as zodResolver9 } from "@hookform/resolvers/zod";
3102
4152
  import {
3103
- Button as Button14,
4153
+ Button as Button17,
3104
4154
  Collapsible as Collapsible2,
3105
4155
  CollapsibleContent as CollapsibleContent2,
3106
4156
  CollapsibleTrigger as CollapsibleTrigger2,
3107
- Input as Input6,
4157
+ Input as Input8,
3108
4158
  Label as Label2,
3109
4159
  Spinner as Spinner3
3110
4160
  } from "@mesob/ui/components";
3111
- import { IconChevronDown as IconChevronDown2, IconEye as IconEye5, IconEyeOff as IconEyeOff5 } from "@tabler/icons-react";
3112
- import { useState as useState17 } from "react";
3113
- import { useForm as useForm7 } from "react-hook-form";
3114
- import { toast as toast9 } from "sonner";
3115
- import { z as z7 } from "zod";
3116
- import { jsx as jsx25, jsxs as jsxs22 } from "react/jsx-runtime";
3117
- var changePasswordSchema = z7.object({
3118
- currentPassword: z7.string().min(8, "Password must be at least 8 characters"),
3119
- newPassword: z7.string().min(8, "Password must be at least 8 characters"),
3120
- confirmPassword: z7.string().min(8, "Password must be at least 8 characters")
4161
+ import { IconChevronDown as IconChevronDown2, IconEye as IconEye6, IconEyeOff as IconEyeOff6 } from "@tabler/icons-react";
4162
+ import { useState as useState19 } from "react";
4163
+ import { useForm as useForm9 } from "react-hook-form";
4164
+ import { toast as toast12 } from "sonner";
4165
+ import { z as z9 } from "zod";
4166
+ import { jsx as jsx33, jsxs as jsxs28 } from "react/jsx-runtime";
4167
+ var changePasswordSchema = z9.object({
4168
+ currentPassword: z9.string().min(8, "Password must be at least 8 characters"),
4169
+ newPassword: z9.string().min(8, "Password must be at least 8 characters"),
4170
+ confirmPassword: z9.string().min(8, "Password must be at least 8 characters")
3121
4171
  }).refine((data) => data.newPassword === data.confirmPassword, {
3122
4172
  message: "Passwords don't match",
3123
4173
  path: ["confirmPassword"]
@@ -3171,13 +4221,13 @@ function getPasswordChangeErrorMessage(error) {
3171
4221
  }
3172
4222
  function ChangePasswordForm() {
3173
4223
  const { user: _user } = useSession();
3174
- const [isOpen, setIsOpen] = useState17(false);
3175
- const [isSubmitting, setIsSubmitting] = useState17(false);
3176
- const [showPassword, setShowPassword] = useState17(false);
3177
- const [showNewPassword, setShowNewPassword] = useState17(false);
3178
- const [showConfirmPassword, setShowConfirmPassword] = useState17(false);
3179
- const form = useForm7({
3180
- resolver: zodResolver7(changePasswordSchema),
4224
+ const [isOpen, setIsOpen] = useState19(false);
4225
+ const [isSubmitting, setIsSubmitting] = useState19(false);
4226
+ const [showPassword, setShowPassword] = useState19(false);
4227
+ const [showNewPassword, setShowNewPassword] = useState19(false);
4228
+ const [showConfirmPassword, setShowConfirmPassword] = useState19(false);
4229
+ const form = useForm9({
4230
+ resolver: zodResolver9(changePasswordSchema),
3181
4231
  defaultValues: {
3182
4232
  currentPassword: "",
3183
4233
  newPassword: "",
@@ -3188,32 +4238,32 @@ function ChangePasswordForm() {
3188
4238
  const onSubmit = (_data) => {
3189
4239
  try {
3190
4240
  setIsSubmitting(true);
3191
- toast9.error("Password change unavailable");
4241
+ toast12.error("Password change unavailable");
3192
4242
  setIsOpen(false);
3193
4243
  } catch (error) {
3194
4244
  const errorMessage = getPasswordChangeErrorMessage(error);
3195
- toast9.error(errorMessage);
4245
+ toast12.error(errorMessage);
3196
4246
  } finally {
3197
4247
  setIsSubmitting(false);
3198
4248
  }
3199
4249
  };
3200
- return /* @__PURE__ */ jsx25(Collapsible2, { open: isOpen, onOpenChange: setIsOpen, children: /* @__PURE__ */ jsxs22("div", { className: "border rounded-lg", children: [
3201
- /* @__PURE__ */ jsxs22(
4250
+ return /* @__PURE__ */ jsx33(Collapsible2, { open: isOpen, onOpenChange: setIsOpen, children: /* @__PURE__ */ jsxs28("div", { className: "border rounded-lg", children: [
4251
+ /* @__PURE__ */ jsxs28(
3202
4252
  CollapsibleTrigger2,
3203
4253
  {
3204
- render: /* @__PURE__ */ jsx25(
3205
- Button14,
4254
+ render: /* @__PURE__ */ jsx33(
4255
+ Button17,
3206
4256
  {
3207
4257
  variant: "ghost",
3208
4258
  className: "w-full justify-between p-4 h-auto"
3209
4259
  }
3210
4260
  ),
3211
4261
  children: [
3212
- /* @__PURE__ */ jsxs22("div", { className: "flex flex-col items-start", children: [
3213
- /* @__PURE__ */ jsx25("span", { className: "font-medium", children: "Change Password" }),
3214
- /* @__PURE__ */ jsx25("span", { className: "text-sm text-muted-foreground", children: "Update your account password" })
4262
+ /* @__PURE__ */ jsxs28("div", { className: "flex flex-col items-start", children: [
4263
+ /* @__PURE__ */ jsx33("span", { className: "font-medium", children: "Change Password" }),
4264
+ /* @__PURE__ */ jsx33("span", { className: "text-sm text-muted-foreground", children: "Update your account password" })
3215
4265
  ] }),
3216
- /* @__PURE__ */ jsx25(
4266
+ /* @__PURE__ */ jsx33(
3217
4267
  IconChevronDown2,
3218
4268
  {
3219
4269
  className: `h-4 w-4 transition-transform ${isOpen ? "rotate-180" : ""}`
@@ -3222,17 +4272,17 @@ function ChangePasswordForm() {
3222
4272
  ]
3223
4273
  }
3224
4274
  ),
3225
- /* @__PURE__ */ jsx25(CollapsibleContent2, { children: /* @__PURE__ */ jsxs22(
4275
+ /* @__PURE__ */ jsx33(CollapsibleContent2, { children: /* @__PURE__ */ jsxs28(
3226
4276
  "form",
3227
4277
  {
3228
4278
  onSubmit: handleSubmit(onSubmit),
3229
4279
  className: "p-4 space-y-4 border-t",
3230
4280
  children: [
3231
- /* @__PURE__ */ jsxs22("div", { className: "space-y-2 w-full md:w-1/2", children: [
3232
- /* @__PURE__ */ jsx25(Label2, { htmlFor: "currentPassword", children: "Old Password" }),
3233
- /* @__PURE__ */ jsxs22("div", { className: "relative", children: [
3234
- /* @__PURE__ */ jsx25(
3235
- Input6,
4281
+ /* @__PURE__ */ jsxs28("div", { className: "space-y-2 w-full md:w-1/2", children: [
4282
+ /* @__PURE__ */ jsx33(Label2, { htmlFor: "currentPassword", children: "Old Password" }),
4283
+ /* @__PURE__ */ jsxs28("div", { className: "relative", children: [
4284
+ /* @__PURE__ */ jsx33(
4285
+ Input8,
3236
4286
  {
3237
4287
  id: "currentPassword",
3238
4288
  type: showPassword ? "text" : "password",
@@ -3241,23 +4291,23 @@ function ChangePasswordForm() {
3241
4291
  ...register("currentPassword")
3242
4292
  }
3243
4293
  ),
3244
- /* @__PURE__ */ jsx25(
4294
+ /* @__PURE__ */ jsx33(
3245
4295
  "button",
3246
4296
  {
3247
4297
  type: "button",
3248
4298
  onClick: () => setShowPassword(!showPassword),
3249
4299
  className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground",
3250
- children: showPassword ? /* @__PURE__ */ jsx25(IconEyeOff5, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx25(IconEye5, { className: "h-4 w-4" })
4300
+ children: showPassword ? /* @__PURE__ */ jsx33(IconEyeOff6, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx33(IconEye6, { className: "h-4 w-4" })
3251
4301
  }
3252
4302
  )
3253
4303
  ] }),
3254
- formState.errors.currentPassword && /* @__PURE__ */ jsx25("p", { className: "text-sm text-destructive", children: formState.errors.currentPassword.message })
4304
+ formState.errors.currentPassword && /* @__PURE__ */ jsx33("p", { className: "text-sm text-destructive", children: formState.errors.currentPassword.message })
3255
4305
  ] }),
3256
- /* @__PURE__ */ jsxs22("div", { className: "space-y-2 w-full md:w-1/2", children: [
3257
- /* @__PURE__ */ jsx25(Label2, { htmlFor: "newPassword", children: "New Password" }),
3258
- /* @__PURE__ */ jsxs22("div", { className: "relative", children: [
3259
- /* @__PURE__ */ jsx25(
3260
- Input6,
4306
+ /* @__PURE__ */ jsxs28("div", { className: "space-y-2 w-full md:w-1/2", children: [
4307
+ /* @__PURE__ */ jsx33(Label2, { htmlFor: "newPassword", children: "New Password" }),
4308
+ /* @__PURE__ */ jsxs28("div", { className: "relative", children: [
4309
+ /* @__PURE__ */ jsx33(
4310
+ Input8,
3261
4311
  {
3262
4312
  id: "newPassword",
3263
4313
  type: showNewPassword ? "text" : "password",
@@ -3266,23 +4316,23 @@ function ChangePasswordForm() {
3266
4316
  ...register("newPassword")
3267
4317
  }
3268
4318
  ),
3269
- /* @__PURE__ */ jsx25(
4319
+ /* @__PURE__ */ jsx33(
3270
4320
  "button",
3271
4321
  {
3272
4322
  type: "button",
3273
4323
  onClick: () => setShowNewPassword(!showNewPassword),
3274
4324
  className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground",
3275
- children: showNewPassword ? /* @__PURE__ */ jsx25(IconEyeOff5, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx25(IconEye5, { className: "h-4 w-4" })
4325
+ children: showNewPassword ? /* @__PURE__ */ jsx33(IconEyeOff6, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx33(IconEye6, { className: "h-4 w-4" })
3276
4326
  }
3277
4327
  )
3278
4328
  ] }),
3279
- formState.errors.newPassword && /* @__PURE__ */ jsx25("p", { className: "text-sm text-destructive", children: formState.errors.newPassword.message })
4329
+ formState.errors.newPassword && /* @__PURE__ */ jsx33("p", { className: "text-sm text-destructive", children: formState.errors.newPassword.message })
3280
4330
  ] }),
3281
- /* @__PURE__ */ jsxs22("div", { className: "space-y-2 w-full md:w-1/2", children: [
3282
- /* @__PURE__ */ jsx25(Label2, { htmlFor: "confirmPassword", children: "Confirm New Password" }),
3283
- /* @__PURE__ */ jsxs22("div", { className: "relative", children: [
3284
- /* @__PURE__ */ jsx25(
3285
- Input6,
4331
+ /* @__PURE__ */ jsxs28("div", { className: "space-y-2 w-full md:w-1/2", children: [
4332
+ /* @__PURE__ */ jsx33(Label2, { htmlFor: "confirmPassword", children: "Confirm New Password" }),
4333
+ /* @__PURE__ */ jsxs28("div", { className: "relative", children: [
4334
+ /* @__PURE__ */ jsx33(
4335
+ Input8,
3286
4336
  {
3287
4337
  id: "confirmPassword",
3288
4338
  type: showConfirmPassword ? "text" : "password",
@@ -3291,21 +4341,21 @@ function ChangePasswordForm() {
3291
4341
  ...register("confirmPassword")
3292
4342
  }
3293
4343
  ),
3294
- /* @__PURE__ */ jsx25(
4344
+ /* @__PURE__ */ jsx33(
3295
4345
  "button",
3296
4346
  {
3297
4347
  type: "button",
3298
4348
  onClick: () => setShowConfirmPassword(!showConfirmPassword),
3299
4349
  className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground",
3300
- children: showConfirmPassword ? /* @__PURE__ */ jsx25(IconEyeOff5, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx25(IconEye5, { className: "h-4 w-4" })
4350
+ children: showConfirmPassword ? /* @__PURE__ */ jsx33(IconEyeOff6, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx33(IconEye6, { className: "h-4 w-4" })
3301
4351
  }
3302
4352
  )
3303
4353
  ] }),
3304
- formState.errors.confirmPassword && /* @__PURE__ */ jsx25("p", { className: "text-sm text-destructive", children: formState.errors.confirmPassword.message })
4354
+ formState.errors.confirmPassword && /* @__PURE__ */ jsx33("p", { className: "text-sm text-destructive", children: formState.errors.confirmPassword.message })
3305
4355
  ] }),
3306
- /* @__PURE__ */ jsxs22("div", { className: "flex justify-end gap-2", children: [
3307
- /* @__PURE__ */ jsx25(
3308
- Button14,
4356
+ /* @__PURE__ */ jsxs28("div", { className: "flex justify-end gap-2", children: [
4357
+ /* @__PURE__ */ jsx33(
4358
+ Button17,
3309
4359
  {
3310
4360
  type: "button",
3311
4361
  variant: "outline",
@@ -3317,8 +4367,8 @@ function ChangePasswordForm() {
3317
4367
  children: "Cancel"
3318
4368
  }
3319
4369
  ),
3320
- /* @__PURE__ */ jsxs22(Button14, { type: "submit", disabled: isSubmitting, children: [
3321
- isSubmitting && /* @__PURE__ */ jsx25(Spinner3, { className: "mr-2 h-4 w-4" }),
4370
+ /* @__PURE__ */ jsxs28(Button17, { type: "submit", disabled: isSubmitting, children: [
4371
+ isSubmitting && /* @__PURE__ */ jsx33(Spinner3, { className: "mr-2 h-4 w-4" }),
3322
4372
  "Change Password"
3323
4373
  ] })
3324
4374
  ] })
@@ -3330,25 +4380,25 @@ function ChangePasswordForm() {
3330
4380
 
3331
4381
  // src/components/profile/change-phone-form.tsx
3332
4382
  import {
3333
- Button as Button16,
4383
+ Button as Button19,
3334
4384
  Collapsible as Collapsible3,
3335
4385
  CollapsibleContent as CollapsibleContent3,
3336
4386
  CollapsibleTrigger as CollapsibleTrigger3
3337
4387
  } from "@mesob/ui/components";
3338
4388
  import { IconChevronDown as IconChevronDown3 } from "@tabler/icons-react";
3339
- import { useState as useState20 } from "react";
4389
+ import { useState as useState22 } from "react";
3340
4390
 
3341
4391
  // src/components/profile/request-change-phone-form.tsx
3342
- import { zodResolver as zodResolver8 } from "@hookform/resolvers/zod";
3343
- import { Button as Button15, Input as Input7, Label as Label3, Spinner as Spinner4 } from "@mesob/ui/components";
3344
- import { IconEye as IconEye6, IconEyeOff as IconEyeOff6 } from "@tabler/icons-react";
3345
- import { useEffect as useEffect9, useState as useState18 } from "react";
3346
- import { useForm as useForm8 } from "react-hook-form";
3347
- import { toast as toast10 } from "sonner";
3348
- import { z as z8 } from "zod";
3349
- import { jsx as jsx26, jsxs as jsxs23 } from "react/jsx-runtime";
3350
- var phonePasswordSchema = (phoneRegex) => z8.object({
3351
- phone: z8.string().trim().min(1, { message: "Phone number is required" }).refine(
4392
+ import { zodResolver as zodResolver10 } from "@hookform/resolvers/zod";
4393
+ import { Button as Button18, Input as Input9, Label as Label3, Spinner as Spinner4 } from "@mesob/ui/components";
4394
+ import { IconEye as IconEye7, IconEyeOff as IconEyeOff7 } from "@tabler/icons-react";
4395
+ import { useEffect as useEffect11, useState as useState20 } from "react";
4396
+ import { useForm as useForm10 } from "react-hook-form";
4397
+ import { toast as toast13 } from "sonner";
4398
+ import { z as z10 } from "zod";
4399
+ import { jsx as jsx34, jsxs as jsxs29 } from "react/jsx-runtime";
4400
+ var phonePasswordSchema = (phoneRegex) => z10.object({
4401
+ phone: z10.string().trim().min(1, { message: "Phone number is required" }).refine(
3352
4402
  (val) => {
3353
4403
  const isPhone3 = phoneRegex.test(val);
3354
4404
  return isPhone3;
@@ -3357,7 +4407,7 @@ var phonePasswordSchema = (phoneRegex) => z8.object({
3357
4407
  message: "Invalid phone number"
3358
4408
  }
3359
4409
  ),
3360
- password: z8.string().min(8, "Password must be at least 8 characters").max(128, "Password too long")
4410
+ password: z10.string().min(8, "Password must be at least 8 characters").max(128, "Password too long")
3361
4411
  });
3362
4412
  function isAuthError5(error) {
3363
4413
  return typeof error === "object" && error !== null && ("code" in error || "message" in error || "name" in error);
@@ -3413,9 +4463,9 @@ function RequestChangePhoneForm({
3413
4463
  const { user } = useSession();
3414
4464
  const { hooks } = useApi();
3415
4465
  const { config } = useConfig();
3416
- const [isSubmitting, setIsSubmitting] = useState18(false);
3417
- const [isChecking, setIsChecking] = useState18(true);
3418
- const [showPassword, setShowPassword] = useState18(false);
4466
+ const [isSubmitting, setIsSubmitting] = useState20(false);
4467
+ const [isChecking, setIsChecking] = useState20(true);
4468
+ const [showPassword, setShowPassword] = useState20(false);
3419
4469
  const phoneRegex = typeof config.phoneRegex === "string" ? new RegExp(config.phoneRegex) : config.phoneRegex || /^(\+2519|\+2517|2519|2517|09|07)\d{8}$/;
3420
4470
  const getPendingAccountChangeQuery = hooks.useQuery(
3421
4471
  "get",
@@ -3429,8 +4479,8 @@ function RequestChangePhoneForm({
3429
4479
  "post",
3430
4480
  "/phone/verification/request"
3431
4481
  );
3432
- const phonePasswordForm = useForm8({
3433
- resolver: zodResolver8(phonePasswordSchema(phoneRegex)),
4482
+ const phonePasswordForm = useForm10({
4483
+ resolver: zodResolver10(phonePasswordSchema(phoneRegex)),
3434
4484
  defaultValues: {
3435
4485
  phone: "",
3436
4486
  password: ""
@@ -3443,7 +4493,7 @@ function RequestChangePhoneForm({
3443
4493
  setValue,
3444
4494
  formState: { errors }
3445
4495
  } = phonePasswordForm;
3446
- useEffect9(() => {
4496
+ useEffect11(() => {
3447
4497
  let active = true;
3448
4498
  const run = async () => {
3449
4499
  try {
@@ -3467,7 +4517,7 @@ function RequestChangePhoneForm({
3467
4517
  }
3468
4518
  setValue("phone", accountChange.newPhone, { shouldValidate: true });
3469
4519
  if (verificationId) {
3470
- toast10.message("Resuming verification\u2026");
4520
+ toast13.message("Resuming verification\u2026");
3471
4521
  onSuccess(verificationId, accountChange.newPhone);
3472
4522
  return;
3473
4523
  }
@@ -3483,7 +4533,7 @@ function RequestChangePhoneForm({
3483
4533
  }, [getPendingAccountChangeQuery.refetch, getValues, onSuccess, setValue]);
3484
4534
  const onPhonePasswordSubmit = async (data) => {
3485
4535
  if (!user) {
3486
- toast10.error("User not found");
4536
+ toast13.error("User not found");
3487
4537
  return;
3488
4538
  }
3489
4539
  try {
@@ -3497,10 +4547,10 @@ function RequestChangePhoneForm({
3497
4547
  });
3498
4548
  if (checkResult.data?.exists) {
3499
4549
  if (user?.phone?.replace(/\s/g, "") === normalizedPhone.replace(/\s/g, "")) {
3500
- toast10.error("This is already your current phone number.");
4550
+ toast13.error("This is already your current phone number.");
3501
4551
  return;
3502
4552
  }
3503
- toast10.error(
4553
+ toast13.error(
3504
4554
  "This phone number is already taken. Please use a different number."
3505
4555
  );
3506
4556
  return;
@@ -3511,34 +4561,34 @@ function RequestChangePhoneForm({
3511
4561
  context: "change-phone"
3512
4562
  }
3513
4563
  });
3514
- toast10.success("Verification code sent to your phone");
4564
+ toast13.success("Verification code sent to your phone");
3515
4565
  onSuccess(verification.data?.verificationId ?? "", normalizedPhone);
3516
4566
  } catch (error) {
3517
4567
  const errorMessage = getErrorMessage3(error);
3518
4568
  if (isAuthError5(error)) {
3519
4569
  const errorCode = getErrorCode4(error);
3520
4570
  if (errorCode === "INVALID_PASSWORD" || errorCode === "USER_NOT_FOUND") {
3521
- toast10.error("Incorrect password. Please try again.");
4571
+ toast13.error("Incorrect password. Please try again.");
3522
4572
  return;
3523
4573
  }
3524
4574
  }
3525
- toast10.error(errorMessage);
4575
+ toast13.error(errorMessage);
3526
4576
  } finally {
3527
4577
  setIsSubmitting(false);
3528
4578
  }
3529
4579
  };
3530
4580
  const isLoading = isSubmitting || isChecking;
3531
- return /* @__PURE__ */ jsxs23(
4581
+ return /* @__PURE__ */ jsxs29(
3532
4582
  "form",
3533
4583
  {
3534
4584
  onSubmit: handleSubmit(onPhonePasswordSubmit),
3535
4585
  className: "p-4 space-y-4 border-t",
3536
4586
  children: [
3537
- /* @__PURE__ */ jsxs23("div", { className: "space-y-4 w-full md:w-1/2", children: [
3538
- /* @__PURE__ */ jsxs23("div", { className: "space-y-2", children: [
3539
- /* @__PURE__ */ jsx26(Label3, { htmlFor: "phone", children: "Phone Number" }),
3540
- /* @__PURE__ */ jsx26(
3541
- Input7,
4587
+ /* @__PURE__ */ jsxs29("div", { className: "space-y-4 w-full md:w-1/2", children: [
4588
+ /* @__PURE__ */ jsxs29("div", { className: "space-y-2", children: [
4589
+ /* @__PURE__ */ jsx34(Label3, { htmlFor: "phone", children: "Phone Number" }),
4590
+ /* @__PURE__ */ jsx34(
4591
+ Input9,
3542
4592
  {
3543
4593
  id: "phone",
3544
4594
  type: "tel",
@@ -3547,13 +4597,13 @@ function RequestChangePhoneForm({
3547
4597
  disabled: isLoading
3548
4598
  }
3549
4599
  ),
3550
- errors.phone && /* @__PURE__ */ jsx26("p", { className: "text-sm text-destructive", children: errors.phone.message })
4600
+ errors.phone && /* @__PURE__ */ jsx34("p", { className: "text-sm text-destructive", children: errors.phone.message })
3551
4601
  ] }),
3552
- /* @__PURE__ */ jsxs23("div", { className: "space-y-2", children: [
3553
- /* @__PURE__ */ jsx26(Label3, { htmlFor: "password", children: "Password" }),
3554
- /* @__PURE__ */ jsxs23("div", { className: "relative", children: [
3555
- /* @__PURE__ */ jsx26(
3556
- Input7,
4602
+ /* @__PURE__ */ jsxs29("div", { className: "space-y-2", children: [
4603
+ /* @__PURE__ */ jsx34(Label3, { htmlFor: "password", children: "Password" }),
4604
+ /* @__PURE__ */ jsxs29("div", { className: "relative", children: [
4605
+ /* @__PURE__ */ jsx34(
4606
+ Input9,
3557
4607
  {
3558
4608
  id: "password",
3559
4609
  type: showPassword ? "text" : "password",
@@ -3563,22 +4613,22 @@ function RequestChangePhoneForm({
3563
4613
  disabled: isLoading
3564
4614
  }
3565
4615
  ),
3566
- /* @__PURE__ */ jsx26(
4616
+ /* @__PURE__ */ jsx34(
3567
4617
  "button",
3568
4618
  {
3569
4619
  type: "button",
3570
4620
  onClick: () => setShowPassword(!showPassword),
3571
4621
  className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground",
3572
- children: showPassword ? /* @__PURE__ */ jsx26(IconEyeOff6, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx26(IconEye6, { className: "h-4 w-4" })
4622
+ children: showPassword ? /* @__PURE__ */ jsx34(IconEyeOff7, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx34(IconEye7, { className: "h-4 w-4" })
3573
4623
  }
3574
4624
  )
3575
4625
  ] }),
3576
- errors.password && /* @__PURE__ */ jsx26("p", { className: "text-sm text-destructive", children: errors.password.message })
4626
+ errors.password && /* @__PURE__ */ jsx34("p", { className: "text-sm text-destructive", children: errors.password.message })
3577
4627
  ] })
3578
4628
  ] }),
3579
- /* @__PURE__ */ jsxs23("div", { className: "flex justify-end gap-2", children: [
3580
- /* @__PURE__ */ jsx26(
3581
- Button15,
4629
+ /* @__PURE__ */ jsxs29("div", { className: "flex justify-end gap-2", children: [
4630
+ /* @__PURE__ */ jsx34(
4631
+ Button18,
3582
4632
  {
3583
4633
  type: "button",
3584
4634
  variant: "outline",
@@ -3587,8 +4637,8 @@ function RequestChangePhoneForm({
3587
4637
  children: "Cancel"
3588
4638
  }
3589
4639
  ),
3590
- /* @__PURE__ */ jsxs23(Button15, { type: "submit", disabled: isLoading, children: [
3591
- isLoading && /* @__PURE__ */ jsx26(Spinner4, { className: "mr-2 h-4 w-4" }),
4640
+ /* @__PURE__ */ jsxs29(Button18, { type: "submit", disabled: isLoading, children: [
4641
+ isLoading && /* @__PURE__ */ jsx34(Spinner4, { className: "mr-2 h-4 w-4" }),
3592
4642
  isChecking ? "Checking\u2026" : buttonText
3593
4643
  ] })
3594
4644
  ] })
@@ -3598,9 +4648,9 @@ function RequestChangePhoneForm({
3598
4648
  }
3599
4649
 
3600
4650
  // src/components/profile/verify-change-phone-form.tsx
3601
- import { useState as useState19 } from "react";
3602
- import { toast as toast11 } from "sonner";
3603
- import { jsx as jsx27 } from "react/jsx-runtime";
4651
+ import { useState as useState21 } from "react";
4652
+ import { toast as toast14 } from "sonner";
4653
+ import { jsx as jsx35 } from "react/jsx-runtime";
3604
4654
  function isAuthError6(error) {
3605
4655
  return typeof error === "object" && error !== null && ("code" in error || "message" in error || "name" in error);
3606
4656
  }
@@ -3655,8 +4705,8 @@ function VerifyChangePhoneForm({
3655
4705
  }) {
3656
4706
  const { refresh } = useSession();
3657
4707
  const { hooks } = useApi();
3658
- const [isSubmitting, setIsSubmitting] = useState19(false);
3659
- const [currentVerificationId, setCurrentVerificationId] = useState19(verificationId);
4708
+ const [isSubmitting, setIsSubmitting] = useState21(false);
4709
+ const [currentVerificationId, setCurrentVerificationId] = useState21(verificationId);
3660
4710
  const verifyPhoneOtpMutation = hooks.useMutation(
3661
4711
  "post",
3662
4712
  "/phone/verification/confirm"
@@ -3668,7 +4718,7 @@ function VerifyChangePhoneForm({
3668
4718
  );
3669
4719
  const onOtpSubmit = async (code) => {
3670
4720
  if (!currentVerificationId) {
3671
- toast11.error("Verification not found. Please request a new code.");
4721
+ toast14.error("Verification not found. Please request a new code.");
3672
4722
  return;
3673
4723
  }
3674
4724
  try {
@@ -3683,21 +4733,21 @@ function VerifyChangePhoneForm({
3683
4733
  await updatePhoneMutation.mutateAsync({
3684
4734
  body: { phone }
3685
4735
  });
3686
- toast11.success("Phone number updated successfully");
4736
+ toast14.success("Phone number updated successfully");
3687
4737
  await refresh();
3688
4738
  onSuccess();
3689
4739
  } catch (error) {
3690
4740
  const errorMessage = getErrorMessage4(error);
3691
- toast11.error(errorMessage);
4741
+ toast14.error(errorMessage);
3692
4742
  } finally {
3693
4743
  setIsSubmitting(false);
3694
4744
  }
3695
4745
  };
3696
4746
  if (!currentVerificationId) {
3697
- toast11.error("Verification not found. Please request a new code.");
4747
+ toast14.error("Verification not found. Please request a new code.");
3698
4748
  return null;
3699
4749
  }
3700
- return /* @__PURE__ */ jsx27(
4750
+ return /* @__PURE__ */ jsx35(
3701
4751
  OtpVerificationModal,
3702
4752
  {
3703
4753
  open: true,
@@ -3716,9 +4766,9 @@ function VerifyChangePhoneForm({
3716
4766
  }
3717
4767
  });
3718
4768
  setCurrentVerificationId(next.data?.verificationId ?? null);
3719
- toast11.success("Verification code resent");
4769
+ toast14.success("Verification code resent");
3720
4770
  } catch (error) {
3721
- toast11.error(getErrorMessage4(error));
4771
+ toast14.error(getErrorMessage4(error));
3722
4772
  } finally {
3723
4773
  setIsSubmitting(false);
3724
4774
  }
@@ -3729,13 +4779,13 @@ function VerifyChangePhoneForm({
3729
4779
  }
3730
4780
 
3731
4781
  // src/components/profile/change-phone-form.tsx
3732
- import { jsx as jsx28, jsxs as jsxs24 } from "react/jsx-runtime";
4782
+ import { jsx as jsx36, jsxs as jsxs30 } from "react/jsx-runtime";
3733
4783
  function ChangePhoneForm() {
3734
4784
  const { user } = useSession();
3735
- const [isOpen, setIsOpen] = useState20(false);
3736
- const [showOtp, setShowOtp] = useState20(false);
3737
- const [verificationId, setVerificationId] = useState20(null);
3738
- const [newPhone, setNewPhone] = useState20("");
4785
+ const [isOpen, setIsOpen] = useState22(false);
4786
+ const [showOtp, setShowOtp] = useState22(false);
4787
+ const [verificationId, setVerificationId] = useState22(null);
4788
+ const [newPhone, setNewPhone] = useState22("");
3739
4789
  const resetForms = () => {
3740
4790
  setShowOtp(false);
3741
4791
  setVerificationId(null);
@@ -3756,23 +4806,23 @@ function ChangePhoneForm() {
3756
4806
  };
3757
4807
  const title = user?.phone ? "Change Phone" : "Add Phone";
3758
4808
  const description = user?.phone ? "Update your phone number" : "Add a phone number to your account";
3759
- return /* @__PURE__ */ jsx28(Collapsible3, { open: isOpen, onOpenChange: setIsOpen, children: /* @__PURE__ */ jsxs24("div", { className: "border rounded-lg", children: [
3760
- /* @__PURE__ */ jsxs24(
4809
+ return /* @__PURE__ */ jsx36(Collapsible3, { open: isOpen, onOpenChange: setIsOpen, children: /* @__PURE__ */ jsxs30("div", { className: "border rounded-lg", children: [
4810
+ /* @__PURE__ */ jsxs30(
3761
4811
  CollapsibleTrigger3,
3762
4812
  {
3763
- render: /* @__PURE__ */ jsx28(
3764
- Button16,
4813
+ render: /* @__PURE__ */ jsx36(
4814
+ Button19,
3765
4815
  {
3766
4816
  variant: "ghost",
3767
4817
  className: "w-full justify-between p-4 h-auto"
3768
4818
  }
3769
4819
  ),
3770
4820
  children: [
3771
- /* @__PURE__ */ jsxs24("div", { className: "flex flex-col items-start", children: [
3772
- /* @__PURE__ */ jsx28("span", { className: "font-medium", children: title }),
3773
- /* @__PURE__ */ jsx28("span", { className: "text-sm text-muted-foreground", children: description })
4821
+ /* @__PURE__ */ jsxs30("div", { className: "flex flex-col items-start", children: [
4822
+ /* @__PURE__ */ jsx36("span", { className: "font-medium", children: title }),
4823
+ /* @__PURE__ */ jsx36("span", { className: "text-sm text-muted-foreground", children: description })
3774
4824
  ] }),
3775
- /* @__PURE__ */ jsx28(
4825
+ /* @__PURE__ */ jsx36(
3776
4826
  IconChevronDown3,
3777
4827
  {
3778
4828
  className: `h-4 w-4 transition-transform ${isOpen ? "rotate-180" : ""}`
@@ -3781,7 +4831,7 @@ function ChangePhoneForm() {
3781
4831
  ]
3782
4832
  }
3783
4833
  ),
3784
- /* @__PURE__ */ jsx28(CollapsibleContent3, { children: showOtp ? /* @__PURE__ */ jsx28(
4834
+ /* @__PURE__ */ jsx36(CollapsibleContent3, { children: showOtp ? /* @__PURE__ */ jsx36(
3785
4835
  VerifyChangePhoneForm,
3786
4836
  {
3787
4837
  phone: newPhone,
@@ -3789,7 +4839,7 @@ function ChangePhoneForm() {
3789
4839
  onSuccess: handleVerifySuccess,
3790
4840
  onCancel: handleCancel
3791
4841
  }
3792
- ) : /* @__PURE__ */ jsx28(
4842
+ ) : /* @__PURE__ */ jsx36(
3793
4843
  RequestChangePhoneForm,
3794
4844
  {
3795
4845
  onSuccess: handleRequestSuccess,
@@ -3801,70 +4851,101 @@ function ChangePhoneForm() {
3801
4851
  }
3802
4852
 
3803
4853
  // src/components/profile/security.tsx
3804
- import { jsx as jsx29, jsxs as jsxs25 } from "react/jsx-runtime";
4854
+ import { jsx as jsx37, jsxs as jsxs31 } from "react/jsx-runtime";
3805
4855
  function Security() {
3806
- return /* @__PURE__ */ jsxs25("div", { className: "p-6 space-y-6", children: [
3807
- /* @__PURE__ */ jsxs25("div", { children: [
3808
- /* @__PURE__ */ jsx29("h1", { className: "text-2xl font-semibold", children: "Security" }),
3809
- /* @__PURE__ */ jsx29("p", { className: "text-muted-foreground", children: "Manage your security settings" })
4856
+ const { user } = useSession();
4857
+ return /* @__PURE__ */ jsxs31("div", { className: "mx-auto flex w-full max-w-6xl flex-col gap-6", children: [
4858
+ /* @__PURE__ */ jsxs31("div", { className: "relative overflow-hidden rounded-[2rem] border border-border/60 bg-gradient-to-br from-background via-background to-amber-500/5 p-6 shadow-sm", children: [
4859
+ /* @__PURE__ */ jsx37("div", { className: "absolute left-0 top-0 h-32 w-32 rounded-full bg-primary/10 blur-3xl" }),
4860
+ /* @__PURE__ */ jsxs31("div", { className: "relative flex flex-col gap-4", children: [
4861
+ /* @__PURE__ */ jsxs31("div", { className: "flex flex-wrap gap-2", children: [
4862
+ /* @__PURE__ */ jsx37(Badge9, { variant: "outline", children: "Security center" }),
4863
+ /* @__PURE__ */ jsx37(Badge9, { variant: "secondary", children: user?.emailVerified || user?.phoneVerified ? "Recovery methods available" : "Add a recovery method" })
4864
+ ] }),
4865
+ /* @__PURE__ */ jsxs31("div", { className: "space-y-2", children: [
4866
+ /* @__PURE__ */ jsx37("h1", { className: "text-2xl font-semibold tracking-tight", children: "Security" }),
4867
+ /* @__PURE__ */ jsx37("p", { className: "max-w-2xl text-sm text-muted-foreground", children: "Password, email, and phone updates all live here. Keep recovery channels current so account recovery stays predictable." })
4868
+ ] })
4869
+ ] })
3810
4870
  ] }),
3811
- /* @__PURE__ */ jsxs25("div", { className: "space-y-4", children: [
3812
- /* @__PURE__ */ jsx29(ChangePasswordForm, {}),
3813
- /* @__PURE__ */ jsx29(ChangeEmailForm, {}),
3814
- /* @__PURE__ */ jsx29(ChangePhoneForm, {})
4871
+ /* @__PURE__ */ jsxs31("div", { className: "grid gap-4 lg:grid-cols-[0.85fr_1.4fr]", children: [
4872
+ /* @__PURE__ */ jsx37(Card3, { className: "rounded-[1.75rem] border-border/60 shadow-sm", children: /* @__PURE__ */ jsxs31(CardContent2, { className: "space-y-5 p-6", children: [
4873
+ /* @__PURE__ */ jsxs31("div", { className: "space-y-1", children: [
4874
+ /* @__PURE__ */ jsx37("div", { className: "text-sm font-medium text-muted-foreground", children: "Verification state" }),
4875
+ /* @__PURE__ */ jsx37("div", { className: "text-lg font-semibold", children: "Recovery readiness" })
4876
+ ] }),
4877
+ /* @__PURE__ */ jsx37(Separator2, {}),
4878
+ /* @__PURE__ */ jsxs31("div", { className: "space-y-3", children: [
4879
+ /* @__PURE__ */ jsxs31("div", { className: "rounded-2xl border border-border/60 bg-muted/20 p-4", children: [
4880
+ /* @__PURE__ */ jsx37("div", { className: "text-sm font-medium", children: "Email" }),
4881
+ /* @__PURE__ */ jsx37("div", { className: "mt-1 text-sm text-muted-foreground", children: user?.email ?? "No email added" }),
4882
+ /* @__PURE__ */ jsx37("div", { className: "mt-3", children: /* @__PURE__ */ jsx37(Badge9, { variant: "outline", children: user?.emailVerified ? "Verified" : "Unverified" }) })
4883
+ ] }),
4884
+ /* @__PURE__ */ jsxs31("div", { className: "rounded-2xl border border-border/60 bg-muted/20 p-4", children: [
4885
+ /* @__PURE__ */ jsx37("div", { className: "text-sm font-medium", children: "Phone" }),
4886
+ /* @__PURE__ */ jsx37("div", { className: "mt-1 text-sm text-muted-foreground", children: user?.phone ?? "No phone added" }),
4887
+ /* @__PURE__ */ jsx37("div", { className: "mt-3", children: /* @__PURE__ */ jsx37(Badge9, { variant: "outline", children: user?.phoneVerified ? "Verified" : "Unverified" }) })
4888
+ ] })
4889
+ ] })
4890
+ ] }) }),
4891
+ /* @__PURE__ */ jsxs31("div", { className: "space-y-4", children: [
4892
+ /* @__PURE__ */ jsx37(ChangePasswordForm, {}),
4893
+ /* @__PURE__ */ jsx37(ChangeEmailForm, {}),
4894
+ /* @__PURE__ */ jsx37(ChangePhoneForm, {})
4895
+ ] })
3815
4896
  ] })
3816
4897
  ] });
3817
4898
  }
3818
4899
 
3819
4900
  // src/components/skeletons/auth-form-skeleton.tsx
3820
- import { Skeleton as Skeleton2 } from "@mesob/ui/components";
3821
- import { jsx as jsx30, jsxs as jsxs26 } from "react/jsx-runtime";
4901
+ import { Skeleton as Skeleton3 } from "@mesob/ui/components";
4902
+ import { jsx as jsx38, jsxs as jsxs32 } from "react/jsx-runtime";
3822
4903
  function AuthFormSkeleton() {
3823
- return /* @__PURE__ */ jsxs26("div", { className: "w-full max-w-md space-y-6 p-6", children: [
3824
- /* @__PURE__ */ jsxs26("div", { className: "space-y-2 text-center", children: [
3825
- /* @__PURE__ */ jsx30(Skeleton2, { className: "h-8 w-48 mx-auto" }),
3826
- /* @__PURE__ */ jsx30(Skeleton2, { className: "h-4 w-64 mx-auto" })
4904
+ return /* @__PURE__ */ jsxs32("div", { className: "w-full max-w-md space-y-6 p-6", children: [
4905
+ /* @__PURE__ */ jsxs32("div", { className: "space-y-2 text-center", children: [
4906
+ /* @__PURE__ */ jsx38(Skeleton3, { className: "h-8 w-48 mx-auto" }),
4907
+ /* @__PURE__ */ jsx38(Skeleton3, { className: "h-4 w-64 mx-auto" })
3827
4908
  ] }),
3828
- /* @__PURE__ */ jsxs26("div", { className: "space-y-4", children: [
3829
- /* @__PURE__ */ jsxs26("div", { className: "space-y-2", children: [
3830
- /* @__PURE__ */ jsx30(Skeleton2, { className: "h-4 w-24" }),
3831
- /* @__PURE__ */ jsx30(Skeleton2, { className: "h-10 w-full" })
4909
+ /* @__PURE__ */ jsxs32("div", { className: "space-y-4", children: [
4910
+ /* @__PURE__ */ jsxs32("div", { className: "space-y-2", children: [
4911
+ /* @__PURE__ */ jsx38(Skeleton3, { className: "h-4 w-24" }),
4912
+ /* @__PURE__ */ jsx38(Skeleton3, { className: "h-10 w-full" })
3832
4913
  ] }),
3833
- /* @__PURE__ */ jsxs26("div", { className: "space-y-2", children: [
3834
- /* @__PURE__ */ jsx30(Skeleton2, { className: "h-4 w-24" }),
3835
- /* @__PURE__ */ jsx30(Skeleton2, { className: "h-10 w-full" })
4914
+ /* @__PURE__ */ jsxs32("div", { className: "space-y-2", children: [
4915
+ /* @__PURE__ */ jsx38(Skeleton3, { className: "h-4 w-24" }),
4916
+ /* @__PURE__ */ jsx38(Skeleton3, { className: "h-10 w-full" })
3836
4917
  ] }),
3837
- /* @__PURE__ */ jsx30(Skeleton2, { className: "h-10 w-full" })
4918
+ /* @__PURE__ */ jsx38(Skeleton3, { className: "h-10 w-full" })
3838
4919
  ] }),
3839
- /* @__PURE__ */ jsxs26("div", { className: "space-y-2", children: [
3840
- /* @__PURE__ */ jsx30(Skeleton2, { className: "h-px w-full" }),
3841
- /* @__PURE__ */ jsx30(Skeleton2, { className: "h-4 w-32 mx-auto" })
4920
+ /* @__PURE__ */ jsxs32("div", { className: "space-y-2", children: [
4921
+ /* @__PURE__ */ jsx38(Skeleton3, { className: "h-px w-full" }),
4922
+ /* @__PURE__ */ jsx38(Skeleton3, { className: "h-4 w-32 mx-auto" })
3842
4923
  ] })
3843
4924
  ] });
3844
4925
  }
3845
4926
 
3846
4927
  // src/components/skeletons/profile-skeleton.tsx
3847
- import { Skeleton as Skeleton3 } from "@mesob/ui/components";
3848
- import { jsx as jsx31, jsxs as jsxs27 } from "react/jsx-runtime";
4928
+ import { Skeleton as Skeleton4 } from "@mesob/ui/components";
4929
+ import { jsx as jsx39, jsxs as jsxs33 } from "react/jsx-runtime";
3849
4930
  function ProfileSkeleton() {
3850
- return /* @__PURE__ */ jsxs27("div", { className: "w-full max-w-4xl space-y-8 p-6", children: [
3851
- /* @__PURE__ */ jsxs27("div", { className: "flex items-center gap-6", children: [
3852
- /* @__PURE__ */ jsx31(Skeleton3, { className: "h-24 w-24 rounded-full" }),
3853
- /* @__PURE__ */ jsxs27("div", { className: "space-y-2 flex-1", children: [
3854
- /* @__PURE__ */ jsx31(Skeleton3, { className: "h-8 w-48" }),
3855
- /* @__PURE__ */ jsx31(Skeleton3, { className: "h-4 w-64" })
4931
+ return /* @__PURE__ */ jsxs33("div", { className: "w-full max-w-4xl space-y-8 p-6", children: [
4932
+ /* @__PURE__ */ jsxs33("div", { className: "flex items-center gap-6", children: [
4933
+ /* @__PURE__ */ jsx39(Skeleton4, { className: "h-24 w-24 rounded-full" }),
4934
+ /* @__PURE__ */ jsxs33("div", { className: "space-y-2 flex-1", children: [
4935
+ /* @__PURE__ */ jsx39(Skeleton4, { className: "h-8 w-48" }),
4936
+ /* @__PURE__ */ jsx39(Skeleton4, { className: "h-4 w-64" })
3856
4937
  ] })
3857
4938
  ] }),
3858
- /* @__PURE__ */ jsx31("div", { className: "space-y-6", children: [1, 2, 3].map((i) => /* @__PURE__ */ jsxs27("div", { className: "space-y-4", children: [
3859
- /* @__PURE__ */ jsx31(Skeleton3, { className: "h-6 w-32" }),
3860
- /* @__PURE__ */ jsxs27("div", { className: "space-y-3", children: [
3861
- /* @__PURE__ */ jsxs27("div", { className: "flex justify-between items-center", children: [
3862
- /* @__PURE__ */ jsx31(Skeleton3, { className: "h-4 w-24" }),
3863
- /* @__PURE__ */ jsx31(Skeleton3, { className: "h-4 w-32" })
4939
+ /* @__PURE__ */ jsx39("div", { className: "space-y-6", children: [1, 2, 3].map((i) => /* @__PURE__ */ jsxs33("div", { className: "space-y-4", children: [
4940
+ /* @__PURE__ */ jsx39(Skeleton4, { className: "h-6 w-32" }),
4941
+ /* @__PURE__ */ jsxs33("div", { className: "space-y-3", children: [
4942
+ /* @__PURE__ */ jsxs33("div", { className: "flex justify-between items-center", children: [
4943
+ /* @__PURE__ */ jsx39(Skeleton4, { className: "h-4 w-24" }),
4944
+ /* @__PURE__ */ jsx39(Skeleton4, { className: "h-4 w-32" })
3864
4945
  ] }),
3865
- /* @__PURE__ */ jsxs27("div", { className: "flex justify-between items-center", children: [
3866
- /* @__PURE__ */ jsx31(Skeleton3, { className: "h-4 w-24" }),
3867
- /* @__PURE__ */ jsx31(Skeleton3, { className: "h-4 w-40" })
4946
+ /* @__PURE__ */ jsxs33("div", { className: "flex justify-between items-center", children: [
4947
+ /* @__PURE__ */ jsx39(Skeleton4, { className: "h-4 w-24" }),
4948
+ /* @__PURE__ */ jsx39(Skeleton4, { className: "h-4 w-40" })
3868
4949
  ] })
3869
4950
  ] })
3870
4951
  ] }, i)) })
@@ -3882,15 +4963,22 @@ export {
3882
4963
  AuthErrorBoundary,
3883
4964
  AuthFormSkeleton,
3884
4965
  DataTable,
4966
+ Deny,
3885
4967
  ErrorBoundary,
3886
4968
  ForgotPassword,
4969
+ Grant,
3887
4970
  MesobAuthProvider,
4971
+ PermissionSelector,
3888
4972
  Permissions,
3889
4973
  ProfileSkeleton,
3890
4974
  ResetPasswordForm,
4975
+ RoleDetailLayout,
4976
+ RoleDetailPage,
4977
+ RolePermissionsPage,
3891
4978
  Roles,
3892
4979
  Security,
3893
4980
  Sessions,
4981
+ SetPassword,
3894
4982
  SignIn,
3895
4983
  SignUp,
3896
4984
  TableSkeleton,