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 0000000..b47d0c6
--- /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 763feb9..8c3ed88 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 c20abab..41ec212 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 0000000..2e4acea
--- /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 a662e45..4bff894 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 15b6b29..ffb673e 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 && (