diff --git a/components/core/Auth/TwitterSignup.js b/components/core/Auth/TwitterSignup.js index 1bcddcf0..eb627777 100644 --- a/components/core/Auth/TwitterSignup.js +++ b/components/core/Auth/TwitterSignup.js @@ -1,10 +1,12 @@ import * as React from "react"; import * as System from "~/components/system"; import * as Validations from "~/common/validations"; +import * as Actions from "~/common/actions"; import Field from "~/components/core/Field"; import { AnimateSharedLayout, motion } from "framer-motion"; +import { LoaderSpinner } from "~/components/system/components/Loaders"; import { css } from "@emotion/react"; import { useForm } from "~/common/hooks"; @@ -24,7 +26,40 @@ const useTwitterSignup = () => { return { ...handlers, scene }; }; -const handleValidation = ({ username, email, acceptTerms }, errors) => { +const useCheckUser = () => { + const MESSAGE = "The username is taken."; + + const usernamesAllowed = React.useRef([]); + const usernamesTaken = React.useRef([]); + + return async ({ username }, errors) => { + if (usernamesAllowed.current.some((value) => value === username)) { + return; + } + + if (usernamesTaken.current.some((value) => value === username)) { + errors.username = MESSAGE; + return; + } + + const response = await Actions.checkUsername({ + username, + }); + if (response.data) { + errors.username = "The username is taken."; + usernamesTaken.current.push(username); + return; + } + usernamesAllowed.current.push(username); + }; +}; + +const createValidations = (validateUsername) => async ( + { username, email, acceptTerms }, + errors +) => { + await validateUsername({ username }, errors); + if (!Validations.username(username)) errors.username = "Invalid username"; // Note(amine): username should not be an email if (Validations.email(username)) errors.username = "Username shouldn't be an email"; @@ -49,14 +84,18 @@ export default function TwitterSignup({ onSignupWithVerification, }) { const { scene, goToVerification } = useTwitterSignup(); + + const validateUsername = useCheckUser(); + const { getFieldProps, getFormProps, values: { email, username }, isSubmitting, + isValidating, } = useForm({ initialValues: { username: "", email: initialEmail, acceptTerms: false }, - validate: handleValidation, + validate: createValidations(validateUsername), onSubmit: async ({ username, email }) => { if (email !== initialEmail) { const response = await createVerification({ email }); @@ -84,6 +123,22 @@ export default function TwitterSignup({ placeholder="Username" name="username" type="text" + success="The username is available." + icon={ + isValidating + ? () => ( + + ) + : null + } {...getFieldProps("username")} style={{ backgroundColor: "rgba(242,242,247,0.5)" }} />