190 lines
6.5 KiB
TypeScript
190 lines
6.5 KiB
TypeScript
import Input from "@/twui/components/form/Input";
|
|
import Button from "@/twui/components/layout/Button";
|
|
import Stack from "@/twui/components/layout/Stack";
|
|
import useSignupForm from "../(hooks)/use-signup-form";
|
|
import fetchApi from "@/twui/components/utils/fetch/fetchApi";
|
|
import { APIReqObject } from "@/src/types";
|
|
import { APIResponseObject } from "@moduletrace/datasquirel/dist/package-shared/types";
|
|
import { useEffect } from "react";
|
|
import { NSQLITE_TURBOCI_ADMIN_USERS } from "@/src/db/types";
|
|
|
|
type Props = {
|
|
new_deployment_user?: boolean;
|
|
existing_user?: NSQLITE_TURBOCI_ADMIN_USERS;
|
|
};
|
|
|
|
export default function SignupForm({
|
|
new_deployment_user,
|
|
existing_user,
|
|
}: Props) {
|
|
const {
|
|
newUser,
|
|
setNewUser,
|
|
loading,
|
|
setLoading,
|
|
isPasswordConfirmed,
|
|
setIsPasswordConfirmed,
|
|
pageProps,
|
|
} = useSignupForm({ new_deployment_user, existing_user });
|
|
|
|
const is_password_valid = Boolean(
|
|
isPasswordConfirmed &&
|
|
Boolean(newUser.password?.match(/./)) &&
|
|
Boolean(newUser.confirmed_password?.match(/./)),
|
|
);
|
|
|
|
return (
|
|
<form
|
|
onSubmit={(e) => {
|
|
e.preventDefault();
|
|
}}
|
|
>
|
|
<Stack className="w-full items-stretch gap-6">
|
|
<Input
|
|
placeholder="Eg. John"
|
|
title="First Name"
|
|
changeHandler={(v) => {
|
|
setNewUser((prev) => ({
|
|
...prev,
|
|
first_name: v,
|
|
}));
|
|
}}
|
|
required
|
|
showLabel
|
|
/>
|
|
<Input
|
|
placeholder="Eg. Doe"
|
|
title="Last Name"
|
|
changeHandler={(v) => {
|
|
setNewUser((prev) => ({
|
|
...prev,
|
|
last_name: v,
|
|
}));
|
|
}}
|
|
showLabel
|
|
/>
|
|
<Input
|
|
placeholder="Email Address"
|
|
title="Email"
|
|
type="email"
|
|
changeHandler={(v) => {
|
|
setNewUser((prev) => ({
|
|
...prev,
|
|
email: v,
|
|
}));
|
|
}}
|
|
required
|
|
showLabel
|
|
/>
|
|
{pageProps.user.id ? (
|
|
<Input
|
|
placeholder="Username"
|
|
title="Username"
|
|
changeHandler={(v) => {
|
|
setNewUser((prev) => ({
|
|
...prev,
|
|
username: v,
|
|
}));
|
|
}}
|
|
validationRegex={/^[a-z0-9\-]{3,}$/}
|
|
info={
|
|
<>
|
|
Allowed characters:{" "}
|
|
<code>
|
|
<b>a-z, 0-9, -</b>
|
|
</code>
|
|
.
|
|
</>
|
|
}
|
|
wrapperWrapperProps={{
|
|
className: "items-start!",
|
|
}}
|
|
required
|
|
showLabel
|
|
/>
|
|
) : null}
|
|
<Input
|
|
placeholder="Password"
|
|
title="Password"
|
|
type="password"
|
|
changeHandler={(v) => {
|
|
setNewUser((prev) => ({
|
|
...prev,
|
|
password: v,
|
|
}));
|
|
}}
|
|
validity={{
|
|
isValid:
|
|
!Boolean(newUser.password?.match(/./)) ||
|
|
!Boolean(newUser.confirmed_password?.match(/./))
|
|
? true
|
|
: is_password_valid,
|
|
msg: `Passwords don't match`,
|
|
}}
|
|
required
|
|
showLabel
|
|
/>
|
|
<Input
|
|
placeholder="Confirm Password"
|
|
title="Confirm Password"
|
|
type="password"
|
|
changeHandler={(v) => {
|
|
setNewUser((prev) => ({
|
|
...prev,
|
|
confirmed_password: v,
|
|
}));
|
|
|
|
setIsPasswordConfirmed(v == newUser.password);
|
|
}}
|
|
showLabel
|
|
/>
|
|
<Button
|
|
title="Login"
|
|
onClick={() => {
|
|
if (!is_password_valid) {
|
|
return;
|
|
}
|
|
|
|
const confirm_msg = pageProps.user.id
|
|
? `Add New User?`
|
|
: `Create Super Admin Account?`;
|
|
|
|
if (!window.confirm(confirm_msg)) {
|
|
return;
|
|
}
|
|
|
|
setLoading(true);
|
|
|
|
fetchApi<APIReqObject, APIResponseObject>(
|
|
`/api/auth/signup`,
|
|
{
|
|
method: "POST",
|
|
body: {
|
|
new_user: newUser,
|
|
},
|
|
},
|
|
)
|
|
.then((res) => {
|
|
if (res.success) {
|
|
if (pageProps.user.id) {
|
|
window.location.pathname = `/admin/users`;
|
|
} else {
|
|
window.location.reload();
|
|
}
|
|
}
|
|
})
|
|
.finally(() => {});
|
|
}}
|
|
loading={loading}
|
|
>
|
|
{existing_user?.id
|
|
? ``
|
|
: pageProps.user.super_admin
|
|
? "Add User"
|
|
: "Signup"}
|
|
</Button>
|
|
</Stack>
|
|
</form>
|
|
);
|
|
}
|