added create user button (#173)

This commit is contained in:
Zai Shi 2024-08-08 13:50:38 -07:00 committed by Konstantin Wohlwend
parent 2ca5150b07
commit fc9826aaa2
3 changed files with 86 additions and 2 deletions

View File

@ -1,18 +1,62 @@
"use client";
import { UserTable } from "@/components/data-table/user-table";
import { FormDialog } from "@/components/form-dialog";
import { InputField, SwitchField } from "@/components/form-fields";
import { StyledLink } from "@/components/link";
import { Alert } from "@stackframe/stack-ui";
import { Alert, Button } from "@stackframe/stack-ui";
import * as yup from "yup";
import { PageLayout } from "../page-layout";
import { useAdminApp } from "../use-admin-app";
function CreateDialog(props: {
open?: boolean,
onOpenChange?: (open: boolean) => void,
trigger?: React.ReactNode,
}) {
const adminApp = useAdminApp();
const formSchema = yup.object({
displayName: yup.string().optional(),
primaryEmail: yup.string().email().required(),
primaryEmailVerified: yup.boolean().optional(),
password: yup.string().required(),
});
return <FormDialog
trigger={props.trigger}
title={"Create User"}
formSchema={formSchema}
okButton={{ label: "Create" }}
onSubmit={async (values) => {
await adminApp.createUser(values);
}}
cancelButton
render={(form) => (
<>
<InputField control={form.control} label="Display Name" name="displayName" />
<div className="flex gap-4 items-end">
<div className="flex-1">
<InputField control={form.control} label="Primary Email" name="primaryEmail" required />
</div>
<div className="mb-2">
<SwitchField control={form.control} label="Verified" name="primaryEmailVerified" />
</div>
</div>
<InputField control={form.control} label="Password" name="password" type="password" required />
</>
)}
/>;
}
export default function PageClient() {
const stackAdminApp = useAdminApp();
const allUsers = stackAdminApp.useUsers();
return (
<PageLayout title="Users">
<PageLayout title="Users" actions={<CreateDialog trigger={<Button>Create User</Button>} />}>
{allUsers.length > 0 ? null : (
<Alert variant='success'>
Congratulations on starting your project! Check the <StyledLink href="https://docs.stack-auth.com">documentation</StyledLink> to add your first users.

View File

@ -72,6 +72,21 @@ export class StackServerInterface extends StackClientInterface {
}
}
async createServerUser(data: UsersCrud['Server']['Create']): Promise<UsersCrud['Server']['Read']> {
const response = await this.sendServerRequest(
"/users",
{
method: "POST",
headers: {
"content-type": "application/json",
},
body: JSON.stringify(data),
},
null,
);
return await response.json();
}
async getServerUserByToken(session: InternalSession): Promise<CurrentUserCrud['Server']['Read'] | null> {
const responseOrError = await this.sendServerRequestAndCatchKnownError(
"/users/me",

View File

@ -1568,6 +1568,12 @@ class _StackServerAppImpl<HasTokenStore extends boolean, ProjectId extends strin
};
}
async createUser(options: ServerUserCreateOptions): Promise<ServerUser> {
const crud = await this._interface.createServerUser(serverUserCreateOptionsToCrud(options));
await this._refreshUsers();
return this._serverUserFromCrud(crud);
}
async getUser(options: GetUserOptions<HasTokenStore> & { or: 'redirect' }): Promise<ProjectCurrentServerUser<ProjectId>>;
async getUser(options: GetUserOptions<HasTokenStore> & { or: 'throw' }): Promise<ProjectCurrentServerUser<ProjectId>>;
@ -2236,6 +2242,23 @@ function serverUserUpdateOptionsToCrud(options: ServerUserUpdateOptions): Curren
}
type ServerUserCreateOptions = {
primaryEmail: string,
password: string,
displayName?: string,
primaryEmailVerified?: boolean,
}
function serverUserCreateOptionsToCrud(options: ServerUserCreateOptions): UsersCrud["Server"]["Create"] {
return {
primary_email: options.primaryEmail,
password: options.password,
primary_email_auth_enabled: true,
display_name: options.displayName,
primary_email_verified: options.primaryEmailVerified,
};
}
type _______________PROJECT_______________ = never; // this is a marker for VSCode's outline view
export type Project = {
@ -2616,6 +2639,8 @@ export type StackServerApp<HasTokenStore extends boolean = boolean, ProjectId ex
*/
getServerUser(): Promise<ProjectCurrentServerUser<ProjectId> | null>,
createUser(options: ServerUserCreateOptions): Promise<ServerUser>,
useUser(options: GetUserOptions<HasTokenStore> & { or: 'redirect' }): ProjectCurrentServerUser<ProjectId>,
useUser(options: GetUserOptions<HasTokenStore> & { or: 'throw' }): ProjectCurrentServerUser<ProjectId>,
useUser(options?: GetUserOptions<HasTokenStore>): ProjectCurrentServerUser<ProjectId> | null,