From bf2e1b0ee2d53d2a0faaa9260fd451b782becb9e Mon Sep 17 00:00:00 2001 From: Maria Rushkova <66270386+mrushkova@users.noreply.github.com> Date: Wed, 5 Jan 2022 16:55:52 +0100 Subject: [PATCH] Create profile errors (#174) * Change clear buttons * Add name creating errors * Disable Next button on error * Add useNameError hook --- .../src/components/Form/NameError.tsx | 44 +++++++++++++++++++ .../src/components/Form/inputStyles.ts | 16 +++++++ .../src/components/Icons/ClearIcon.tsx | 15 +++++++ .../src/components/Icons/ClearIconFull.tsx | 31 +++++++++++++ .../src/components/Modals/ProfileModal.tsx | 29 ++++-------- .../components/Modals/UserCreationModal.tsx | 30 ++++++++++--- .../react-chat/src/hooks/useNameError.tsx | 40 +++++++++++++++++ 7 files changed, 178 insertions(+), 27 deletions(-) create mode 100644 packages/react-chat/src/components/Form/NameError.tsx create mode 100644 packages/react-chat/src/components/Icons/ClearIconFull.tsx create mode 100644 packages/react-chat/src/hooks/useNameError.tsx diff --git a/packages/react-chat/src/components/Form/NameError.tsx b/packages/react-chat/src/components/Form/NameError.tsx new file mode 100644 index 00000000..b47d0c62 --- /dev/null +++ b/packages/react-chat/src/components/Form/NameError.tsx @@ -0,0 +1,44 @@ +import React from "react"; +import styled from "styled-components"; + +import { NameErrors } from "../../hooks/useNameError"; +import { Hint } from "../Modals/ModalStyle"; + +type NameErrorProps = { + error: NameErrors; +}; + +export function NameError({ error }: NameErrorProps) { + switch (error) { + case NameErrors.NoError: + return null; + case NameErrors.NameExists: + return ( + + Sorry, the name you have chosen is not allowed, try picking another + username + + ); + case NameErrors.BadCharacters: + return ( + + Only letters, numbers, underscores and hypens allowed + + ); + case NameErrors.EndingWithEth: + return ( + + Usernames ending with “_eth” or "-eth" are not allowed + + ); + case NameErrors.TooLong: + return 24 character username limit; + } +} + +const ErrorText = styled(Hint)` + color: ${({ theme }) => theme.redColor}; + text-align: center; + width: 328px; + margin: 8px 0; +`; diff --git a/packages/react-chat/src/components/Form/inputStyles.ts b/packages/react-chat/src/components/Form/inputStyles.ts index 763feb97..8c3ed884 100644 --- a/packages/react-chat/src/components/Form/inputStyles.ts +++ b/packages/react-chat/src/components/Form/inputStyles.ts @@ -69,9 +69,25 @@ export const InputBtn = styled.button` border-radius: 6px; `; +export const NameInputWrapper = styled.div` + position: relative; +`; + export const NameInput = styled.input` width: 328px; padding: 11px 16px; ${inputStyles} `; + +export const ClearBtn = styled.button` + position: absolute; + right: 16px; + top: 50%; + transform: translateY(-50%); + border-radius: 50%; + + & > svg { + fill: ${({ theme }) => theme.secondary}; + } +`; diff --git a/packages/react-chat/src/components/Icons/ClearIcon.tsx b/packages/react-chat/src/components/Icons/ClearIcon.tsx index c20abab7..41ec2120 100644 --- a/packages/react-chat/src/components/Icons/ClearIcon.tsx +++ b/packages/react-chat/src/components/Icons/ClearIcon.tsx @@ -26,6 +26,21 @@ export function ClearSvg({ height, width, className }: ClearSvgProps) { ); } + + +; + export const ClearIcon = () => { return ; }; diff --git a/packages/react-chat/src/components/Icons/ClearIconFull.tsx b/packages/react-chat/src/components/Icons/ClearIconFull.tsx new file mode 100644 index 00000000..2e4acea6 --- /dev/null +++ b/packages/react-chat/src/components/Icons/ClearIconFull.tsx @@ -0,0 +1,31 @@ +import React from "react"; +import styled from "styled-components"; + +type ClearSvgFullProps = { + width: number; + height: number; + className?: string; +}; + +export function ClearSvgFull({ height, width, className }: ClearSvgFullProps) { + return ( + + + + ); +} + +const Icon = styled.svg` + fill: ${({ theme }) => theme.secondary}; +`; diff --git a/packages/react-chat/src/components/Modals/ProfileModal.tsx b/packages/react-chat/src/components/Modals/ProfileModal.tsx index a662e459..4bff8941 100644 --- a/packages/react-chat/src/components/Modals/ProfileModal.tsx +++ b/packages/react-chat/src/components/Modals/ProfileModal.tsx @@ -9,8 +9,13 @@ import { useToasts } from "../../contexts/toastProvider"; import { useManageContact } from "../../hooks/useManageContact"; import { copy } from "../../utils"; import { buttonStyles } from "../Buttons/buttonStyle"; -import { inputStyles, NameInput } from "../Form/inputStyles"; -import { ClearSvg } from "../Icons/ClearIcon"; +import { + ClearBtn, + inputStyles, + NameInput, + NameInputWrapper, +} from "../Form/inputStyles"; +import { ClearSvgFull } from "../Icons/ClearIconFull"; import { CopySvg } from "../Icons/CopyIcon"; import { EditSvg } from "../Icons/EditIcon"; import { LeftIconSvg } from "../Icons/LeftIcon"; @@ -124,14 +129,14 @@ export const ProfileModal = () => { value={customNameInput} onChange={(e) => setCustomNameInput(e.currentTarget.value)} /> - {contact.customName && ( + {customNameInput && ( { setCustomName(undefined); setCustomNameInput(""); }} > - + )} @@ -401,22 +406,6 @@ const CopyButton = styled.button` } `; -const ClearBtn = styled.button` - position: absolute; - right: 16px; - top: 50%; - transform: translateY(-50%); - border-radius: 50%; - - & > svg { - fill: ${({ theme }) => theme.secondary}; - } -`; - -const NameInputWrapper = styled.div` - position: relative; -`; - const RequestSection = styled.div` width: 100%; display: flex; diff --git a/packages/react-chat/src/components/Modals/UserCreationModal.tsx b/packages/react-chat/src/components/Modals/UserCreationModal.tsx index 15b6b29a..ffb673ea 100644 --- a/packages/react-chat/src/components/Modals/UserCreationModal.tsx +++ b/packages/react-chat/src/components/Modals/UserCreationModal.tsx @@ -9,15 +9,18 @@ import { useWalletIdentity, } from "../../contexts/identityProvider"; import { useModal } from "../../contexts/modalProvider"; +import { useNameError } from "../../hooks/useNameError"; import { Contact } from "../../models/Contact"; import { decryptIdentity, loadEncryptedIdentity, saveIdentity, } from "../../utils"; -import { NameInput } from "../Form/inputStyles"; +import { NameError } from "../Form/NameError"; +import { ClearBtn, NameInput, NameInputWrapper } from "../Form/inputStyles"; import { AddIcon } from "../Icons/AddIcon"; import { ChainIcon } from "../Icons/ChainIcon"; +import { ClearSvgFull } from "../Icons/ClearIconFull"; import { LeftIconSvg } from "../Icons/LeftIcon"; import { UserLogo } from "../Members/UserLogo"; @@ -45,8 +48,10 @@ export function UserCreationModal() { const encryptedIdentity = useMemo(() => loadEncryptedIdentity(), []); const [customNameInput, setCustomNameInput] = useState(""); + const error = useNameError(customNameInput); const [nextStep, setNextStep] = useState(false); const { setModal } = useModal(UserCreationModalName); + return (
@@ -89,12 +94,23 @@ export function UserCreationModal() { )} {!nextStep && ( - setCustomNameInput(e.currentTarget.value)} - /> + + setCustomNameInput(e.currentTarget.value)} + maxLength={24} + /> + {customNameInput && ( + setCustomNameInput("")}> + + + )} + )} + + + {!nextStep && encryptedIdentity && !walletIdentity && (