From 1c7e602464d14a59c7e0ef0e33aebcc37abd8ca8 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Mon, 28 Feb 2022 16:40:16 -0800 Subject: [PATCH] Refactor and redesign LoginModal --- components/LoginModal/index.scss | 43 +++++++--- components/LoginModal/index.tsx | 141 +++++++++++++++++-------------- 2 files changed, 109 insertions(+), 75 deletions(-) diff --git a/components/LoginModal/index.scss b/components/LoginModal/index.scss index ea98dd58..e9628d99 100644 --- a/components/LoginModal/index.scss +++ b/components/LoginModal/index.scss @@ -1,14 +1,31 @@ -.LoginForm { - #fields { - display: flex; - flex-direction: column; - gap: $unit; - } - .fieldset { - display: flex; - flex-direction: column; - gap: 4px; - margin-bottom: 8px; - } -} +.Login.Dialog form { + display: flex; + flex-direction: column; + gap: $unit / 2; + margin-bottom: $unit; + .Button { + font-size: $font-regular; + padding: ($unit * 1.5) ($unit * 2); + width: 100%; + + &.btn-disabled { + background: $grey-90; + color: $grey-70; + cursor: not-allowed; + } + + &:not(.btn-disabled) { + background: $grey-90; + color: $grey-40; + + &:hover { + background: $grey-80; + } + } + } + + input { + background: $grey-90; + } +} \ No newline at end of file diff --git a/components/LoginModal/index.tsx b/components/LoginModal/index.tsx index a3c4763b..e74f44f4 100644 --- a/components/LoginModal/index.tsx +++ b/components/LoginModal/index.tsx @@ -1,21 +1,18 @@ import React, { useState } from 'react' -import { withCookies, Cookies } from 'react-cookie' -import { createPortal } from 'react-dom' +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 Modal from '~components/Modal' -import Overlay from '~components/Overlay' +import CrossIcon from '~public/icons/Cross.svg' import './index.scss' -interface Props { - cookies: Cookies - close: () => void -} +interface Props {} interface ErrorMap { [index: string]: string @@ -26,31 +23,40 @@ 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,}))$/ const LoginModal = (props: Props) => { - const emailInput: React.RefObject = React.createRef() - const passwordInput: React.RefObject = React.createRef() - const form: React.RefObject[] = [emailInput, passwordInput] - + // Set up form states and error handling const [formValid, setFormValid] = useState(false) const [errors, setErrors] = useState({ email: '', password: '' }) - function handleChange(event: React.ChangeEvent) { - event.preventDefault() + // Cookies + const [cookies, setCookies] = useCookies() + // States + const [open, setOpen] = useState(false) + + // Set up form refs + const emailInput: React.RefObject = React.createRef() + const passwordInput: React.RefObject = React.createRef() + const form: React.RefObject[] = [emailInput, passwordInput] + + function handleChange(event: React.ChangeEvent) { const { name, value } = event.target - let newErrors = errors + let newErrors = {...errors} switch(name) { case 'email': - errors.email = emailRegex.test(value) - ? '' - : 'That email address is not valid' + if (value.length == 0) + newErrors.email = 'Please enter your email' + else if (!emailRegex.test(value)) + newErrors.email = 'That email address is not valid' + else + newErrors.email = '' break case 'password': - errors.password = value.length == 0 + newErrors.password = value.length == 0 ? 'Please enter your password' : '' break @@ -60,10 +66,10 @@ const LoginModal = (props: Props) => { } setErrors(newErrors) - setFormValid(validateForm()) + setFormValid(validateForm(newErrors)) } - function validateForm() { + function validateForm(errors: ErrorMap) { let valid = true Object.values(form).forEach( @@ -73,11 +79,11 @@ const LoginModal = (props: Props) => { Object.values(errors).forEach( (error) => error.length > 0 && (valid = false) ) - + return valid } - function submit(event: React.FormEvent) { + function login(event: React.FormEvent) { event.preventDefault() const body = { @@ -89,65 +95,76 @@ const LoginModal = (props: Props) => { if (formValid) { api.login(body) .then((response) => { - const cookies = props.cookies - const cookieObj = { user_id: response.data.user.id, username: response.data.user.username, access_token: response.data.access_token } - cookies.set('user', cookieObj, { path: '/'}) + setCookies('user', cookieObj, { path: '/'}) accountState.account.authorized = true accountState.account.user = { id: cookieObj.user_id, username: cookieObj.username } - props.close() + setOpen(false) }, (error) => { console.error(error) }) } } - return ( - createPortal( -
- {} } - > -
-
-
+ function openChange(open: boolean) { + setOpen(open) + setErrors({ + email: '', + password: '' + }) + } -
-
-
- Forgot your password? - -
+ return ( + + +
  • + Log in +
  • +
    + + event.preventDefault() }> +
    + Log in + + + + + +
    + + +
    + +
    + + - - -
    , - document.body - ) + + + + ) } -export default withCookies(LoginModal) \ No newline at end of file +export default LoginModal \ No newline at end of file