From 8fb34f2e85d346f86e1cc75dd3b9ebb7ed6114f9 Mon Sep 17 00:00:00 2001 From: Gorjan Petrovski Date: Fri, 17 Sep 2021 18:14:53 +0200 Subject: [PATCH] feat: improve 2fa styles based on feedback (#635) * feat: improve 2fa styles based on feedback * fix: preferences panes and dialogs electron compatibility * fix: no horizontal line when opening two factor activation * feat: improve two factor activation styles * feat: further 2fa style improvements * feat: padding 2fa widgets * feat: add padding between QR code and content * feat: refresh 2fa after passcode confirmation * feat: don't autocomplete passwords for DecoratedInput --- app/assets/icons/ic-check.svg | 3 + .../javascripts/components/DecoratedInput.tsx | 30 +++++-- app/assets/javascripts/components/Icon.tsx | 2 + .../javascripts/components/IconButton.tsx | 19 +++- app/assets/javascripts/components/Switch.tsx | 2 +- .../components/shared/ModalDialog.tsx | 38 +++++--- .../preferences/PreferencesView.tsx | 2 +- .../preferences/components/MenuItem.tsx | 1 + .../components/PreferencesPane.tsx | 18 ++-- .../panes/account/changeEmail/index.tsx | 40 ++++----- .../two-factor-auth/AuthAppInfoPopup.tsx | 26 ++++-- .../panes/two-factor-auth/Bullet.tsx | 7 ++ .../panes/two-factor-auth/CopyButton.tsx | 23 +++++ .../panes/two-factor-auth/SaveSecretKey.tsx | 50 ++++++----- .../panes/two-factor-auth/ScanQRCode.tsx | 68 +++++++-------- .../two-factor-auth/TwoFactorActivation.ts | 72 ++++++++++------ .../TwoFactorActivationView.tsx | 24 +++--- .../panes/two-factor-auth/TwoFactorAuth.ts | 61 +++++++------ .../two-factor-auth/TwoFactorAuthView.tsx | 86 ++++++++++++++----- .../two-factor-auth/TwoFactorSuccess.tsx | 36 ++++++++ .../panes/two-factor-auth/Verification.tsx | 43 +++++++--- app/assets/stylesheets/_preferences.scss | 1 - app/assets/stylesheets/_sn.scss | 60 +++++++++++++ package.json | 2 +- yarn.lock | 8 +- 25 files changed, 494 insertions(+), 228 deletions(-) create mode 100644 app/assets/icons/ic-check.svg create mode 100644 app/assets/javascripts/preferences/panes/two-factor-auth/Bullet.tsx create mode 100644 app/assets/javascripts/preferences/panes/two-factor-auth/CopyButton.tsx create mode 100644 app/assets/javascripts/preferences/panes/two-factor-auth/TwoFactorSuccess.tsx diff --git a/app/assets/icons/ic-check.svg b/app/assets/icons/ic-check.svg new file mode 100644 index 000000000..93a4a4a42 --- /dev/null +++ b/app/assets/icons/ic-check.svg @@ -0,0 +1,3 @@ + + + diff --git a/app/assets/javascripts/components/DecoratedInput.tsx b/app/assets/javascripts/components/DecoratedInput.tsx index e9058b6dd..fed3ded66 100644 --- a/app/assets/javascripts/components/DecoratedInput.tsx +++ b/app/assets/javascripts/components/DecoratedInput.tsx @@ -10,6 +10,7 @@ interface Props { text?: string; placeholder?: string; onChange?: (text: string) => void; + autocomplete?: boolean; } /** @@ -24,30 +25,47 @@ export const DecoratedInput: FunctionalComponent = ({ text, placeholder = '', onChange, + autocomplete = false, }) => { - const base = - 'rounded py-1.5 px-3 text-input my-1 h-8 flex flex-row items-center gap-4'; + const baseClasses = + 'rounded py-1.5 px-3 text-input my-1 h-8 flex flex-row items-center'; const stateClasses = disabled ? 'no-border bg-grey-5' : 'border-solid border-1 border-gray-300'; - const classes = `${base} ${stateClasses} ${className}`; + const classes = `${baseClasses} ${stateClasses} ${className}`; + const inputBaseClasses = 'w-full no-border color-black focus:shadow-none'; + const inputStateClasses = disabled ? 'overflow-ellipsis' : ''; return (
- {left} + {left?.map((leftChild, idx, arr) => ( + <> + {leftChild} + {idx < arr.length - 1 &&
} + + ))} + {left !== undefined &&
}
onChange && onChange((e.target as HTMLInputElement).value) } + data-lpignore={type !== 'password' ? true : false} + autocomplete={autocomplete ? 'on' : 'off'} />
- {right} + {right !== undefined &&
} + {right?.map((rightChild, idx, arr) => ( + <> + {rightChild} + {idx < arr.length - 1 &&
} + + ))}
); }; diff --git a/app/assets/javascripts/components/Icon.tsx b/app/assets/javascripts/components/Icon.tsx index 1a30ee761..7814ba9b6 100644 --- a/app/assets/javascripts/components/Icon.tsx +++ b/app/assets/javascripts/components/Icon.tsx @@ -26,6 +26,7 @@ import UserIcon from '../../icons/ic-user.svg'; import CopyIcon from '../../icons/ic-copy.svg'; import DownloadIcon from '../../icons/ic-download.svg'; import InfoIcon from '../../icons/ic-info.svg'; +import CheckIcon from '../../icons/ic-check.svg'; import { toDirective } from './utils'; import { FunctionalComponent } from 'preact'; @@ -58,6 +59,7 @@ const ICONS = { copy: CopyIcon, download: DownloadIcon, info: InfoIcon, + check: CheckIcon }; export type IconType = keyof typeof ICONS; diff --git a/app/assets/javascripts/components/IconButton.tsx b/app/assets/javascripts/components/IconButton.tsx index e15517419..e229a23ae 100644 --- a/app/assets/javascripts/components/IconButton.tsx +++ b/app/assets/javascripts/components/IconButton.tsx @@ -10,6 +10,15 @@ interface Props { className?: string; icon: IconType; + + iconClassName?: string; + + /** + * Button tooltip + */ + title: string; + + focusable: boolean; } /** @@ -18,18 +27,20 @@ interface Props { */ export const IconButton: FunctionComponent = ({ onClick, - className, + className = '', icon, + title, + focusable, }) => { const click = (e: MouseEvent) => { e.preventDefault(); onClick(); }; + const focusableClass = focusable ? '' : 'focus:shadow-none'; return (