diff --git a/components/auth/SignUpView.tsx b/components/auth/SignUpView.tsx index bb88f4b01..f7a064ee3 100644 --- a/components/auth/SignUpView.tsx +++ b/components/auth/SignUpView.tsx @@ -1,77 +1,78 @@ import { FC, useEffect, useState } from 'react' -import { Logo, Modal, Button, Input } from '@components/ui' +import { Logo, Button, Input } from '@components/ui' import useSignup from '@lib/bigcommerce/use-signup' -import useLogin from '@lib/bigcommerce/use-login' import { useUI } from '@components/ui/context' +import { validate } from 'email-validator' interface Props {} +interface Error { + code: string + message: string +} + const LoginView: FC = () => { + // Form State const [email, setEmail] = useState('') - const [pass, setPass] = useState('') + const [password, setPassword] = useState('') + const [firstName, setFirstName] = useState('') + const [lastName, setLastName] = useState('') + const [loading, setLoading] = useState(false) + const [disabled, setDisabled] = useState(true) + const [message, setMessage] = useState('') const signup = useSignup() - const login = useLogin() - const { setModalView } = useUI() - // // Data about the currently logged in customer, it will update - // // automatically after a signup/login/logout - // const { data } = useCustomer() - // TODO: use this method. It can take more than 5 seconds to do a signup + const { setModalView, closeModal } = useUI() + const handleSignup = async () => { - // TODO: validate the password and email before calling the signup - // Passwords must be at least 7 characters and contain both alphabetic - // and numeric characters. try { + setLoading(true) + setMessage('') await signup({ - // This account already exists, so it will throw the "duplicated_email" error - email: 'luis@vercel.com', - firstName: 'Luis', - lastName: 'Alvarez', - password: 'luis123', + email, + firstName, + lastName, + password, }) - } catch (error) { - if (error.code === 'duplicated_email') { - // TODO: handle duplicated email - } - // Show a generic error saying that something bad happened, try again later + setLoading(false) + closeModal() + } catch ({ errors }) { + setMessage(errors[0].message) + setLoading(false) } } - const handleLogin = async () => { - // TODO: validate the password and email before calling the signup - // Passwords must be at least 7 characters and contain both alphabetic - // and numeric characters. - try { - await login({ - email: 'luis@vercel.com', - // This is an invalid password so it will throw the "invalid_credentials" error - password: 'luis1234', // will work with `luis123` - }) - } catch (error) { - if (error.code === 'invalid_credentials') { - // The email and password didn't match an existing account - } - // Show a generic error saying that something bad happened, try again later - } - } + useEffect(() => { + // Test for Alphanumeric password + const validPassword = /^(?=.*[a-zA-Z])(?=.*[0-9])/.test(password) + + // Unable to send form unless fields are valid. + setDisabled(!validate(email) || password.length < 7 || !validPassword) + }, [email, password]) return ( -
+
-
- -
-
- -
- - Don't have an account? + Do you have an account? {` `} { Component?: string | JSXElementConstructor width?: string | number loading?: boolean + disabled?: boolean } const Button: React.FC = forwardRef((props, buttonRef) => { @@ -28,10 +29,10 @@ const Button: React.FC = forwardRef((props, buttonRef) => { children, active, onClick, - disabled, width, Component = 'button', loading = false, + disabled = false, style = {}, ...rest } = props @@ -52,6 +53,7 @@ const Button: React.FC = forwardRef((props, buttonRef) => { { [s.slim]: variant === 'slim', [s.loading]: loading, + [s.disabled]: disabled, }, className ) @@ -64,6 +66,7 @@ const Button: React.FC = forwardRef((props, buttonRef) => { {...buttonProps} data-active={isPressed ? '' : undefined} className={rootClassName} + disabled={disabled} style={{ width, ...style, diff --git a/components/ui/Input/Input.module.css b/components/ui/Input/Input.module.css index 83570f065..ccaf833db 100644 --- a/components/ui/Input/Input.module.css +++ b/components/ui/Input/Input.module.css @@ -1,4 +1,5 @@ .root { - @apply focus:outline-none bg-primary focus:shadow-outline-gray border-none py-2 - px-6 w-full appearance-none transition duration-150 ease-in-out placeholder-accents-5 pr-10; + @apply focus:outline-none bg-primary focus:shadow-outline-gray py-2 + px-6 w-full appearance-none transition duration-150 ease-in-out + placeholder-accents-5 pr-10 border border-accents-3 text-accents-6; } diff --git a/package.json b/package.json index 58bd461b4..39939bbaf 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "bowser": "^2.11.0", "classnames": "^2.2.6", "cookie": "^0.4.1", + "email-validator": "^2.0.4", "intersection-observer": "^0.11.0", "js-cookie": "^2.2.1", "keen-slider": "^5.2.4", diff --git a/yarn.lock b/yarn.lock index e4d916590..b01e9bda2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3907,6 +3907,11 @@ elliptic@^6.5.3: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.0" +email-validator@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/email-validator/-/email-validator-2.0.4.tgz#b8dfaa5d0dae28f1b03c95881d904d4e40bfe7ed" + integrity sha512-gYCwo7kh5S3IDyZPLZf6hSS0MnZT8QmJFqYvbqlDZSbwdZlY6QZWxJ4i/6UhITOJ4XzyI647Bm2MXKCLqnJ4nQ== + emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"