Files
Homarr/src/pages/manage/users/create.tsx
Meier Lukas df890b8c0a 💄 Polish layouts
2023-08-01 01:13:21 +02:00

214 lines
6.3 KiB
TypeScript

import { Alert, Button, Card, Flex, Group, Stepper, Table, Text, Title } from '@mantine/core';
import { useForm, zodResolver } from '@mantine/form';
import {
IconArrowLeft,
IconCheck,
IconInfoCircle,
IconKey,
IconMail,
IconMailCheck,
IconUser,
IconUserPlus,
} from '@tabler/icons-react';
import Head from 'next/head';
import Link from 'next/link';
import { useState } from 'react';
import { z } from 'zod';
import {
CreateAccountStep,
createAccountStepValidationSchema,
} from '~/components/Admin/CreateNewUser/create-account-step';
import {
CreateAccountSecurityStep,
createAccountSecurityStepValidationSchema,
} from '~/components/Admin/CreateNewUser/security-step';
import { ManageLayout } from '~/components/layout/Templates/ManageLayout';
import { api } from '~/utils/api';
const CreateNewUserPage = () => {
const [active, setActive] = useState(0);
const nextStep = () => setActive((current) => (current < 3 ? current + 1 : current));
const prevStep = () => setActive((current) => (current > 0 ? current - 1 : current));
const form = useForm({
initialValues: {
account: {
username: '',
eMail: '',
},
security: {
password: '',
},
},
validate: zodResolver(
z.object({
account: createAccountStepValidationSchema,
security: createAccountSecurityStepValidationSchema,
})
),
});
const context = api.useContext();
const { mutateAsync, isLoading } = api.user.createUser.useMutation({
onSettled: () => {
void context.user.getAll.invalidate();
},
onSuccess: () => {
nextStep();
},
});
return (
<ManageLayout>
<Head>
<title>Create user Homarr</title>
</Head>
<Stepper active={active} onStepClick={setActive} breakpoint="sm" mih="100%">
<Stepper.Step
allowStepClick={false}
allowStepSelect={false}
icon={<IconUser />}
label="First step"
description="Create account"
>
<CreateAccountStep
nextStep={(value) => {
form.setFieldValue('account', value);
nextStep();
}}
/>
</Stepper.Step>
<Stepper.Step
allowStepClick={false}
allowStepSelect={false}
icon={<IconKey />}
label="Second step"
description="Password"
>
<CreateAccountSecurityStep
nextStep={(value) => {
form.setFieldValue('security', value);
nextStep();
}}
prevStep={prevStep}
/>
</Stepper.Step>
<Stepper.Step
allowStepClick={false}
allowStepSelect={false}
icon={<IconMailCheck />}
label="Final step"
description="Save to database"
>
<Card mih={400}>
<Title order={5}>Review your inputs</Title>
<Text mb="xl">
After you submit your data to the database, the user will be able to log in. Are you
sure that you want to store this user in the database and activate the login?
</Text>
<Table mb="lg" withBorder highlightOnHover>
<thead>
<tr>
<th>Property</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<Group spacing="xs">
<IconUser size="1rem" />
<Text>Username</Text>
</Group>
</td>
<td>{form.values.account.username}</td>
</tr>
<tr>
<td>
<Group spacing="xs">
<IconMail size="1rem" />
<Text>E-Mail</Text>
</Group>
</td>
<td>
{form.values.account.eMail ? (
<Text>{form.values.account.eMail}</Text>
) : (
<Group spacing="xs">
<IconInfoCircle size="1rem" color="orange" />
<Text color="orange">Not set</Text>
</Group>
)}
</td>
</tr>
<tr>
<td>
<Group spacing="xs">
<IconKey size="1rem" />
<Text>Password</Text>
</Group>
</td>
<td>
<Group spacing="xs">
<IconCheck size="1rem" color="green" />
<Text color="green">Valid</Text>
</Group>
</td>
</tr>
</tbody>
</Table>
<Flex justify="end" wrap="nowrap">
<Button
onClick={async () => {
await mutateAsync({
username: form.values.account.username,
password: form.values.security.password,
email: form.values.account.eMail === '' ? undefined : form.values.account.eMail,
});
}}
loading={isLoading}
rightIcon={<IconCheck size="1rem" />}
variant="light"
px="xl"
>
Confirm
</Button>
</Flex>
</Card>
</Stepper.Step>
<Stepper.Completed>
<Alert title="User was created" color="green" mb="md">
User has been created in the database. They can now log in.
</Alert>
<Group>
<Button
onClick={() => {
form.reset();
setActive(0);
}}
leftIcon={<IconUserPlus size="1rem" />}
variant="default"
>
Create another
</Button>
<Button
component={Link}
leftIcon={<IconArrowLeft size="1rem" />}
variant="default"
href="/manage/users"
>
Go back to users
</Button>
</Group>
</Stepper.Completed>
</Stepper>
</ManageLayout>
);
};
export default CreateNewUserPage;