@explita/cloud-auth-client 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/components/change-password.js +58 -75
  2. package/dist/components/icons/alert-circle.d.ts +5 -0
  3. package/dist/components/icons/alert-circle.js +13 -0
  4. package/dist/components/icons/chevron-down.d.ts +5 -0
  5. package/dist/components/icons/chevron-down.js +11 -0
  6. package/dist/components/icons/lock.d.ts +2 -1
  7. package/dist/components/icons/lock.js +2 -2
  8. package/dist/components/icons/logout.d.ts +2 -1
  9. package/dist/components/icons/logout.js +2 -2
  10. package/dist/components/icons/setting.d.ts +2 -1
  11. package/dist/components/icons/setting.js +2 -2
  12. package/dist/components/icons/shield.d.ts +5 -0
  13. package/dist/components/icons/shield.js +11 -0
  14. package/dist/components/icons/user.d.ts +5 -0
  15. package/dist/components/icons/user.js +12 -0
  16. package/dist/components/login-form.d.ts +3 -1
  17. package/dist/components/login-form.js +45 -34
  18. package/dist/components/reset-password.d.ts +2 -1
  19. package/dist/components/reset-password.js +62 -60
  20. package/dist/components/settings.js +16 -8
  21. package/dist/components/signup-form.d.ts +4 -3
  22. package/dist/components/signup-form.js +72 -60
  23. package/dist/components/toggle-2fa.js +42 -26
  24. package/dist/components/toggle-account-status.js +55 -64
  25. package/dist/components/ui/input.js +1 -1
  26. package/dist/components/user-card.js +48 -23
  27. package/dist/contexts/auth-provider.js +1 -1
  28. package/dist/index.d.ts +1 -1
  29. package/dist/lib/utils.js +7 -1
  30. package/dist/server/user.d.ts +3 -1
  31. package/dist/server/user.js +33 -0
  32. package/dist/styles.css +901 -61
  33. package/dist/types.d.ts +21 -7
  34. package/package.json +1 -1
@@ -10,20 +10,28 @@ const auth_provider_1 = require("../contexts/auth-provider");
10
10
  const must_login_1 = require("./must-login");
11
11
  const toggle_2fa_1 = require("./toggle-2fa");
12
12
  const utils_1 = require("../lib/utils");
13
+ const setting_1 = require("./icons/setting");
13
14
  function Settings({ open, onOpenChange, onToggle2FA }) {
14
15
  const { user } = (0, auth_provider_1.useAuth)();
15
16
  return (react_1.default.createElement(dialog_1.Dialog, { open: open, onOpenChange: (state) => {
16
17
  onOpenChange(state);
17
18
  (0, utils_1.unstuckPointerEvents)();
18
19
  } },
19
- react_1.default.createElement(dialog_1.DialogContent, null, !user ? (react_1.default.createElement(must_login_1.MustLogin, { onOpenChange: (state) => {
20
+ react_1.default.createElement(dialog_1.DialogContent, { className: "ecpauth:p-0 ecpauth:overflow-hidden ecpauth:border-gray-200 ecpauth:dark:border-gray-800 ecpauth:shadow-2xl ecpauth:rounded-2xl ecpauth:max-w-xl" }, !user ? (react_1.default.createElement(must_login_1.MustLogin, { onOpenChange: (state) => {
20
21
  onOpenChange(state);
21
22
  (0, utils_1.unstuckPointerEvents)();
22
- } })) : (react_1.default.createElement("div", { className: "ecpauth:relative" },
23
- react_1.default.createElement(dialog_1.DialogHeader, { className: "ecpauth:border-b ecpauth:border-gray-200 ecpauth:dark:border-gray-800 ecpauth:pb-2" },
24
- react_1.default.createElement(dialog_1.DialogTitle, { className: "ecpauth:flex ecpauth:items-center ecpauth:justify-between" },
25
- react_1.default.createElement("span", { className: "ecpauth:text-stone-800 ecpauth:dark:text-stone-50" }, "Account Settings")),
26
- react_1.default.createElement(dialog_1.DialogDescription, { className: "ecpauth:sr-only" }, "Manage your account settings here.")),
27
- react_1.default.createElement("div", { className: "ecpauth:flex-1 ecpauth:flex ecpauth:flex-col ecpauth:gap-6 ecpauth:my-5 ecpauth:p-0 ecpauth:!max-h-[calc(100vh-12rem)] ecpauth:overflow-y-auto" },
28
- react_1.default.createElement(toggle_2fa_1.Toggle2FA, { onSubmit: onToggle2FA })))))));
23
+ } })) : (react_1.default.createElement("div", { className: "ecpauth:flex ecpauth:flex-col" },
24
+ react_1.default.createElement("div", { className: "ecpauth:relative ecpauth:px-6 ecpauth:pt-8 ecpauth:pb-6 ecpauth:border-b ecpauth:border-gray-100 ecpauth:dark:border-gray-800/50" },
25
+ react_1.default.createElement("div", { className: "ecpauth:relative ecpauth:z-10 ecpauth:flex ecpauth:items-center ecpauth:gap-4" },
26
+ react_1.default.createElement("div", { className: "ecpauth:size-12 ecpauth:rounded-xl ecpauth:bg-blue-50 ecpauth:dark:bg-blue-900/20 ecpauth:text-blue-600 ecpauth:dark:text-blue-400 ecpauth:flex ecpauth:items-center ecpauth:justify-center ecpauth:shadow-sm ecpauth:border ecpauth:border-blue-100 ecpauth:dark:border-blue-800/50" },
27
+ react_1.default.createElement(setting_1.SettingIcon, { size: 24 })),
28
+ react_1.default.createElement(dialog_1.DialogHeader, { className: "ecpauth:space-y-0.5" },
29
+ react_1.default.createElement(dialog_1.DialogTitle, { className: "ecpauth:text-xl ecpauth:font-bold ecpauth:text-gray-900 ecpauth:dark:text-white" }, "Account Settings"),
30
+ react_1.default.createElement(dialog_1.DialogDescription, { className: "ecpauth:text-sm ecpauth:text-gray-500 ecpauth:dark:text-gray-400" }, "Manage your security preferences and account details.")))),
31
+ react_1.default.createElement("div", { className: "ecpauth:p-6 ecpauth:overflow-y-auto ecpauth:max-h-[70vh]" },
32
+ react_1.default.createElement("div", { className: "ecpauth:space-y-8" },
33
+ react_1.default.createElement("section", null,
34
+ react_1.default.createElement(toggle_2fa_1.Toggle2FA, { onSubmit: onToggle2FA })))),
35
+ react_1.default.createElement("div", { className: "ecpauth:px-6 ecpauth:py-4 ecpauth:bg-gray-50 ecpauth:dark:bg-gray-900/50 ecpauth:border-t ecpauth:border-gray-100 ecpauth:dark:border-gray-800/50 ecpauth:flex ecpauth:justify-end" },
36
+ react_1.default.createElement("button", { type: "button", onClick: () => onOpenChange(false), className: "ecpauth:px-4 ecpauth:py-2 ecpauth:text-sm ecpauth:font-semibold ecpauth:text-gray-600 ecpauth:dark:text-gray-400 ecpauth:hover:text-gray-900 ecpauth:dark:hover:text-white ecpauth:transition-colors" }, "Close Settings")))))));
29
37
  }
