chore (litmus-portal): Refactor Settings section to use InputField (#2000)
Refactored all the components inside of the Settings section to use the unified and customisable InputField component. This will ensures consistency in styling as well as input handling and validation methods. Signed-off-by: Saswata Mukherjee <saswataminsta@yahoo.com> Co-authored-by: Sayan Mondal <sayan.mondal@mayadata.io>
This commit is contained in:
parent
f29c20e2cd
commit
85b495541a
|
|
@ -1,24 +1,17 @@
|
|||
import { Button, Divider, Typography } from '@material-ui/core';
|
||||
import React, { useRef } from 'react';
|
||||
import InputField from '../../../../../containers/layouts/InputField';
|
||||
import Unimodal from '../../../../../containers/layouts/Unimodal';
|
||||
import {
|
||||
FormControl,
|
||||
IconButton,
|
||||
Input,
|
||||
InputAdornment,
|
||||
InputLabel,
|
||||
Button,
|
||||
Typography,
|
||||
Divider,
|
||||
} from '@material-ui/core';
|
||||
import Visibility from '@material-ui/icons/Visibility';
|
||||
import VisibilityOff from '@material-ui/icons/VisibilityOff';
|
||||
import React from 'react';
|
||||
validateConfirmPassword,
|
||||
validateStartEmptySpacing,
|
||||
} from '../../../../../utils/validate';
|
||||
import PersonalDetails from '../PersonalDetails';
|
||||
import useStyles from './styles';
|
||||
import Unimodal from '../../../../../containers/layouts/Unimodal';
|
||||
|
||||
// used for password field
|
||||
interface Password {
|
||||
password: string;
|
||||
err: boolean;
|
||||
showPassword: boolean;
|
||||
}
|
||||
|
||||
|
|
@ -28,101 +21,62 @@ const AccountSettings: React.FC = () => {
|
|||
|
||||
// used for modal
|
||||
const [open, setOpen] = React.useState(false);
|
||||
const isSuccess = useRef<boolean>(false);
|
||||
|
||||
const handleClose = () => {
|
||||
setOpen(false);
|
||||
};
|
||||
|
||||
// used for password validation
|
||||
const regularExpression = new RegExp(
|
||||
'^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[!@#$%^&*])(?=.{8,})'
|
||||
);
|
||||
|
||||
// states for the three password fields
|
||||
const [currPassword, setCurrPassword] = React.useState<Password>({
|
||||
password: '',
|
||||
showPassword: false,
|
||||
err: false,
|
||||
});
|
||||
const [newPassword, setNewPassword] = React.useState<Password>({
|
||||
password: '',
|
||||
showPassword: false,
|
||||
err: false,
|
||||
});
|
||||
const [confNewPassword, setConfNewPassword] = React.useState<Password>({
|
||||
password: '',
|
||||
showPassword: false,
|
||||
err: false,
|
||||
});
|
||||
|
||||
// handleNewPassword handles password validation for second password field
|
||||
// handleCurrPassword handles password for first password field
|
||||
const handleCurrPassword = (prop: keyof Password) => (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
setCurrPassword({
|
||||
...currPassword,
|
||||
[prop]: event.target.value,
|
||||
});
|
||||
};
|
||||
|
||||
// handleNewPassword handles password for second password field
|
||||
const handleNewPassword = (prop: keyof Password) => (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
if (
|
||||
event.target.value !== currPassword.password &&
|
||||
regularExpression.test(event.target.value) &&
|
||||
(confNewPassword.password.length === 0 ||
|
||||
event.target.value === confNewPassword.password)
|
||||
) {
|
||||
setNewPassword({
|
||||
...newPassword,
|
||||
err: false,
|
||||
[prop]: event.target.value,
|
||||
});
|
||||
setConfNewPassword({ ...confNewPassword, err: false });
|
||||
} else {
|
||||
setNewPassword({ ...newPassword, err: true, [prop]: event.target.value });
|
||||
setConfNewPassword({ ...confNewPassword });
|
||||
}
|
||||
setNewPassword({
|
||||
...newPassword,
|
||||
[prop]: event.target.value,
|
||||
});
|
||||
};
|
||||
|
||||
// handleConfPassword handles password validation for third password field
|
||||
// handleConfPassword handles password for third password field
|
||||
const handleConfPassword = (prop: keyof Password) => (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
if (
|
||||
event.target.value === newPassword.password &&
|
||||
regularExpression.test(event.target.value)
|
||||
) {
|
||||
setConfNewPassword({
|
||||
...confNewPassword,
|
||||
err: false,
|
||||
[prop]: event.target.value,
|
||||
});
|
||||
setNewPassword({ ...newPassword, err: false });
|
||||
} else {
|
||||
setConfNewPassword({
|
||||
...confNewPassword,
|
||||
err: true,
|
||||
[prop]: event.target.value,
|
||||
});
|
||||
setNewPassword({ ...newPassword });
|
||||
}
|
||||
};
|
||||
|
||||
// implements the logic for visibility of password
|
||||
const handleClickShowPassword1 = () => {
|
||||
setCurrPassword({
|
||||
...currPassword,
|
||||
showPassword: !currPassword.showPassword,
|
||||
});
|
||||
};
|
||||
const handleClickShowPassword2 = () => {
|
||||
setNewPassword({ ...newPassword, showPassword: !newPassword.showPassword });
|
||||
};
|
||||
const handleClickShowPassword3 = () => {
|
||||
setConfNewPassword({
|
||||
...confNewPassword,
|
||||
showPassword: !confNewPassword.showPassword,
|
||||
[prop]: event.target.value,
|
||||
});
|
||||
};
|
||||
|
||||
const handleMouseDownPassword = (
|
||||
event: React.MouseEvent<HTMLButtonElement>
|
||||
) => {
|
||||
event.preventDefault();
|
||||
};
|
||||
if (
|
||||
confNewPassword.password.length > 0 &&
|
||||
newPassword.password === confNewPassword.password
|
||||
)
|
||||
isSuccess.current = true;
|
||||
else isSuccess.current = false;
|
||||
|
||||
return (
|
||||
<div className={classes.container}>
|
||||
|
|
@ -139,106 +93,60 @@ const AccountSettings: React.FC = () => {
|
|||
<div className={classes.outerPass}>
|
||||
<form className={classes.innerPass}>
|
||||
{/* Current Password */}
|
||||
<FormControl>
|
||||
<Input
|
||||
className={classes.pass}
|
||||
defaultValue={currPassword.password}
|
||||
id="outlined-adornment-password"
|
||||
type={currPassword.showPassword ? 'text' : 'password'}
|
||||
disableUnderline
|
||||
endAdornment={
|
||||
<InputAdornment position="end">
|
||||
<IconButton
|
||||
aria-label="toggle password visibility"
|
||||
onClick={handleClickShowPassword1}
|
||||
edge="end"
|
||||
>
|
||||
{currPassword.showPassword ? (
|
||||
<Visibility />
|
||||
) : (
|
||||
<VisibilityOff />
|
||||
)}
|
||||
</IconButton>
|
||||
</InputAdornment>
|
||||
}
|
||||
/>
|
||||
<InputLabel htmlFor="outlined-adornment-password">
|
||||
Current Password
|
||||
</InputLabel>
|
||||
</FormControl>
|
||||
<InputField
|
||||
required
|
||||
value={currPassword.password}
|
||||
handleChange={handleCurrPassword('password')}
|
||||
type="password"
|
||||
label="Current Password"
|
||||
validationError={false}
|
||||
/>
|
||||
|
||||
{/* New Password */}
|
||||
<FormControl>
|
||||
<Input
|
||||
data-cy="changePassword"
|
||||
className={`${classes.pass} ${
|
||||
newPassword.err ? classes.error : classes.success
|
||||
}`}
|
||||
id="outlined-adornment-password"
|
||||
type={newPassword.showPassword ? 'text' : 'password'}
|
||||
onChange={handleNewPassword('password')}
|
||||
disableUnderline
|
||||
endAdornment={
|
||||
<InputAdornment position="end">
|
||||
<IconButton
|
||||
data-cy="conVisibilty"
|
||||
aria-label="toggle password visibility"
|
||||
onClick={handleClickShowPassword2}
|
||||
onMouseDown={handleMouseDownPassword}
|
||||
edge="end"
|
||||
>
|
||||
{newPassword.showPassword ? (
|
||||
<Visibility data-cy="visIcon" />
|
||||
) : (
|
||||
<VisibilityOff data-cy="invisIcon" />
|
||||
)}
|
||||
</IconButton>
|
||||
</InputAdornment>
|
||||
}
|
||||
/>
|
||||
<InputLabel htmlFor="outlined-adornment-password">
|
||||
New Password
|
||||
</InputLabel>
|
||||
</FormControl>
|
||||
<InputField
|
||||
required
|
||||
type="password"
|
||||
handleChange={handleNewPassword('password')}
|
||||
success={isSuccess.current}
|
||||
helperText={
|
||||
validateStartEmptySpacing(newPassword.password)
|
||||
? 'Should not start with empty space'
|
||||
: ''
|
||||
}
|
||||
label="New Password"
|
||||
validationError={validateStartEmptySpacing(
|
||||
newPassword.password
|
||||
)}
|
||||
value={newPassword.password}
|
||||
/>
|
||||
|
||||
{/* Confirm new password */}
|
||||
<FormControl>
|
||||
<Input
|
||||
data-cy="confirmPassword"
|
||||
className={`${classes.pass} ${
|
||||
confNewPassword.err ? classes.error : classes.success
|
||||
}`}
|
||||
id="outlined-adornment-password"
|
||||
type={confNewPassword.showPassword ? 'text' : 'password'}
|
||||
onChange={handleConfPassword('password')}
|
||||
disableUnderline
|
||||
endAdornment={
|
||||
<InputAdornment position="end">
|
||||
<IconButton
|
||||
data-cy="conVisibilty"
|
||||
aria-label="toggle password visibility"
|
||||
onClick={handleClickShowPassword3}
|
||||
onMouseDown={handleMouseDownPassword}
|
||||
edge="end"
|
||||
>
|
||||
{confNewPassword.showPassword ? (
|
||||
<Visibility data-cy="visIcon" />
|
||||
) : (
|
||||
<VisibilityOff data-cy="invisIcon" />
|
||||
)}
|
||||
</IconButton>
|
||||
</InputAdornment>
|
||||
}
|
||||
/>
|
||||
<InputLabel htmlFor="outlined-adornment-password">
|
||||
Confirm new password
|
||||
</InputLabel>
|
||||
</FormControl>
|
||||
<InputField
|
||||
helperText={
|
||||
validateConfirmPassword(
|
||||
newPassword.password,
|
||||
confNewPassword.password
|
||||
)
|
||||
? 'Password is not same'
|
||||
: ''
|
||||
}
|
||||
required
|
||||
type="password"
|
||||
handleChange={handleConfPassword('password')}
|
||||
success={isSuccess.current}
|
||||
label="Confirm Password"
|
||||
validationError={validateConfirmPassword(
|
||||
newPassword.password,
|
||||
confNewPassword.password
|
||||
)}
|
||||
value={confNewPassword.password}
|
||||
/>
|
||||
<Button
|
||||
data-cy="button"
|
||||
variant="contained"
|
||||
className={classes.button}
|
||||
onClick={() => {
|
||||
if (
|
||||
!(newPassword.err && confNewPassword.err) &&
|
||||
newPassword.password.length > 0 &&
|
||||
confNewPassword.password.length > 0
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -44,14 +44,6 @@ const useStyles = makeStyles((theme: Theme) => ({
|
|||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
},
|
||||
pass: {
|
||||
width: '24.43rem',
|
||||
height: '4.8125rem',
|
||||
marginBottom: theme.spacing(2.5),
|
||||
padding: theme.spacing(1),
|
||||
border: '1px solid rgba(0, 0, 0, 0.2)',
|
||||
borderRadius: 3,
|
||||
},
|
||||
col2: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
|
|
@ -74,14 +66,6 @@ const useStyles = makeStyles((theme: Theme) => ({
|
|||
marginBottom: theme.spacing(2.5),
|
||||
fontSize: '1rem',
|
||||
},
|
||||
success: {
|
||||
border: '0.0625rem solid',
|
||||
borderColor: theme.palette.secondary.dark,
|
||||
},
|
||||
error: {
|
||||
border: '0.0625rem solid',
|
||||
borderColor: theme.palette.error.main,
|
||||
},
|
||||
|
||||
// Password Modal content styles
|
||||
body: {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,12 @@
|
|||
import { Avatar, TextField, Typography } from '@material-ui/core';
|
||||
import { Avatar, Typography } from '@material-ui/core';
|
||||
import React from 'react';
|
||||
import InputField from '../../../../../../containers/layouts/InputField';
|
||||
import userAvatar from '../../../../../../utils/user';
|
||||
import useStyles from './styles';
|
||||
import {
|
||||
validateEmail,
|
||||
validateStartEmptySpacing,
|
||||
} from '../../../../../../utils/validate';
|
||||
|
||||
interface PersonalDetailsProps {
|
||||
handleNameChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
||||
|
|
@ -53,45 +58,39 @@ const UserDetails: React.FC<PersonalDetailsProps> = ({
|
|||
</div>
|
||||
{/* Fields for details including Full name, email, username */}
|
||||
<div className={classes.details1}>
|
||||
<TextField
|
||||
<InputField
|
||||
required
|
||||
helperText={
|
||||
validateStartEmptySpacing(nameValue)
|
||||
? 'Should not start with an empty space'
|
||||
: ''
|
||||
}
|
||||
value={nameValue}
|
||||
disabled={nameIsDisabled}
|
||||
onChange={handleNameChange}
|
||||
className={classes.user}
|
||||
id="filled-user-input"
|
||||
handleChange={handleNameChange}
|
||||
validationError={validateStartEmptySpacing(nameValue)}
|
||||
label="Full Name"
|
||||
InputProps={{ disableUnderline: true }}
|
||||
data-cy="fullName"
|
||||
/>
|
||||
|
||||
<TextField
|
||||
<InputField
|
||||
required
|
||||
helperText={
|
||||
validateEmail(emailValue) ? 'Should be a valid email' : ''
|
||||
}
|
||||
type="email"
|
||||
value={emailValue}
|
||||
disabled={emailIsDisabled}
|
||||
onChange={handleEmailChange}
|
||||
className={classes.user}
|
||||
id="filled-email-input"
|
||||
handleChange={handleEmailChange}
|
||||
validationError={validateEmail(emailValue)}
|
||||
label="Email Address"
|
||||
name="email"
|
||||
InputProps={{
|
||||
disableUnderline: true,
|
||||
}}
|
||||
data-cy="inputEmail"
|
||||
/>
|
||||
{/* Username is not editable normal user */}
|
||||
<TextField
|
||||
<InputField
|
||||
value={userValue}
|
||||
onChange={handleUserChange}
|
||||
className={classes.user}
|
||||
id="filled-username-input"
|
||||
handleChange={handleUserChange}
|
||||
label="Username"
|
||||
disabled={usernameIsDisabled}
|
||||
InputProps={{
|
||||
disableUnderline: true,
|
||||
}}
|
||||
data-cy="username"
|
||||
validationError={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -48,16 +48,6 @@ const useStyles = makeStyles((theme: Theme) => ({
|
|||
|
||||
marginRight: theme.spacing(2.5),
|
||||
},
|
||||
user: {
|
||||
border: '1px solid rgba(0, 0, 0, 0.2)',
|
||||
borderRadius: '0.1875rem',
|
||||
width: '24.43rem',
|
||||
height: '4.8125rem',
|
||||
marginLeft: theme.spacing(2.5),
|
||||
marginRight: theme.spacing(2.5),
|
||||
paddingLeft: theme.spacing(3.75),
|
||||
marginBottom: theme.spacing(2.5),
|
||||
},
|
||||
// Style for ProfileDropdownSection and ProfileDropdownItems.
|
||||
avatarBackground: {
|
||||
backgroundColor: theme.palette.secondary.main,
|
||||
|
|
|
|||
|
|
@ -1,23 +1,16 @@
|
|||
import {
|
||||
Divider,
|
||||
FormControl,
|
||||
IconButton,
|
||||
Input,
|
||||
InputAdornment,
|
||||
InputLabel,
|
||||
TextField,
|
||||
Typography,
|
||||
} from '@material-ui/core';
|
||||
import Visibility from '@material-ui/icons/Visibility';
|
||||
import VisibilityOff from '@material-ui/icons/VisibilityOff';
|
||||
import { Divider, IconButton, Typography } from '@material-ui/core';
|
||||
import React from 'react';
|
||||
import NewUserModal from './NewUserModal';
|
||||
import InputField from '../../../../../containers/layouts/InputField';
|
||||
import useStyles from './styles';
|
||||
import UserDetails from './UserDetails';
|
||||
import {
|
||||
validateStartEmptySpacing,
|
||||
validateLength,
|
||||
} from '../../../../../utils/validate';
|
||||
|
||||
interface Password {
|
||||
password: string;
|
||||
err: boolean;
|
||||
showPassword: boolean;
|
||||
}
|
||||
|
||||
|
|
@ -36,51 +29,22 @@ interface CreateUserProps {
|
|||
const CreateUser: React.FC<CreateUserProps> = ({ handleDiv }) => {
|
||||
const classes = useStyles();
|
||||
|
||||
// for password validation
|
||||
const regularExpression = new RegExp(
|
||||
'^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[!@#$%^&*])(?=.{8,})'
|
||||
);
|
||||
|
||||
// for conditional rendering of reset password div
|
||||
|
||||
const [createPAssword, setCreatePassword] = React.useState<Password>({
|
||||
password: '',
|
||||
showPassword: false,
|
||||
err: false,
|
||||
});
|
||||
|
||||
// handles password field
|
||||
const handleCreatePassword = (prop: keyof Password) => (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
if (regularExpression.test(event.target.value)) {
|
||||
setCreatePassword({
|
||||
...createPAssword,
|
||||
err: false,
|
||||
[prop]: event.target.value,
|
||||
});
|
||||
} else {
|
||||
setCreatePassword({
|
||||
...createPAssword,
|
||||
err: true,
|
||||
[prop]: event.target.value,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleClickShowPassword = () => {
|
||||
setCreatePassword({
|
||||
...createPAssword,
|
||||
showPassword: !createPAssword.showPassword,
|
||||
[prop]: event.target.value,
|
||||
});
|
||||
};
|
||||
|
||||
const handleMouseDownPassword = (
|
||||
event: React.MouseEvent<HTMLButtonElement>
|
||||
) => {
|
||||
event.preventDefault();
|
||||
};
|
||||
|
||||
// for personal details fields
|
||||
const [personalData, setPersonalData] = React.useState<personalData>({
|
||||
email: '',
|
||||
|
|
@ -88,6 +52,13 @@ const CreateUser: React.FC<CreateUserProps> = ({ handleDiv }) => {
|
|||
fullName: '',
|
||||
});
|
||||
|
||||
const handleUsername = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setPersonalData({
|
||||
...personalData,
|
||||
userName: event.target.value,
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={classes.headDiv}>
|
||||
|
|
@ -149,53 +120,35 @@ const CreateUser: React.FC<CreateUserProps> = ({ handleDiv }) => {
|
|||
<div>
|
||||
<form>
|
||||
<div className={classes.details1}>
|
||||
<TextField
|
||||
className={classes.userDetail}
|
||||
id="filled-username-input"
|
||||
<InputField
|
||||
helperText={
|
||||
validateStartEmptySpacing(personalData.userName)
|
||||
? 'Should not start with an empty space'
|
||||
: ''
|
||||
}
|
||||
label="Username"
|
||||
defaultValue="RichardHill"
|
||||
value={personalData.userName}
|
||||
handleChange={handleUsername}
|
||||
validationError={validateStartEmptySpacing(
|
||||
personalData.userName
|
||||
)}
|
||||
disabled
|
||||
InputProps={{
|
||||
disableUnderline: true,
|
||||
}}
|
||||
data-cy="username"
|
||||
/>
|
||||
<FormControl>
|
||||
<Input
|
||||
required
|
||||
data-cy="changePassword"
|
||||
className={`${classes.pass} ${
|
||||
createPAssword.err ? classes.error : classes.success
|
||||
}`}
|
||||
id="outlined-adornment-password"
|
||||
type={
|
||||
createPAssword.showPassword ? 'text' : 'password'
|
||||
}
|
||||
onChange={handleCreatePassword('password')}
|
||||
disableUnderline
|
||||
endAdornment={
|
||||
<InputAdornment position="end">
|
||||
<IconButton
|
||||
data-cy="conVisibilty"
|
||||
aria-label="toggle password visibility"
|
||||
onClick={handleClickShowPassword}
|
||||
onMouseDown={handleMouseDownPassword}
|
||||
edge="end"
|
||||
>
|
||||
{createPAssword.showPassword ? (
|
||||
<Visibility data-cy="visIcon" />
|
||||
) : (
|
||||
<VisibilityOff data-cy="invisIcon" />
|
||||
)}
|
||||
</IconButton>
|
||||
</InputAdornment>
|
||||
}
|
||||
/>
|
||||
<InputLabel htmlFor="outlined-adornment-password">
|
||||
New Password
|
||||
</InputLabel>
|
||||
</FormControl>
|
||||
<InputField
|
||||
required
|
||||
type="password"
|
||||
helperText={
|
||||
validateLength(createPAssword.password)
|
||||
? 'Password is too short'
|
||||
: ''
|
||||
}
|
||||
handleChange={handleCreatePassword('password')}
|
||||
value={createPAssword.password}
|
||||
validationError={validateLength(
|
||||
createPAssword.password
|
||||
)}
|
||||
label="New Password"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
|
@ -206,7 +159,6 @@ const CreateUser: React.FC<CreateUserProps> = ({ handleDiv }) => {
|
|||
<div className={classes.buttonGroup}>
|
||||
<NewUserModal
|
||||
showModal={
|
||||
!createPAssword.err &&
|
||||
personalData.userName.length > 0 &&
|
||||
createPAssword.password.length > 0
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,26 +56,6 @@ const useStyles = makeStyles((theme: Theme) => ({
|
|||
alignContent: 'flex-start',
|
||||
flexWrap: 'wrap',
|
||||
},
|
||||
// for username field
|
||||
userDetail: {
|
||||
border: '1px solid rgba(0, 0, 0, 0.2)',
|
||||
borderRadius: 3,
|
||||
width: '24.43rem',
|
||||
height: '4.8125rem',
|
||||
marginRight: theme.spacing(2.5),
|
||||
paddingLeft: theme.spacing(3.75),
|
||||
marginBottom: theme.spacing(2.5),
|
||||
},
|
||||
|
||||
// for password
|
||||
pass: {
|
||||
width: '24.43rem',
|
||||
height: '4.8125rem',
|
||||
marginBottom: theme.spacing(2.5),
|
||||
padding: theme.spacing(1),
|
||||
border: '1px solid rgba(0, 0, 0, 0.2)',
|
||||
borderRadius: 3,
|
||||
},
|
||||
|
||||
divider: {
|
||||
marginTop: theme.spacing(3.75),
|
||||
|
|
@ -89,17 +69,6 @@ const useStyles = makeStyles((theme: Theme) => ({
|
|||
color: theme.palette.text.disabled,
|
||||
},
|
||||
|
||||
// button success and button error
|
||||
success: {
|
||||
border: '0.0625rem solid',
|
||||
borderColor: theme.palette.secondary.dark,
|
||||
},
|
||||
|
||||
error: {
|
||||
border: '0.0625rem solid',
|
||||
borderColor: theme.palette.error.main,
|
||||
},
|
||||
|
||||
createRandomButton: {
|
||||
background: theme.palette.secondary.dark,
|
||||
color: theme.palette.secondary.contrastText,
|
||||
|
|
|
|||
|
|
@ -1,23 +1,14 @@
|
|||
import {
|
||||
Divider,
|
||||
FormControl,
|
||||
IconButton,
|
||||
Input,
|
||||
InputAdornment,
|
||||
InputLabel,
|
||||
Typography,
|
||||
} from '@material-ui/core';
|
||||
import Visibility from '@material-ui/icons/Visibility';
|
||||
import VisibilityOff from '@material-ui/icons/VisibilityOff';
|
||||
import { Divider, IconButton, Typography } from '@material-ui/core';
|
||||
import React from 'react';
|
||||
import DelUser from './DelUser';
|
||||
import ResetModal from './ResetModal';
|
||||
import UserDetails from '../CreateUser/UserDetails';
|
||||
import useStyles from './styles';
|
||||
import InputField from '../../../../../containers/layouts/InputField';
|
||||
import { validateLength } from '../../../../../utils/validate';
|
||||
|
||||
interface Password {
|
||||
password: string;
|
||||
err: boolean;
|
||||
showPassword: boolean;
|
||||
}
|
||||
|
||||
|
|
@ -38,51 +29,23 @@ const EditUser: React.FC<EditUserProps> = ({
|
|||
}) => {
|
||||
const classes = useStyles();
|
||||
|
||||
// for password validation
|
||||
const regularExpression = new RegExp(
|
||||
'^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[!@#$%^&*])(?=.{8,})'
|
||||
);
|
||||
|
||||
// for conditional rendering of reset password div
|
||||
|
||||
const [createPAssword, setCreatePassword] = React.useState<Password>({
|
||||
password: '',
|
||||
showPassword: false,
|
||||
err: false,
|
||||
});
|
||||
|
||||
// handles password field
|
||||
const handleCreatePassword = (prop: keyof Password) => (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
if (regularExpression.test(event.target.value)) {
|
||||
setCreatePassword({
|
||||
...createPAssword,
|
||||
err: false,
|
||||
[prop]: event.target.value,
|
||||
});
|
||||
} else {
|
||||
setCreatePassword({
|
||||
...createPAssword,
|
||||
err: true,
|
||||
[prop]: event.target.value,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleClickShowPassword = () => {
|
||||
setCreatePassword({
|
||||
...createPAssword,
|
||||
showPassword: !createPAssword.showPassword,
|
||||
[prop]: event.target.value,
|
||||
});
|
||||
};
|
||||
|
||||
const handleMouseDownPassword = (
|
||||
event: React.MouseEvent<HTMLButtonElement>
|
||||
) => {
|
||||
event.preventDefault();
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={classes.headDiv}>
|
||||
|
|
@ -122,41 +85,21 @@ const EditUser: React.FC<EditUserProps> = ({
|
|||
<div>
|
||||
<form>
|
||||
<div className={classes.details1}>
|
||||
<FormControl>
|
||||
<Input
|
||||
required
|
||||
data-cy="changePassword"
|
||||
className={`${classes.pass} ${
|
||||
createPAssword.err ? classes.error : classes.success
|
||||
}`}
|
||||
id="outlined-adornment-password"
|
||||
type={
|
||||
createPAssword.showPassword ? 'text' : 'password'
|
||||
}
|
||||
onChange={handleCreatePassword('password')}
|
||||
disableUnderline
|
||||
endAdornment={
|
||||
<InputAdornment position="end">
|
||||
<IconButton
|
||||
data-cy="conVisibilty"
|
||||
aria-label="toggle password visibility"
|
||||
onClick={handleClickShowPassword}
|
||||
onMouseDown={handleMouseDownPassword}
|
||||
edge="end"
|
||||
>
|
||||
{createPAssword.showPassword ? (
|
||||
<Visibility data-cy="visIcon" />
|
||||
) : (
|
||||
<VisibilityOff data-cy="invisIcon" />
|
||||
)}
|
||||
</IconButton>
|
||||
</InputAdornment>
|
||||
}
|
||||
/>
|
||||
<InputLabel htmlFor="outlined-adornment-password">
|
||||
New Password
|
||||
</InputLabel>
|
||||
</FormControl>
|
||||
<InputField
|
||||
required
|
||||
helperText={
|
||||
validateLength(createPAssword.password)
|
||||
? 'Password is too short'
|
||||
: ''
|
||||
}
|
||||
handleChange={handleCreatePassword('password')}
|
||||
type="password"
|
||||
validationError={validateLength(
|
||||
createPAssword.password
|
||||
)}
|
||||
label="New Password"
|
||||
value={createPAssword.password}
|
||||
/>
|
||||
</div>
|
||||
<Divider className={classes.divider} />
|
||||
<DelUser handleModal={handleDiv} tableDelete={false} />
|
||||
|
|
|
|||
|
|
@ -67,16 +67,6 @@ const useStyles = makeStyles((theme: Theme) => ({
|
|||
marginBottom: theme.spacing(2.5),
|
||||
},
|
||||
|
||||
// for password
|
||||
pass: {
|
||||
width: '24.43rem',
|
||||
height: '4.8125rem',
|
||||
marginBottom: theme.spacing(2.5),
|
||||
padding: theme.spacing(1),
|
||||
border: '1px solid rgba(0, 0, 0, 0.2)',
|
||||
borderRadius: 3,
|
||||
},
|
||||
|
||||
divider: {
|
||||
marginTop: theme.spacing(3.75),
|
||||
maxWidth: '58.75rem',
|
||||
|
|
@ -89,17 +79,6 @@ const useStyles = makeStyles((theme: Theme) => ({
|
|||
color: theme.palette.text.disabled,
|
||||
},
|
||||
|
||||
// button success and button error
|
||||
success: {
|
||||
border: '0.0625rem solid',
|
||||
borderColor: theme.palette.secondary.dark,
|
||||
},
|
||||
|
||||
error: {
|
||||
border: '0.0625rem solid',
|
||||
borderColor: theme.palette.error.main,
|
||||
},
|
||||
|
||||
createRandomButton: {
|
||||
background: theme.palette.secondary.dark,
|
||||
color: theme.palette.secondary.contrastText,
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import {
|
|||
createStyles,
|
||||
FormControl,
|
||||
IconButton,
|
||||
InputBase,
|
||||
InputAdornment,
|
||||
Menu,
|
||||
MenuItem,
|
||||
|
|
@ -15,7 +16,6 @@ import {
|
|||
TableContainer,
|
||||
TableHead,
|
||||
TableRow,
|
||||
TextField,
|
||||
Theme,
|
||||
Toolbar,
|
||||
Typography,
|
||||
|
|
@ -148,8 +148,8 @@ const UserManagement: React.FC = () => {
|
|||
<div>
|
||||
<Toolbar className={classes.toolbar}>
|
||||
{/* Search user */}
|
||||
<TextField
|
||||
id="input-with-icon-textfield"
|
||||
<InputBase
|
||||
id="input-with-icon-adornment"
|
||||
placeholder="Search..."
|
||||
onChange={(e) => {
|
||||
setRows(
|
||||
|
|
@ -158,16 +158,11 @@ const UserManagement: React.FC = () => {
|
|||
)
|
||||
);
|
||||
}}
|
||||
InputProps={{
|
||||
style: {
|
||||
maxWidth: '15.75rem',
|
||||
},
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
<SearchIcon />
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
startAdornment={
|
||||
<InputAdornment position="start">
|
||||
<SearchIcon />
|
||||
</InputAdornment>
|
||||
}
|
||||
/>
|
||||
{/* filter menu */}
|
||||
<div className={classes.filter}>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import ButtonFilled from '../Button/ButtonFilled';
|
|||
import config from '../../config';
|
||||
import { CREATE_USER } from '../../graphql';
|
||||
import { RootState } from '../../redux/reducers';
|
||||
import InputField from '../InputField';
|
||||
import InputField from '../../containers/layouts/InputField';
|
||||
import ModalPage from './Modalpage';
|
||||
import useStyles from './styles';
|
||||
import {
|
||||
|
|
|
|||
|
|
@ -13,16 +13,18 @@ interface InputFieldProps {
|
|||
helperText?: string;
|
||||
validationError: boolean;
|
||||
success?: boolean;
|
||||
disabled?: boolean;
|
||||
value: string;
|
||||
required: boolean;
|
||||
required?: boolean;
|
||||
iconType?: string | undefined;
|
||||
handleChange: (event: React.ChangeEvent<{ value: string }>) => void;
|
||||
handleChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
||||
}
|
||||
|
||||
const InputField: React.FC<InputFieldProps> = ({
|
||||
type,
|
||||
label,
|
||||
value,
|
||||
disabled,
|
||||
helperText,
|
||||
validationError,
|
||||
success,
|
||||
|
|
@ -310,6 +312,7 @@ const InputField: React.FC<InputFieldProps> = ({
|
|||
<TextField
|
||||
className={LitmusTextFieldStylesExternal.inputArea}
|
||||
error={validationError}
|
||||
disabled={disabled}
|
||||
label={label}
|
||||
helperText={helperText}
|
||||
value={value}
|
||||
|
|
@ -2,7 +2,7 @@ import { Button, Typography } from '@material-ui/core';
|
|||
import React, { useState } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import InputField from '../../components/InputField';
|
||||
import InputField from '../../containers/layouts/InputField';
|
||||
import config from '../../config';
|
||||
import useActions from '../../redux/actions';
|
||||
import * as UserActions from '../../redux/actions/user';
|
||||
|
|
|
|||
|
|
@ -44,3 +44,8 @@ export const validateOnlyAlphabet = (value: string) => {
|
|||
if (value.match(onlyAplhaValid)) return false;
|
||||
return true;
|
||||
};
|
||||
|
||||
export const validateLength = (value: string) => {
|
||||
if (value.length > 0) return false;
|
||||
return true;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue