import React, { useState } from 'react' import { useCookies } from 'react-cookie' import * as Dialog from '@radix-ui/react-dialog' import api from '~utils/api' import { accountState } from '~utils/accountState' import Button from '~components/Button' import Fieldset from '~components/Fieldset' import CrossIcon from '~public/icons/Cross.svg' import './index.scss' interface Props {} interface ErrorMap { [index: string]: string username: string email: string password: string passwordConfirmation: string } 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,}))$/ const SignupModal = (props: Props) => { // Set up form states and error handling const [formValid, setFormValid] = useState(false) const [errors, setErrors] = useState({ username: '', email: '', password: '', passwordConfirmation: '' }) // Cookies const [cookies, setCookies] = useCookies() // States const [open, setOpen] = useState(false) // Set up form refs const usernameInput = React.createRef() const emailInput = React.createRef() const passwordInput = React.createRef() const passwordConfirmationInput = React.createRef() const form = [usernameInput, emailInput, passwordInput, passwordConfirmationInput] function register(event: React.FormEvent) { event.preventDefault() const body = { user: { username: usernameInput.current?.value, email: emailInput.current?.value, password: passwordInput.current?.value, password_confirmation: passwordConfirmationInput.current?.value } } if (formValid) api.endpoints.users.create(body) .then((response) => { // Set cookies setCookies('user', response.data.user, { path: '/'}) // Set states accountState.account.authorized = true accountState.account.user = { id: response.data.user.id, username: response.data.user.username } // Close the modal setOpen(false) }, (error) => { console.error(error) }) .catch(error => { console.error(error) }) } function handleNameChange(event: React.ChangeEvent) { event.preventDefault() const fieldName = event.target.name const value = event.target.value if (value.length >= 3) { api.check(fieldName, value) .then((response) => { processNameCheck(fieldName, value, response.data.available) }, (error) => { console.error(error) }) } else { validateName(fieldName, value) } } function processNameCheck(fieldName: string, value: string, available: boolean) { const newErrors = {...errors} if (available) { // Continue checking for errors newErrors[fieldName] = '' setErrors(newErrors) setFormValid(true) validateName(fieldName, value) } else { newErrors[fieldName] = `This ${fieldName} is already in use` setErrors(newErrors) setFormValid(false) } } function validateName(fieldName: string, value: string) { let newErrors = {...errors} switch(fieldName) { case 'username': if (value.length < 3) newErrors.username = 'Username must be at least 3 characters' else if (value.length > 20) newErrors.username = 'Username must be less than 20 characters' else newErrors.username = '' break case 'email': newErrors.email = emailRegex.test(value) ? '' : 'That email address is not valid' break default: break } setErrors(newErrors) setFormValid(validateForm(newErrors)) } function handlePasswordChange(event: React.ChangeEvent) { event.preventDefault() const { name, value } = event.target let newErrors = {...errors} switch(name) { case 'password': newErrors.password = passwordInput.current?.value.includes(usernameInput.current?.value!) ? 'Your password should not contain your username' : '' break case 'password': newErrors.password = value.length < 8 ? 'Password must be at least 8 characters' : '' break case 'confirm_password': newErrors.passwordConfirmation = passwordInput.current?.value === passwordConfirmationInput.current?.value ? '' : 'Your passwords don\'t match' break default: break } setErrors(newErrors) setFormValid(validateForm(newErrors)) } function validateForm(errors: ErrorMap) { let valid = true Object.values(form).forEach( (input) => input.current?.value.length == 0 && (valid = false) ) Object.values(errors).forEach( (error) => error.length > 0 && (valid = false) ) return valid } function openChange(open: boolean) { setOpen(open) setErrors({ username: '', email: '', password: '', passwordConfirmation: '' }) } return (
  • Sign up
  • event.preventDefault() }>
    Sign up
    By signing up, I agree to the
    Terms and Conditions and Usage Guidelines.
    ) } export default SignupModal