@stackframe/stack 2.5.19 → 2.5.21
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/CHANGELOG.md +20 -0
- package/dist/components/elements/maybe-full-page.d.mts +4 -1
- package/dist/components/elements/maybe-full-page.d.ts +4 -1
- package/dist/components/elements/maybe-full-page.js +6 -3
- package/dist/components/elements/maybe-full-page.js.map +1 -1
- package/dist/components/elements/sidebar-layout.d.mts +9 -9
- package/dist/components/elements/sidebar-layout.d.ts +9 -9
- package/dist/components/elements/sidebar-layout.js +45 -59
- package/dist/components/elements/sidebar-layout.js.map +1 -1
- package/dist/components/oauth-button.js +12 -0
- package/dist/components/oauth-button.js.map +1 -1
- package/dist/components/selected-team-switcher.js +8 -25
- package/dist/components/selected-team-switcher.js.map +1 -1
- package/dist/components/team-icon.d.mts +18 -0
- package/dist/components/team-icon.d.ts +18 -0
- package/dist/components/team-icon.js +50 -0
- package/dist/components/team-icon.js.map +1 -0
- package/dist/components-page/account-settings.d.mts +2 -1
- package/dist/components-page/account-settings.d.ts +2 -1
- package/dist/components-page/account-settings.js +390 -203
- package/dist/components-page/account-settings.js.map +1 -1
- package/dist/components-page/stack-handler.js +2 -24
- package/dist/components-page/stack-handler.js.map +1 -1
- package/dist/esm/components/elements/maybe-full-page.js +7 -4
- package/dist/esm/components/elements/maybe-full-page.js.map +1 -1
- package/dist/esm/components/elements/sidebar-layout.js +44 -47
- package/dist/esm/components/elements/sidebar-layout.js.map +1 -1
- package/dist/esm/components/oauth-button.js +12 -0
- package/dist/esm/components/oauth-button.js.map +1 -1
- package/dist/esm/components/selected-team-switcher.js +6 -13
- package/dist/esm/components/selected-team-switcher.js.map +1 -1
- package/dist/esm/components/team-icon.js +15 -0
- package/dist/esm/components/team-icon.js.map +1 -0
- package/dist/esm/components-page/account-settings.js +393 -207
- package/dist/esm/components-page/account-settings.js.map +1 -1
- package/dist/esm/components-page/stack-handler.js +2 -24
- package/dist/esm/components-page/stack-handler.js.map +1 -1
- package/dist/esm/lib/stack-app.js +11 -5
- package/dist/esm/lib/stack-app.js.map +1 -1
- package/dist/esm/providers/stack-provider.js.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/lib/stack-app.d.mts +6 -2
- package/dist/lib/stack-app.d.ts +6 -2
- package/dist/lib/stack-app.js +11 -5
- package/dist/lib/stack-app.js.map +1 -1
- package/dist/providers/stack-provider.d.mts +2 -2
- package/dist/providers/stack-provider.d.ts +2 -2
- package/dist/providers/stack-provider.js.map +1 -1
- package/package.json +4 -4
- package/dist/components-page/team-settings.d.mts +0 -8
- package/dist/components-page/team-settings.d.ts +0 -8
- package/dist/components-page/team-settings.js +0 -139
- package/dist/components-page/team-settings.js.map +0 -1
- package/dist/esm/components-page/team-settings.js +0 -115
- package/dist/esm/components-page/team-settings.js.map +0 -1
|
@@ -32,11 +32,14 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
32
32
|
// src/components-page/account-settings.tsx
|
|
33
33
|
var account_settings_exports = {};
|
|
34
34
|
__export(account_settings_exports, {
|
|
35
|
-
AccountSettings: () => AccountSettings
|
|
35
|
+
AccountSettings: () => AccountSettings,
|
|
36
|
+
TeamCreation: () => TeamCreation
|
|
36
37
|
});
|
|
37
38
|
module.exports = __toCommonJS(account_settings_exports);
|
|
39
|
+
var import_yup = require("@hookform/resolvers/yup");
|
|
38
40
|
var import_password = require("@stackframe/stack-shared/dist/helpers/password");
|
|
39
41
|
var import_use_async_callback = require("@stackframe/stack-shared/dist/hooks/use-async-callback");
|
|
42
|
+
var import_schema_fields = require("@stackframe/stack-shared/dist/schema-fields");
|
|
40
43
|
var import_crypto = require("@stackframe/stack-shared/dist/utils/crypto");
|
|
41
44
|
var import_errors = require("@stackframe/stack-shared/dist/utils/errors");
|
|
42
45
|
var import_promises = require("@stackframe/stack-shared/dist/utils/promises");
|
|
@@ -45,216 +48,215 @@ var import_lucide_react = require("lucide-react");
|
|
|
45
48
|
var import_otp = require("oslo/otp");
|
|
46
49
|
var QRCode = __toESM(require("qrcode"));
|
|
47
50
|
var import_react = require("react");
|
|
51
|
+
var import_react_hook_form = require("react-hook-form");
|
|
52
|
+
var yup = __toESM(require("yup"));
|
|
48
53
|
var import__ = require("..");
|
|
49
54
|
var import_form_warning = require("../components/elements/form-warning");
|
|
50
55
|
var import_sidebar_layout = require("../components/elements/sidebar-layout");
|
|
51
56
|
var import_user_avatar = require("../components/elements/user-avatar");
|
|
57
|
+
var import_team_icon = require("../components/team-icon");
|
|
52
58
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
53
59
|
function AccountSettings({ fullPage = false }) {
|
|
54
60
|
const user = (0, import__.useUser)({ or: "redirect" });
|
|
55
|
-
const
|
|
61
|
+
const teams = user.useTeams();
|
|
62
|
+
const project = (0, import__.useStackApp)().useProject();
|
|
63
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
56
64
|
import_sidebar_layout.SidebarLayout,
|
|
57
65
|
{
|
|
58
66
|
items: [
|
|
59
|
-
{
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
67
|
+
{
|
|
68
|
+
title: "My Profile",
|
|
69
|
+
type: "item",
|
|
70
|
+
subpath: "/profile",
|
|
71
|
+
icon: import_lucide_react.Contact,
|
|
72
|
+
content: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ProfileSection, {})
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
title: "Security",
|
|
76
|
+
type: "item",
|
|
77
|
+
icon: import_lucide_react.ShieldCheck,
|
|
78
|
+
subpath: "/security",
|
|
79
|
+
content: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col gap-8", children: [
|
|
80
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(EmailVerificationSection, {}),
|
|
81
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(PasswordSection, {}),
|
|
82
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(MfaSection, {})
|
|
83
|
+
] })
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
title: "Sign Out",
|
|
87
|
+
subpath: "/sign-out",
|
|
88
|
+
type: "item",
|
|
89
|
+
icon: import_lucide_react.LogOut,
|
|
90
|
+
content: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SignOutSection, {})
|
|
91
|
+
},
|
|
92
|
+
...teams.length > 0 || project.config.clientTeamCreationEnabled ? [{
|
|
93
|
+
title: "Teams",
|
|
94
|
+
type: "divider"
|
|
95
|
+
}] : [],
|
|
96
|
+
...teams.map((team) => ({
|
|
97
|
+
title: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex gap-2 items-center", children: [
|
|
98
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_team_icon.TeamIcon, { team }),
|
|
99
|
+
team.displayName
|
|
100
|
+
] }),
|
|
101
|
+
type: "item",
|
|
102
|
+
subpath: `/teams/${team.id}`,
|
|
103
|
+
content: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col gap-8", children: [
|
|
104
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ProfileSettings, { team }),
|
|
105
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ManagementSettings, { team }),
|
|
106
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(MemberInvitation, { team }),
|
|
107
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(MembersSettings, { team }),
|
|
108
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(UserSettings, { team })
|
|
109
|
+
] })
|
|
110
|
+
})),
|
|
111
|
+
...project.config.clientTeamCreationEnabled ? [{
|
|
112
|
+
title: "Create a team",
|
|
113
|
+
icon: import_lucide_react.CirclePlus,
|
|
114
|
+
type: "item",
|
|
115
|
+
subpath: "/team-creation",
|
|
116
|
+
content: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TeamCreation, {})
|
|
117
|
+
}] : []
|
|
118
|
+
].filter((p) => p.type === "divider" || p.content),
|
|
119
|
+
title: "Account Settings",
|
|
120
|
+
basePath: "/handler/account-settings"
|
|
68
121
|
}
|
|
69
122
|
);
|
|
70
|
-
if (fullPage) {
|
|
71
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Container, { size: 800, className: "stack-scope", children: inner });
|
|
72
|
-
} else {
|
|
73
|
-
return inner;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
function SettingSection(props) {
|
|
77
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_stack_ui.Card, { children: [
|
|
78
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.CardHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
79
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { type: "h4", children: props.title }),
|
|
80
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { type: "label", variant: "secondary", children: props.desc })
|
|
81
|
-
] }) }),
|
|
82
|
-
props.children && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.CardContent, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex flex-col gap-4", children: props.children }) }),
|
|
83
|
-
props.buttonText && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.CardFooter, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex justify-end w-full", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
84
|
-
import_stack_ui.Button,
|
|
85
|
-
{
|
|
86
|
-
disabled: props.buttonDisabled,
|
|
87
|
-
onClick: props.onButtonClick,
|
|
88
|
-
variant: props.buttonVariant,
|
|
89
|
-
children: props.buttonText
|
|
90
|
-
}
|
|
91
|
-
) }) })
|
|
92
|
-
] });
|
|
93
123
|
}
|
|
94
124
|
function ProfileSection() {
|
|
95
|
-
const user = (0, import__.useUser)();
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
desc: "Your profile information",
|
|
103
|
-
buttonDisabled: !changed,
|
|
104
|
-
buttonText: "Save",
|
|
105
|
-
onButtonClick: async () => {
|
|
106
|
-
await user.update(userInfo);
|
|
107
|
-
setChanged(false);
|
|
108
|
-
},
|
|
109
|
-
children: [
|
|
110
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex gap-4 items-center", children: [
|
|
111
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_user_avatar.UserAvatar, { user, size: 50 }),
|
|
112
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col", children: [
|
|
113
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { children: user.displayName }),
|
|
114
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "secondary", type: "label", children: user.primaryEmail })
|
|
115
|
-
] })
|
|
116
|
-
] }),
|
|
117
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col", children: [
|
|
118
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Label, { htmlFor: "display-name", className: "mb-1", children: "Display Name" }),
|
|
119
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
120
|
-
import_stack_ui.Input,
|
|
121
|
-
{
|
|
122
|
-
id: "display-name",
|
|
123
|
-
value: userInfo.displayName,
|
|
124
|
-
onChange: (e) => {
|
|
125
|
-
setUserInfo((i) => ({ ...i, displayName: e.target.value }));
|
|
126
|
-
setChanged(true);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
)
|
|
130
|
-
] })
|
|
131
|
-
]
|
|
132
|
-
}
|
|
133
|
-
);
|
|
125
|
+
const user = (0, import__.useUser)({ or: "redirect" });
|
|
126
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
127
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Label, { children: "Display name" }),
|
|
128
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.EditableText, { value: user.displayName || "", onSave: async (newDisplayName) => {
|
|
129
|
+
await user.update({ displayName: newDisplayName });
|
|
130
|
+
} })
|
|
131
|
+
] }) });
|
|
134
132
|
}
|
|
135
133
|
function EmailVerificationSection() {
|
|
136
|
-
const user = (0, import__.useUser)();
|
|
134
|
+
const user = (0, import__.useUser)({ or: "redirect" });
|
|
137
135
|
const [emailSent, setEmailSent] = (0, import_react.useState)(false);
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
136
|
+
if (!user.primaryEmail) {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
140
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Label, { children: "Email Verification" }),
|
|
141
|
+
user.primaryEmailVerified ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "success", children: "Your email has been verified." }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
142
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "destructive", children: "Your email has not been verified." }),
|
|
143
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex mt-4", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
144
|
+
import_stack_ui.Button,
|
|
145
|
+
{
|
|
146
|
+
disabled: emailSent,
|
|
147
|
+
onClick: async () => {
|
|
148
|
+
await user.sendVerificationEmail();
|
|
149
|
+
setEmailSent(true);
|
|
150
|
+
},
|
|
151
|
+
children: emailSent ? "Email sent!" : "Send Verification Email"
|
|
152
|
+
}
|
|
153
|
+
) })
|
|
154
|
+
] })
|
|
155
|
+
] }) });
|
|
152
156
|
}
|
|
157
|
+
var passwordSchema = (0, import_schema_fields.yupObject)({
|
|
158
|
+
oldPassword: (0, import_schema_fields.yupString)().required("Please enter your old password"),
|
|
159
|
+
newPassword: (0, import_schema_fields.yupString)().required("Please enter your password").test({
|
|
160
|
+
name: "is-valid-password",
|
|
161
|
+
test: (value, ctx) => {
|
|
162
|
+
const error = (0, import_password.getPasswordError)(value);
|
|
163
|
+
if (error) {
|
|
164
|
+
return ctx.createError({ message: error.message });
|
|
165
|
+
} else {
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}),
|
|
170
|
+
newPasswordRepeat: (0, import_schema_fields.yupString)().nullable().oneOf([yup.ref("newPassword"), "", null], "Passwords do not match").required("Please repeat your password")
|
|
171
|
+
});
|
|
153
172
|
function PasswordSection() {
|
|
154
173
|
const user = (0, import__.useUser)({ or: "throw" });
|
|
155
|
-
const [
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
const [
|
|
160
|
-
const [
|
|
161
|
-
const
|
|
174
|
+
const [changingPassword, setChangingPassword] = (0, import_react.useState)(false);
|
|
175
|
+
const { register, handleSubmit, setError, formState: { errors }, clearErrors, reset } = (0, import_react_hook_form.useForm)({
|
|
176
|
+
resolver: (0, import_yup.yupResolver)(passwordSchema)
|
|
177
|
+
});
|
|
178
|
+
const [alreadyReset, setAlreadyReset] = (0, import_react.useState)(false);
|
|
179
|
+
const [loading, setLoading] = (0, import_react.useState)(false);
|
|
180
|
+
const onSubmit = async (data) => {
|
|
181
|
+
setLoading(true);
|
|
182
|
+
try {
|
|
183
|
+
const { oldPassword, newPassword } = data;
|
|
184
|
+
const error = await user.updatePassword({ oldPassword, newPassword });
|
|
185
|
+
if (error) {
|
|
186
|
+
setError("oldPassword", { type: "manual", message: "Incorrect password" });
|
|
187
|
+
} else {
|
|
188
|
+
reset();
|
|
189
|
+
setAlreadyReset(true);
|
|
190
|
+
}
|
|
191
|
+
} finally {
|
|
192
|
+
setLoading(false);
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
const registerPassword = register("newPassword");
|
|
196
|
+
const registerPasswordRepeat = register("newPasswordRepeat");
|
|
162
197
|
if (!user.hasPassword) {
|
|
163
198
|
return null;
|
|
164
199
|
}
|
|
165
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
166
|
-
|
|
167
|
-
{
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
setRepeatNewPasswordError("Please repeat your new password");
|
|
184
|
-
return;
|
|
185
|
-
} else {
|
|
186
|
-
const errorMessage = (0, import_password.getPasswordError)(newPassword);
|
|
187
|
-
if (errorMessage) {
|
|
188
|
-
setNewPasswordError(errorMessage.message);
|
|
189
|
-
} else {
|
|
190
|
-
if (newPassword !== repeatNewPassword) {
|
|
191
|
-
setRepeatNewPasswordError("Passwords do not match");
|
|
192
|
-
return;
|
|
193
|
-
}
|
|
194
|
-
const errorCode = await user.updatePassword({ oldPassword, newPassword });
|
|
195
|
-
if (errorCode) {
|
|
196
|
-
setOldPasswordError("Incorrect password");
|
|
197
|
-
} else {
|
|
198
|
-
setOldPassword("");
|
|
199
|
-
setNewPassword("");
|
|
200
|
-
setRepeatNewPassword("");
|
|
201
|
-
setPasswordChanged(true);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
},
|
|
206
|
-
children: [
|
|
207
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col", children: [
|
|
208
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Label, { htmlFor: "old-password", className: "mb-1", children: "Old Password" }),
|
|
200
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
201
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Label, { children: "Change password" }),
|
|
202
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: alreadyReset ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "success", children: "Password changed successfully!" }) : !changingPassword ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
203
|
+
import_stack_ui.Button,
|
|
204
|
+
{
|
|
205
|
+
variant: "secondary",
|
|
206
|
+
onClick: async () => {
|
|
207
|
+
setChangingPassword(true);
|
|
208
|
+
},
|
|
209
|
+
children: "Change Password"
|
|
210
|
+
}
|
|
211
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
212
|
+
"form",
|
|
213
|
+
{
|
|
214
|
+
onSubmit: (e) => (0, import_promises.runAsynchronouslyWithAlert)(handleSubmit(onSubmit)(e)),
|
|
215
|
+
noValidate: true,
|
|
216
|
+
children: [
|
|
217
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Label, { htmlFor: "old-password", className: "mb-1", children: "Old password" }),
|
|
209
218
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
210
|
-
import_stack_ui.
|
|
219
|
+
import_stack_ui.Input,
|
|
211
220
|
{
|
|
212
221
|
id: "old-password",
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
setOldPassword(e.target.value);
|
|
216
|
-
setOldPasswordError("");
|
|
217
|
-
setPasswordChanged(false);
|
|
218
|
-
}
|
|
222
|
+
type: "password",
|
|
223
|
+
...register("oldPassword")
|
|
219
224
|
}
|
|
220
225
|
),
|
|
221
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_form_warning.FormWarningText, { text:
|
|
222
|
-
|
|
223
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col", children: [
|
|
224
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Label, { htmlFor: "new-password", className: "mb-1", children: "New Password" }),
|
|
226
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_form_warning.FormWarningText, { text: errors.oldPassword?.message?.toString() }),
|
|
227
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Label, { htmlFor: "new-password", className: "mt-4 mb-1", children: "Password" }),
|
|
225
228
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
226
229
|
import_stack_ui.PasswordInput,
|
|
227
230
|
{
|
|
228
231
|
id: "new-password",
|
|
229
|
-
|
|
232
|
+
...registerPassword,
|
|
230
233
|
onChange: (e) => {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
+
clearErrors("newPassword");
|
|
235
|
+
clearErrors("newPasswordRepeat");
|
|
236
|
+
(0, import_promises.runAsynchronously)(registerPassword.onChange(e));
|
|
234
237
|
}
|
|
235
238
|
}
|
|
236
239
|
),
|
|
237
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_form_warning.FormWarningText, { text:
|
|
238
|
-
|
|
239
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col", children: [
|
|
240
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Label, { htmlFor: "repeat-new-password", className: "mb-1", children: "Repeat New Password" }),
|
|
240
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_form_warning.FormWarningText, { text: errors.newPassword?.message?.toString() }),
|
|
241
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Label, { htmlFor: "repeat-password", className: "mt-4 mb-1", children: "Repeat password" }),
|
|
241
242
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
242
243
|
import_stack_ui.PasswordInput,
|
|
243
244
|
{
|
|
244
|
-
id: "repeat-
|
|
245
|
-
|
|
245
|
+
id: "repeat-password",
|
|
246
|
+
...registerPasswordRepeat,
|
|
246
247
|
onChange: (e) => {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
248
|
+
clearErrors("newPassword");
|
|
249
|
+
clearErrors("newPasswordRepeat");
|
|
250
|
+
(0, import_promises.runAsynchronously)(registerPasswordRepeat.onChange(e));
|
|
250
251
|
}
|
|
251
252
|
}
|
|
252
253
|
),
|
|
253
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_form_warning.FormWarningText, { text:
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
254
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_form_warning.FormWarningText, { text: errors.newPasswordRepeat?.message?.toString() }),
|
|
255
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Button, { type: "submit", className: "mt-6", loading, children: "Change Password" })
|
|
256
|
+
]
|
|
257
|
+
}
|
|
258
|
+
) })
|
|
259
|
+
] });
|
|
258
260
|
}
|
|
259
261
|
function MfaSection() {
|
|
260
262
|
const project = (0, import__.useStackApp)().useProject();
|
|
@@ -281,29 +283,10 @@ function MfaSection() {
|
|
|
281
283
|
setIsMaybeWrong(true);
|
|
282
284
|
});
|
|
283
285
|
}, [mfaCode, generatedSecret, handleSubmit]);
|
|
284
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
285
|
-
|
|
286
|
-
{
|
|
287
|
-
|
|
288
|
-
desc: "Secure your account with an additional layer of security.",
|
|
289
|
-
buttonVariant: "secondary",
|
|
290
|
-
buttonText: isEnabled ? "Disable" : generatedSecret ? "Cancel" : "Enable",
|
|
291
|
-
onButtonClick: async () => {
|
|
292
|
-
if (isEnabled) {
|
|
293
|
-
await user.update({
|
|
294
|
-
totpMultiFactorSecret: null
|
|
295
|
-
});
|
|
296
|
-
} else if (!generatedSecret) {
|
|
297
|
-
const secret = (0, import_crypto.generateRandomValues)(new Uint8Array(20));
|
|
298
|
-
setQrCodeUrl(await generateTotpQrCode(project, user, secret));
|
|
299
|
-
setGeneratedSecret(secret);
|
|
300
|
-
} else {
|
|
301
|
-
setGeneratedSecret(null);
|
|
302
|
-
setQrCodeUrl(null);
|
|
303
|
-
setMfaCode("");
|
|
304
|
-
}
|
|
305
|
-
},
|
|
306
|
-
children: isEnabled ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "success", children: "Multi-factor authentication is currently enabled." }) : generatedSecret ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col gap-4 items-center", children: [
|
|
286
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
287
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Label, { children: "Multi-factor Authentication" }),
|
|
288
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
289
|
+
isEnabled ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "success", children: "Multi-factor authentication is currently enabled." }) : generatedSecret ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col gap-4 items-center", children: [
|
|
307
290
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { children: "Scan this QR code with your authenticator app:" }),
|
|
308
291
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", { width: 200, height: 200, src: qrCodeUrl ?? (0, import_errors.throwErr)("TOTP QR code failed to generate"), alt: "TOTP multi-factor authentication QR code" }),
|
|
309
292
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { children: "Then, enter your six-digit MFA code:" }),
|
|
@@ -321,9 +304,32 @@ function MfaSection() {
|
|
|
321
304
|
}
|
|
322
305
|
),
|
|
323
306
|
isMaybeWrong && mfaCode.length === 6 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "destructive", children: "Incorrect code. Please try again." })
|
|
324
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "destructive", children: "Multi-factor authentication is currently disabled." })
|
|
325
|
-
|
|
326
|
-
|
|
307
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "destructive", children: "Multi-factor authentication is currently disabled." }),
|
|
308
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
309
|
+
import_stack_ui.Button,
|
|
310
|
+
{
|
|
311
|
+
className: "mt-4",
|
|
312
|
+
variant: isEnabled ? "secondary" : "default",
|
|
313
|
+
onClick: async () => {
|
|
314
|
+
if (isEnabled) {
|
|
315
|
+
await user.update({
|
|
316
|
+
totpMultiFactorSecret: null
|
|
317
|
+
});
|
|
318
|
+
} else if (!generatedSecret) {
|
|
319
|
+
const secret = (0, import_crypto.generateRandomValues)(new Uint8Array(20));
|
|
320
|
+
setQrCodeUrl(await generateTotpQrCode(project, user, secret));
|
|
321
|
+
setGeneratedSecret(secret);
|
|
322
|
+
} else {
|
|
323
|
+
setGeneratedSecret(null);
|
|
324
|
+
setQrCodeUrl(null);
|
|
325
|
+
setMfaCode("");
|
|
326
|
+
}
|
|
327
|
+
},
|
|
328
|
+
children: isEnabled ? "Disable" : generatedSecret ? "Cancel" : "Enable"
|
|
329
|
+
}
|
|
330
|
+
)
|
|
331
|
+
] })
|
|
332
|
+
] }) });
|
|
327
333
|
}
|
|
328
334
|
async function generateTotpQrCode(project, user, secret) {
|
|
329
335
|
const uri = (0, import_otp.createTOTPKeyURI)(project.displayName, user.primaryEmail ?? user.id, secret);
|
|
@@ -331,19 +337,200 @@ async function generateTotpQrCode(project, user, secret) {
|
|
|
331
337
|
}
|
|
332
338
|
function SignOutSection() {
|
|
333
339
|
const user = (0, import__.useUser)({ or: "throw" });
|
|
334
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
335
|
-
|
|
340
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex flex-col gap-2", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
341
|
+
import_stack_ui.Button,
|
|
336
342
|
{
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
buttonText: "Sign Out",
|
|
341
|
-
onButtonClick: () => user.signOut()
|
|
343
|
+
variant: "secondary",
|
|
344
|
+
onClick: () => user.signOut(),
|
|
345
|
+
children: "Sign Out"
|
|
342
346
|
}
|
|
343
|
-
);
|
|
347
|
+
) }) });
|
|
348
|
+
}
|
|
349
|
+
function UserSettings(props) {
|
|
350
|
+
const app = (0, import__.useStackApp)();
|
|
351
|
+
const user = (0, import__.useUser)({ or: "redirect" });
|
|
352
|
+
const [leaving, setLeaving] = (0, import_react.useState)(false);
|
|
353
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex flex-col gap-2", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: !leaving ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
354
|
+
import_stack_ui.Button,
|
|
355
|
+
{
|
|
356
|
+
variant: "secondary",
|
|
357
|
+
onClick: async () => setLeaving(true),
|
|
358
|
+
children: "Leave team"
|
|
359
|
+
}
|
|
360
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "", children: [
|
|
361
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { variant: "destructive", children: "Are you sure you want to leave the team?" }),
|
|
362
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex gap-2", children: [
|
|
363
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Button, { variant: "destructive", onClick: async () => {
|
|
364
|
+
await user.leaveTeam(props.team);
|
|
365
|
+
window.location.reload();
|
|
366
|
+
}, children: "Leave" }),
|
|
367
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Button, { variant: "secondary", onClick: () => setLeaving(false), children: "Cancel" })
|
|
368
|
+
] })
|
|
369
|
+
] }) }) });
|
|
370
|
+
}
|
|
371
|
+
function ManagementSettings(props) {
|
|
372
|
+
const user = (0, import__.useUser)({ or: "redirect" });
|
|
373
|
+
const updateTeamPermission = user.usePermission(props.team, "$update_team");
|
|
374
|
+
if (!updateTeamPermission) {
|
|
375
|
+
return null;
|
|
376
|
+
}
|
|
377
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
378
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Label, { children: "Team display name" }),
|
|
379
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
380
|
+
import_stack_ui.EditableText,
|
|
381
|
+
{
|
|
382
|
+
value: props.team.displayName,
|
|
383
|
+
onSave: async (newDisplayName) => await props.team.update({ displayName: newDisplayName })
|
|
384
|
+
}
|
|
385
|
+
)
|
|
386
|
+
] }) });
|
|
387
|
+
}
|
|
388
|
+
function ProfileSettings(props) {
|
|
389
|
+
const user = (0, import__.useUser)({ or: "redirect" });
|
|
390
|
+
const profile = user.useTeamProfile(props.team);
|
|
391
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex flex-col", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col", children: [
|
|
392
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_stack_ui.Label, { className: "flex gap-2", children: [
|
|
393
|
+
"User display name ",
|
|
394
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.SimpleTooltip, { tooltip: "This overwrites your user display name in the account setting", type: "info" })
|
|
395
|
+
] }),
|
|
396
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
397
|
+
import_stack_ui.EditableText,
|
|
398
|
+
{
|
|
399
|
+
value: profile.displayName || "",
|
|
400
|
+
onSave: async (newDisplayName) => {
|
|
401
|
+
await profile.update({ displayName: newDisplayName });
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
)
|
|
405
|
+
] }) });
|
|
406
|
+
}
|
|
407
|
+
var invitationSchema = (0, import_schema_fields.yupObject)({
|
|
408
|
+
email: (0, import_schema_fields.yupString)().email().required("Please enter an email address")
|
|
409
|
+
});
|
|
410
|
+
function MemberInvitation(props) {
|
|
411
|
+
const project = (0, import__.useStackApp)().useProject();
|
|
412
|
+
if (!project.config.clientTeamCreationEnabled) {
|
|
413
|
+
return null;
|
|
414
|
+
}
|
|
415
|
+
const { register, handleSubmit, formState: { errors }, watch } = (0, import_react_hook_form.useForm)({
|
|
416
|
+
resolver: (0, import_yup.yupResolver)(invitationSchema)
|
|
417
|
+
});
|
|
418
|
+
const [loading, setLoading] = (0, import_react.useState)(false);
|
|
419
|
+
const [invitedEmail, setInvitedEmail] = (0, import_react.useState)(null);
|
|
420
|
+
const onSubmit = async (data) => {
|
|
421
|
+
setLoading(true);
|
|
422
|
+
try {
|
|
423
|
+
await props.team.inviteUser({ email: data.email });
|
|
424
|
+
setInvitedEmail(data.email);
|
|
425
|
+
} finally {
|
|
426
|
+
setLoading(false);
|
|
427
|
+
}
|
|
428
|
+
};
|
|
429
|
+
(0, import_react.useEffect)(() => {
|
|
430
|
+
setInvitedEmail(null);
|
|
431
|
+
}, [watch("email")]);
|
|
432
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
433
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Label, { children: "Invite a user to team" }),
|
|
434
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
435
|
+
"form",
|
|
436
|
+
{
|
|
437
|
+
onSubmit: (e) => (0, import_promises.runAsynchronouslyWithAlert)(handleSubmit(onSubmit)(e)),
|
|
438
|
+
noValidate: true,
|
|
439
|
+
children: [
|
|
440
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col gap-4 md:flex-row", children: [
|
|
441
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
442
|
+
import_stack_ui.Input,
|
|
443
|
+
{
|
|
444
|
+
placeholder: "Email",
|
|
445
|
+
...register("email")
|
|
446
|
+
}
|
|
447
|
+
) }),
|
|
448
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Button, { type: "submit", loading, children: "Invite User" })
|
|
449
|
+
] }),
|
|
450
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_form_warning.FormWarningText, { text: errors.email?.message?.toString() }),
|
|
451
|
+
invitedEmail && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_stack_ui.Typography, { type: "label", variant: "secondary", children: [
|
|
452
|
+
"Invited ",
|
|
453
|
+
invitedEmail
|
|
454
|
+
] })
|
|
455
|
+
]
|
|
456
|
+
}
|
|
457
|
+
)
|
|
458
|
+
] });
|
|
459
|
+
}
|
|
460
|
+
function MembersSettings(props) {
|
|
461
|
+
const user = (0, import__.useUser)({ or: "redirect" });
|
|
462
|
+
const readMemberPermission = user.usePermission(props.team, "$read_members");
|
|
463
|
+
const inviteMemberPermission = user.usePermission(props.team, "$invite_members");
|
|
464
|
+
if (!readMemberPermission && !inviteMemberPermission) {
|
|
465
|
+
return null;
|
|
466
|
+
}
|
|
467
|
+
const users = props.team.useUsers();
|
|
468
|
+
if (!readMemberPermission) {
|
|
469
|
+
return null;
|
|
470
|
+
}
|
|
471
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
472
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Label, { children: "Members" }),
|
|
473
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_stack_ui.Table, { children: [
|
|
474
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.TableHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_stack_ui.TableRow, { children: [
|
|
475
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.TableHead, { className: "w-[100px]", children: "User" }),
|
|
476
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.TableHead, { className: "w-[200px]", children: "Name" })
|
|
477
|
+
] }) }),
|
|
478
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.TableBody, { children: users.map(({ id, teamProfile }, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_stack_ui.TableRow, { children: [
|
|
479
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_user_avatar.UserAvatar, { user: teamProfile }) }),
|
|
480
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Typography, { children: teamProfile.displayName }) })
|
|
481
|
+
] }, id)) })
|
|
482
|
+
] })
|
|
483
|
+
] });
|
|
484
|
+
}
|
|
485
|
+
var teamCreationSchema = (0, import_schema_fields.yupObject)({
|
|
486
|
+
displayName: (0, import_schema_fields.yupString)().required("Please enter a team name")
|
|
487
|
+
});
|
|
488
|
+
function TeamCreation() {
|
|
489
|
+
const { register, handleSubmit, formState: { errors } } = (0, import_react_hook_form.useForm)({
|
|
490
|
+
resolver: (0, import_yup.yupResolver)(teamCreationSchema)
|
|
491
|
+
});
|
|
492
|
+
const app = (0, import__.useStackApp)();
|
|
493
|
+
const project = app.useProject();
|
|
494
|
+
const user = (0, import__.useUser)({ or: "redirect" });
|
|
495
|
+
const [loading, setLoading] = (0, import_react.useState)(false);
|
|
496
|
+
if (!project.config.clientTeamCreationEnabled) {
|
|
497
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import__.MessageCard, { title: "Team creation is not enabled" });
|
|
498
|
+
}
|
|
499
|
+
const onSubmit = async (data) => {
|
|
500
|
+
setLoading(true);
|
|
501
|
+
try {
|
|
502
|
+
const team = await user.createTeam({ displayName: data.displayName });
|
|
503
|
+
} finally {
|
|
504
|
+
setLoading(false);
|
|
505
|
+
}
|
|
506
|
+
};
|
|
507
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "stack-scope flex flex-col items-stretch", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mb-6", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
508
|
+
"form",
|
|
509
|
+
{
|
|
510
|
+
className: "flex flex-col items-stretch stack-scope",
|
|
511
|
+
onSubmit: (e) => (0, import_promises.runAsynchronouslyWithAlert)(handleSubmit(onSubmit)(e)),
|
|
512
|
+
noValidate: true,
|
|
513
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-end gap-4", children: [
|
|
514
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
515
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Label, { htmlFor: "email", className: "mb-1", children: "Display name" }),
|
|
516
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
517
|
+
import_stack_ui.Input,
|
|
518
|
+
{
|
|
519
|
+
id: "email",
|
|
520
|
+
type: "email",
|
|
521
|
+
...register("displayName")
|
|
522
|
+
}
|
|
523
|
+
)
|
|
524
|
+
] }),
|
|
525
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_form_warning.FormWarningText, { text: errors.displayName?.message?.toString() }),
|
|
526
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stack_ui.Button, { type: "submit", className: "mt-6", loading, children: "Create" })
|
|
527
|
+
] })
|
|
528
|
+
}
|
|
529
|
+
) }) });
|
|
344
530
|
}
|
|
345
531
|
// Annotate the CommonJS export names for ESM import in node:
|
|
346
532
|
0 && (module.exports = {
|
|
347
|
-
AccountSettings
|
|
533
|
+
AccountSettings,
|
|
534
|
+
TeamCreation
|
|
348
535
|
});
|
|
349
536
|
//# sourceMappingURL=account-settings.js.map
|