@@ -3,9 +3,10 @@ import { CreateUser, FormResponse, User } from "../types";
3
3
  type Props = {
4
4
  className?: string;
5
5
  onSubmit: (data: CreateUser) => Promise<FormResponse<User>>;
6
- groupId?: string | null;
7
- metaData?: Record<string, string>;
6
+ groupId: string | number;
7
+ metadata?: Record<string, string>;
8
8
  acceptUsername?: boolean;
9
+ logo?: React.ReactNode;
9
10
  };
10
- export declare function Signup({ className, onSubmit, groupId, metaData, acceptUsername, ...props }: Props): React.JSX.Element;
11
+ export declare function Signup({ className, onSubmit, groupId, metadata, acceptUsername, logo, ...props }: Props): React.JSX.Element;
11
12
  export {};
@@ -43,10 +43,22 @@ const input_1 = require("./ui/input");
43
43
  const label_1 = require("./ui/label");
44
44
  const message_1 = require("./message");
45
45
  const auth_provider_1 = require("../contexts/auth-provider");
46
- function Signup({ className, onSubmit, groupId, metaData, acceptUsername = true, ...props }) {
46
+ function Signup({ className, onSubmit, groupId, metadata, acceptUsername = true, logo, ...props }) {
47
47
  const { computedRouteContext } = (0, auth_provider_1.useAuth)();
48
+ const [isPending, setIsPending] = react_1.default.useState(false);
49
+ const [state, setState] = react_1.default.useState({
50
+ message: "",
51
+ //@ts-ignore
52
+ status: "",
53
+ form: {},
54
+ errors: undefined,
55
+ authToken: "",
56
+ });
48
57
  const { loginUrl } = computedRouteContext;
49
- const [state, handleSubmit, isPending] = (0, react_1.useActionState)(async function (prevState, formData) {
58
+ async function handleSubmit(e) {
59
+ e.preventDefault();
60
+ const formData = new FormData(e.currentTarget);
61
+ //@ts-ignore
50
62
  const form = {
51
63
  firstName: formData.get("firstName"),
52
64
  lastName: formData.get("lastName"),
@@ -55,24 +67,26 @@ function Signup({ className, onSubmit, groupId, metaData, acceptUsername = true,
55
67
  password: formData.get("password"),
56
68
  confirmPassword: formData.get("confirmPassword"),
57
69
  groupId,
58
- metaData,
70
+ metadata,
59
71
  };
60
72
  if (typeof onSubmit !== "function") {
61
- return {
73
+ setState({
62
74
  message: "onSubmit function is not defined. Please pass onSubmit function to SignupForm component.",
63
75
  status: "failure",
64
- form,
76
+ //@ts-ignore
65
77
  errors: undefined,
66
78
  authToken: undefined,
67
- };
79
+ });
68
80
  }
81
+ setIsPending(true);
69
82
  const result = await onSubmit({ ...form });
70
- return {
83
+ setIsPending(false);
84
+ setState({
71
85
  ...result,
72
- form: result.status !== "success" ? form : undefined,
86
+ //@ts-ignore
73
87
  authToken: result.status === "success" ? result.authToken : undefined,
74
- };
75
- }, undefined);
88
+ });
89
+ }
76
90
  (0, react_1.useEffect)(() => {
77
91
  let timer;
78
92
  if (state?.status === "success" && loginUrl) {
@@ -84,54 +98,52 @@ function Signup({ className, onSubmit, groupId, metaData, acceptUsername = true,
84
98
  clearTimeout(timer);
85
99
  };
86
100
  }, [state?.status, loginUrl]);
87
- return (react_1.default.createElement("div", { className: (0, utils_1.cn)("ecpauth:flex ecpauth:flex-col ecpauth:gap-6 ecpauth:w-full ecpauth:max-w-sm", className), ...props },
88
- react_1.default.createElement(card_1.Card, null,
89
- react_1.default.createElement(card_1.CardHeader, null,
90
- react_1.default.createElement(card_1.CardTitle, { className: "ecpauth:text-2xl" }, "Sign Up"),
91
- react_1.default.createElement(card_1.CardDescription, null, "Provide your details to sign up from your account.")),
92
- react_1.default.createElement(card_1.CardContent, null,
93
- state?.status === "success" ? (react_1.default.createElement(message_1.Message, { message: state?.message, className: "ecpauth:mb-4 ecpauth:font-semibold ecpauth:text-lg", variant: "success" })) : (react_1.default.createElement(message_1.Message, { message: state?.message, className: "ecpauth:mb-4" })),
94
- react_1.default.createElement("form", { action: handleSubmit },
95
- react_1.default.createElement("div", { className: "ecpauth:flex ecpauth:flex-col ecpauth:gap-6" },
96
- react_1.default.createElement("div", { className: "ecpauth:grid ecpauth:gap-2" },
97
- react_1.default.createElement(label_1.Label, { htmlFor: "firstName" }, "First Name"),
98
- react_1.default.createElement(input_1.Input, { id: "firstName", type: "text", placeholder: "First Name", name: "firstName", defaultValue: state?.form?.firstName }),
99
- react_1.default.createElement(message_1.Message, { message: state?.status === "validation-error"
100
- ? state?.errors?.firstName
101
- : "" })),
102
- react_1.default.createElement("div", { className: "ecpauth:grid ecpauth:gap-2" },
103
- react_1.default.createElement(label_1.Label, { htmlFor: "lastName" }, "Last Name"),
104
- react_1.default.createElement(input_1.Input, { id: "lastName", type: "text", placeholder: "Last Name", name: "lastName", defaultValue: state?.form?.lastName }),
105
- react_1.default.createElement(message_1.Message, { message: state?.status === "validation-error"
106
- ? state?.errors?.lastName
107
- : "" })),
108
- react_1.default.createElement("div", { className: "ecpauth:grid ecpauth:gap-2" },
109
- react_1.default.createElement(label_1.Label, { htmlFor: "email" }, "Email"),
110
- react_1.default.createElement(input_1.Input, { id: "email", type: "email", placeholder: "email@example.com", name: "email", defaultValue: state?.form?.email }),
111
- react_1.default.createElement(message_1.Message, { message: state?.status === "validation-error"
112
- ? state?.errors?.email
113
- : "" })),
114
- acceptUsername && (react_1.default.createElement("div", { className: "ecpauth:grid ecpauth:gap-2" },
115
- react_1.default.createElement(label_1.Label, { htmlFor: "username" }, "Username"),
116
- react_1.default.createElement(input_1.Input, { id: "username", type: "text", placeholder: "Username", name: "username", defaultValue: state?.form?.username }),
117
- react_1.default.createElement(message_1.Message, { message: state?.status === "validation-error"
118
- ? state?.errors?.username
119
- : "" }))),
120
- react_1.default.createElement("div", { className: "ecpauth:grid ecpauth:gap-2" },
121
- react_1.default.createElement(label_1.Label, { htmlFor: "password" }, "Password"),
122
- react_1.default.createElement(input_1.Input, { id: "password", type: "password", name: "password" }),
123
- react_1.default.createElement(message_1.Message, { message: state?.status === "validation-error"
124
- ? state?.errors?.password
125
- : "" })),
126
- react_1.default.createElement("div", { className: "ecpauth:grid ecpauth:gap-2" },
127
- react_1.default.createElement(label_1.Label, { htmlFor: "confirmPassword" }, "Confirm Password"),
128
- react_1.default.createElement(input_1.Input, { id: "confirmPassword", type: "password", name: "confirmPassword" }),
129
- react_1.default.createElement(message_1.Message, { message: state?.status === "validation-error"
130
- ? state?.errors?.confirmPassword
131
- : "" })),
132
- react_1.default.createElement(button_1.Button, { type: "submit", className: "ecpauth:w-full ecpauth:cursor-pointer", disabled: isPending }, isPending ? "Signing up..." : "Sign Up")),
133
- loginUrl && (react_1.default.createElement("div", { className: "ecpauth:mt-4 ecpauth:text-center ecpauth:text-sm" },
134
- "Already have an account?",
135
- " ",
136
- react_1.default.createElement("a", { href: loginUrl, className: "ecpauth:underline ecpauth:underline-offset-4" }, "Login"))))))));
101
+ return (react_1.default.createElement("div", { className: (0, utils_1.cn)("ecpauth:relative ecpauth:flex ecpauth:flex-col ecpauth:items-center ecpauth:justify-center ecpauth:w-full ecpauth:mx-auto ecpauth:px-4", className), ...props },
102
+ react_1.default.createElement(card_1.Card, { className: "ecpauth:relative ecpauth:w-full ecpauth:max-w-[550px] ecpauth:overflow-hidden ecpauth:shadow-none ecpauth:lg:shadow-xl ecpauth:border-none ecpauth:rounded-xl" },
103
+ react_1.default.createElement(card_1.CardHeader, { className: "ecpauth:space-y-4 ecpauth:text-center ecpauth:pb-2 ecpauth:pt-10" },
104
+ logo && (react_1.default.createElement("div", { className: "ecpauth:flex ecpauth:items-center ecpauth:justify-center ecpauth:space-x-2 ecpauth:text-xl ecpauth:font-bold ecpauth:text-gray-900 ecpauth:dark:text-white" }, logo)),
105
+ react_1.default.createElement("div", { className: "ecpauth:space-y-2" },
106
+ react_1.default.createElement(card_1.CardTitle, { className: "ecpauth:text-2xl ecpauth:font-black ecpauth:tracking-tight ecpauth:text-gray-900 ecpauth:dark:text-white" }, "Create Account"),
107
+ react_1.default.createElement(card_1.CardDescription, { className: "ecpauth:text-sm ecpauth:text-gray-500 ecpauth:dark:text-gray-400" }, "Provide your details to sign up for your account.")),
108
+ state?.status === "success" ? (react_1.default.createElement("div", { className: "ecpauth:mt-3" },
109
+ react_1.default.createElement(message_1.Message, { message: state?.message, className: "ecpauth:font-medium ecpauth:text-sm ecpauth:p-3 ecpauth:rounded-lg ecpauth:bg-green-50 ecpauth:dark:bg-green-900/10 ecpauth:border ecpauth:border-green-100 ecpauth:dark:border-green-800/30 ecpauth:text-green-700 ecpauth:dark:text-green-400", variant: "success" }))) : state?.message ? (react_1.default.createElement("div", { className: "ecpauth:mt-3" },
110
+ react_1.default.createElement(message_1.Message, { message: state?.message, className: "ecpauth:font-medium ecpauth:text-sm ecpauth:p-3 ecpauth:rounded-lg ecpauth:bg-red-50 ecpauth:dark:bg-red-900/10 ecpauth:border ecpauth:border-red-100 ecpauth:dark:border-red-800/30 ecpauth:text-red-700 ecpauth:dark:text-red-400" }))) : null),
111
+ react_1.default.createElement(card_1.CardContent, { className: "ecpauth:space-y-6 ecpauth:p-8 ecpauth:px-12" },
112
+ react_1.default.createElement("form", { onSubmit: handleSubmit, className: "ecpauth:space-y-6" },
113
+ react_1.default.createElement("div", { className: "ecpauth:grid ecpauth:grid-cols-1 ecpauth:md:grid-cols-2 ecpauth:gap-4" },
114
+ react_1.default.createElement("div", { className: "ecpauth:space-y-2" },
115
+ react_1.default.createElement(label_1.Label, { htmlFor: "firstName", className: "ecpauth:text-sm ecpauth:font-medium ecpauth:text-gray-700 ecpauth:dark:text-gray-300" }, "First Name"),
116
+ react_1.default.createElement(input_1.Input, { id: "firstName", type: "text", placeholder: "First Name", name: "firstName" }),
117
+ state?.status === "validation-error" &&
118
+ state?.errors?.firstName && (react_1.default.createElement("p", { className: "ecpauth:mt-1 ecpauth:text-[11px] ecpauth:text-red-500" }, state.errors.firstName))),
119
+ react_1.default.createElement("div", { className: "ecpauth:space-y-2" },
120
+ react_1.default.createElement(label_1.Label, { htmlFor: "lastName", className: "ecpauth:text-sm ecpauth:font-medium ecpauth:text-gray-700 ecpauth:dark:text-gray-300" }, "Last Name"),
121
+ react_1.default.createElement(input_1.Input, { id: "lastName", type: "text", placeholder: "Last Name", name: "lastName" }),
122
+ state?.status === "validation-error" &&
123
+ state?.errors?.lastName && (react_1.default.createElement("p", { className: "ecpauth:mt-1 ecpauth:text-[11px] ecpauth:text-red-500" }, state.errors.lastName)))),
124
+ react_1.default.createElement("div", { className: "ecpauth:space-y-2" },
125
+ react_1.default.createElement(label_1.Label, { htmlFor: "email", className: "ecpauth:text-sm ecpauth:font-medium ecpauth:text-gray-700 ecpauth:dark:text-gray-300" }, "Email Address"),
126
+ react_1.default.createElement(input_1.Input, { id: "email", type: "email", placeholder: "email@example.com", name: "email" }),
127
+ state?.status === "validation-error" && state?.errors?.email && (react_1.default.createElement("p", { className: "ecpauth:mt-1 ecpauth:text-[11px] ecpauth:text-red-500" }, state.errors.email))),
128
+ acceptUsername && (react_1.default.createElement("div", { className: "ecpauth:space-y-2" },
129
+ react_1.default.createElement(label_1.Label, { htmlFor: "username", className: "ecpauth:text-sm ecpauth:font-medium ecpauth:text-gray-700 ecpauth:dark:text-gray-300" }, "Username"),
130
+ react_1.default.createElement(input_1.Input, { id: "username", type: "text", placeholder: "Username", name: "username" }),
131
+ state?.status === "validation-error" &&
132
+ state?.errors?.username && (react_1.default.createElement("p", { className: "ecpauth:mt-1 ecpauth:text-[11px] ecpauth:text-red-500" }, state.errors.username)))),
133
+ react_1.default.createElement("div", { className: "ecpauth:grid ecpauth:grid-cols-1 ecpauth:md:grid-cols-2 ecpauth:gap-4" },
134
+ react_1.default.createElement("div", { className: "ecpauth:space-y-2" },
135
+ react_1.default.createElement(label_1.Label, { htmlFor: "password", className: "ecpauth:text-sm ecpauth:font-medium ecpauth:text-gray-700 ecpauth:dark:text-gray-300" }, "Password"),
136
+ react_1.default.createElement(input_1.Input, { id: "password", type: "password", name: "password", placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" }),
137
+ state?.status === "validation-error" &&
138
+ state?.errors?.password && (react_1.default.createElement("p", { className: "ecpauth:mt-1 ecpauth:text-[11px] ecpauth:text-red-500" }, state.errors.password))),
139
+ react_1.default.createElement("div", { className: "ecpauth:space-y-2" },
140
+ react_1.default.createElement(label_1.Label, { htmlFor: "confirmPassword", className: "ecpauth:text-sm ecpauth:font-medium ecpauth:text-gray-700 ecpauth:dark:text-gray-300" }, "Confirm Password"),
141
+ react_1.default.createElement(input_1.Input, { id: "confirmPassword", type: "password", name: "confirmPassword", placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" }),
142
+ state?.status === "validation-error" &&
143
+ state?.errors?.confirmPassword && (react_1.default.createElement("p", { className: "ecpauth:mt-1 ecpauth:text-[11px] ecpauth:text-red-500" }, state.errors.confirmPassword)))),
144
+ react_1.default.createElement(button_1.Button, { type: "submit", className: "ecpauth:w-full ecpauth:h-11 ecpauth:bg-blue-600! ecpauth:hover:bg-blue-700! ecpauth:text-white! ecpauth:font-semibold ecpauth:text-base ecpauth:shadow-lg ecpauth:shadow-blue-600/20 ecpauth:rounded-lg ecpauth:transition-all ecpauth:active:scale-[0.98]", disabled: isPending }, isPending ? "Signing up..." : "Sign Up")),
145
+ loginUrl && (react_1.default.createElement("div", { className: "ecpauth:text-center ecpauth:text-sm ecpauth:text-gray-500 ecpauth:border-t ecpauth:border-gray-100 ecpauth:dark:border-gray-800 ecpauth:pt-6" },
146
+ "Already have an account?",
147
+ " ",
148
+ react_1.default.createElement("a", { href: loginUrl, className: "ecpauth:font-semibold ecpauth:text-gray-900 ecpauth:hover:underline ecpauth:dark:text-white" }, "Login")))))));
137
149
  }
@@ -41,41 +41,57 @@ const switch_1 = require("./ui/switch");
41
41
  const loader_1 = require("./loader");
42
42
  const message_1 = require("./message");
43
43
  const utils_1 = require("../lib/utils");
44
+ const shield_1 = require("./icons/shield");
44
45
  function Toggle2FA({ onSubmit }) {
45
46
  const { user, revalidate } = (0, auth_provider_1.useAuth)();
47
+ const [isPending, setIsPending] = react_1.default.useState(false);
48
+ const [state, setState] = react_1.default.useState({
49
+ message: "",
50
+ //@ts-ignore
51
+ status: "",
52
+ });
46
53
  const [_, startTransition] = (0, react_1.useTransition)();
47
54
  const canUseOtp = (0, utils_1.isOtpAvailable)();
48
- const [state, handleSubmit, isPending] = (0, react_1.useActionState)(async function () {
55
+ async function handleSubmit() {
49
56
  if (typeof onSubmit !== "function") {
50
- return {
57
+ setState({
51
58
  message: "Toggle 2FA function is not defined. Please pass onSubmit function to Settings component. If you are using UserCard component, please pass onToggle2FA function to it.",
52
59
  status: "failure",
53
- };
60
+ });
61
+ return;
54
62
  }
55
- try {
56
- const result = await onSubmit();
63
+ setIsPending(true);
64
+ const result = await onSubmit();
65
+ if (result.status !== "failure") {
57
66
  revalidate();
58
- return result;
59
67
  }
60
- catch (error) {
61
- console.log(error);
62
- }
63
- }, undefined);
64
- return (react_1.default.createElement("div", { className: "ecpauth:text-stone-800 ecpauth:dark:text-stone-50" },
68
+ setIsPending(false);
69
+ setState(result);
70
+ }
71
+ return (react_1.default.createElement("div", { className: "ecpauth:flex ecpauth:flex-col ecpauth:gap-6 ecpauth:text-gray-900 ecpauth:dark:text-white" },
65
72
  isPending && react_1.default.createElement(loader_1.Loader, null),
66
- react_1.default.createElement("p", { className: "ecpauth:font-semibold ecpauth:text-lg ecpauth:mb-2" }, "Toggle Two Factor Authentication"),
67
- state?.status === "success" ? (react_1.default.createElement(message_1.Message, { message: state?.message, className: "ecpauth:my-2 ecpauth:font-semibold ecpauth:text-base", variant: "success" })) : (react_1.default.createElement(message_1.Message, { message: state?.message, className: "ecpauth:my-2" })),
68
- react_1.default.createElement("p", null,
69
- "This action will enable or disable 2FA on your account. If enabled, you\u2019ll be asked for a code sent to ",
70
- react_1.default.createElement("strong", null, user?.email),
71
- " during login."),
72
- react_1.default.createElement("div", { className: "ecpauth:flex ecpauth:items-center ecpauth:justify-between ecpauth:py-3 ecpauth:my-3 ecpauth:border-y ecpauth:border-gray-200 ecpauth:dark:border-gray-800" },
73
- react_1.default.createElement("p", { className: "ecpauth:flex-1 ecpauth:mb-0" }, "You can enable or disable your Two Factor Authentication"),
74
- react_1.default.createElement("div", { className: "ecpauth:w-40 ecpauth:flex ecpauth:justify-end ecpauth:pe-3" },
75
- react_1.default.createElement(switch_1.Switch, { checked: !!user?.with2fa, onCheckedChange: () => startTransition(handleSubmit), disabled: !canUseOtp }))),
76
- !canUseOtp && (react_1.default.createElement("p", { className: "ecpauth:text-red-500 ecpauth:my-2 ecpauth:text-sm" },
77
- "2FA is not available. Please install",
78
- " ",
79
- react_1.default.createElement("code", null, "@explita/cloud-otp-client"),
80
- " to enable it."))));
73
+ react_1.default.createElement("div", { className: "ecpauth:space-y-1.5" },
74
+ react_1.default.createElement("h3", { className: "ecpauth:text-base ecpauth:font-bold ecpauth:flex ecpauth:items-center ecpauth:gap-2" },
75
+ react_1.default.createElement(shield_1.ShieldIcon, { size: 18, className: "ecpauth:text-blue-600 ecpauth:dark:text-blue-400" }),
76
+ "Two-Factor Authentication"),
77
+ react_1.default.createElement("p", { className: "ecpauth:text-sm ecpauth:text-gray-500 ecpauth:dark:text-gray-400" }, "Add an extra layer of security to your account by requiring a verification code.")),
78
+ state?.status === "success" ? (react_1.default.createElement(message_1.Message, { message: state?.message, className: "ecpauth:font-medium ecpauth:text-sm ecpauth:p-3 ecpauth:rounded-lg ecpauth:bg-green-50 ecpauth:dark:bg-green-900/10 ecpauth:border ecpauth:border-green-100 ecpauth:dark:border-green-800/30 ecpauth:text-green-700 ecpauth:dark:text-green-400", variant: "success" })) : state?.message ? (react_1.default.createElement(message_1.Message, { message: state?.message, className: "ecpauth:font-medium ecpauth:text-sm ecpauth:p-3 ecpauth:rounded-lg ecpauth:bg-red-50 ecpauth:dark:bg-red-900/10 ecpauth:border ecpauth:border-red-100 ecpauth:dark:border-red-800/30 ecpauth:text-red-700 ecpauth:dark:text-red-400" })) : null,
79
+ react_1.default.createElement("div", { className: "ecpauth:group ecpauth:relative ecpauth:p-4 ecpauth:rounded-xl ecpauth:border ecpauth:border-gray-200 ecpauth:dark:border-gray-800 ecpauth:bg-gray-50/50 ecpauth:dark:bg-white/5 ecpauth:transition-all ecpauth:hover:border-blue-200 ecpauth:dark:hover:border-blue-900/30" },
80
+ react_1.default.createElement("div", { className: "ecpauth:flex ecpauth:items-start ecpauth:justify-between ecpauth:gap-4" },
81
+ react_1.default.createElement("div", { className: "ecpauth:space-y-1" },
82
+ react_1.default.createElement("p", { className: "ecpauth:text-sm ecpauth:font-bold ecpauth:text-gray-900 ecpauth:dark:text-white" }, "Email Authentication"),
83
+ react_1.default.createElement("p", { className: "ecpauth:text-xs ecpauth:leading-relaxed ecpauth:text-gray-500 ecpauth:dark:text-gray-400" },
84
+ "A verification code will be sent to",
85
+ " ",
86
+ react_1.default.createElement("span", { className: "ecpauth:font-semibold ecpauth:text-gray-700 ecpauth:dark:text-gray-200" }, user?.email),
87
+ " ",
88
+ "whenever you sign in.")),
89
+ react_1.default.createElement("div", { className: "ecpauth:pt-1" },
90
+ react_1.default.createElement(switch_1.Switch, { checked: !!user?.with2fa, onCheckedChange: () => startTransition(handleSubmit), disabled: !canUseOtp, className: "ecpauth:data-[state=checked]:bg-blue-600" }))),
91
+ !canUseOtp && (react_1.default.createElement("div", { className: "ecpauth:mt-3 ecpauth:pt-3 ecpauth:border-t ecpauth:border-gray-200/50 ecpauth:dark:border-gray-800/50" },
92
+ react_1.default.createElement("p", { className: "ecpauth:text-[11px] ecpauth:text-red-500 ecpauth:flex ecpauth:items-center ecpauth:gap-1.5 ecpauth:font-medium" },
93
+ react_1.default.createElement("span", { className: "ecpauth:size-1.5 ecpauth:bg-red-500 ecpauth:rounded-full ecpauth:animate-pulse" }),
94
+ "Feature unavailable: please install @explita/cloud-otp-client")))),
95
+ react_1.default.createElement("div", { className: "ecpauth:px-2" },
96
+ react_1.default.createElement("p", { className: "ecpauth:text-[11px] ecpauth:text-gray-400 ecpauth:dark:text-gray-500 ecpauth:italic" }, "Note: Disabling 2FA makes your account and your data more vulnerable to unauthorized access."))));
81
97
  }
@@ -1,49 +1,26 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
35
5
  Object.defineProperty(exports, "__esModule", { value: true });
36
6
  exports.ToggleAccountStatus = ToggleAccountStatus;
37
- const react_1 = __importStar(require("react"));
7
+ const react_1 = __importDefault(require("react"));
38
8
  const dialog_1 = require("./ui/dialog");
39
9
  const button_1 = require("./ui/button");
40
10
  const auth_provider_1 = require("../contexts/auth-provider");
41
11
  const message_1 = require("./message");
42
12
  const must_login_1 = require("./must-login");
43
13
  const utils_1 = require("../lib/utils");
14
+ const alert_circle_1 = require("./icons/alert-circle");
44
15
  function ToggleAccountStatus({ user, open, onOpenChange, onSuccess, onSubmit, }) {
45
16
  const { user: loggedInUser } = (0, auth_provider_1.useAuth)();
46
- const [state, handleSubmit, isPending] = (0, react_1.useActionState)(async function () {
17
+ const [isPending, setIsPending] = react_1.default.useState(false);
18
+ const [state, setState] = react_1.default.useState({
19
+ message: "",
20
+ //@ts-ignore
21
+ status: "",
22
+ });
23
+ async function handleSubmit() {
47
24
  if (!user) {
48
25
  return {
49
26
  message: "Please provide a user to toggle account status.",
@@ -56,43 +33,57 @@ function ToggleAccountStatus({ user, open, onOpenChange, onSuccess, onSubmit, })
56
33
  status: "failure",
57
34
  };
58
35
  }
59
- try {
60
- const result = await onSubmit(user.id);
36
+ setIsPending(true);
37
+ const result = await onSubmit(user.id);
38
+ setIsPending(false);
39
+ if (result.status !== "failure") {
61
40
  onSuccess?.();
62
- return result;
63
- }
64
- catch (error) {
65
- console.log(error);
66
41
  }
67
- }, undefined);
42
+ setState(result);
43
+ }
44
+ const isSuspending = user?.isActive;
68
45
  return (react_1.default.createElement(dialog_1.Dialog, { open: open, onOpenChange: (state) => {
69
46
  onOpenChange(state);
70
47
  (0, utils_1.unstuckPointerEvents)();
71
48
  } },
72
- react_1.default.createElement(dialog_1.DialogContent, null, !loggedInUser ? (react_1.default.createElement(must_login_1.MustLogin, { onOpenChange: (state) => {
49
+ react_1.default.createElement(dialog_1.DialogContent, { className: "ecpauth:p-0 ecpauth:overflow-hidden ecpauth:border-gray-200 ecpauth:dark:border-gray-800 ecpauth:shadow-2xl ecpauth:rounded-2xl ecpauth:max-w-md" }, !loggedInUser ? (react_1.default.createElement(must_login_1.MustLogin, { onOpenChange: (state) => {
73
50
  onOpenChange(state);
74
51
  (0, utils_1.unstuckPointerEvents)();
75
- } })) : (react_1.default.createElement("form", { action: handleSubmit },
76
- react_1.default.createElement(dialog_1.DialogHeader, null,
77
- react_1.default.createElement(dialog_1.DialogTitle, null,
78
- "Toggle account status (",
79
- user?.firstName,
80
- " ",
81
- user?.lastName,
82
- ")"),
83
- state?.status === "success" ? (react_1.default.createElement(message_1.Message, { message: state?.message, className: "ecpauth:my-2 ecpauth:font-semibold ecpauth:text-base", variant: "success" })) : (react_1.default.createElement(message_1.Message, { message: state?.message, className: "ecpauth:my-2" }))),
84
- react_1.default.createElement(dialog_1.DialogDescription, { className: "ecpauth:flex ecpauth:flex-col ecpauth:gap-2 ecpauth:text-gray-700 ecpauth:dark:text-gray-50 ecpauth:mt-4" },
85
- react_1.default.createElement("span", null,
86
- "This action will",
52
+ } })) : (react_1.default.createElement("form", { onSubmit: handleSubmit, className: "ecpauth:flex ecpauth:flex-col" },
53
+ react_1.default.createElement("div", { className: "ecpauth:relative ecpauth:px-6 ecpauth:pt-8 ecpauth:pb-6 ecpauth:text-center" },
54
+ react_1.default.createElement("div", { className: "ecpauth:relative ecpauth:z-10 ecpauth:flex ecpauth:flex-col ecpauth:items-center ecpauth:justify-center" },
55
+ react_1.default.createElement("div", { className: (0, utils_1.cn)("ecpauth:size-12 ecpauth:rounded-xl ecpauth:flex ecpauth:items-center ecpauth:justify-center ecpauth:mb-4 ecpauth:shadow-sm ecpauth:border", isSuspending
56
+ ? "ecpauth:bg-amber-50 ecpauth:dark:bg-amber-900/20 ecpauth:text-amber-600 ecpauth:dark:text-amber-400 ecpauth:border-amber-100 ecpauth:dark:border-amber-800/50"
57
+ : "ecpauth:bg-blue-50 ecpauth:dark:bg-blue-900/20 ecpauth:text-blue-600 ecpauth:dark:text-blue-400 ecpauth:border-blue-100 ecpauth:dark:border-blue-800/50") },
58
+ react_1.default.createElement(alert_circle_1.AlertCircleIcon, { size: 24 })),
59
+ react_1.default.createElement(dialog_1.DialogHeader, { className: "ecpauth:space-y-1" },
60
+ react_1.default.createElement(dialog_1.DialogTitle, { className: "ecpauth:text-xl ecpauth:font-bold ecpauth:text-gray-900 ecpauth:dark:text-white ecpauth:text-center" }, isSuspending ? "Suspend Account" : "Unsuspend Account"),
61
+ react_1.default.createElement(dialog_1.DialogDescription, { className: "ecpauth:text-gray-500 ecpauth:dark:text-gray-400 ecpauth:text-center" },
62
+ "Manage status for ",
63
+ user?.firstName,
64
+ " ",
65
+ user?.lastName)))),
66
+ react_1.default.createElement("div", { className: "ecpauth:px-8 ecpauth:pb-6" }, state?.status === "success" ? (react_1.default.createElement("div", { className: "ecpauth:mb-6" },
67
+ react_1.default.createElement(message_1.Message, { message: state?.message, className: "ecpauth:font-medium ecpauth:text-sm ecpauth:p-3 ecpauth:rounded-xl ecpauth:bg-green-50 ecpauth:dark:bg-green-900/10 ecpauth:border ecpauth:border-green-100 ecpauth:dark:border-green-800/30 ecpauth:text-green-700 ecpauth:dark:text-green-400", variant: "success" }))) : state?.message ? (react_1.default.createElement("div", { className: "ecpauth:mb-6" },
68
+ react_1.default.createElement(message_1.Message, { message: state?.message, className: "ecpauth:font-medium ecpauth:text-sm ecpauth:p-3 ecpauth:rounded-xl ecpauth:bg-red-50 ecpauth:dark:bg-red-900/10 ecpauth:border ecpauth:border-red-100 ecpauth:dark:border-red-800/30 ecpauth:text-red-700 ecpauth:dark:text-red-400" }))) : (react_1.default.createElement("div", { className: "ecpauth:p-4 ecpauth:rounded-xl ecpauth:bg-gray-50 ecpauth:dark:bg-white/5 ecpauth:border ecpauth:border-gray-100 ecpauth:dark:border-white/10" },
69
+ react_1.default.createElement("p", { className: "ecpauth:text-sm ecpauth:leading-relaxed ecpauth:text-gray-600 ecpauth:dark:text-gray-300 ecpauth:text-center" },
70
+ "Are you sure you want to",
87
71
  " ",
88
- react_1.default.createElement("strong", null, user?.isActive ? "suspend" : "unsuspend"),
89
- " the user."),
90
- react_1.default.createElement("span", null,
91
- "You can always",
72
+ react_1.default.createElement("strong", null, isSuspending ? "suspend" : "unsuspend"),
92
73
  " ",
93
- react_1.default.createElement("strong", null, user?.isActive ? "unsuspend" : "suspend"),
94
- " the user if you change your mind.")),
95
- react_1.default.createElement(dialog_1.DialogFooter, { className: "ecpauth:flex ecpauth:justify-center ecpauth:gap-2 ecpauth:mt-4" },
96
- react_1.default.createElement(button_1.Button, { type: "button", variant: "outline", onClick: () => onOpenChange(false) }, "Cancel"),
97
- react_1.default.createElement(button_1.Button, { disabled: isPending, type: "submit" }, user?.isActive ? "Suspend" : "Unsuspend")))))));
74
+ "this account?",
75
+ isSuspending
76
+ ? " The user will temporarily lose access to all platform features."
77
+ : " The user will regain access to their account features.")))),
78
+ react_1.default.createElement(dialog_1.DialogFooter, { className: "ecpauth:p-6 ecpauth:pt-0 ecpauth:flex ecpauth:flex-row ecpauth:justify-center ecpauth:gap-3" },
79
+ react_1.default.createElement(button_1.Button, { type: "button", variant: "outline", onClick: () => onOpenChange(false), className: "ecpauth:flex-1 ecpauth:h-11 ecpauth:rounded-xl ecpauth:font-semibold ecpauth:border-gray-200 ecpauth:dark:border-gray-800 ecpauth:hover:bg-gray-50 ecpauth:dark:hover:bg-white/5 ecpauth:transition-all" }, "Cancel"),
80
+ react_1.default.createElement(button_1.Button, { disabled: isPending, type: "submit", className: (0, utils_1.cn)("ecpauth:flex-1 ecpauth:h-11 ecpauth:rounded-xl ecpauth:font-bold ecpauth:text-white! ecpauth:shadow-lg ecpauth:transition-all ecpauth:active:scale-[0.98]", isSuspending
81
+ ? "ecpauth:bg-amber-600! ecpauth:hover:bg-amber-700! ecpauth:shadow-amber-600/20"
82
+ : "ecpauth:bg-blue-600! ecpauth:hover:bg-blue-700! ecpauth:shadow-blue-600/20") }, isPending
83
+ ? isSuspending
84
+ ? "Suspending..."
85
+ : "Unsuspending..."
86
+ : isSuspending
87
+ ? "Confirm Suspension"
88
+ : "Confirm Unsuspension")))))));
98
89
  }
@@ -37,5 +37,5 @@ exports.Input = Input;
37
37
  const React = __importStar(require("react"));
38
38
  const utils_1 = require("../../lib/utils");
39
39
  function Input({ className, type, ...props }) {
40
- return (React.createElement("input", { type: type, "data-slot": "input", className: (0, utils_1.cn)("ecpauth:file:text-stone-950 ecpauth:placeholder:text-stone-500 ecpauth:selection:bg-stone-900 ecpauth:selection:text-stone-50 ecpauth:border-stone-200 ecpauth:flex ecpauth:h-9 ecpauth:w-full ecpauth:min-w-0 ecpauth:rounded-md ecpauth:border ecpauth:bg-transparent ecpauth:px-3 ecpauth:py-1 ecpauth:text-base ecpauth:shadow-xs ecpauth:transition-[color,box-shadow] ecpauth:outline-none ecpauth:file:inline-flex ecpauth:file:h-7 ecpauth:file:border-0 ecpauth:file:bg-transparent ecpauth:file:text-sm ecpauth:file:font-medium ecpauth:disabled:pointer-events-none ecpauth:disabled:cursor-not-allowed ecpauth:disabled:opacity-50 ecpauth:md:text-sm ecpauth:dark:file:text-stone-50 ecpauth:dark:placeholder:text-stone-400 ecpauth:dark:selection:bg-stone-50 ecpauth:dark:selection:text-stone-900 ecpauth:dark:bg-gray-700/50 ecpauth:dark:border-gray-600", "ecpauth:focus-visible:border-stone-950 ecpauth:focus-visible:ring-stone-950/50 ecpauth:focus-visible:ring-[3px] ecpauth:dark:focus-visible:border-stone-300 ecpauth:dark:focus-visible:ring-stone-300/50", "ecpauth:aria-invalid:ring-red-500/20 ecpauth:dark:aria-invalid:ring-red-500/40 ecpauth:aria-invalid:border-red-500 ecpauth:dark:dark:aria-invalid:ring-red-900/40 ecpauth:dark:aria-invalid:border-red-900 ecpauth:focus-visible:ring-2 ecpauth:focus-visible:ring-gray-500", className), ...props }));
40
+ return (React.createElement("input", { type: type, "data-slot": "input", className: (0, utils_1.cn)("ecpauth:file:text-stone-950 ecpauth:placeholder:text-stone-500 ecpauth:selection:bg-stone-900 ecpauth:selection:text-stone-50 ecpauth:border-stone-200 ecpauth:flex ecpauth:h-9 ecpauth:w-full ecpauth:min-w-0 ecpauth:rounded-md ecpauth:border ecpauth:bg-transparent ecpauth:px-3 ecpauth:py-1 ecpauth:text-base ecpauth:shadow-xs ecpauth:transition-[color,box-shadow] ecpauth:outline-none ecpauth:file:inline-flex ecpauth:file:h-7 ecpauth:file:border-0 ecpauth:file:bg-transparent ecpauth:file:text-sm ecpauth:file:font-medium ecpauth:disabled:pointer-events-none ecpauth:disabled:cursor-not-allowed ecpauth:disabled:opacity-50 ecpauth:md:text-sm ecpauth:dark:file:text-stone-50 ecpauth:dark:placeholder:text-stone-400 ecpauth:dark:selection:bg-stone-50 ecpauth:dark:selection:text-stone-900 ecpauth:dark:bg-gray-700/50 ecpauth:dark:border-gray-600", "ecpauth:focus-visible:border-stone-950 ecpauth:focus-visible:ring-stone-950/50 ecpauth:focus-visible:ring-[3px] ecpauth:dark:focus-visible:border-stone-300 ecpauth:dark:focus-visible:ring-stone-300/50", "ecpauth:aria-invalid:ring-red-500/20 ecpauth:dark:aria-invalid:ring-red-500/40 ecpauth:aria-invalid:border-red-500 ecpauth:dark:dark:aria-invalid:ring-red-900/40 ecpauth:dark:aria-invalid:border-red-900 ecpauth:focus-visible:ring-2 ecpauth:focus-visible:ring-gray-500", "ecpauth:h-11 ecpauth:border-blue-200! ecpauth:focus-visible:ring-blue-500! ecpauth:focus-visible:border-blue-500! ecpauth:placeholder:text-gray-400! ecpauth:rounded-2xl!", className), ...props }));
41
41
  }