263 lines
6.1 KiB
JavaScript

import PropTypes from 'prop-types'
import { useState, useEffect } from 'react'
import axios from 'axios'
import { useMediaQuery } from 'react-responsive'
import {
Form,
Input,
Button,
Typography,
Flex,
Steps,
Descriptions,
Divider
} from 'antd'
import { useMessageContext } from '../../context/MessageContext'
import config from '../../../../config'
const { Title } = Typography
const initialNewUserForm = {
username: '',
name: '',
firstName: '',
lastName: '',
email: ''
}
const NewUser = ({ onOk, reset }) => {
const { showError } = useMessageContext()
const [newUserLoading, setNewUserLoading] = useState(false)
const [currentStep, setCurrentStep] = useState(0)
const [nextEnabled, setNextEnabled] = useState(false)
const [newUserForm] = Form.useForm()
const [newUserFormValues, setNewUserFormValues] = useState(initialNewUserForm)
const isMobile = useMediaQuery({ maxWidth: 768 })
const newUserFormUpdateValues = Form.useWatch([], newUserForm)
useEffect(() => {
newUserForm
.validateFields({
validateOnly: true
})
.then(() => setNextEnabled(true))
.catch(() => setNextEnabled(false))
}, [newUserForm, newUserFormUpdateValues])
const summaryItems = [
{
key: 'username',
label: 'Username',
children: newUserFormValues.username
},
{
key: 'name',
label: 'Full Name',
children: newUserFormValues.name || 'n/a'
},
{
key: 'firstName',
label: 'First Name',
children: newUserFormValues.firstName || 'n/a'
},
{
key: 'lastName',
label: 'Last Name',
children: newUserFormValues.lastName || 'n/a'
},
{
key: 'email',
label: 'Email',
children: newUserFormValues.email || 'n/a'
}
]
useEffect(() => {
if (reset) {
newUserForm.resetFields()
}
}, [reset, newUserForm])
const handleNewUser = async () => {
setNewUserLoading(true)
try {
await axios.post(`${config.backendUrl}/users`, newUserFormValues, {
withCredentials: true
})
onOk()
} catch (error) {
showError('Error creating new user: ' + error.message)
} finally {
setNewUserLoading(false)
}
}
const steps = [
{
title: 'Details',
key: 'details',
content: (
<>
<Form.Item
label='Username'
name='username'
rules={[
{
required: true,
message: 'Please enter a username.'
},
{
min: 3,
message: 'Username must be at least 3 characters.'
}
]}
>
<Input />
</Form.Item>
<Form.Item
label='Full Name'
name='name'
rules={[
{
required: true,
message: 'Please enter a full name.'
}
]}
>
<Input />
</Form.Item>
<Form.Item
label='First Name'
name='firstName'
rules={[
{
required: true,
message: 'Please enter a first name.'
}
]}
>
<Input />
</Form.Item>
<Form.Item
label='Last Name'
name='lastName'
rules={[
{
required: true,
message: 'Please enter a last name.'
}
]}
>
<Input />
</Form.Item>
<Form.Item
label='Email'
name='email'
style={{ marginBottom: 8 }}
rules={[
{
required: true,
message: 'Please enter an email address.'
},
{
type: 'email',
message: 'Please enter a valid email address.'
}
]}
>
<Input />
</Form.Item>
</>
)
},
{
title: 'Summary',
key: 'summary',
content: <Descriptions column={1} items={summaryItems} size={'small'} />
}
]
return (
<Flex gap='middle'>
{!isMobile && (
<div style={{ minWidth: '160px' }}>
<Steps
current={currentStep}
items={steps}
direction='vertical'
style={{ width: 'fit-content' }}
/>
</div>
)}
{!isMobile && <Divider type='vertical' style={{ height: 'unset' }} />}
<Flex vertical gap='middle' style={{ flexGrow: 1 }}>
<Title level={2} style={{ marginTop: 0, marginBottom: 4 }}>
New User
</Title>
<Form
name='basic'
autoComplete='off'
form={newUserForm}
onFinish={handleNewUser}
onValuesChange={(changedValues) =>
setNewUserFormValues((prevValues) => ({
...prevValues,
...changedValues
}))
}
initialValues={initialNewUserForm}
>
<div style={{ minHeight: '260px' }}>{steps[currentStep].content}</div>
</Form>
<Flex justify='end'>
<Button
style={{ margin: '0 8px' }}
onClick={() => {
setCurrentStep((prev) => prev - 1)
setNextEnabled(true)
}}
disabled={currentStep === 0}
>
Previous
</Button>
{currentStep < steps.length - 1 ? (
<Button
type='primary'
disabled={!nextEnabled}
onClick={() => {
setCurrentStep((prev) => prev + 1)
setNextEnabled(false)
}}
>
Next
</Button>
) : (
<Button
type='primary'
loading={newUserLoading}
onClick={() => {
newUserForm.submit()
}}
>
Done
</Button>
)}
</Flex>
</Flex>
</Flex>
)
}
NewUser.propTypes = {
onOk: PropTypes.func.isRequired,
reset: PropTypes.bool
}
export default NewUser