Skip to content

Commit

Permalink
Merge pull request #2597 from getAlby/refactor-passwordview
Browse files Browse the repository at this point in the history
refactor: refactor password view into separate component
  • Loading branch information
bumi authored Aug 7, 2023
2 parents 9983a0b + 01e0d10 commit 9a8d071
Show file tree
Hide file tree
Showing 14 changed files with 167 additions and 164 deletions.
51 changes: 15 additions & 36 deletions src/app/components/PasswordForm/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import {
HiddenIcon,
VisibleIcon,
} from "@bitcoin-design/bitcoin-icons-react/outline";
import TextField from "@components/form/TextField";
import type { KeyPrefix } from "i18next";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import PasswordViewAdornment from "~/app/components/PasswordViewAdornment";

export type PasswordFormData = {
password: string;
Expand Down Expand Up @@ -34,7 +31,7 @@ const initialErrors: Record<string, errorMessage> = {
};

export default function PasswordForm<
T extends PasswordFormData = PasswordFormData,
T extends PasswordFormData = PasswordFormData
>({
formData,
setFormData,
Expand All @@ -44,8 +41,8 @@ export default function PasswordForm<
autoFocus = true,
}: Props<T>) {
const [errors, setErrors] = useState(initialErrors);
const [passwordView, setPasswordView] = useState(false);
const [passwordConfirmationView, setPasswordConfirmationView] =
const [passwordViewVisible, setPasswordViewVisible] = useState(false);
const [passwordConfirmationViewVisible, setPasswordConfirmationViewVisible] =
useState(false);
const { t } = useTranslation("translation", {
keyPrefix: i18nKeyPrefix,
Expand Down Expand Up @@ -96,7 +93,7 @@ export default function PasswordForm<
autoFocus={autoFocus}
id="password"
label={t("choose_password.label")}
type={passwordView ? "text" : "password"}
type={passwordViewVisible ? "text" : "password"}
required
onChange={handleChange}
minLength={minLength}
Expand All @@ -108,20 +105,11 @@ export default function PasswordForm<
}
onBlur={validate}
endAdornment={
<button
type="button"
tabIndex={-1}
className="flex justify-center items-center w-10 h-8"
onClick={() => {
setPasswordView(!passwordView);
<PasswordViewAdornment
onChange={(passwordView) => {
setPasswordViewVisible(passwordView);
}}
>
{passwordView ? (
<HiddenIcon className="h-6 w-6" />
) : (
<VisibleIcon className="h-6 w-6" />
)}
</button>
/>
}
/>
{errors.passwordErrorMessage && (
Expand All @@ -135,25 +123,16 @@ export default function PasswordForm<
<TextField
id="passwordConfirmation"
label={t("confirm_password.label")}
type={passwordConfirmationView ? "text" : "password"}
type={passwordConfirmationViewVisible ? "text" : "password"}
required
onChange={handleChange}
onBlur={validate}
endAdornment={
<button
type="button"
className="flex justify-center items-center w-10 h-8"
tabIndex={-1}
onClick={() =>
setPasswordConfirmationView(!passwordConfirmationView)
}
>
{passwordConfirmationView ? (
<HiddenIcon className="h-6 w-6" />
) : (
<VisibleIcon className="h-6 w-6" />
)}
</button>
<PasswordViewAdornment
onChange={(passwordView) => {
setPasswordConfirmationViewVisible(passwordView);
}}
/>
}
/>
{errors.passwordConfirmationErrorMessage && (
Expand Down
39 changes: 39 additions & 0 deletions src/app/components/PasswordViewAdornment/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import {
HiddenIcon,
VisibleIcon,
} from "@bitcoin-design/bitcoin-icons-react/outline";
import { useEffect, useState } from "react";

type Props = {
onChange: (viewingPassword: boolean) => void;
isRevealed?: boolean;
};

export default function PasswordViewAdornment({ onChange, isRevealed }: Props) {
const [_isRevealed, setRevealed] = useState(false);

// toggle the button if password view is handled by component itself
useEffect(() => {
if (typeof isRevealed !== "undefined") {
setRevealed(isRevealed);
}
}, [isRevealed]);

return (
<button
type="button"
tabIndex={-1}
className="flex justify-center items-center w-10 h-8"
onClick={() => {
setRevealed(!_isRevealed);
onChange(!_isRevealed);
}}
>
{_isRevealed ? (
<VisibleIcon className="h-6 w-6" />
) : (
<HiddenIcon className="h-6 w-6" />
)}
</button>
);
}
29 changes: 11 additions & 18 deletions src/app/components/mnemonic/MnemonicInputs/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import {
HiddenIcon,
VisibleIcon,
} from "@bitcoin-design/bitcoin-icons-react/filled";
import { wordlist } from "@scure/bip39/wordlists/english";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import PasswordViewAdornment from "~/app/components/PasswordViewAdornment";
import Input from "~/app/components/form/Input";

type MnemonicInputsProps = {
Expand Down Expand Up @@ -42,7 +39,7 @@ export default function MnemonicInputs({
const inputId = `mnemonic-word-${i}`;
return (
<div key={i} className="flex justify-center items-center">
<span className="w-7 text-gray-500 slashed-zero dark:text-neutral-500">
<span className="w-7 text-gray-500 slashed-zero dark:text-neutral-500 ml-1 -mr-1">
{i + 1}.
</span>
<div className="relative">
Expand All @@ -53,7 +50,7 @@ export default function MnemonicInputs({
onBlur={() => setRevealedIndex(undefined)}
readOnly={readOnly}
block={false}
className="w-24 text-center"
className="w-20 text-center"
list={readOnly ? undefined : "wordlist"}
value={isRevealed ? word : word.length ? "•••••" : ""}
onChange={(e) => {
Expand All @@ -69,18 +66,14 @@ export default function MnemonicInputs({
);
}}
endAdornment={
<button
type="button"
tabIndex={-1}
className="mr-2"
onClick={() => document.getElementById(inputId)?.focus()}
>
{isRevealed ? (
<VisibleIcon className="h-6 w-6" />
) : (
<HiddenIcon className="h-6 w-6" />
)}
</button>
<PasswordViewAdornment
isRevealed={isRevealed}
onChange={(passwordView) => {
if (passwordView) {
document.getElementById(inputId)?.focus();
}
}}
/>
}
/>
</div>
Expand Down
22 changes: 5 additions & 17 deletions src/app/screens/Accounts/NostrSettings/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
import {
HiddenIcon,
VisibleIcon,
} from "@bitcoin-design/bitcoin-icons-react/filled";
import Container from "@components/Container";
import Loading from "@components/Loading";
import { FormEvent, useCallback, useEffect, useState } from "react";
Expand All @@ -12,6 +8,7 @@ import Alert from "~/app/components/Alert";
import Button from "~/app/components/Button";
import { ContentBox } from "~/app/components/ContentBox";
import InputCopyButton from "~/app/components/InputCopyButton";
import PasswordViewAdornment from "~/app/components/PasswordViewAdornment";
import TextField from "~/app/components/form/TextField";
import api, { GetAccountRes } from "~/common/lib/api";
import { default as nostr, default as nostrlib } from "~/common/lib/nostr";
Expand Down Expand Up @@ -191,20 +188,11 @@ function NostrSettings() {
}}
endAdornment={
<div className="flex items-center gap-1 px-2">
<button
type="button"
tabIndex={-1}
className="flex justify-center items-center h-8"
onClick={() => {
setNostrPrivateKeyVisible(!nostrPrivateKeyVisible);
<PasswordViewAdornment
onChange={(passwordView) => {
setNostrPrivateKeyVisible(passwordView);
}}
>
{nostrPrivateKeyVisible ? (
<HiddenIcon className="h-6 w-6" />
) : (
<VisibleIcon className="h-6 w-6" />
)}
</button>
/>
<InputCopyButton value={nostrPrivateKey} className="w-6" />
</div>
}
Expand Down
25 changes: 7 additions & 18 deletions src/app/screens/Unlock/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
import {
HiddenIcon,
VisibleIcon,
} from "@bitcoin-design/bitcoin-icons-react/outline";
import AlbyLogo from "@components/AlbyLogo";
import Button from "@components/Button";
import Container from "@components/Container";
Expand All @@ -10,13 +6,14 @@ import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { useLocation, useNavigate } from "react-router-dom";
import Hyperlink from "~/app/components/Hyperlink";
import PasswordViewAdornment from "~/app/components/PasswordViewAdornment";
import { useAccount } from "~/app/context/AccountContext";
import msg from "~/common/lib/msg";
import utils from "~/common/lib/utils";

function Unlock() {
const [password, setPassword] = useState("");
const [passwordView, setPasswordView] = useState(false);
const [passwordViewVisible, setPasswordViewVisible] = useState(false);
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
const navigate = useNavigate();
Expand Down Expand Up @@ -72,24 +69,16 @@ function Unlock() {
<div className="mb-5">
<Input
placeholder={t("unlock_password")}
type={passwordView ? "text" : "password"}
type={passwordViewVisible ? "text" : "password"}
autoFocus
value={password}
onChange={handlePasswordChange}
endAdornment={
<button
type="button"
className="flex justify-center items-center w-10 h-8"
onClick={() => {
setPasswordView(!passwordView);
<PasswordViewAdornment
onChange={(passwordView) => {
setPasswordViewVisible(passwordView);
}}
>
{passwordView ? (
<HiddenIcon className="h-6 w-6" />
) : (
<VisibleIcon className="h-6 w-6" />
)}
</button>
/>
}
/>
{error && (
Expand Down
28 changes: 9 additions & 19 deletions src/app/screens/connectors/ConnectCitadel/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import {
HiddenIcon,
VisibleIcon,
} from "@bitcoin-design/bitcoin-icons-react/outline";
import logo from "/static/assets/icons/citadel.png";
import CompanionDownloadInfo from "@components/CompanionDownloadInfo";
import ConnectorForm from "@components/ConnectorForm";
import TextField from "@components/form/TextField";
Expand All @@ -10,16 +7,15 @@ import { useState } from "react";
import { Trans, useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
import { toast } from "react-toastify";
import PasswordViewAdornment from "~/app/components/PasswordViewAdornment";
import msg from "~/common/lib/msg";

import logo from "/static/assets/icons/citadel.png";

export default function ConnectCitadel() {
const navigate = useNavigate();
const { t } = useTranslation("translation", {
keyPrefix: "choose_connector.citadel",
});
const [passwordView, setPasswordView] = useState(false);
const [passwordViewVisible, setPasswordViewVisible] = useState(false);
const [formData, setFormData] = useState({
password: "",
url: "",
Expand Down Expand Up @@ -116,22 +112,16 @@ export default function ConnectCitadel() {
label={t("password.label")}
id="password"
autoComplete="new-password"
type={passwordView ? "text" : "password"}
type={passwordViewVisible ? "text" : "password"}
autoFocus={true}
required
onChange={handleChange}
endAdornment={
<button
type="button"
className="flex justify-center items-center w-10 h-8"
onClick={() => setPasswordView(!passwordView)}
>
{passwordView ? (
<HiddenIcon className="h-6 w-6" />
) : (
<VisibleIcon className="h-6 w-6" />
)}
</button>
<PasswordViewAdornment
onChange={(passwordView) => {
setPasswordViewVisible(passwordView);
}}
/>
}
/>
</div>
Expand Down
25 changes: 6 additions & 19 deletions src/app/screens/connectors/ConnectCommando/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import {
HiddenIcon,
VisibleIcon,
} from "@bitcoin-design/bitcoin-icons-react/outline";
import logo from "/static/assets/icons/core_ln.svg";
import Button from "@components/Button";
import ConnectorForm from "@components/ConnectorForm";
import TextField from "@components/form/TextField";
Expand All @@ -11,10 +8,9 @@ import { useState } from "react";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
import { toast } from "react-toastify";
import PasswordViewAdornment from "~/app/components/PasswordViewAdornment";
import msg from "~/common/lib/msg";

import logo from "/static/assets/icons/core_ln.svg";

export default function ConnectCommando() {
const navigate = useNavigate();
const { t } = useTranslation("translation", {
Expand Down Expand Up @@ -181,20 +177,11 @@ export default function ConnectCommando() {
autoComplete="new-password"
value={formData.privateKey}
endAdornment={
<button
type="button"
tabIndex={-1}
className="flex justify-center items-center w-10 h-8"
onClick={() => {
setCommandoPrivateKeyVisible(!commandoPrivateKeyVisible);
<PasswordViewAdornment
onChange={(passwordView) => {
setCommandoPrivateKeyVisible(passwordView);
}}
>
{commandoPrivateKeyVisible ? (
<HiddenIcon className="h-6 w-6" />
) : (
<VisibleIcon className="h-6 w-6" />
)}
</button>
/>
}
/>
</div>
Expand Down
Loading

0 comments on commit 9a8d071

Please sign in to comment.