From 305f0e1f88f9868e9472d959a50b76863e529ee1 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Tue, 1 Feb 2022 00:20:04 -0800 Subject: [PATCH] Refactor SignupModal --- components/SignupModal/index.tsx | 204 ++++++++++++++----------------- 1 file changed, 95 insertions(+), 109 deletions(-) diff --git a/components/SignupModal/index.tsx b/components/SignupModal/index.tsx index 845c67cc..19fdc515 100644 --- a/components/SignupModal/index.tsx +++ b/components/SignupModal/index.tsx @@ -1,6 +1,8 @@ -import React from 'react' +import React, { useContext, useState } from 'react' import { withCookies, Cookies } from 'react-cookie' import { createPortal } from 'react-dom' + +import AppContext from '~context/AppContext' import api from '~utils/api' import Button from '~components/Button' @@ -10,18 +12,11 @@ import Overlay from '~components/Overlay' import './index.scss' -// import New from '../../../assets/new' - interface Props { cookies: Cookies close: () => void } -interface State { - formValid: boolean - errors: ErrorMap -} - interface ErrorMap { [index: string]: string username: string @@ -32,117 +27,111 @@ interface ErrorMap { const emailRegex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ -class SignupModal extends React.Component { - usernameInput: React.RefObject - emailInput: React.RefObject - passwordInput: React.RefObject - passwordConfirmationInput: React.RefObject - form: React.RefObject[] +const SignupModal = (props: Props) => { + const { setAuthenticated } = useContext(AppContext) - constructor(props: Props) { - super(props) - this.state = { - formValid: false, - errors: { - username: '', - email: '', - password: '', - passwordConfirmation: '' - } - } - - this.usernameInput = React.createRef() - this.emailInput = React.createRef() - this.passwordInput = React.createRef() - this.passwordConfirmationInput = React.createRef() - this.form = [this.usernameInput, this.emailInput, this.passwordInput, this.passwordConfirmationInput] - } + const [formValid, setFormValid] = useState(false) + const [errors, setErrors] = useState({ + username: '', + email: '', + password: '', + passwordConfirmation: '' + }) + + const usernameInput = React.createRef() + const emailInput = React.createRef() + const passwordInput = React.createRef() + const passwordConfirmationInput = React.createRef() + const form = [usernameInput, emailInput, passwordInput, passwordConfirmationInput] - check = (event: React.ChangeEvent) => { + function check(event: React.ChangeEvent) { const name = event.target.name const value = event.target.value - if (value.length > 0 && this.state.errors[name].length == 0) { - const errors = this.state.errors + if (value.length > 0 && errors[name].length == 0) { + const newErrors = errors api.check(name, value) .then((response) => { if (!response.data.available) { - errors[name] = `This ${name} is already in use` + newErrors[name] = `This ${name} is already in use` } - this.setState({ errors: errors }) + setErrors(newErrors) }, (error) => { console.log(error) }) } } - process = (event: React.FormEvent) => { + function process(event: React.FormEvent) { event.preventDefault() const body = { user: { - username: this.usernameInput.current?.value, - email: this.emailInput.current?.value, - password: this.passwordInput.current?.value, - password_confirmation: this.passwordConfirmationInput.current?.value + username: usernameInput.current?.value, + email: emailInput.current?.value, + password: passwordInput.current?.value, + password_confirmation: passwordConfirmationInput.current?.value } } - if (this.state.formValid) { + if (formValid) { api.endpoints.users.create(body) .then((response) => { - const cookies = this.props.cookies + const cookies = props.cookies cookies.set('user', response.data.user, { path: '/'}) - this.props.close() + + setAuthenticated(true) + + props.close() }, (error) => { console.log(error) }) } } - validateForm = () => { + function validateForm() { let valid = true - Object.values(this.form).forEach( + Object.values(form).forEach( (input) => input.current?.value.length == 0 && (valid = false) ) - Object.values(this.state.errors).forEach( + Object.values(errors).forEach( (error) => error.length > 0 && (valid = false) ) return valid } - handleChange = (event: React.ChangeEvent) => { + function handleChange(event: React.ChangeEvent) { event.preventDefault() const { name, value } = event.target - const errors = this.state.errors + let newErrors = errors switch(name) { case 'username': - errors.username = value.length < 3 + newErrors.username = value.length < 3 ? 'Username must be at least 3 characters' : '' break case 'email': - errors.email = emailRegex.test(value) + newErrors.email = emailRegex.test(value) ? '' : 'That email address is not valid' break case 'password': - errors.password = value.length < 8 + newErrors.password = value.length < 8 ? 'Password must be at least 8 characters' : '' break case 'confirm_password': - errors.passwordConfirmation = this.passwordInput.current?.value === this.passwordConfirmationInput.current?.value + newErrors.passwordConfirmation = passwordInput.current?.value === passwordConfirmationInput.current?.value ? '' : 'Your passwords don\'t match' break @@ -151,67 +140,64 @@ class SignupModal extends React.Component { break } - this.setState({ errors: errors }) - this.setState({ formValid: this.validateForm() }) + setErrors(newErrors) + setFormValid(validateForm()) } - render() { - const errors = this.state.errors - return ( - createPortal( -
- {} } - > -
-
-
+ return ( + createPortal( +
+ {} } + > + +
+
-
+
-
+
-
-
-
- -
- -
- -
, - document.body - ) +
+
+
+ +
+ +
+ +
, + document.body ) - } + ) }