@explita/cloud-auth-client 0.1.0 → 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.
- package/dist/components/change-password.js +58 -75
- package/dist/components/icons/alert-circle.d.ts +5 -0
- package/dist/components/icons/alert-circle.js +13 -0
- package/dist/components/icons/chevron-down.d.ts +5 -0
- package/dist/components/icons/chevron-down.js +11 -0
- package/dist/components/icons/lock.d.ts +2 -1
- package/dist/components/icons/lock.js +2 -2
- package/dist/components/icons/logout.d.ts +2 -1
- package/dist/components/icons/logout.js +2 -2
- package/dist/components/icons/setting.d.ts +2 -1
- package/dist/components/icons/setting.js +2 -2
- package/dist/components/icons/shield.d.ts +5 -0
- package/dist/components/icons/shield.js +11 -0
- package/dist/components/icons/user.d.ts +5 -0
- package/dist/components/icons/user.js +12 -0
- package/dist/components/login-form.d.ts +3 -1
- package/dist/components/login-form.js +45 -34
- package/dist/components/reset-password.d.ts +2 -1
- package/dist/components/reset-password.js +62 -60
- package/dist/components/settings.js +16 -8
- package/dist/components/signup-form.d.ts +4 -3
- package/dist/components/signup-form.js +72 -60
- package/dist/components/toggle-2fa.js +42 -26
- package/dist/components/toggle-account-status.js +55 -64
- package/dist/components/ui/input.js +1 -1
- package/dist/components/user-card.js +48 -23
- package/dist/contexts/auth-provider.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/lib/utils.js +7 -1
- package/dist/server/user.d.ts +3 -1
- package/dist/server/user.js +33 -0
- package/dist/styles.css +901 -61
- package/dist/types.d.ts +21 -7
- package/package.json +2 -2
|
@@ -1,40 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
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.ChangePassword = ChangePassword;
|
|
37
|
-
const react_1 =
|
|
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 label_1 = require("./ui/label");
|
|
@@ -43,61 +13,74 @@ const auth_provider_1 = require("../contexts/auth-provider");
|
|
|
43
13
|
const message_1 = require("./message");
|
|
44
14
|
const must_login_1 = require("./must-login");
|
|
45
15
|
const utils_1 = require("../lib/utils");
|
|
16
|
+
const shield_1 = require("./icons/shield");
|
|
46
17
|
function ChangePassword({ user, open, onOpenChange, onSubmit, onSuccess, }) {
|
|
47
18
|
const { user: loggedInUser } = (0, auth_provider_1.useAuth)();
|
|
48
|
-
const [
|
|
19
|
+
const [isPending, setIsPending] = react_1.default.useState(false);
|
|
20
|
+
const [state, setState] = react_1.default.useState({
|
|
21
|
+
message: "",
|
|
22
|
+
//@ts-ignore
|
|
23
|
+
status: "",
|
|
24
|
+
errors: {},
|
|
25
|
+
});
|
|
26
|
+
async function handleSubmit(e) {
|
|
27
|
+
e.preventDefault();
|
|
28
|
+
const formData = new FormData(e.currentTarget);
|
|
49
29
|
if (!onSubmit || typeof onSubmit !== "function") {
|
|
50
30
|
return {
|
|
51
31
|
message: "Password change handler is not defined. Please pass onSubmit handler to ChangePassword component. If you are using UserCard component, please pass onChangePassword handler to it.",
|
|
52
32
|
status: "failure",
|
|
53
33
|
};
|
|
54
34
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
35
|
+
setIsPending(true);
|
|
36
|
+
const result = await onSubmit({
|
|
37
|
+
userId: user?.id || loggedInUser.id,
|
|
38
|
+
password: formData.get("password"),
|
|
39
|
+
confirmPassword: formData.get("confirmPassword"),
|
|
40
|
+
});
|
|
41
|
+
setIsPending(false);
|
|
42
|
+
if (result.status === "success") {
|
|
61
43
|
onSuccess?.();
|
|
62
|
-
return result;
|
|
63
|
-
}
|
|
64
|
-
catch (error) {
|
|
65
|
-
console.log(error);
|
|
66
44
|
}
|
|
67
|
-
|
|
45
|
+
setState(result);
|
|
46
|
+
}
|
|
68
47
|
return (react_1.default.createElement(dialog_1.Dialog, { open: open, onOpenChange: (state) => {
|
|
69
48
|
onOpenChange(state);
|
|
70
49
|
(0, utils_1.unstuckPointerEvents)();
|
|
71
50
|
} },
|
|
72
|
-
react_1.default.createElement(dialog_1.DialogContent,
|
|
51
|
+
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
52
|
onOpenChange(state);
|
|
74
53
|
(0, utils_1.unstuckPointerEvents)();
|
|
75
|
-
} })) : (react_1.default.createElement("form", {
|
|
76
|
-
react_1.default.createElement(
|
|
77
|
-
|
|
78
|
-
"
|
|
79
|
-
|
|
80
|
-
"
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
user
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
react_1.default.createElement(
|
|
91
|
-
react_1.default.createElement(message_1.Message, { message: state?.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
54
|
+
} })) : (react_1.default.createElement("form", { onSubmit: handleSubmit, className: "ecpauth:flex ecpauth:flex-col" },
|
|
55
|
+
react_1.default.createElement("div", { className: "ecpauth:relative ecpauth:px-6 ecpauth:pt-8 ecpauth:pb-6" },
|
|
56
|
+
react_1.default.createElement("div", { className: "ecpauth:relative ecpauth:z-10 ecpauth:flex ecpauth:flex-col ecpauth:items-center ecpauth:justify-center ecpauth:text-center" },
|
|
57
|
+
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:mb-4 ecpauth:shadow-sm ecpauth:border ecpauth:border-blue-100 ecpauth:dark:border-blue-800/50" },
|
|
58
|
+
react_1.default.createElement(shield_1.ShieldIcon, { 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" }, !user || loggedInUser.id === user.id
|
|
61
|
+
? "Change Password"
|
|
62
|
+
: `Update ${user.firstName}'s Password`),
|
|
63
|
+
react_1.default.createElement(dialog_1.DialogDescription, { className: "ecpauth:text-gray-500 ecpauth:dark:text-gray-400 ecpauth:text-center" }, "Ensure your account stays secure with a strong password.")),
|
|
64
|
+
user && loggedInUser.id !== user?.id && (react_1.default.createElement("div", { className: "ecpauth:mt-3 ecpauth:px-3 ecpauth:py-1 ecpauth:bg-gray-100 ecpauth:dark:bg-gray-800 ecpauth:rounded-full ecpauth:text-xs ecpauth:font-medium ecpauth:text-gray-600 ecpauth:dark:text-gray-300" },
|
|
65
|
+
"Target: ",
|
|
66
|
+
user?.email)))),
|
|
67
|
+
react_1.default.createElement("div", { className: "ecpauth:px-6 ecpauth:pb-8" },
|
|
68
|
+
state?.status === "success" ? (react_1.default.createElement("div", { className: "ecpauth:mb-6" },
|
|
69
|
+
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:mb-6" },
|
|
70
|
+
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,
|
|
71
|
+
react_1.default.createElement("div", { className: "ecpauth:space-y-5" },
|
|
72
|
+
react_1.default.createElement("div", { className: "ecpauth:space-y-2" },
|
|
73
|
+
react_1.default.createElement(label_1.Label, { htmlFor: "password", className: "ecpauth:text-sm ecpauth:font-semibold ecpauth:text-gray-700 ecpauth:dark:text-gray-300 ecpauth:ml-0.5" }, "New Password"),
|
|
74
|
+
react_1.default.createElement("div", { className: "ecpauth:relative" },
|
|
75
|
+
react_1.default.createElement(input_1.Input, { id: "password", type: "password", name: "password", placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", className: "ecpauth:h-11 ecpauth:rounded-xl ecpauth:border-gray-200 ecpauth:dark:border-gray-800 ecpauth:bg-gray-50/50 ecpauth:dark:bg-gray-900/50 ecpauth:focus:bg-white ecpauth:dark:focus:bg-gray-950 ecpauth:transition-all" })),
|
|
76
|
+
state?.status === "validation-error" &&
|
|
77
|
+
state?.errors?.password && (react_1.default.createElement("p", { className: "ecpauth:text-[11px] ecpauth:font-medium ecpauth:text-red-500 ecpauth:mt-1 ecpauth:ml-1" }, state.errors.password))),
|
|
78
|
+
react_1.default.createElement("div", { className: "ecpauth:space-y-2" },
|
|
79
|
+
react_1.default.createElement(label_1.Label, { htmlFor: "confirmPassword", className: "ecpauth:text-sm ecpauth:font-semibold ecpauth:text-gray-700 ecpauth:dark:text-gray-300 ecpauth:ml-0.5" }, "Confirm New Password"),
|
|
80
|
+
react_1.default.createElement(input_1.Input, { id: "confirmPassword", type: "password", name: "confirmPassword", placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", className: "ecpauth:h-11 ecpauth:rounded-xl ecpauth:border-gray-200 ecpauth:dark:border-gray-800 ecpauth:bg-gray-50/50 ecpauth:dark:bg-gray-900/50 ecpauth:focus:bg-white ecpauth:dark:focus:bg-gray-950 ecpauth:transition-all" }),
|
|
81
|
+
state?.status === "validation-error" &&
|
|
82
|
+
state?.errors?.confirmPassword && (react_1.default.createElement("p", { className: "ecpauth:text-[11px] ecpauth:font-medium ecpauth:text-red-500 ecpauth:mt-1 ecpauth:ml-1" }, state.errors.confirmPassword)))),
|
|
83
|
+
react_1.default.createElement("div", { className: "ecpauth:flex ecpauth:items-center ecpauth:gap-3 ecpauth:mt-10" },
|
|
84
|
+
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:border-gray-200 ecpauth:dark:border-gray-800 ecpauth:text-gray-600 ecpauth:dark:text-gray-400 ecpauth:font-semibold ecpauth:hover:bg-gray-50 ecpauth:dark:hover:bg-white/5 ecpauth:transition-colors" }, "Cancel"),
|
|
85
|
+
react_1.default.createElement(button_1.Button, { disabled: isPending, type: "submit", className: "ecpauth:flex-1 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]" }, isPending ? "Updating..." : "Update Password"))))))));
|
|
103
86
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.AlertCircleIcon = AlertCircleIcon;
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
8
|
+
function AlertCircleIcon({ size = 24, className, }) {
|
|
9
|
+
return (react_1.default.createElement("svg", { stroke: "currentColor", fill: "none", strokeWidth: "2", viewBox: "0 0 24 24", strokeLinecap: "round", strokeLinejoin: "round", height: `${size}px`, width: `${size}px`, xmlns: "http://www.w3.org/2000/svg", className: className },
|
|
10
|
+
react_1.default.createElement("circle", { cx: "12", cy: "12", r: "10" }),
|
|
11
|
+
react_1.default.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
|
|
12
|
+
react_1.default.createElement("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })));
|
|
13
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ChevronDownIcon = ChevronDownIcon;
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
8
|
+
function ChevronDownIcon({ size = 20, className, }) {
|
|
9
|
+
return (react_1.default.createElement("svg", { stroke: "currentColor", fill: "none", strokeWidth: "2", viewBox: "0 0 24 24", strokeLinecap: "round", strokeLinejoin: "round", height: `${size}px`, width: `${size}px`, xmlns: "http://www.w3.org/2000/svg", className: className },
|
|
10
|
+
react_1.default.createElement("path", { d: "m6 9 6 6 6-6" })));
|
|
11
|
+
}
|
|
@@ -5,8 +5,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.LockIcon = LockIcon;
|
|
7
7
|
const react_1 = __importDefault(require("react"));
|
|
8
|
-
function LockIcon({ size = 24 }) {
|
|
9
|
-
return (react_1.default.createElement("svg", { stroke: "currentColor", fill: "none", strokeWidth: "2", viewBox: "0 0 24 24", strokeLinecap: "round", strokeLinejoin: "round", height: `${size}px`, width: `${size}px`, xmlns: "http://www.w3.org/2000/svg" },
|
|
8
|
+
function LockIcon({ size = 24, className, }) {
|
|
9
|
+
return (react_1.default.createElement("svg", { stroke: "currentColor", fill: "none", strokeWidth: "2", viewBox: "0 0 24 24", strokeLinecap: "round", strokeLinejoin: "round", height: `${size}px`, width: `${size}px`, xmlns: "http://www.w3.org/2000/svg", className: className },
|
|
10
10
|
react_1.default.createElement("path", { d: "M15 21h-8a2 2 0 0 1 -2 -2v-6a2 2 0 0 1 2 -2h10c.265 0 .518 .052 .75 .145" }),
|
|
11
11
|
react_1.default.createElement("path", { d: "M11 16a1 1 0 1 0 2 0a1 1 0 0 0 -2 0" }),
|
|
12
12
|
react_1.default.createElement("path", { d: "M8 11v-4a4 4 0 1 1 8 0v4" }),
|
|
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.LogoutIcon = LogoutIcon;
|
|
7
7
|
const react_1 = __importDefault(require("react"));
|
|
8
|
-
function LogoutIcon({ size = 24 }) {
|
|
9
|
-
return (react_1.default.createElement("svg", { stroke: "currentColor", fill: "currentColor", strokeWidth: "0", viewBox: "0 0 20 20", "aria-hidden": "true", height: `${size}px`, width: `${size}px`, xmlns: "http://www.w3.org/2000/svg" },
|
|
8
|
+
function LogoutIcon({ size = 24, className, }) {
|
|
9
|
+
return (react_1.default.createElement("svg", { stroke: "currentColor", fill: "currentColor", strokeWidth: "0", viewBox: "0 0 20 20", "aria-hidden": "true", height: `${size}px`, width: `${size}px`, xmlns: "http://www.w3.org/2000/svg", className: className },
|
|
10
10
|
react_1.default.createElement("path", { fillRule: "evenodd", d: "M3 3a1 1 0 00-1 1v12a1 1 0 102 0V4a1 1 0 00-1-1zm10.293 9.293a1 1 0 001.414 1.414l3-3a1 1 0 000-1.414l-3-3a1 1 0 10-1.414 1.414L14.586 9H7a1 1 0 100 2h7.586l-1.293 1.293z", clipRule: "evenodd" })));
|
|
11
11
|
}
|
|
@@ -5,8 +5,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.SettingIcon = SettingIcon;
|
|
7
7
|
const react_1 = __importDefault(require("react"));
|
|
8
|
-
function SettingIcon({ size = 24 }) {
|
|
9
|
-
return (react_1.default.createElement("svg", { stroke: "currentColor", fill: "currentColor", strokeWidth: "0", viewBox: "0 0 24 24", height: `${size}px`, width: `${size}px`, xmlns: "http://www.w3.org/2000/svg" },
|
|
8
|
+
function SettingIcon({ size = 24, className, }) {
|
|
9
|
+
return (react_1.default.createElement("svg", { stroke: "currentColor", fill: "currentColor", strokeWidth: "0", viewBox: "0 0 24 24", height: `${size}px`, width: `${size}px`, xmlns: "http://www.w3.org/2000/svg", className: className },
|
|
10
10
|
react_1.default.createElement("path", { fill: "none", d: "M0 0h24v24H0z" }),
|
|
11
11
|
react_1.default.createElement("path", { d: "M17.41 6.59 15 5.5l2.41-1.09L18.5 2l1.09 2.41L22 5.5l-2.41 1.09L18.5 9l-1.09-2.41zm3.87 6.13L20.5 11l-.78 1.72-1.72.78 1.72.78.78 1.72.78-1.72L23 13.5l-1.72-.78zm-5.04 1.65 1.94 1.47-2.5 4.33-2.24-.94c-.2.13-.42.26-.64.37l-.3 2.4h-5l-.3-2.41c-.22-.11-.43-.23-.64-.37l-2.24.94-2.5-4.33 1.94-1.47c-.01-.11-.01-.24-.01-.36s0-.25.01-.37l-1.94-1.47 2.5-4.33 2.24.94c.2-.13.42-.26.64-.37L7.5 6h5l.3 2.41c.22.11.43.23.64.37l2.24-.94 2.5 4.33-1.94 1.47c.01.12.01.24.01.37s0 .24-.01.36zM13 14c0-1.66-1.34-3-3-3s-3 1.34-3 3 1.34 3 3 3 3-1.34 3-3z" })));
|
|
12
12
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ShieldIcon = ShieldIcon;
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
8
|
+
function ShieldIcon({ size = 20, className, }) {
|
|
9
|
+
return (react_1.default.createElement("svg", { stroke: "currentColor", fill: "none", strokeWidth: "2", viewBox: "0 0 24 24", strokeLinecap: "round", strokeLinejoin: "round", height: `${size}px`, width: `${size}px`, xmlns: "http://www.w3.org/2000/svg", className: className },
|
|
10
|
+
react_1.default.createElement("path", { d: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10" })));
|
|
11
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.UserIcon = UserIcon;
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
8
|
+
function UserIcon({ size = 20, className, }) {
|
|
9
|
+
return (react_1.default.createElement("svg", { stroke: "currentColor", fill: "none", strokeWidth: "2", viewBox: "0 0 24 24", strokeLinecap: "round", strokeLinejoin: "round", height: `${size}px`, width: `${size}px`, xmlns: "http://www.w3.org/2000/svg", className: className },
|
|
10
|
+
react_1.default.createElement("path", { d: "M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2" }),
|
|
11
|
+
react_1.default.createElement("circle", { cx: "12", cy: "7", r: "4" })));
|
|
12
|
+
}
|
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
export declare function Login({ className, ...props }: React.ComponentPropsWithoutRef<"div">
|
|
2
|
+
export declare function Login({ className, logo, ...props }: React.ComponentPropsWithoutRef<"div"> & {
|
|
3
|
+
logo?: React.ReactNode;
|
|
4
|
+
}): React.JSX.Element;
|
|
@@ -44,9 +44,11 @@ const label_1 = require("../components/ui/label");
|
|
|
44
44
|
const auth_provider_1 = require("../contexts/auth-provider");
|
|
45
45
|
const loader_1 = require("./loader");
|
|
46
46
|
const message_1 = require("./message");
|
|
47
|
-
function Login({ className, ...props }) {
|
|
48
|
-
const { login, error, computedRouteContext
|
|
47
|
+
function Login({ className, logo, ...props }) {
|
|
48
|
+
const { login, error, computedRouteContext } = (0, auth_provider_1.useAuth)();
|
|
49
49
|
const [authToken, setAuthToken] = react_1.default.useState(null);
|
|
50
|
+
const [isPending, setIsPending] = react_1.default.useState(false);
|
|
51
|
+
const [isAuthenticated, setIsAuthenticated] = react_1.default.useState(false);
|
|
50
52
|
const { resetPasswordUrl, signupUrl, loginUrl } = computedRouteContext;
|
|
51
53
|
(0, react_1.useEffect)(() => {
|
|
52
54
|
const authToken = new URLSearchParams(window.location.search).get("authToken");
|
|
@@ -63,39 +65,48 @@ function Login({ className, ...props }) {
|
|
|
63
65
|
});
|
|
64
66
|
}
|
|
65
67
|
}, [authToken]);
|
|
66
|
-
|
|
67
|
-
|
|
68
|
+
async function handleSubmit(e) {
|
|
69
|
+
e.preventDefault();
|
|
70
|
+
const formData = new FormData(e.currentTarget);
|
|
71
|
+
setIsPending(true);
|
|
72
|
+
const res = await login({
|
|
68
73
|
email: formData.get("email"),
|
|
69
74
|
password: formData.get("password"),
|
|
70
75
|
});
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
react_1.default.createElement(
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
react_1.default.createElement("
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
react_1.default.createElement(input_1.Input, { id: "
|
|
95
|
-
react_1.default.createElement(message_1.Message, { message: error?.errors?.
|
|
96
|
-
react_1.default.createElement(
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
76
|
+
if (!res) {
|
|
77
|
+
setIsAuthenticated(true);
|
|
78
|
+
}
|
|
79
|
+
setIsPending(false);
|
|
80
|
+
// return { email: formData.get("email") as string };
|
|
81
|
+
}
|
|
82
|
+
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 },
|
|
83
|
+
isAuthenticated && react_1.default.createElement(loader_1.Loader, null),
|
|
84
|
+
react_1.default.createElement(card_1.Card, { className: "ecpauth:relative ecpauth:w-full ecpauth:max-w-[450px] ecpauth:overflow-hidden ecpauth:shadow-none ecpauth:lg:shadow-xl ecpauth:border-none ecpauth:rounded-xl" },
|
|
85
|
+
authToken && !error && (react_1.default.createElement("div", { className: "ecpauth:absolute ecpauth:inset-0 ecpauth:flex ecpauth:flex-col ecpauth:items-center ecpauth:justify-center ecpauth:gap-2 ecpauth:text-black ecpauth:dark:text-white ecpauth:bg-white/90 ecpauth:dark:bg-gray-900/90 ecpauth:z-50 ecpauth:rounded-xl" },
|
|
86
|
+
react_1.default.createElement("p", { className: "ecpauth:font-medium" }, "Please wait..."),
|
|
87
|
+
react_1.default.createElement("a", { href: loginUrl, className: "ecpauth:underline ecpauth:underline-offset-4 ecpauth:text-blue-500! ecpauth:hover:text-blue-600!" }, "Or go back to login"))),
|
|
88
|
+
react_1.default.createElement(card_1.CardHeader, { className: "ecpauth:space-y-4 ecpauth:text-center ecpauth:pb-2 ecpauth:pt-10" },
|
|
89
|
+
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)),
|
|
90
|
+
react_1.default.createElement("div", { className: "ecpauth:space-y-2" },
|
|
91
|
+
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" }, "Welcome Back"),
|
|
92
|
+
react_1.default.createElement(card_1.CardDescription, { className: "ecpauth:text-sm ecpauth:text-gray-500 ecpauth:dark:text-gray-400" }, "Enter your credentials to access the dashboard.")),
|
|
93
|
+
error?.message && (react_1.default.createElement("p", { className: "ecpauth:text-red-500 ecpauth:mt-3 ecpauth:text-sm ecpauth:font-medium" }, error.message))),
|
|
94
|
+
react_1.default.createElement(card_1.CardContent, { className: "ecpauth:space-y-6 ecpauth:p-8 ecpauth:px-12" },
|
|
95
|
+
react_1.default.createElement("form", { onSubmit: handleSubmit, className: "ecpauth:space-y-6" },
|
|
96
|
+
react_1.default.createElement("div", { className: "ecpauth:space-y-4" },
|
|
97
|
+
react_1.default.createElement("div", { className: "ecpauth:space-y-2" },
|
|
98
|
+
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 or Username"),
|
|
99
|
+
react_1.default.createElement(input_1.Input, { id: "email", type: "text", placeholder: "e.g. user@example.com", name: "email" }),
|
|
100
|
+
react_1.default.createElement(message_1.Message, { message: error?.errors?.email, className: "ecpauth:mt-1 ecpauth:text-[11px] ecpauth:text-red-500" })),
|
|
101
|
+
react_1.default.createElement("div", { className: "ecpauth:space-y-2" },
|
|
102
|
+
react_1.default.createElement("div", { className: "ecpauth:flex ecpauth:items-center ecpauth:justify-between" },
|
|
103
|
+
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")),
|
|
104
|
+
react_1.default.createElement(input_1.Input, { id: "password", type: "password", name: "password", placeholder: "Enter your password" }),
|
|
105
|
+
react_1.default.createElement(message_1.Message, { message: error?.errors?.password, className: "ecpauth:mt-1 ecpauth:text-[11px] ecpauth:text-red-500" }),
|
|
106
|
+
react_1.default.createElement("div", { className: "ecpauth:flex ecpauth:justify-end" }, resetPasswordUrl && (react_1.default.createElement("a", { href: resetPasswordUrl, className: "ecpauth:text-xs ecpauth:font-semibold ecpauth:text-blue-600 ecpauth:hover:text-blue-700 ecpauth:hover:underline" }, "Forgot Password?"))))),
|
|
107
|
+
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 || isAuthenticated }, isPending ? "Logging In..." : "Log In")),
|
|
108
|
+
signupUrl && (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" },
|
|
109
|
+
"Don't have an account?",
|
|
110
|
+
" ",
|
|
111
|
+
react_1.default.createElement("a", { href: signupUrl, className: "ecpauth:font-semibold ecpauth:text-gray-900 ecpauth:hover:underline ecpauth:dark:text-white" }, "Sign Up")))))));
|
|
101
112
|
}
|
|
@@ -3,6 +3,7 @@ import { GeneralResponse, ResetPasswordWithToken } from "../types";
|
|
|
3
3
|
type Props = {
|
|
4
4
|
className?: string;
|
|
5
5
|
onChangePassword: (data: ResetPasswordWithToken) => Promise<GeneralResponse>;
|
|
6
|
+
logo?: React.ReactNode;
|
|
6
7
|
};
|
|
7
|
-
export declare function ResetPassword({ className, onChangePassword, ...props }: Props): React.JSX.Element;
|
|
8
|
+
export declare function ResetPassword({ className, onChangePassword, logo, ...props }: Props): React.JSX.Element;
|
|
8
9
|
export {};
|
|
@@ -43,75 +43,77 @@ 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 ResetPassword({ className, onChangePassword, ...props }) {
|
|
46
|
+
function ResetPassword({ className, onChangePassword, logo, ...props }) {
|
|
47
47
|
const { sendPasswordResetRequest, 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
|
+
errors: {},
|
|
54
|
+
});
|
|
48
55
|
const [token, setToken] = (0, react_1.useState)(null);
|
|
49
56
|
const { loginUrl } = computedRouteContext;
|
|
50
57
|
(0, react_1.useEffect)(() => {
|
|
51
58
|
const token = new URLSearchParams(window.location.search).get("token");
|
|
52
59
|
setToken(token);
|
|
53
60
|
}, []);
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
status: "failure",
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
const result = await onChangePassword({
|
|
67
|
-
token,
|
|
68
|
-
password: formData.get("password"),
|
|
69
|
-
confirmPassword: formData.get("confirmPassword"),
|
|
70
|
-
});
|
|
71
|
-
return result;
|
|
61
|
+
async function handleSubmit(event) {
|
|
62
|
+
event.preventDefault();
|
|
63
|
+
const formData = new FormData(event.currentTarget);
|
|
64
|
+
setIsPending(true);
|
|
65
|
+
if (!token) {
|
|
66
|
+
const result = await sendPasswordResetRequest(formData.get("email"));
|
|
67
|
+
setIsPending(false);
|
|
68
|
+
setState({ ...result });
|
|
69
|
+
return;
|
|
72
70
|
}
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
if (typeof onChangePassword !== "function") {
|
|
72
|
+
setState({
|
|
73
|
+
message: "onChangePassword function is not defined. Please pass onChangePassword function to ResetPassword component.",
|
|
74
|
+
status: "failure",
|
|
75
|
+
});
|
|
76
|
+
return;
|
|
75
77
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
react_1.default.createElement(
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
react_1.default.createElement("div", { className: "ecpauth:
|
|
106
|
-
react_1.default.createElement("div", { className: "ecpauth:
|
|
107
|
-
react_1.default.createElement(label_1.Label, { htmlFor: "password" }, "Password"),
|
|
108
|
-
react_1.default.createElement(input_1.Input, { id: "password", type: "password", name: "password" })),
|
|
109
|
-
react_1.default.createElement("div", { className: "ecpauth:
|
|
110
|
-
react_1.default.createElement(label_1.Label, { htmlFor: "confirmPassword" }, "Confirm Password"),
|
|
111
|
-
react_1.default.createElement(input_1.Input, { id: "confirmPassword", type: "password", name: "confirmPassword" })),
|
|
112
|
-
|
|
113
|
-
loginUrl && (react_1.default.createElement("div", { className: "ecpauth:
|
|
78
|
+
setIsPending(true);
|
|
79
|
+
const result = await onChangePassword({
|
|
80
|
+
token,
|
|
81
|
+
password: formData.get("password"),
|
|
82
|
+
confirmPassword: formData.get("confirmPassword"),
|
|
83
|
+
});
|
|
84
|
+
setIsPending(false);
|
|
85
|
+
setState({ ...result });
|
|
86
|
+
}
|
|
87
|
+
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 },
|
|
88
|
+
react_1.default.createElement(card_1.Card, { className: "ecpauth:relative ecpauth:w-full ecpauth:max-w-[450px] ecpauth:overflow-hidden ecpauth:shadow-none ecpauth:lg:shadow-xl ecpauth:border-none ecpauth:rounded-xl" },
|
|
89
|
+
react_1.default.createElement(card_1.CardHeader, { className: "ecpauth:space-y-4 ecpauth:text-center ecpauth:pb-2 ecpauth:pt-10" },
|
|
90
|
+
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)),
|
|
91
|
+
react_1.default.createElement("div", { className: "ecpauth:space-y-2" },
|
|
92
|
+
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" }, "Reset Password"),
|
|
93
|
+
react_1.default.createElement(card_1.CardDescription, { className: "ecpauth:text-sm ecpauth:text-gray-500 ecpauth:dark:text-gray-400" }, token
|
|
94
|
+
? "Enter your new password below."
|
|
95
|
+
: "Provide your email to receive a reset link.")),
|
|
96
|
+
state?.status === "success" ? (react_1.default.createElement("div", { className: "ecpauth:mt-3" },
|
|
97
|
+
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" },
|
|
98
|
+
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),
|
|
99
|
+
react_1.default.createElement(card_1.CardContent, { className: "ecpauth:space-y-6 ecpauth:p-8 ecpauth:px-12" },
|
|
100
|
+
!token ? (react_1.default.createElement("form", { onSubmit: handleSubmit, className: "ecpauth:space-y-6" },
|
|
101
|
+
react_1.default.createElement("div", { className: "ecpauth:space-y-2" },
|
|
102
|
+
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"),
|
|
103
|
+
react_1.default.createElement(input_1.Input, { id: "email", type: "email", placeholder: "email@example.com", name: "email", defaultValue:
|
|
104
|
+
//@ts-ignore
|
|
105
|
+
state?.form?.email, className: "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-lg" })),
|
|
106
|
+
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 ? "Sending..." : "Send Reset Link"))) : (react_1.default.createElement("form", { onSubmit: handleSubmit, className: "ecpauth:space-y-6" },
|
|
107
|
+
react_1.default.createElement("div", { className: "ecpauth:space-y-4" },
|
|
108
|
+
react_1.default.createElement("div", { className: "ecpauth:space-y-2" },
|
|
109
|
+
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" }, "New Password"),
|
|
110
|
+
react_1.default.createElement(input_1.Input, { id: "password", type: "password", name: "password", placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", className: "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-lg" })),
|
|
111
|
+
react_1.default.createElement("div", { className: "ecpauth:space-y-2" },
|
|
112
|
+
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 New Password"),
|
|
113
|
+
react_1.default.createElement(input_1.Input, { id: "confirmPassword", type: "password", name: "confirmPassword", placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", className: "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-lg" }))),
|
|
114
|
+
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 ? "Resetting..." : "Reset Password"))),
|
|
115
|
+
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" },
|
|
114
116
|
"Back to",
|
|
115
117
|
" ",
|
|
116
|
-
react_1.default.createElement("a", { href: loginUrl, className: "ecpauth:underline ecpauth:
|
|
118
|
+
react_1.default.createElement("a", { href: loginUrl, className: "ecpauth:font-semibold ecpauth:text-gray-900 ecpauth:hover:underline ecpauth:dark:text-white" }, "Login")))))));
|
|
117
119
|
}
|