@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.
- package/dist/components/auth/forgot-password.js +5 -1
- package/dist/components/auth/forgot-password.js.map +1 -1
- package/dist/components/auth/reset-password-form.js +5 -1
- package/dist/components/auth/reset-password-form.js.map +1 -1
- package/dist/components/auth/set-password.d.ts +9 -0
- package/dist/components/auth/set-password.js +527 -0
- package/dist/components/auth/set-password.js.map +1 -0
- package/dist/components/auth/sign-in.js +22 -1
- package/dist/components/auth/sign-in.js.map +1 -1
- package/dist/components/auth/sign-up.js +7 -5
- package/dist/components/auth/sign-up.js.map +1 -1
- package/dist/components/auth/verify-email.js +5 -1
- package/dist/components/auth/verify-email.js.map +1 -1
- package/dist/components/auth/verify-phone.js +5 -1
- package/dist/components/auth/verify-phone.js.map +1 -1
- package/dist/components/authorization/deny.d.ts +11 -0
- package/dist/components/authorization/deny.js +52 -0
- package/dist/components/authorization/deny.js.map +1 -0
- package/dist/components/authorization/grant.d.ts +12 -0
- package/dist/components/authorization/grant.js +57 -0
- package/dist/components/authorization/grant.js.map +1 -0
- package/dist/components/error-boundary.d.ts +2 -2
- package/dist/components/iam/permission-selector.d.ts +19 -0
- package/dist/components/iam/permission-selector.js +122 -0
- package/dist/components/iam/permission-selector.js.map +1 -0
- package/dist/components/iam/permissions.js +12 -31
- package/dist/components/iam/permissions.js.map +1 -1
- package/dist/components/iam/role-detail-layout.d.ts +11 -0
- package/dist/components/iam/role-detail-layout.js +137 -0
- package/dist/components/iam/role-detail-layout.js.map +1 -0
- package/dist/components/iam/role-detail-page.d.ts +9 -0
- package/dist/components/iam/role-detail-page.js +229 -0
- package/dist/components/iam/role-detail-page.js.map +1 -0
- package/dist/components/iam/role-permissions-page.d.ts +8 -0
- package/dist/components/iam/role-permissions-page.js +397 -0
- package/dist/components/iam/role-permissions-page.js.map +1 -0
- package/dist/components/iam/roles.js +11 -8
- package/dist/components/iam/roles.js.map +1 -1
- package/dist/components/iam/users.js +1 -7
- package/dist/components/iam/users.js.map +1 -1
- package/dist/components/profile/account.js +110 -19
- package/dist/components/profile/account.js.map +1 -1
- package/dist/components/profile/change-profile.d.ts +2 -1
- package/dist/components/profile/change-profile.js +16 -8
- package/dist/components/profile/change-profile.js.map +1 -1
- package/dist/components/profile/security.js +51 -17
- package/dist/components/profile/security.js.map +1 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +1813 -725
- package/dist/index.js.map +1 -1
- package/dist/pages/auth/forgot-password.d.ts +7 -0
- package/dist/pages/auth/forgot-password.js +784 -0
- package/dist/pages/auth/forgot-password.js.map +1 -0
- package/dist/pages/auth/layout.d.ts +8 -0
- package/dist/pages/auth/layout.js +562 -0
- package/dist/pages/auth/layout.js.map +1 -0
- package/dist/pages/auth/reset-password.d.ts +10 -0
- package/dist/pages/auth/reset-password.js +913 -0
- package/dist/pages/auth/reset-password.js.map +1 -0
- package/dist/pages/auth/set-password.d.ts +10 -0
- package/dist/pages/auth/set-password.js +946 -0
- package/dist/pages/auth/set-password.js.map +1 -0
- package/dist/pages/auth/sign-in.d.ts +10 -0
- package/dist/pages/auth/sign-in.js +984 -0
- package/dist/pages/auth/sign-in.js.map +1 -0
- package/dist/pages/auth/sign-up.d.ts +10 -0
- package/dist/pages/auth/sign-up.js +940 -0
- package/dist/pages/auth/sign-up.js.map +1 -0
- package/dist/pages/auth/verify-email.d.ts +10 -0
- package/dist/pages/auth/verify-email.js +950 -0
- package/dist/pages/auth/verify-email.js.map +1 -0
- package/dist/pages/auth/verify-phone.d.ts +10 -0
- package/dist/pages/auth/verify-phone.js +964 -0
- package/dist/pages/auth/verify-phone.js.map +1 -0
- package/dist/pages/iam/permissions.d.ts +5 -0
- package/dist/pages/iam/permissions.js +308 -0
- package/dist/pages/iam/permissions.js.map +1 -0
- package/dist/pages/iam/role-detail-layout.d.ts +12 -0
- package/dist/pages/iam/role-detail-layout.js +145 -0
- package/dist/pages/iam/role-detail-layout.js.map +1 -0
- package/dist/pages/iam/role-detail.d.ts +12 -0
- package/dist/pages/iam/role-detail.js +241 -0
- package/dist/pages/iam/role-detail.js.map +1 -0
- package/dist/pages/iam/role-permissions.d.ts +12 -0
- package/dist/pages/iam/role-permissions.js +409 -0
- package/dist/pages/iam/role-permissions.js.map +1 -0
- package/dist/pages/iam/role-users.d.ts +12 -0
- package/dist/pages/iam/role-users.js +825 -0
- package/dist/pages/iam/role-users.js.map +1 -0
- package/dist/pages/iam/roles.d.ts +5 -0
- package/dist/pages/iam/roles.js +684 -0
- package/dist/pages/iam/roles.js.map +1 -0
- package/dist/pages/iam/sessions.d.ts +5 -0
- package/dist/pages/iam/sessions.js +315 -0
- package/dist/pages/iam/sessions.js.map +1 -0
- package/dist/pages/iam/tenant-detail.d.ts +10 -0
- package/dist/pages/iam/tenant-detail.js +186 -0
- package/dist/pages/iam/tenant-detail.js.map +1 -0
- package/dist/pages/iam/tenants.d.ts +5 -0
- package/dist/pages/iam/tenants.js +610 -0
- package/dist/pages/iam/tenants.js.map +1 -0
- package/dist/pages/iam/user-activity.d.ts +10 -0
- package/dist/pages/iam/user-activity.js +850 -0
- package/dist/pages/iam/user-activity.js.map +1 -0
- package/dist/pages/iam/user-detail-layout.d.ts +12 -0
- package/dist/pages/iam/user-detail-layout.js +106 -0
- package/dist/pages/iam/user-detail-layout.js.map +1 -0
- package/dist/pages/iam/user-detail.d.ts +10 -0
- package/dist/pages/iam/user-detail.js +102 -0
- package/dist/pages/iam/user-detail.js.map +1 -0
- package/dist/pages/iam/users.d.ts +5 -0
- package/dist/pages/iam/users.js +1275 -0
- package/dist/pages/iam/users.js.map +1 -0
- package/dist/pages/profile/account.d.ts +5 -0
- package/dist/pages/profile/account.js +182 -0
- package/dist/pages/profile/account.js.map +1 -0
- package/dist/pages/profile/layout.d.ts +8 -0
- package/dist/pages/profile/layout.js +133 -0
- package/dist/pages/profile/layout.js.map +1 -0
- package/dist/pages/profile/security.d.ts +5 -0
- package/dist/pages/profile/security.js +1539 -0
- package/dist/pages/profile/security.js.map +1 -0
- package/dist/{types-vcfvnAzQ.d.ts → types-g9QcNRxT.d.ts} +13 -7
- 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
|
|
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/
|
|
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/
|
|
896
|
-
import {
|
|
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
|
|
927
|
-
|
|
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 =
|
|
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:
|
|
936
|
-
|
|
937
|
-
|
|
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 =
|
|
1231
|
+
const mesob = useMesob5();
|
|
944
1232
|
const t = useTranslator("Auth.signIn");
|
|
945
1233
|
const Link = mesob?.navigation?.Link;
|
|
946
|
-
const [isLoading, setIsLoading] =
|
|
947
|
-
const [error, setError] =
|
|
948
|
-
const [showPasswordField, setShowPasswordField] =
|
|
949
|
-
const [showPassword, setShowPassword] =
|
|
950
|
-
const [username, setUsername] =
|
|
951
|
-
const [isChecking, setIsChecking] =
|
|
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 =
|
|
965
|
-
resolver:
|
|
1253
|
+
const form = useForm4({
|
|
1254
|
+
resolver: zodResolver4(signInSchema(t, phoneRegex)),
|
|
966
1255
|
defaultValues: { username: "", password: "" },
|
|
967
1256
|
mode: "onBlur"
|
|
968
1257
|
});
|
|
969
|
-
|
|
1258
|
+
useEffect4(() => {
|
|
970
1259
|
if (error) {
|
|
971
|
-
|
|
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__ */
|
|
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__ */
|
|
1074
|
-
/* @__PURE__ */
|
|
1075
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1078
|
-
|
|
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__ */
|
|
1090
|
-
|
|
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__ */
|
|
1101
|
-
|
|
1405
|
+
/* @__PURE__ */ jsx7(
|
|
1406
|
+
FormField4,
|
|
1102
1407
|
{
|
|
1103
1408
|
control: form.control,
|
|
1104
1409
|
name: "password",
|
|
1105
|
-
render: ({ field }) => /* @__PURE__ */
|
|
1106
|
-
/* @__PURE__ */
|
|
1107
|
-
/* @__PURE__ */
|
|
1108
|
-
|
|
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__ */
|
|
1420
|
+
/* @__PURE__ */ jsx7(FormMessage4, {})
|
|
1116
1421
|
] })
|
|
1117
1422
|
}
|
|
1118
1423
|
)
|
|
1119
|
-
] }) : /* @__PURE__ */
|
|
1120
|
-
|
|
1424
|
+
] }) : /* @__PURE__ */ jsx7(
|
|
1425
|
+
FormField4,
|
|
1121
1426
|
{
|
|
1122
1427
|
control: form.control,
|
|
1123
1428
|
name: "username",
|
|
1124
|
-
render: ({ field }) => /* @__PURE__ */
|
|
1125
|
-
/* @__PURE__ */
|
|
1126
|
-
/* @__PURE__ */
|
|
1127
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1132
|
-
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
1172
|
-
/* @__PURE__ */
|
|
1173
|
-
/* @__PURE__ */
|
|
1174
|
-
/* @__PURE__ */
|
|
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
|
|
1487
|
+
import { zodResolver as zodResolver5 } from "@hookform/resolvers/zod";
|
|
1183
1488
|
import {
|
|
1184
|
-
Alert as
|
|
1185
|
-
AlertDescription as
|
|
1186
|
-
AlertTitle as
|
|
1187
|
-
Button as
|
|
1188
|
-
Form as
|
|
1189
|
-
FormControl as
|
|
1190
|
-
FormField as
|
|
1191
|
-
FormItem as
|
|
1192
|
-
FormLabel as
|
|
1193
|
-
FormMessage as
|
|
1194
|
-
Input as
|
|
1195
|
-
useFormField as
|
|
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
|
|
1198
|
-
import { IconAlertCircle as
|
|
1199
|
-
import { useEffect as
|
|
1200
|
-
import { useForm as
|
|
1201
|
-
import { toast as
|
|
1202
|
-
import { z as
|
|
1203
|
-
import { jsx as
|
|
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
|
|
1206
|
-
const { formItemId, error } =
|
|
1207
|
-
return /* @__PURE__ */
|
|
1208
|
-
/* @__PURE__ */
|
|
1209
|
-
|
|
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__ */
|
|
1219
|
-
|
|
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__ */
|
|
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) =>
|
|
1233
|
-
fullName:
|
|
1234
|
-
identifier:
|
|
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:
|
|
1246
|
-
confirmPassword:
|
|
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 =
|
|
1562
|
+
const mesob = useMesob6();
|
|
1258
1563
|
const t = useTranslator("Auth.signUp");
|
|
1259
1564
|
const Link = mesob?.navigation?.Link;
|
|
1260
|
-
const [isLoading, setIsLoading] =
|
|
1261
|
-
const [error, setError] =
|
|
1262
|
-
const [showPassword, setShowPassword] =
|
|
1263
|
-
const [showConfirmPassword, setShowConfirmPassword] =
|
|
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 =
|
|
1275
|
-
resolver:
|
|
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
|
-
|
|
1588
|
+
useEffect5(() => {
|
|
1284
1589
|
if (initialIdentifier) {
|
|
1285
1590
|
form.setValue("identifier", initialIdentifier);
|
|
1286
1591
|
}
|
|
1287
1592
|
}, [initialIdentifier, form]);
|
|
1288
|
-
|
|
1593
|
+
useEffect5(() => {
|
|
1289
1594
|
if (error) {
|
|
1290
|
-
|
|
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__ */
|
|
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__ */
|
|
1664
|
+
footer: /* @__PURE__ */ jsxs6("p", { children: [
|
|
1362
1665
|
t("footer.hasAccount"),
|
|
1363
1666
|
" ",
|
|
1364
|
-
Link ? /* @__PURE__ */
|
|
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__ */
|
|
1379
|
-
/* @__PURE__ */
|
|
1380
|
-
|
|
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__ */
|
|
1385
|
-
/* @__PURE__ */
|
|
1386
|
-
/* @__PURE__ */
|
|
1387
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1392
|
-
|
|
1694
|
+
/* @__PURE__ */ jsx8(
|
|
1695
|
+
FormField5,
|
|
1393
1696
|
{
|
|
1394
1697
|
control: form.control,
|
|
1395
1698
|
name: "identifier",
|
|
1396
|
-
render: ({ field }) => /* @__PURE__ */
|
|
1397
|
-
/* @__PURE__ */
|
|
1398
|
-
|
|
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__ */
|
|
1405
|
-
|
|
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__ */
|
|
1715
|
+
/* @__PURE__ */ jsx8(FormMessage5, {})
|
|
1413
1716
|
] })
|
|
1414
1717
|
}
|
|
1415
1718
|
),
|
|
1416
|
-
/* @__PURE__ */
|
|
1417
|
-
|
|
1719
|
+
/* @__PURE__ */ jsx8(
|
|
1720
|
+
FormField5,
|
|
1418
1721
|
{
|
|
1419
1722
|
control: form.control,
|
|
1420
1723
|
name: "password",
|
|
1421
|
-
render: ({ field }) => /* @__PURE__ */
|
|
1422
|
-
/* @__PURE__ */
|
|
1423
|
-
/* @__PURE__ */
|
|
1424
|
-
|
|
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__ */
|
|
1734
|
+
/* @__PURE__ */ jsx8(FormMessage5, {})
|
|
1432
1735
|
] })
|
|
1433
1736
|
}
|
|
1434
1737
|
),
|
|
1435
|
-
/* @__PURE__ */
|
|
1436
|
-
|
|
1738
|
+
/* @__PURE__ */ jsx8(
|
|
1739
|
+
FormField5,
|
|
1437
1740
|
{
|
|
1438
1741
|
control: form.control,
|
|
1439
1742
|
name: "confirmPassword",
|
|
1440
|
-
render: ({ field }) => /* @__PURE__ */
|
|
1441
|
-
/* @__PURE__ */
|
|
1442
|
-
/* @__PURE__ */
|
|
1443
|
-
|
|
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__ */
|
|
1753
|
+
/* @__PURE__ */ jsx8(FormMessage5, {})
|
|
1451
1754
|
] })
|
|
1452
1755
|
}
|
|
1453
1756
|
),
|
|
1454
|
-
/* @__PURE__ */
|
|
1455
|
-
|
|
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__ */
|
|
1466
|
-
/* @__PURE__ */
|
|
1467
|
-
/* @__PURE__ */
|
|
1468
|
-
/* @__PURE__ */
|
|
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
|
|
1779
|
+
import { zodResolver as zodResolver6 } from "@hookform/resolvers/zod";
|
|
1477
1780
|
import {
|
|
1478
|
-
Button as
|
|
1479
|
-
Form as
|
|
1480
|
-
FormControl as
|
|
1481
|
-
FormField as
|
|
1482
|
-
FormItem as
|
|
1483
|
-
FormLabel as
|
|
1484
|
-
FormMessage as
|
|
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
|
|
1490
|
-
import { z as
|
|
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
|
|
1495
|
-
import { jsx as
|
|
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] =
|
|
1503
|
-
const [isResending, setIsResending] =
|
|
1504
|
-
|
|
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__ */
|
|
1834
|
+
return /* @__PURE__ */ jsx9("p", { className: "text-sm text-muted-foreground", children: t("resendIn", { seconds }) });
|
|
1532
1835
|
}
|
|
1533
|
-
return /* @__PURE__ */
|
|
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__ */
|
|
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
|
|
1550
|
-
var verificationSchema = (t) =>
|
|
1551
|
-
code:
|
|
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 =
|
|
1560
|
-
resolver:
|
|
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__ */
|
|
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__ */
|
|
1575
|
-
|
|
1877
|
+
/* @__PURE__ */ jsx10(
|
|
1878
|
+
FormField6,
|
|
1576
1879
|
{
|
|
1577
1880
|
control: form.control,
|
|
1578
1881
|
name: "code",
|
|
1579
|
-
render: ({ field }) => /* @__PURE__ */
|
|
1580
|
-
/* @__PURE__ */
|
|
1581
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1591
|
-
/* @__PURE__ */
|
|
1592
|
-
/* @__PURE__ */
|
|
1593
|
-
/* @__PURE__ */
|
|
1594
|
-
/* @__PURE__ */
|
|
1595
|
-
/* @__PURE__ */
|
|
1596
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1903
|
+
/* @__PURE__ */ jsx10(FormMessage6, {})
|
|
1601
1904
|
] })
|
|
1602
1905
|
}
|
|
1603
1906
|
),
|
|
1604
|
-
/* @__PURE__ */
|
|
1605
|
-
|
|
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__ */
|
|
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
|
|
1623
|
-
import { useMesob as
|
|
1624
|
-
import { IconAlertCircle as
|
|
1625
|
-
import { useEffect as
|
|
1626
|
-
import { toast as
|
|
1627
|
-
import { jsx as
|
|
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 =
|
|
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] =
|
|
1641
|
-
const [error, setError] =
|
|
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
|
-
|
|
1961
|
+
useEffect7(() => {
|
|
1659
1962
|
if (error) {
|
|
1660
|
-
|
|
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__ */
|
|
2018
|
+
return /* @__PURE__ */ jsx11(
|
|
1716
2019
|
AuthLayout,
|
|
1717
2020
|
{
|
|
1718
2021
|
title: common("invalidLinkTitle"),
|
|
1719
2022
|
description: common("invalidLinkDescription"),
|
|
1720
|
-
footer: Link ? /* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
1774
|
-
/* @__PURE__ */
|
|
1775
|
-
/* @__PURE__ */
|
|
1776
|
-
/* @__PURE__ */
|
|
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
|
|
1785
|
-
import { useMesob as
|
|
1786
|
-
import { IconAlertCircle as
|
|
1787
|
-
import { useEffect as
|
|
1788
|
-
import { toast as
|
|
1789
|
-
import { jsx as
|
|
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 =
|
|
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] =
|
|
1804
|
-
const [error, setError] =
|
|
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
|
-
|
|
2124
|
+
useEffect8(() => {
|
|
1822
2125
|
if (error) {
|
|
1823
|
-
|
|
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__ */
|
|
2194
|
+
return /* @__PURE__ */ jsx12(
|
|
1892
2195
|
AuthLayout,
|
|
1893
2196
|
{
|
|
1894
2197
|
title: common("invalidLinkTitle"),
|
|
1895
2198
|
description: common("invalidLinkDescription"),
|
|
1896
|
-
footer: /* @__PURE__ */
|
|
1897
|
-
children: /* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
1941
|
-
/* @__PURE__ */
|
|
1942
|
-
/* @__PURE__ */
|
|
1943
|
-
/* @__PURE__ */
|
|
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
|
|
2289
|
+
import { Button as Button7 } from "@mesob/ui/components";
|
|
1952
2290
|
import { Component } from "react";
|
|
1953
|
-
import { jsx as
|
|
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__ */
|
|
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__ */
|
|
1982
|
-
/* @__PURE__ */
|
|
1983
|
-
/* @__PURE__ */
|
|
1984
|
-
/* @__PURE__ */
|
|
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__ */
|
|
2324
|
+
/* @__PURE__ */ jsx15(Button7, { onClick: reset, variant: "outline", children: "Try again" })
|
|
1987
2325
|
] }) });
|
|
1988
2326
|
}
|
|
1989
2327
|
function AuthErrorBoundary({ children }) {
|
|
1990
|
-
return /* @__PURE__ */
|
|
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
|
|
1995
|
-
import {
|
|
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
|
|
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__ */
|
|
2019
|
-
/* @__PURE__ */
|
|
2020
|
-
/* @__PURE__ */
|
|
2021
|
-
/* @__PURE__ */
|
|
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__ */
|
|
2024
|
-
/* @__PURE__ */
|
|
2025
|
-
/* @__PURE__ */
|
|
2026
|
-
/* @__PURE__ */
|
|
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__ */
|
|
2029
|
-
/* @__PURE__ */
|
|
2030
|
-
rowKeys.map((rowKey, rowIdx) => /* @__PURE__ */
|
|
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__ */
|
|
2033
|
-
/* @__PURE__ */
|
|
2034
|
-
/* @__PURE__ */
|
|
2035
|
-
/* @__PURE__ */
|
|
2036
|
-
/* @__PURE__ */
|
|
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
|
|
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__ */
|
|
2475
|
+
return /* @__PURE__ */ jsx18(TableSkeleton, { columns: columns.length, rows: 5 });
|
|
2054
2476
|
}
|
|
2055
2477
|
if (data.length === 0) {
|
|
2056
|
-
return /* @__PURE__ */
|
|
2057
|
-
/* @__PURE__ */
|
|
2058
|
-
actions && /* @__PURE__ */
|
|
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__ */
|
|
2062
|
-
actions && /* @__PURE__ */
|
|
2063
|
-
/* @__PURE__ */
|
|
2064
|
-
/* @__PURE__ */
|
|
2065
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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
|
|
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
|
|
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: "
|
|
2108
|
-
header: "Permission",
|
|
2109
|
-
cell: (permission) => /* @__PURE__ */
|
|
2110
|
-
/* @__PURE__ */
|
|
2111
|
-
/* @__PURE__ */
|
|
2112
|
-
] })
|
|
2113
|
-
},
|
|
2114
|
-
{
|
|
2115
|
-
key: "
|
|
2116
|
-
header: "
|
|
2117
|
-
cell: (permission) => /* @__PURE__ */
|
|
2118
|
-
},
|
|
2119
|
-
{
|
|
2120
|
-
key: "
|
|
2121
|
-
header: "
|
|
2122
|
-
cell: (permission) => /* @__PURE__ */
|
|
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
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
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
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
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
|
-
|
|
2136
|
-
|
|
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
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
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
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2965
|
+
view: currentView,
|
|
2966
|
+
rowCount: params.pageSize,
|
|
2967
|
+
columnCount: TABLE_COLUMN_COUNT,
|
|
2968
|
+
cardCount: params.pageSize
|
|
2153
2969
|
}
|
|
2154
|
-
)
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
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
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
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
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
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
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
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
|
|
2183
|
-
import { useLocale
|
|
2184
|
-
import { useState as
|
|
2185
|
-
import { jsx as
|
|
2186
|
-
function
|
|
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 =
|
|
2201
|
-
const [page, setPage] =
|
|
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__ */
|
|
2216
|
-
/* @__PURE__ */
|
|
2217
|
-
/* @__PURE__ */
|
|
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: "
|
|
2222
|
-
header: "
|
|
2223
|
-
cell: (role) => /* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
2243
|
-
/* @__PURE__ */
|
|
2244
|
-
/* @__PURE__ */
|
|
2245
|
-
/* @__PURE__ */
|
|
2246
|
-
/* @__PURE__ */
|
|
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__ */
|
|
3208
|
+
/* @__PURE__ */ jsx23(Button10, { children: "Create Role" })
|
|
2249
3209
|
] }),
|
|
2250
|
-
/* @__PURE__ */
|
|
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__ */
|
|
2260
|
-
/* @__PURE__ */
|
|
2261
|
-
|
|
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__ */
|
|
3229
|
+
/* @__PURE__ */ jsxs19("span", { className: "text-sm text-muted-foreground", children: [
|
|
2270
3230
|
"Page ",
|
|
2271
3231
|
page
|
|
2272
3232
|
] }),
|
|
2273
|
-
/* @__PURE__ */
|
|
2274
|
-
|
|
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
|
|
2287
|
-
import { useState as
|
|
2288
|
-
import { jsx as
|
|
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] =
|
|
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__ */
|
|
2318
|
-
/* @__PURE__ */
|
|
2319
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
2341
|
-
|
|
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__ */
|
|
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__ */
|
|
2356
|
-
/* @__PURE__ */
|
|
2357
|
-
/* @__PURE__ */
|
|
2358
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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
|
|
2374
|
-
import { useState as
|
|
2375
|
-
import { jsx as
|
|
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] =
|
|
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__ */
|
|
2393
|
-
/* @__PURE__ */
|
|
2394
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
2414
|
-
/* @__PURE__ */
|
|
2415
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
2423
|
-
/* @__PURE__ */
|
|
2424
|
-
/* @__PURE__ */
|
|
2425
|
-
/* @__PURE__ */
|
|
2426
|
-
/* @__PURE__ */
|
|
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__ */
|
|
3388
|
+
/* @__PURE__ */ jsx25(Button12, { children: "Create Tenant" })
|
|
2429
3389
|
] }),
|
|
2430
|
-
/* @__PURE__ */
|
|
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__ */
|
|
2440
|
-
/* @__PURE__ */
|
|
2441
|
-
|
|
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__ */
|
|
3409
|
+
/* @__PURE__ */ jsxs21("span", { className: "text-sm text-muted-foreground", children: [
|
|
2450
3410
|
"Page ",
|
|
2451
3411
|
page
|
|
2452
3412
|
] }),
|
|
2453
|
-
/* @__PURE__ */
|
|
2454
|
-
|
|
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
|
|
2467
|
-
import { useState as
|
|
2468
|
-
import { jsx as
|
|
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] =
|
|
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__ */
|
|
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__ */
|
|
2497
|
-
user.email && /* @__PURE__ */
|
|
2498
|
-
/* @__PURE__ */
|
|
2499
|
-
user.emailVerified && /* @__PURE__ */
|
|
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__ */
|
|
2502
|
-
/* @__PURE__ */
|
|
2503
|
-
user.phoneVerified && /* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
2516
|
-
/* @__PURE__ */
|
|
2517
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
2525
|
-
/* @__PURE__ */
|
|
2526
|
-
/* @__PURE__ */
|
|
2527
|
-
/* @__PURE__ */
|
|
2528
|
-
/* @__PURE__ */
|
|
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__ */
|
|
3484
|
+
/* @__PURE__ */ jsx26(Button13, { children: "Create User" })
|
|
2531
3485
|
] }),
|
|
2532
|
-
/* @__PURE__ */
|
|
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__ */
|
|
2542
|
-
/* @__PURE__ */
|
|
2543
|
-
|
|
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__ */
|
|
3505
|
+
/* @__PURE__ */ jsxs22("span", { className: "text-sm text-muted-foreground", children: [
|
|
2552
3506
|
"Page ",
|
|
2553
3507
|
page
|
|
2554
3508
|
] }),
|
|
2555
|
-
/* @__PURE__ */
|
|
2556
|
-
|
|
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
|
-
|
|
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__ */
|
|
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
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
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
|
|
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
|
|
3654
|
+
import { useState as useState18 } from "react";
|
|
2605
3655
|
|
|
2606
3656
|
// src/components/profile/request-change-email-form.tsx
|
|
2607
|
-
import { zodResolver as
|
|
2608
|
-
import { Button as
|
|
2609
|
-
import { IconEye as
|
|
2610
|
-
import { useEffect as
|
|
2611
|
-
import { useForm as
|
|
2612
|
-
import { toast as
|
|
2613
|
-
import { z as
|
|
2614
|
-
import { jsx as
|
|
2615
|
-
var emailPasswordSchema =
|
|
2616
|
-
email:
|
|
2617
|
-
password:
|
|
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] =
|
|
2673
|
-
const [isChecking, setIsChecking] =
|
|
2674
|
-
const [showPassword, setShowPassword] =
|
|
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 =
|
|
2688
|
-
resolver:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3804
|
+
toast10.error("This is already your current email address.");
|
|
2755
3805
|
return;
|
|
2756
3806
|
}
|
|
2757
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3822
|
+
toast10.error("Incorrect password. Please try again.");
|
|
2773
3823
|
return;
|
|
2774
3824
|
}
|
|
2775
3825
|
}
|
|
2776
|
-
|
|
3826
|
+
toast10.error(errorMessage);
|
|
2777
3827
|
} finally {
|
|
2778
3828
|
setIsSubmitting(false);
|
|
2779
3829
|
}
|
|
2780
3830
|
};
|
|
2781
3831
|
const isLoading = isSubmitting || isChecking;
|
|
2782
|
-
return /* @__PURE__ */
|
|
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__ */
|
|
2789
|
-
/* @__PURE__ */
|
|
2790
|
-
/* @__PURE__ */
|
|
2791
|
-
/* @__PURE__ */
|
|
2792
|
-
|
|
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__ */
|
|
3851
|
+
errors.email && /* @__PURE__ */ jsx29("p", { className: "text-sm text-destructive", children: errors.email.message })
|
|
2802
3852
|
] }),
|
|
2803
|
-
/* @__PURE__ */
|
|
2804
|
-
/* @__PURE__ */
|
|
2805
|
-
/* @__PURE__ */
|
|
2806
|
-
/* @__PURE__ */
|
|
2807
|
-
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
3878
|
+
errors.password && /* @__PURE__ */ jsx29("p", { className: "text-sm text-destructive", children: errors.password.message })
|
|
2829
3879
|
] })
|
|
2830
3880
|
] }),
|
|
2831
|
-
/* @__PURE__ */
|
|
2832
|
-
/* @__PURE__ */
|
|
2833
|
-
|
|
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__ */
|
|
2843
|
-
isLoading && /* @__PURE__ */
|
|
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
|
|
2854
|
-
import { toast as
|
|
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
|
|
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__ */
|
|
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__ */
|
|
2885
|
-
/* @__PURE__ */
|
|
2886
|
-
/* @__PURE__ */
|
|
2887
|
-
description && /* @__PURE__ */
|
|
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__ */
|
|
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
|
|
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] =
|
|
2960
|
-
const [currentVerificationId, setCurrentVerificationId] =
|
|
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
|
-
|
|
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
|
-
|
|
4036
|
+
toast11.success("Email updated successfully");
|
|
2987
4037
|
await refresh();
|
|
2988
4038
|
onSuccess();
|
|
2989
4039
|
} catch (error) {
|
|
2990
4040
|
const errorMessage = getErrorMessage2(error);
|
|
2991
|
-
|
|
4041
|
+
toast11.error(errorMessage);
|
|
2992
4042
|
} finally {
|
|
2993
4043
|
setIsSubmitting(false);
|
|
2994
4044
|
}
|
|
2995
4045
|
};
|
|
2996
4046
|
if (!currentVerificationId) {
|
|
2997
|
-
|
|
4047
|
+
toast11.error("Verification not found. Please request a new code.");
|
|
2998
4048
|
return null;
|
|
2999
4049
|
}
|
|
3000
|
-
return /* @__PURE__ */
|
|
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
|
-
|
|
4066
|
+
toast11.success("Verification code resent");
|
|
3017
4067
|
} catch (error) {
|
|
3018
|
-
|
|
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
|
|
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] =
|
|
3033
|
-
const [showOtp, setShowOtp] =
|
|
3034
|
-
const [verificationId, setVerificationId] =
|
|
3035
|
-
const [newEmail, setNewEmail] =
|
|
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__ */
|
|
3057
|
-
/* @__PURE__ */
|
|
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__ */
|
|
3061
|
-
|
|
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__ */
|
|
3069
|
-
/* @__PURE__ */
|
|
3070
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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
|
|
4151
|
+
import { zodResolver as zodResolver9 } from "@hookform/resolvers/zod";
|
|
3102
4152
|
import {
|
|
3103
|
-
Button as
|
|
4153
|
+
Button as Button17,
|
|
3104
4154
|
Collapsible as Collapsible2,
|
|
3105
4155
|
CollapsibleContent as CollapsibleContent2,
|
|
3106
4156
|
CollapsibleTrigger as CollapsibleTrigger2,
|
|
3107
|
-
Input as
|
|
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
|
|
3112
|
-
import { useState as
|
|
3113
|
-
import { useForm as
|
|
3114
|
-
import { toast as
|
|
3115
|
-
import { z as
|
|
3116
|
-
import { jsx as
|
|
3117
|
-
var changePasswordSchema =
|
|
3118
|
-
currentPassword:
|
|
3119
|
-
newPassword:
|
|
3120
|
-
confirmPassword:
|
|
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] =
|
|
3175
|
-
const [isSubmitting, setIsSubmitting] =
|
|
3176
|
-
const [showPassword, setShowPassword] =
|
|
3177
|
-
const [showNewPassword, setShowNewPassword] =
|
|
3178
|
-
const [showConfirmPassword, setShowConfirmPassword] =
|
|
3179
|
-
const form =
|
|
3180
|
-
resolver:
|
|
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
|
-
|
|
4241
|
+
toast12.error("Password change unavailable");
|
|
3192
4242
|
setIsOpen(false);
|
|
3193
4243
|
} catch (error) {
|
|
3194
4244
|
const errorMessage = getPasswordChangeErrorMessage(error);
|
|
3195
|
-
|
|
4245
|
+
toast12.error(errorMessage);
|
|
3196
4246
|
} finally {
|
|
3197
4247
|
setIsSubmitting(false);
|
|
3198
4248
|
}
|
|
3199
4249
|
};
|
|
3200
|
-
return /* @__PURE__ */
|
|
3201
|
-
/* @__PURE__ */
|
|
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__ */
|
|
3205
|
-
|
|
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__ */
|
|
3213
|
-
/* @__PURE__ */
|
|
3214
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
3232
|
-
/* @__PURE__ */
|
|
3233
|
-
/* @__PURE__ */
|
|
3234
|
-
/* @__PURE__ */
|
|
3235
|
-
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
4304
|
+
formState.errors.currentPassword && /* @__PURE__ */ jsx33("p", { className: "text-sm text-destructive", children: formState.errors.currentPassword.message })
|
|
3255
4305
|
] }),
|
|
3256
|
-
/* @__PURE__ */
|
|
3257
|
-
/* @__PURE__ */
|
|
3258
|
-
/* @__PURE__ */
|
|
3259
|
-
/* @__PURE__ */
|
|
3260
|
-
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
4329
|
+
formState.errors.newPassword && /* @__PURE__ */ jsx33("p", { className: "text-sm text-destructive", children: formState.errors.newPassword.message })
|
|
3280
4330
|
] }),
|
|
3281
|
-
/* @__PURE__ */
|
|
3282
|
-
/* @__PURE__ */
|
|
3283
|
-
/* @__PURE__ */
|
|
3284
|
-
/* @__PURE__ */
|
|
3285
|
-
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
4354
|
+
formState.errors.confirmPassword && /* @__PURE__ */ jsx33("p", { className: "text-sm text-destructive", children: formState.errors.confirmPassword.message })
|
|
3305
4355
|
] }),
|
|
3306
|
-
/* @__PURE__ */
|
|
3307
|
-
/* @__PURE__ */
|
|
3308
|
-
|
|
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__ */
|
|
3321
|
-
isSubmitting && /* @__PURE__ */
|
|
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
|
|
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
|
|
4389
|
+
import { useState as useState22 } from "react";
|
|
3340
4390
|
|
|
3341
4391
|
// src/components/profile/request-change-phone-form.tsx
|
|
3342
|
-
import { zodResolver as
|
|
3343
|
-
import { Button as
|
|
3344
|
-
import { IconEye as
|
|
3345
|
-
import { useEffect as
|
|
3346
|
-
import { useForm as
|
|
3347
|
-
import { toast as
|
|
3348
|
-
import { z as
|
|
3349
|
-
import { jsx as
|
|
3350
|
-
var phonePasswordSchema = (phoneRegex) =>
|
|
3351
|
-
phone:
|
|
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:
|
|
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] =
|
|
3417
|
-
const [isChecking, setIsChecking] =
|
|
3418
|
-
const [showPassword, setShowPassword] =
|
|
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 =
|
|
3433
|
-
resolver:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
4550
|
+
toast13.error("This is already your current phone number.");
|
|
3501
4551
|
return;
|
|
3502
4552
|
}
|
|
3503
|
-
|
|
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
|
-
|
|
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
|
-
|
|
4571
|
+
toast13.error("Incorrect password. Please try again.");
|
|
3522
4572
|
return;
|
|
3523
4573
|
}
|
|
3524
4574
|
}
|
|
3525
|
-
|
|
4575
|
+
toast13.error(errorMessage);
|
|
3526
4576
|
} finally {
|
|
3527
4577
|
setIsSubmitting(false);
|
|
3528
4578
|
}
|
|
3529
4579
|
};
|
|
3530
4580
|
const isLoading = isSubmitting || isChecking;
|
|
3531
|
-
return /* @__PURE__ */
|
|
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__ */
|
|
3538
|
-
/* @__PURE__ */
|
|
3539
|
-
/* @__PURE__ */
|
|
3540
|
-
/* @__PURE__ */
|
|
3541
|
-
|
|
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__ */
|
|
4600
|
+
errors.phone && /* @__PURE__ */ jsx34("p", { className: "text-sm text-destructive", children: errors.phone.message })
|
|
3551
4601
|
] }),
|
|
3552
|
-
/* @__PURE__ */
|
|
3553
|
-
/* @__PURE__ */
|
|
3554
|
-
/* @__PURE__ */
|
|
3555
|
-
/* @__PURE__ */
|
|
3556
|
-
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
4626
|
+
errors.password && /* @__PURE__ */ jsx34("p", { className: "text-sm text-destructive", children: errors.password.message })
|
|
3577
4627
|
] })
|
|
3578
4628
|
] }),
|
|
3579
|
-
/* @__PURE__ */
|
|
3580
|
-
/* @__PURE__ */
|
|
3581
|
-
|
|
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__ */
|
|
3591
|
-
isLoading && /* @__PURE__ */
|
|
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
|
|
3602
|
-
import { toast as
|
|
3603
|
-
import { jsx as
|
|
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] =
|
|
3659
|
-
const [currentVerificationId, setCurrentVerificationId] =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
4741
|
+
toast14.error(errorMessage);
|
|
3692
4742
|
} finally {
|
|
3693
4743
|
setIsSubmitting(false);
|
|
3694
4744
|
}
|
|
3695
4745
|
};
|
|
3696
4746
|
if (!currentVerificationId) {
|
|
3697
|
-
|
|
4747
|
+
toast14.error("Verification not found. Please request a new code.");
|
|
3698
4748
|
return null;
|
|
3699
4749
|
}
|
|
3700
|
-
return /* @__PURE__ */
|
|
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
|
-
|
|
4769
|
+
toast14.success("Verification code resent");
|
|
3720
4770
|
} catch (error) {
|
|
3721
|
-
|
|
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
|
|
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] =
|
|
3736
|
-
const [showOtp, setShowOtp] =
|
|
3737
|
-
const [verificationId, setVerificationId] =
|
|
3738
|
-
const [newPhone, setNewPhone] =
|
|
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__ */
|
|
3760
|
-
/* @__PURE__ */
|
|
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__ */
|
|
3764
|
-
|
|
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__ */
|
|
3772
|
-
/* @__PURE__ */
|
|
3773
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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
|
|
4854
|
+
import { jsx as jsx37, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
3805
4855
|
function Security() {
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
/* @__PURE__ */
|
|
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__ */
|
|
3812
|
-
/* @__PURE__ */
|
|
3813
|
-
|
|
3814
|
-
|
|
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
|
|
3821
|
-
import { jsx as
|
|
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__ */
|
|
3824
|
-
/* @__PURE__ */
|
|
3825
|
-
/* @__PURE__ */
|
|
3826
|
-
/* @__PURE__ */
|
|
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__ */
|
|
3829
|
-
/* @__PURE__ */
|
|
3830
|
-
/* @__PURE__ */
|
|
3831
|
-
/* @__PURE__ */
|
|
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__ */
|
|
3834
|
-
/* @__PURE__ */
|
|
3835
|
-
/* @__PURE__ */
|
|
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__ */
|
|
4918
|
+
/* @__PURE__ */ jsx38(Skeleton3, { className: "h-10 w-full" })
|
|
3838
4919
|
] }),
|
|
3839
|
-
/* @__PURE__ */
|
|
3840
|
-
/* @__PURE__ */
|
|
3841
|
-
/* @__PURE__ */
|
|
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
|
|
3848
|
-
import { jsx as
|
|
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__ */
|
|
3851
|
-
/* @__PURE__ */
|
|
3852
|
-
/* @__PURE__ */
|
|
3853
|
-
/* @__PURE__ */
|
|
3854
|
-
/* @__PURE__ */
|
|
3855
|
-
/* @__PURE__ */
|
|
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__ */
|
|
3859
|
-
/* @__PURE__ */
|
|
3860
|
-
/* @__PURE__ */
|
|
3861
|
-
/* @__PURE__ */
|
|
3862
|
-
/* @__PURE__ */
|
|
3863
|
-
/* @__PURE__ */
|
|
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__ */
|
|
3866
|
-
/* @__PURE__ */
|
|
3867
|
-
/* @__PURE__ */
|
|
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,
|