-
Björn Modée authoredBjörn Modée authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
AddUser.tsx 8.30 KiB
/** Add a user component */
import { Button, FormControl, InputLabel, MenuItem, Popover, TextField } from '@material-ui/core'
import PersonAddIcon from '@material-ui/icons/PersonAdd'
import { Alert, AlertTitle } from '@material-ui/lab'
import axios from 'axios'
import { Formik, FormikHelpers } from 'formik'
import React from 'react'
import * as Yup from 'yup'
import { getSearchUsers } from '../../../actions/searchUser'
import { useAppDispatch, useAppSelector } from '../../../hooks'
import { City, Role } from '../../../interfaces/ApiModels'
import { AddUserModel, FormModel } from '../../../interfaces/FormModels'
import { AddButton, AddContent, AddForm } from '../styledComp'
type formType = FormModel<AddUserModel>
const noRoleSelected = 'Välj roll'
const noCitySelected = 'Välj stad'
/** Form when adding a user with some constraints */
const userSchema: Yup.SchemaOf<formType> = Yup.object({
model: Yup.object()
.shape({
name: Yup.string(),
email: Yup.string().email().required('Email krävs'),
password: Yup.string()
.required('Lösenord krävs.')
.min(6, 'Lösenord måste vara minst 6 tecken.')
.matches(/[a-zA-Z]/, 'Lösenord får enbart innehålla a-z, A-Z.'),
role: Yup.string().required('Roll krävs').notOneOf([noCitySelected], 'Välj en roll'),
city: Yup.string().required('Stad krävs').notOneOf([noRoleSelected], 'Välj en stad'),
})
.required(),
error: Yup.string().optional(),
})
const AddUser: React.FC = (props: any) => {
const [anchorEl, setAnchorEl] = React.useState<HTMLButtonElement | null>(null)
const [selectedRole, setSelectedRole] = React.useState<Role | undefined>()
const roles = useAppSelector((state) => state.roles.roles)
const [selectedCity, setSelectedCity] = React.useState<City | undefined>()
const cities = useAppSelector((state) => state.cities.cities)
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
setAnchorEl(event.currentTarget)
}
const handleClose = () => {
setAnchorEl(null)
}
const open = Boolean(anchorEl)
const dispatch = useAppDispatch()
const id = open ? 'simple-popover' : undefined
const handleSubmit = async (values: formType, actions: FormikHelpers<formType>) => {
const params = {
email: values.model.email,
password: values.model.password,
//name: values.model.name,
city_id: selectedCity?.id as number,
role_id: selectedRole?.id as number,
}
await axios
.post('/api/auth/signup', params)
.then(() => {
actions.resetForm()
setAnchorEl(null)
dispatch(getSearchUsers())
setSelectedCity(undefined)
setSelectedRole(undefined)
})
.catch(({ response }) => {
console.warn(response.data)
if (response.data && response.data.message)
actions.setFieldError('error', response.data && response.data.message)
else actions.setFieldError('error', 'Something went wrong, please try again')
})
.finally(() => {
actions.setSubmitting(false)
})
}
const userInitialValues: formType = {
model: { email: '', password: '', name: '', city: noCitySelected, role: noRoleSelected },
}
return (
<div>
<AddButton
style={{ backgroundColor: '#4caf50', color: '#fcfcfc' }}
color="default"
variant="contained"
onClick={handleClick}
endIcon={<PersonAddIcon></PersonAddIcon>}
>
Ny Användare
</AddButton>
<Popover
id={id}
open={open}
anchorEl={anchorEl}
onClose={handleClose}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'center',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'center',
}}
>
<AddContent>
<Formik initialValues={userInitialValues} validationSchema={userSchema} onSubmit={handleSubmit}>
{(formik) => (
<AddForm onSubmit={formik.handleSubmit}>
<TextField
label="Email"
name="model.email"
helperText={formik.touched.model?.email ? formik.errors.model?.email : ''}
error={Boolean(formik.touched.model?.email && formik.errors.model?.email)}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
margin="normal"
/>
<TextField
label="Lösenord"
name="model.password"
helperText={formik.touched.model?.password ? formik.errors.model?.password : ''}
error={Boolean(formik.touched.model?.password && formik.errors.model?.password)}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
margin="normal"
/>
<TextField
label="Namn"
name="model.name"
helperText={formik.touched.model?.name ? formik.errors.model?.name : ''}
error={Boolean(formik.touched.model?.name && formik.errors.model?.name)}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
margin="normal"
/>
<FormControl>
<InputLabel shrink id="demo-customized-select-native">
Region
</InputLabel>
<TextField
select
name="model.city"
id="standard-select-currency"
value={selectedCity ? selectedCity.name : noCitySelected}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
error={Boolean(formik.errors.model?.city && formik.touched.model?.city)}
helperText={formik.touched.model?.city && formik.errors.model?.city}
margin="normal"
>
<MenuItem value={noCitySelected} onClick={() => setSelectedCity(undefined)}>
{noCitySelected}
</MenuItem>
{cities &&
cities.map((city) => (
<MenuItem key={city.name} value={city.name} onClick={() => setSelectedCity(city)}>
{city.name}
</MenuItem>
))}
</TextField>
</FormControl>
<FormControl>
<InputLabel shrink id="demo-customized-select-native">
Roll
</InputLabel>
<TextField
select
name="model.role"
id="standard-select-currency"
value={selectedRole ? selectedRole.name : noRoleSelected}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
error={Boolean(formik.errors.model?.role && formik.touched.model?.role)}
helperText={formik.touched.model?.role && formik.errors.model?.role}
margin="normal"
>
<MenuItem value={noRoleSelected} onClick={() => setSelectedRole(undefined)}>
{noRoleSelected}
</MenuItem>
{roles &&
roles.map((role) => (
<MenuItem key={role.name} value={role.name} onClick={() => setSelectedRole(role)}>
{role.name}
</MenuItem>
))}
</TextField>
</FormControl>
<Button
type="submit"
fullWidth
variant="contained"
color="secondary"
disabled={!formik.isValid || !formik.values.model?.name || !formik.values.model?.city}
>
Lägg till
</Button>
{formik.errors.error && (
<Alert severity="error">
<AlertTitle>Error</AlertTitle>
{formik.errors.error}
</Alert>
)}
</AddForm>
)}
</Formik>
</AddContent>
</Popover>
</div>
)
}
export default AddUser