From fa133c40edb633c63d37619682ba0771d4481ed9 Mon Sep 17 00:00:00 2001 From: ilyayudovin Date: Fri, 28 Aug 2020 02:24:00 +0300 Subject: fix input validation errors --- src/containers/Registration/Registration.tsx | 103 ++++++++++++++++----------- 1 file changed, 63 insertions(+), 40 deletions(-) (limited to 'src/containers/Registration/Registration.tsx') diff --git a/src/containers/Registration/Registration.tsx b/src/containers/Registration/Registration.tsx index 9bcea8e..7d2a758 100644 --- a/src/containers/Registration/Registration.tsx +++ b/src/containers/Registration/Registration.tsx @@ -1,10 +1,13 @@ import React, { useState, useRef } from 'react'; import { useHistory } from 'react-router-dom'; import { makeStyles } from '@material-ui/core/styles'; -import TextField from '@material-ui/core/TextField'; -import Button from '@material-ui/core/Button'; -import CheckCircleIcon from '@material-ui/icons/CheckCircle'; -import InputAdornment from '@material-ui/core/InputAdornment'; +import { + TextField, + Button, + InputAdornment, + IconButton +} from '@material-ui/core'; +import { CheckCircle, Visibility, VisibilityOff } from '@material-ui/icons'; import { post } from '../../requests'; import { useAuth } from '../../hooks/useAuth'; @@ -35,18 +38,20 @@ const useStyles = makeStyles(theme => ({ } })); -const inputStyle = { WebkitBoxShadow: '0 0 0 1000px snow inset' }; - +interface ValidationStates { + validUsername: boolean | undefined; + validEmail: boolean | undefined; + validPassword: boolean | undefined; + showPassword: boolean; +} const Registration: React.FC = () => { - const errorOutputs = { - usernameError: 'Username is required', - emailError: 'Invalid email address', - passwordError: 'Should be at least 6 characters' - }; - const [errorPassword, setErrorPassword] = useState(false); - const [errorEmail, setErrorEmail] = useState(false); - const [errorUsername, setErrorUsername] = useState(false); + const [values, setValues] = useState({ + validUsername: undefined, + validEmail: undefined, + validPassword: undefined, + showPassword: false + }); const classes = useStyles(); const usernameRef = useRef(); @@ -55,11 +60,15 @@ const Registration: React.FC = () => { const { login } = useAuth(); const history = useHistory(); + const checkFromValidation = () => { + return values.validUsername && values.validEmail && values.validPassword; + }; + const handleSubmit = () => { const username = usernameRef.current?.value?.toLowerCase(); const password = passwordRef.current?.value; const email = emailRef.current?.value; - if (username && password) { + if (username && password && checkFromValidation()) { post('/users', { username, password, email }) .then(() => login(username, password)) .then(() => history.push(`/profile/${username}`)); @@ -70,14 +79,20 @@ const Registration: React.FC = () => { history.push('/login'); }; - const handleLoginChange = (e: React.ChangeEvent) => { - setErrorUsername(e.currentTarget.value.length === 0); + const handleClickShowPassword = () => { + setValues({ ...values, showPassword: !values.showPassword }); + }; + const handleMouseDownPassword = (event: React.MouseEvent) => { + event.preventDefault(); + }; + const handleUsernameChange = (e: React.ChangeEvent) => { + setValues({ ...values, validUsername: e.currentTarget.value.length > 0 }); }; const handleEmailChange = (e: React.ChangeEvent) => { - setErrorEmail(!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(e.currentTarget.value)); + setValues({ ...values, validEmail: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(e.currentTarget.value) }); }; const handlePasswordChange = (e: React.ChangeEvent) => { - setErrorPassword(e.currentTarget.value.length < 6); + setValues({ ...values, validPassword: e.currentTarget.value.length > 6 }); }; return ( @@ -87,46 +102,54 @@ const Registration: React.FC = () => { + {values.validUsername && values.validUsername !== undefined && } + + ) + }} /> - + {values.validEmail && values.validEmail !== undefined && } - ), - inputProps: { - style: inputStyle - } + ) }} /> - + + {values.showPassword ? : } + + {values.validPassword && values.validPassword !== undefined && } - ), - inputProps: { - style: inputStyle - } + ) }} /> -- cgit v1.2.3 From 4bbebc183e75e287e28d5b4369699d1bc40c0cd1 Mon Sep 17 00:00:00 2001 From: ilyayudovin Date: Fri, 28 Aug 2020 18:40:23 +0300 Subject: feat: submit Form on button click --- src/containers/Registration/Registration.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/containers/Registration/Registration.tsx') diff --git a/src/containers/Registration/Registration.tsx b/src/containers/Registration/Registration.tsx index 7d2a758..20bc283 100644 --- a/src/containers/Registration/Registration.tsx +++ b/src/containers/Registration/Registration.tsx @@ -1,4 +1,4 @@ -import React, { useState, useRef } from 'react'; +import React, {useState, useRef, FormEvent} from 'react'; import { useHistory } from 'react-router-dom'; import { makeStyles } from '@material-ui/core/styles'; import { @@ -64,11 +64,13 @@ const Registration: React.FC = () => { return values.validUsername && values.validEmail && values.validPassword; }; - const handleSubmit = () => { + const handleSubmit = (event: FormEvent) => { + event.preventDefault(); const username = usernameRef.current?.value?.toLowerCase(); const password = passwordRef.current?.value; const email = emailRef.current?.value; if (username && password && checkFromValidation()) { + console.log('yes'); post('/users', { username, password, email }) .then(() => login(username, password)) .then(() => history.push(`/profile/${username}`)); @@ -98,7 +100,7 @@ const Registration: React.FC = () => { return ( <>
Sign Up
-
+ { ) }} /> - +
Already have an account?
-- cgit v1.2.3 From b7be53c172869679cdfa65a44591c7bd9c5b9302 Mon Sep 17 00:00:00 2001 From: ilyayudovin Date: Fri, 28 Aug 2020 18:46:47 +0300 Subject: separate validation state into 2 states and remove CheckCircle icon --- src/containers/Registration/Registration.tsx | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) (limited to 'src/containers/Registration/Registration.tsx') diff --git a/src/containers/Registration/Registration.tsx b/src/containers/Registration/Registration.tsx index 20bc283..0746deb 100644 --- a/src/containers/Registration/Registration.tsx +++ b/src/containers/Registration/Registration.tsx @@ -38,20 +38,19 @@ const useStyles = makeStyles(theme => ({ } })); -interface ValidationStates { +interface errors { validUsername: boolean | undefined; validEmail: boolean | undefined; validPassword: boolean | undefined; - showPassword: boolean; } const Registration: React.FC = () => { - const [values, setValues] = useState({ + const [values, setValues] = useState({ validUsername: undefined, validEmail: undefined, validPassword: undefined, - showPassword: false }); + const [showPassword, setShowPassword] = useState(false); const classes = useStyles(); const usernameRef = useRef(); @@ -82,7 +81,7 @@ const Registration: React.FC = () => { }; const handleClickShowPassword = () => { - setValues({ ...values, showPassword: !values.showPassword }); + setShowPassword(prevState => !prevState); }; const handleMouseDownPassword = (event: React.MouseEvent) => { event.preventDefault(); @@ -108,13 +107,6 @@ const Registration: React.FC = () => { helperText={!values.validUsername && 'This field is required'} required onChange={handleUsernameChange} - InputProps={{ - endAdornment: ( - - {values.validUsername && values.validUsername !== undefined && } - - ) - }} /> { error={!values.validEmail} helperText={!values.validEmail && 'Invalid email address'} onChange={handleEmailChange} - InputProps={{ - endAdornment: ( - - {values.validEmail && values.validEmail !== undefined && } - - ) - }} /> { required error={!values.validPassword} helperText={!values.validPassword && 'Should be at least 6 characters'} - type={values.showPassword ? 'text' : 'password'} + type={showPassword ? 'text' : 'password'} onChange={handlePasswordChange} InputProps={{ endAdornment: ( @@ -147,7 +132,7 @@ const Registration: React.FC = () => { onClick={handleClickShowPassword} onMouseDown={handleMouseDownPassword} > - {values.showPassword ? : } + {showPassword ? : } {values.validPassword && values.validPassword !== undefined && } -- cgit v1.2.3 From 9c571fa6e99d3c5e271c5763d86bf4cdd702aebb Mon Sep 17 00:00:00 2001 From: ilyayudovin Date: Fri, 28 Aug 2020 18:47:40 +0300 Subject: change state name --- src/containers/Registration/Registration.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/containers/Registration/Registration.tsx') diff --git a/src/containers/Registration/Registration.tsx b/src/containers/Registration/Registration.tsx index 0746deb..47b5947 100644 --- a/src/containers/Registration/Registration.tsx +++ b/src/containers/Registration/Registration.tsx @@ -38,14 +38,14 @@ const useStyles = makeStyles(theme => ({ } })); -interface errors { +interface ErrorStates { validUsername: boolean | undefined; validEmail: boolean | undefined; validPassword: boolean | undefined; } const Registration: React.FC = () => { - const [values, setValues] = useState({ + const [values, setValues] = useState({ validUsername: undefined, validEmail: undefined, validPassword: undefined, -- cgit v1.2.3 From da1854e8fd34245e2e9e4fd941320f08b1cc40e1 Mon Sep 17 00:00:00 2001 From: ilyayudovin Date: Fri, 28 Aug 2020 18:55:34 +0300 Subject: add useMemo for check validity of the form --- src/containers/Registration/Registration.tsx | 41 ++++++++++++++-------------- 1 file changed, 20 insertions(+), 21 deletions(-) (limited to 'src/containers/Registration/Registration.tsx') diff --git a/src/containers/Registration/Registration.tsx b/src/containers/Registration/Registration.tsx index 47b5947..3269f6e 100644 --- a/src/containers/Registration/Registration.tsx +++ b/src/containers/Registration/Registration.tsx @@ -1,4 +1,4 @@ -import React, {useState, useRef, FormEvent} from 'react'; +import React, {useState, useRef, FormEvent, useMemo} from 'react'; import { useHistory } from 'react-router-dom'; import { makeStyles } from '@material-ui/core/styles'; import { @@ -39,16 +39,16 @@ const useStyles = makeStyles(theme => ({ })); interface ErrorStates { - validUsername: boolean | undefined; - validEmail: boolean | undefined; - validPassword: boolean | undefined; + username: boolean | undefined; + email: boolean | undefined; + password: boolean | undefined; } const Registration: React.FC = () => { const [values, setValues] = useState({ - validUsername: undefined, - validEmail: undefined, - validPassword: undefined, + username: undefined, + email: undefined, + password: undefined, }); const [showPassword, setShowPassword] = useState(false); @@ -59,16 +59,16 @@ const Registration: React.FC = () => { const { login } = useAuth(); const history = useHistory(); - const checkFromValidation = () => { - return values.validUsername && values.validEmail && values.validPassword; - }; + const isValid = useMemo(() => { + return values.username && values.email && values.password; + },[values]); const handleSubmit = (event: FormEvent) => { event.preventDefault(); const username = usernameRef.current?.value?.toLowerCase(); const password = passwordRef.current?.value; const email = emailRef.current?.value; - if (username && password && checkFromValidation()) { + if (username && password && isValid) { console.log('yes'); post('/users', { username, password, email }) .then(() => login(username, password)) @@ -87,13 +87,13 @@ const Registration: React.FC = () => { event.preventDefault(); }; const handleUsernameChange = (e: React.ChangeEvent) => { - setValues({ ...values, validUsername: e.currentTarget.value.length > 0 }); + setValues({ ...values, username: e.currentTarget.value.length > 0 }); }; const handleEmailChange = (e: React.ChangeEvent) => { - setValues({ ...values, validEmail: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(e.currentTarget.value) }); + setValues({ ...values, email: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(e.currentTarget.value) }); }; const handlePasswordChange = (e: React.ChangeEvent) => { - setValues({ ...values, validPassword: e.currentTarget.value.length > 6 }); + setValues({ ...values, password: e.currentTarget.value.length > 6 }); }; return ( @@ -103,24 +103,24 @@ const Registration: React.FC = () => { { > {showPassword ? : } - {values.validPassword && values.validPassword !== undefined && } ) }} -- cgit v1.2.3 From 987c4ecc67dc3cd41d0db04727c942efe35d5c82 Mon Sep 17 00:00:00 2001 From: ilyayudovin Date: Fri, 28 Aug 2020 19:21:11 +0300 Subject: change onChange to onBlur event --- src/containers/Registration/Registration.tsx | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'src/containers/Registration/Registration.tsx') diff --git a/src/containers/Registration/Registration.tsx b/src/containers/Registration/Registration.tsx index 3269f6e..e250397 100644 --- a/src/containers/Registration/Registration.tsx +++ b/src/containers/Registration/Registration.tsx @@ -79,21 +79,29 @@ const Registration: React.FC = () => { const handleLogin = () => { history.push('/login'); }; - const handleClickShowPassword = () => { setShowPassword(prevState => !prevState); }; const handleMouseDownPassword = (event: React.MouseEvent) => { event.preventDefault(); }; - const handleUsernameChange = (e: React.ChangeEvent) => { - setValues({ ...values, username: e.currentTarget.value.length > 0 }); + const handleUsernameChange = (e: React.FocusEvent) => { + setValues({ + ...values, + username: e.currentTarget.value.length > 0 + }); }; - const handleEmailChange = (e: React.ChangeEvent) => { - setValues({ ...values, email: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(e.currentTarget.value) }); + const handleEmailChange = (e: React.FocusEvent) => { + setValues({ + ...values, + email: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(e.currentTarget.value) + }); }; - const handlePasswordChange = (e: React.ChangeEvent) => { - setValues({ ...values, password: e.currentTarget.value.length > 6 }); + const handlePasswordChange = (e: React.FocusEvent) => { + setValues({ + ...values, + password: e.currentTarget.value.length > 6 + }); }; return ( @@ -106,14 +114,14 @@ const Registration: React.FC = () => { error={!values.username} helperText={!values.username && 'This field is required'} required - onChange={handleUsernameChange} + onBlur={handleUsernameChange} /> { error={!values.password} helperText={!values.password && 'Should be at least 6 characters'} type={showPassword ? 'text' : 'password'} - onChange={handlePasswordChange} + onBlur={handlePasswordChange} InputProps={{ endAdornment: ( -- cgit v1.2.3 From be765bb98e19fdc755418cdf4d2eb19d0aa15ecd Mon Sep 17 00:00:00 2001 From: ilyayudovin Date: Fri, 28 Aug 2020 19:41:42 +0300 Subject: fix eslint errors --- src/containers/Registration/Registration.tsx | 42 +++++++++++++++------------- 1 file changed, 23 insertions(+), 19 deletions(-) (limited to 'src/containers/Registration/Registration.tsx') diff --git a/src/containers/Registration/Registration.tsx b/src/containers/Registration/Registration.tsx index e250397..955d900 100644 --- a/src/containers/Registration/Registration.tsx +++ b/src/containers/Registration/Registration.tsx @@ -1,4 +1,9 @@ -import React, {useState, useRef, FormEvent, useMemo} from 'react'; +import React, { + useState, + useRef, + FormEvent, + useMemo +} from 'react'; import { useHistory } from 'react-router-dom'; import { makeStyles } from '@material-ui/core/styles'; import { @@ -7,7 +12,7 @@ import { InputAdornment, IconButton } from '@material-ui/core'; -import { CheckCircle, Visibility, VisibilityOff } from '@material-ui/icons'; +import { Visibility, VisibilityOff } from '@material-ui/icons'; import { post } from '../../requests'; import { useAuth } from '../../hooks/useAuth'; @@ -46,9 +51,9 @@ interface ErrorStates { const Registration: React.FC = () => { const [values, setValues] = useState({ - username: undefined, - email: undefined, - password: undefined, + username: false, + email: false, + password: false }); const [showPassword, setShowPassword] = useState(false); @@ -60,16 +65,15 @@ const Registration: React.FC = () => { const history = useHistory(); const isValid = useMemo(() => { - return values.username && values.email && values.password; - },[values]); + return !values.username && !values.email && !values.password; + }, [values]); - const handleSubmit = (event: FormEvent) => { + const handleSubmit = (event:FormEvent) => { event.preventDefault(); const username = usernameRef.current?.value?.toLowerCase(); const password = passwordRef.current?.value; const email = emailRef.current?.value; if (username && password && isValid) { - console.log('yes'); post('/users', { username, password, email }) .then(() => login(username, password)) .then(() => history.push(`/profile/${username}`)); @@ -88,19 +92,19 @@ const Registration: React.FC = () => { const handleUsernameChange = (e: React.FocusEvent) => { setValues({ ...values, - username: e.currentTarget.value.length > 0 + username: e.currentTarget.value.length === 0 }); }; const handleEmailChange = (e: React.FocusEvent) => { setValues({ ...values, - email: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(e.currentTarget.value) + email: !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(e.currentTarget.value) }); }; const handlePasswordChange = (e: React.FocusEvent) => { setValues({ ...values, - password: e.currentTarget.value.length > 6 + password: e.currentTarget.value.length < 6 }); }; @@ -111,24 +115,24 @@ const Registration: React.FC = () => { { ) }} /> - +
Already have an account?
-- cgit v1.2.3 From 421a1e8d73714dce004e7682dfa3c52ccdb0f71f Mon Sep 17 00:00:00 2001 From: ilyayudovin Date: Fri, 28 Aug 2020 20:15:25 +0300 Subject: convert username input to lowercase --- src/containers/Registration/Registration.tsx | 55 +++++++++++++++------------- 1 file changed, 30 insertions(+), 25 deletions(-) (limited to 'src/containers/Registration/Registration.tsx') diff --git a/src/containers/Registration/Registration.tsx b/src/containers/Registration/Registration.tsx index 955d900..ff9af60 100644 --- a/src/containers/Registration/Registration.tsx +++ b/src/containers/Registration/Registration.tsx @@ -44,13 +44,13 @@ const useStyles = makeStyles(theme => ({ })); interface ErrorStates { - username: boolean | undefined; - email: boolean | undefined; - password: boolean | undefined; + username: boolean; + email: boolean; + password: boolean; } const Registration: React.FC = () => { - const [values, setValues] = useState({ + const [errors, setErrors] = useState({ username: false, email: false, password: false @@ -65,10 +65,10 @@ const Registration: React.FC = () => { const history = useHistory(); const isValid = useMemo(() => { - return !values.username && !values.email && !values.password; - }, [values]); + return !errors.username && !errors.email && !errors.password; + }, [errors]); - const handleSubmit = (event:FormEvent) => { + const handleSubmit = (event: FormEvent) => { event.preventDefault(); const username = usernameRef.current?.value?.toLowerCase(); const password = passwordRef.current?.value; @@ -89,25 +89,29 @@ const Registration: React.FC = () => { const handleMouseDownPassword = (event: React.MouseEvent) => { event.preventDefault(); }; - const handleUsernameChange = (e: React.FocusEvent) => { - setValues({ - ...values, - username: e.currentTarget.value.length === 0 + const handleUsernameChange = (event: React.FocusEvent) => { + setErrors({ + ...errors, + username: event.currentTarget.value.length === 0 }); }; - const handleEmailChange = (e: React.FocusEvent) => { - setValues({ - ...values, - email: !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(e.currentTarget.value) + const handleEmailChange = (event: React.FocusEvent) => { + setErrors({ + ...errors, + email: !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(event.currentTarget.value) }); }; - const handlePasswordChange = (e: React.FocusEvent) => { - setValues({ - ...values, - password: e.currentTarget.value.length < 6 + const handlePasswordChange = (event: React.FocusEvent) => { + setErrors({ + ...errors, + password: event.currentTarget.value.length < 6 }); }; + const handleToLowerCase = (e: React.ChangeEvent) => { + e.target.value = ("" + e.target.value).toLowerCase(); + }; + return ( <>
Sign Up
@@ -115,24 +119,25 @@ const Registration: React.FC = () => { Date: Fri, 28 Aug 2020 20:19:25 +0300 Subject: fix eslint errors --- src/containers/Registration/Registration.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/containers/Registration/Registration.tsx') diff --git a/src/containers/Registration/Registration.tsx b/src/containers/Registration/Registration.tsx index ff9af60..709d04e 100644 --- a/src/containers/Registration/Registration.tsx +++ b/src/containers/Registration/Registration.tsx @@ -109,7 +109,7 @@ const Registration: React.FC = () => { }; const handleToLowerCase = (e: React.ChangeEvent) => { - e.target.value = ("" + e.target.value).toLowerCase(); + e.target.value = e.target.value.toString().toLowerCase(); }; return ( -- cgit v1.2.3 From ae005b8444aacc4071512f38031043156b6854c4 Mon Sep 17 00:00:00 2001 From: ilyayudovin Date: Sat, 29 Aug 2020 00:22:27 +0300 Subject: hide error state onFocue input --- src/containers/Registration/Registration.tsx | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'src/containers/Registration/Registration.tsx') diff --git a/src/containers/Registration/Registration.tsx b/src/containers/Registration/Registration.tsx index 709d04e..e7c8874 100644 --- a/src/containers/Registration/Registration.tsx +++ b/src/containers/Registration/Registration.tsx @@ -44,16 +44,16 @@ const useStyles = makeStyles(theme => ({ })); interface ErrorStates { - username: boolean; - email: boolean; - password: boolean; + username: boolean | undefined; + email: boolean | undefined; + password: boolean | undefined; } const Registration: React.FC = () => { const [errors, setErrors] = useState({ - username: false, - email: false, - password: false + username: undefined, + email: undefined, + password: undefined }); const [showPassword, setShowPassword] = useState(false); @@ -112,6 +112,13 @@ const Registration: React.FC = () => { e.target.value = e.target.value.toString().toLowerCase(); }; + const handleFocus = (value: string) => () => { + setErrors({ + ...errors, + [value]: undefined + }); + }; + return ( <>
Sign Up
@@ -124,6 +131,7 @@ const Registration: React.FC = () => { required onBlur={handleUsernameChange} onInput={handleToLowerCase} + onFocus={handleFocus('username')} /> { error={errors.email} helperText={errors.email && 'Invalid email address'} onBlur={handleEmailChange} + onFocus={handleFocus('email')} /> { helperText={errors.password && 'Should be at least 6 characters'} type={showPassword ? 'text' : 'password'} onBlur={handlePasswordChange} + onFocus={handleFocus('password')} InputProps={{ endAdornment: ( -- cgit v1.2.3 From e3d230ffcc344b9027b19a136525f105149f0982 Mon Sep 17 00:00:00 2001 From: ilyayudovin Date: Sat, 29 Aug 2020 02:20:22 +0300 Subject: add fixed height for inputs to avoid jumping errorText --- src/containers/Registration/Registration.tsx | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/containers/Registration/Registration.tsx') diff --git a/src/containers/Registration/Registration.tsx b/src/containers/Registration/Registration.tsx index e7c8874..422cf92 100644 --- a/src/containers/Registration/Registration.tsx +++ b/src/containers/Registration/Registration.tsx @@ -40,6 +40,9 @@ const useStyles = makeStyles(theme => ({ marginLeft: 10, color: 'green', cursor: 'pointer' + }, + textField: { + height: 70 } })); @@ -132,6 +135,7 @@ const Registration: React.FC = () => { onBlur={handleUsernameChange} onInput={handleToLowerCase} onFocus={handleFocus('username')} + className={classes.textField} /> { helperText={errors.email && 'Invalid email address'} onBlur={handleEmailChange} onFocus={handleFocus('email')} + className={classes.textField} /> { ) }} + className={classes.textField} /> -- cgit v1.2.3 From 868e380262dcef15d9645ceb912d18701ecb61fb Mon Sep 17 00:00:00 2001 From: eug-vs Date: Sat, 29 Aug 2020 14:29:28 +0300 Subject: feat: use yup and formik --- src/containers/Registration/Registration.tsx | 203 +++++++++++---------------- 1 file changed, 84 insertions(+), 119 deletions(-) (limited to 'src/containers/Registration/Registration.tsx') diff --git a/src/containers/Registration/Registration.tsx b/src/containers/Registration/Registration.tsx index 422cf92..b5c56e6 100644 --- a/src/containers/Registration/Registration.tsx +++ b/src/containers/Registration/Registration.tsx @@ -1,10 +1,7 @@ -import React, { - useState, - useRef, - FormEvent, - useMemo -} from 'react'; +import React, { useState } from 'react'; import { useHistory } from 'react-router-dom'; +import { Formik, Form, Field } from 'formik'; +import * as Yup from 'yup'; import { makeStyles } from '@material-ui/core/styles'; import { TextField, @@ -16,6 +13,22 @@ import { Visibility, VisibilityOff } from '@material-ui/icons'; import { post } from '../../requests'; import { useAuth } from '../../hooks/useAuth'; +interface Fields { + username: string; + email: string; + password: string; +} + +const validationSchema = Yup.object({ + username: Yup.string() + .required('This field is required'), + email: Yup.string() + .email('Invalid email address') + .required('This field is required'), + password: Yup.string() + .min(6, 'Should be at least 6 characters') + .required('This field is required'), +}); const useStyles = makeStyles(theme => ({ root: { @@ -42,137 +55,89 @@ const useStyles = makeStyles(theme => ({ cursor: 'pointer' }, textField: { - height: 70 + height: theme.spacing(8) } })); -interface ErrorStates { - username: boolean | undefined; - email: boolean | undefined; - password: boolean | undefined; -} - const Registration: React.FC = () => { - const [errors, setErrors] = useState({ - username: undefined, - email: undefined, - password: undefined - }); - const [showPassword, setShowPassword] = useState(false); - const classes = useStyles(); - const usernameRef = useRef(); - const emailRef = useRef(); - const passwordRef = useRef(); const { login } = useAuth(); const history = useHistory(); - - const isValid = useMemo(() => { - return !errors.username && !errors.email && !errors.password; - }, [errors]); - - const handleSubmit = (event: FormEvent) => { - event.preventDefault(); - const username = usernameRef.current?.value?.toLowerCase(); - const password = passwordRef.current?.value; - const email = emailRef.current?.value; - if (username && password && isValid) { - post('/users', { username, password, email }) - .then(() => login(username, password)) - .then(() => history.push(`/profile/${username}`)); - } - }; + const [showPassword, setShowPassword] = useState(false); const handleLogin = () => { history.push('/login'); }; - const handleClickShowPassword = () => { - setShowPassword(prevState => !prevState); - }; - const handleMouseDownPassword = (event: React.MouseEvent) => { - event.preventDefault(); - }; - const handleUsernameChange = (event: React.FocusEvent) => { - setErrors({ - ...errors, - username: event.currentTarget.value.length === 0 - }); - }; - const handleEmailChange = (event: React.FocusEvent) => { - setErrors({ - ...errors, - email: !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(event.currentTarget.value) - }); - }; - const handlePasswordChange = (event: React.FocusEvent) => { - setErrors({ - ...errors, - password: event.currentTarget.value.length < 6 - }); - }; - const handleToLowerCase = (e: React.ChangeEvent) => { - e.target.value = e.target.value.toString().toLowerCase(); - }; + const handleSubmit = ({ username, email, password }: Fields) => { + post('/users', { username, email, password }) + .then(() => login(username, password)) + .then(() => history.push(`/profile/${username}`)); + } - const handleFocus = (value: string) => () => { - setErrors({ - ...errors, - [value]: undefined - }); + const handleClickShowPassword = () => { + setShowPassword(prevState => !prevState); }; return ( <>
Sign Up
-
- - - - - {showPassword ? : } - - - ) - }} - className={classes.textField} - /> - - + + {({ values, errors, touched, isSubmitting }) => ( +
+ + + + + {showPassword ? : } + + + ) + }} + className={classes.textField} + /> + + + )} +
Already have an account?
Date: Sat, 29 Aug 2020 15:30:48 +0300 Subject: feat: use Formik in Login form --- src/containers/Registration/Registration.tsx | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) (limited to 'src/containers/Registration/Registration.tsx') diff --git a/src/containers/Registration/Registration.tsx b/src/containers/Registration/Registration.tsx index b5c56e6..fb2dc8c 100644 --- a/src/containers/Registration/Registration.tsx +++ b/src/containers/Registration/Registration.tsx @@ -21,6 +21,7 @@ interface Fields { const validationSchema = Yup.object({ username: Yup.string() + .lowercase('Must be lowercase') .required('This field is required'), email: Yup.string() .email('Invalid email address') @@ -54,9 +55,6 @@ const useStyles = makeStyles(theme => ({ color: 'green', cursor: 'pointer' }, - textField: { - height: theme.spacing(8) - } })); const Registration: React.FC = () => { @@ -75,7 +73,7 @@ const Registration: React.FC = () => { .then(() => history.push(`/profile/${username}`)); } - const handleClickShowPassword = () => { + const toggleShowPassword = () => { setShowPassword(prevState => !prevState); }; @@ -88,7 +86,7 @@ const Registration: React.FC = () => { onSubmit={handleSubmit} > {({ values, errors, touched, isSubmitting }) => ( -
+ { error={touched.username && !!errors.username} helperText={touched.username && errors.username} required - className={classes.textField} as={TextField} /> { error={touched.email && !!errors.email} helperText={touched.email && errors.email} required - className={classes.textField} as={TextField} /> { InputProps={{ endAdornment: ( - + {showPassword ? : } ) }} - className={classes.textField} /> -- cgit v1.2.3 From b7aed6ed7df2cea67924d34154671afb75edb7c2 Mon Sep 17 00:00:00 2001 From: eug-vs Date: Sat, 29 Aug 2020 15:34:17 +0300 Subject: fix: resovle eslint errors --- src/containers/Registration/Registration.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/containers/Registration/Registration.tsx') diff --git a/src/containers/Registration/Registration.tsx b/src/containers/Registration/Registration.tsx index fb2dc8c..a3aedb3 100644 --- a/src/containers/Registration/Registration.tsx +++ b/src/containers/Registration/Registration.tsx @@ -28,7 +28,7 @@ const validationSchema = Yup.object({ .required('This field is required'), password: Yup.string() .min(6, 'Should be at least 6 characters') - .required('This field is required'), + .required('This field is required') }); const useStyles = makeStyles(theme => ({ @@ -54,7 +54,7 @@ const useStyles = makeStyles(theme => ({ marginLeft: 10, color: 'green', cursor: 'pointer' - }, + } })); const Registration: React.FC = () => { @@ -71,7 +71,7 @@ const Registration: React.FC = () => { post('/users', { username, email, password }) .then(() => login(username, password)) .then(() => history.push(`/profile/${username}`)); - } + }; const toggleShowPassword = () => { setShowPassword(prevState => !prevState); @@ -118,7 +118,7 @@ const Registration: React.FC = () => { InputProps={{ endAdornment: ( - + {showPassword ? : } -- cgit v1.2.3