Merge branch 'revamp-sign-in-up' into 'main'

Revamp sign in up

Closes #1746

See merge request soapbox-pub/soapbox!3131
This commit is contained in:
Alex Gleason 2024-09-30 23:00:49 +00:00
commit 448298456b
10 changed files with 114 additions and 44 deletions

View File

@ -18,7 +18,7 @@ const Divider = ({ text, textSize = 'md' }: IDivider) => (
{text && (
<div className='relative flex justify-center'>
<span className='bg-white px-2 text-gray-700 dark:bg-gray-900 dark:text-gray-600' data-testid='divider-text'>
<span className='bg-white px-2 text-gray-700 dark:bg-primary-900 dark:text-gray-600' data-testid='divider-text'>
<Text size={textSize} tag='span' theme='inherit'>{text}</Text>
</span>
</div>

View File

@ -16,7 +16,7 @@ const NostrExtensionIndicator: React.FC = () => {
};
return (
<Stack space={2} className='rounded-lg bg-gray-100 p-2 dark:bg-gray-800'>
<Stack space={2} className='flex items-center rounded-lg bg-gray-100 p-2 dark:bg-gray-800'>
<Text size='xs'>
{window.nostr ? (
<FormattedMessage

View File

@ -17,7 +17,7 @@ const NostrLoginModal: React.FC<INostrLoginModal> = ({ onClose, step: firstStep
switch (step) {
case 'extension':
return <ExtensionStep onClickAlt={() => setStep('key-add')} onClose={handleClose} />;
return <ExtensionStep onClickAlt={() => setStep('key-add')} onClose={handleClose} isLogin />;
case 'key-add':
return <KeyAddStep onClose={handleClose} />;
default:

View File

@ -1,18 +1,28 @@
import React from 'react';
import { FormattedMessage } from 'react-intl';
import { Link } from 'react-router-dom';
import { openModal } from 'soapbox/actions/modals';
import { nostrExtensionLogIn } from 'soapbox/actions/nostr';
import EmojiGraphic from 'soapbox/components/emoji-graphic';
import { Button, Stack, Modal } from 'soapbox/components/ui';
import { useAppDispatch } from 'soapbox/hooks';
import { Button, Stack, Modal, Text, Divider, HStack } from 'soapbox/components/ui';
import { useAppDispatch, useInstance, useSoapboxConfig } from 'soapbox/hooks';
interface IExtensionStep {
isLogin?: boolean;
onClickAlt: () => void;
onClose(): void;
}
const ExtensionStep: React.FC<IExtensionStep> = ({ onClickAlt, onClose }) => {
const ExtensionStep: React.FC<IExtensionStep> = ({ isLogin, onClickAlt, onClose }) => {
const dispatch = useAppDispatch();
const instance = useInstance();
const { logo } = useSoapboxConfig();
const handleClose = () => {
onClose();
dispatch(openModal('NOSTR_SIGNUP'));
};
const onClick = () => {
dispatch(nostrExtensionLogIn());
@ -20,18 +30,48 @@ const ExtensionStep: React.FC<IExtensionStep> = ({ onClickAlt, onClose }) => {
};
return (
<Modal title={<FormattedMessage id='nostr_signup.siwe.title' defaultMessage='Sign in' />} onClose={onClose}>
<Stack space={6}>
<EmojiGraphic emoji='🔐' />
<Modal
title={isLogin ?
<FormattedMessage id='nostr_login.siwe.title' defaultMessage='Log in' /> : <FormattedMessage id='nostr_signup.siwe.title' defaultMessage='Sign up' />
}
width='sm'
onClose={onClose}
>
<Stack space={6} justifyContent='center' alignItems='center' className='pb-6'>
<Text weight='semibold'>
<FormattedMessage id='nostr_signin.siwe.welcome' defaultMessage='Welcome to {site_title}' values={{ site_title: instance.title }} />
</Text>
{logo ?
<div className='h-36 w-36'>
<img src={logo} alt='' />
</div>
:
<EmojiGraphic emoji='🔐' />
}
<Stack space={3}>
<Button theme='accent' size='lg' onClick={onClick}>
<FormattedMessage id='nostr_signup.siwe.action' defaultMessage='Sign in with extension' />
{isLogin ? <FormattedMessage id='nostr_login.siwe.action' defaultMessage='Log in with extension' /> : <FormattedMessage id='nostr_signup.siwe.action' defaultMessage='Sign up with extension' /> }
</Button>
<Button theme='transparent' onClick={onClickAlt}>
<FormattedMessage id='nostr_signup.siwe.alt' defaultMessage='Sign in with key' />
<Divider text='or' />
<Button theme={isLogin ? 'muted' : 'transparent'} onClick={onClickAlt} icon={require('@tabler/icons/outline/alert-triangle.svg')}>
{isLogin ? <FormattedMessage id='nostr_login.siwe.alt' defaultMessage='Log in with key' /> : <FormattedMessage id='nostr_signup.siwe.alt' defaultMessage={'Don\'t have an extension?'} /> }
</Button>
{isLogin && <HStack space={2} justifyContent='center'>
<Text size='xs'>
<FormattedMessage id='nostr_signup.siwe.new_user' defaultMessage='New on {site_title}?' values={{ site_title: instance.title }} />
</Text>
<Link to={'/'} className='text-xs text-blue-500' onClick={handleClose}>
<FormattedMessage id='nostr_login.siwe.sign_up' defaultMessage='Sign Up' />
</Link>
</HStack>}
</Stack>
</Stack>
</Modal>

View File

@ -4,7 +4,7 @@ import { FormattedMessage } from 'react-intl';
import { logInNostr } from 'soapbox/actions/nostr';
import EmojiGraphic from 'soapbox/components/emoji-graphic';
import { Button, Stack, Modal, Input, FormGroup, Form } from 'soapbox/components/ui';
import { Button, Stack, Modal, Input, FormGroup, Form, Divider } from 'soapbox/components/ui';
import { NKeys } from 'soapbox/features/nostr/keys';
import { useAppDispatch } from 'soapbox/hooks';
@ -43,9 +43,8 @@ const KeyAddStep: React.FC<IKeyAddStep> = ({ onClose }) => {
};
return (
<Modal title={<FormattedMessage id='nostr_signup.key-add.title' defaultMessage='Import Key' />} onClose={onClose}>
<Modal title={<FormattedMessage id='nostr_signup.key-add.title' defaultMessage='Import Key' />} width='sm' onClose={onClose}>
<Stack className='my-3' space={6}>
<NostrExtensionIndicator />
<EmojiGraphic emoji='🔑' />
@ -60,11 +59,20 @@ const KeyAddStep: React.FC<IKeyAddStep> = ({ onClose }) => {
/>
</FormGroup>
<Button theme='accent' size='lg' type='submit' disabled={!nsec}>
<FormattedMessage id='nostr_signup.key-add.key_button' defaultMessage='Add Key' />
</Button>
<Stack space={2}>
<Button theme='accent' size='lg' type='submit' disabled={!nsec}>
<FormattedMessage id='nostr_signup.key-add.key_button' defaultMessage='Add Key' />
</Button>
<Divider text='or' />
<NostrExtensionIndicator />
</Stack>
</Stack>
</Form>
</Stack>
</Modal>
);

View File

@ -11,7 +11,7 @@ interface INostrSignupModal {
onClose: (type?: string) => void;
}
const NostrSigninModal: React.FC<INostrSignupModal> = ({ onClose }) => {
const NostrSignUpModal: React.FC<INostrSignupModal> = ({ onClose }) => {
const [step, setStep] = useState<Step>(window.nostr ? 'extension' : 'key');
const handleClose = () => onClose('NOSTR_SIGNUP');
@ -28,6 +28,6 @@ const NostrSigninModal: React.FC<INostrSignupModal> = ({ onClose }) => {
}
};
export default NostrSigninModal;
export default NostrSignUpModal;
export type { Step };

View File

@ -3,7 +3,7 @@ import { FormattedMessage } from 'react-intl';
import { openModal } from 'soapbox/actions/modals';
import EmojiGraphic from 'soapbox/components/emoji-graphic';
import { Button, Stack, Modal } from 'soapbox/components/ui';
import { Button, Stack, Modal, Text, Divider } from 'soapbox/components/ui';
import { useAppDispatch } from 'soapbox/hooks';
import NostrExtensionIndicator from '../../nostr-login-modal/components/nostr-extension-indicator';
@ -23,9 +23,12 @@ const KeyStep: React.FC<IKeyStep> = ({ setStep, onClose }) => {
};
return (
<Modal title={<FormattedMessage id='nostr_signup.key.title' defaultMessage='You need a key to continue' />} onClose={onClose}>
<Stack className='my-3' space={6}>
<NostrExtensionIndicator />
<Modal title={<FormattedMessage id='nostr_signup.siwe.title' defaultMessage='Sign up' />} width='sm' onClose={onClose}>
<Stack className='my-3' alignItems='center' space={6}>
<Text weight='semibold'>
<FormattedMessage id='nostr_signup.key.title' defaultMessage='You need a key to continue' />
</Text>
<EmojiGraphic emoji='🔑' />
@ -38,6 +41,13 @@ const KeyStep: React.FC<IKeyStep> = ({ setStep, onClose }) => {
<FormattedMessage id='nostr_signup.has_key' defaultMessage='I already have a key' />
</Button>
</Stack>
</Stack>
<Stack space={4}>
<Divider text='or' />
<NostrExtensionIndicator />
</Stack>
</Modal>
);

View File

@ -7,7 +7,7 @@ import { logInNostr } from 'soapbox/actions/nostr';
import { startOnboarding } from 'soapbox/actions/onboarding';
import CopyableInput from 'soapbox/components/copyable-input';
import EmojiGraphic from 'soapbox/components/emoji-graphic';
import { Button, Stack, Modal, FormGroup, Text, Tooltip } from 'soapbox/components/ui';
import { Button, Stack, Modal, FormGroup, Text, Tooltip, HStack } from 'soapbox/components/ui';
import { useNostr } from 'soapbox/contexts/nostr-context';
import { NKeys } from 'soapbox/features/nostr/keys';
import { useAppDispatch, useInstance } from 'soapbox/hooks';
@ -68,33 +68,33 @@ const KeygenStep: React.FC<IKeygenStep> = ({ onClose }) => {
};
return (
<Modal title={<FormattedMessage id='nostr_signup.keygen.title' defaultMessage='Your new key' />} onClose={onClose}>
<Modal title={<FormattedMessage id='nostr_signup.keygen.title' defaultMessage='Your new key' />} width='sm' onClose={onClose}>
<Stack className='my-3' space={9}>
<EmojiGraphic emoji='🔑' />
<Stack alignItems='center'>
<Button theme='primary' size='lg' icon={require('@tabler/icons/outline/download.svg')} onClick={handleDownload}>
<FormattedMessage id='nostr_signup.keygen.download_key_button' defaultMessage='Download key' />
</Button>
</Stack>
<FormGroup labelText={<FormattedMessage id='nostr_signup.keygen.label_text' defaultMessage='Secret Key' />}>
<CopyableInput value={nsec} type='password' onCopy={handleCopy} />
</FormGroup>
<Stack className='rounded-xl bg-gray-100 p-4 dark:bg-gray-800'>
<Text>
<Text size='xs' className='text-justify' >
<FormattedMessage id='nostr_signup.keygen.text' defaultMessage='Back up your secret key in a secure place. If lost, your account cannot be recovered. Never share your secret key with anyone.' />
</Text>
</Stack>
<Stack alignItems='end'>
<HStack space={6} justifyContent='center' >
<Button theme='secondary' size='lg' icon={require('@tabler/icons/outline/download.svg')} onClick={handleDownload}>
<FormattedMessage id='nostr_signup.keygen.download_key_button' defaultMessage='Download key' />
</Button>
<Tooltip text='Download your key to continue' disabled={downloaded}>
<Button theme='accent' disabled={!downloaded} size='lg' onClick={handleNext}>
<FormattedMessage id='nostr_signup.keygen.next' defaultMessage='Next' />
</Button>
</Tooltip>
</Stack>
</HStack>
</Stack>
</Modal>
);

View File

@ -1165,12 +1165,17 @@
"new_group_panel.title": "Create Group",
"nostr_extension.found": "<link>Sign in</link> with browser extension.",
"nostr_extension.not_found": "Browser extension not found.",
"nostr_login.siwe.action": "Log in with extension",
"nostr_login.siwe.alt": "Log in with key",
"nostr_login.siwe.sign_up": "Sign Up",
"nostr_login.siwe.title": "Log in",
"nostr_panel.message": "Connect with any Nostr client.",
"nostr_panel.title": "Nostr Relay",
"nostr_relays.read_only": "Read-only",
"nostr_relays.read_write": "Read & write",
"nostr_relays.title": "Relays",
"nostr_relays.write_only": "Write-only",
"nostr_signin.siwe.welcome": "Welcome to {site_title}",
"nostr_signup.has_key": "I already have a key",
"nostr_signup.key-add.key_button": "Add Key",
"nostr_signup.key-add.title": "Import Key",
@ -1181,9 +1186,10 @@
"nostr_signup.keygen.next": "Next",
"nostr_signup.keygen.text": "Back up your secret key in a secure place. If lost, your account cannot be recovered. Never share your secret key with anyone.",
"nostr_signup.keygen.title": "Your new key",
"nostr_signup.siwe.action": "Sign in with extension",
"nostr_signup.siwe.alt": "Sign in with key",
"nostr_signup.siwe.title": "Sign in",
"nostr_signup.siwe.action": "Sign up with extension",
"nostr_signup.siwe.alt": "Don't have an extension?",
"nostr_signup.siwe.new_user": "New on {site_title}?",
"nostr_signup.siwe.title": "Sign up",
"notification.ditto:name_grant": "You were granted the name {acct}",
"notification.ditto:zap": "{name} zapped you {amount} sats",
"notification.favourite": "{name} liked your post",

View File

@ -1153,7 +1153,7 @@
"new_group_panel.action": "Criar Grupo",
"new_group_panel.subtitle": "Não encontrou o que procura? Crie seu próprio grupo privado ou público.",
"new_group_panel.title": "Criar Grupo",
"nostr_extension.found": "Faça login com a extensão do navegador.",
"nostr_extension.found": "<link>Faça login</link> com a extensão do navegador.",
"nostr_extension.not_found": "Extensão do navegador não encontrada.",
"nostr_panel.message": "Conecte-se com qualquer cliente Nostr.",
"nostr_panel.title": "Relay Nostr",
@ -1161,19 +1161,25 @@
"nostr_relays.read_write": "Leitura e escrita",
"nostr_relays.title": "Relays",
"nostr_relays.write_only": "Somente escrita",
"nostr_login.siwe.action": "Entrar com uma extensão",
"nostr_login.siwe.alt": "Entrar com uma chave",
"nostr_login.siwe.title": "Entrar",
"nostr_login.siwe.sign_up": "Cadastrar",
"nostr_signup.has_key": "Eu já tenho uma chave",
"nostr_signup.key-add.key_button": "Adicionar chave",
"nostr_signup.key-add.title": "Importar Chave",
"nostr_signup.key.title": "Você precisa de uma chave para continuar",
"nostr_signup.key_generate": "Gerar chave",
"nostr_signup.keygen.title": "Sua nova chave",
"nostr_signup.keygen.download_key_button": "Baixar chave",
"nostr_signup.keygen.label_text": "Chave secreta",
"nostr_signup.keygen.text": "Faça backup da sua chave secreta em um lugar seguro. Se for perdida, sua conta não poderá ser recuperada. Nunca compartilhe sua chave secreta com ninguém.",
"nostr_signup.keygen.next": "Proximo",
"nostr_signup.siwe.action": "Faça login com a extensão",
"nostr_signup.siwe.alt": "Faça login com a chave",
"nostr_signup.siwe.title": "Entrar",
"nostr_signup.keygen.text": "Faça backup da sua chave secreta em um lugar seguro. Se for perdida, sua conta não poderá ser recuperada. Nunca compartilhe sua chave secreta com ninguém.",
"nostr_signup.keygen.title": "Sua nova chave",
"nostr_signup.siwe.alt": "Não tem uma extensão?",
"nostr_signup.siwe.action": "Cadastre-se com uma extensão",
"nostr_signup.siwe.new_user": "Novo no {site_title}?",
"nostr_signup.siwe.title": "Cadastrar",
"nostr_signin.siwe.welcome": "Bem-vindo ao {site_title}",
"notification.ditto:name_grant": "Você recebeu o nome {acct}",
"notification.favourite": "{name} curtiu a sua postagem",
"notification.follow": "{name} te seguiu",