diff options
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static/auth-page.js')
| -rw-r--r-- | packages/meshbay-hub/src/meshbay_hub/static/auth-page.js | 123 |
1 files changed, 94 insertions, 29 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/auth-page.js b/packages/meshbay-hub/src/meshbay_hub/static/auth-page.js index 70c48f2..09c4acf 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/auth-page.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/auth-page.js @@ -207,7 +207,9 @@ export function LoginPage({ onLogin }) { return html` <div class="page-center"> + <div class="welcome-backdrop" aria-hidden="true"></div> <div class="welcome"> + <div class="welcome-side"> <div class="card login-card"> <h2>${t('login.title')}</h2> <form onSubmit=${onSubmit}> @@ -234,6 +236,8 @@ export function LoginPage({ onLogin }) { <a href="#/reset">${t('login.forgot')}</a> </div> </div> + ${!platform.isNative && html`<${WelcomeLinks} />`} + </div> ${!platform.isNative && html`<${WelcomePitch} />`} </div> </div> @@ -244,20 +248,49 @@ export function LoginPage({ onLogin }) { // application the reader has already downloaded it, and the links point at the // project's own site rather than at whichever hub the application is set to. // -// Every sentence here is held to MESHBAY_DESIGN.md §2.3. "Data never transits -// the hub" is a claim the design makes; "the hub cannot read anything" is one it -// forbids (T3), which is why the list below says what never *reaches* the hub -// and stops there. "End-to-end" means device to node, as §2.3 defines it. +// Written for somebody who is not in IT: what it does for them first, how it +// works in three steps, and privacy said once, plainly. Every sentence is held +// to MESHBAY_DESIGN.md §2.3 — "your content never passes through meshbay.org" +// is a claim the design makes; "meshbay.org cannot read anything" is one it +// forbids (T3). "Encrypted all the way" means device to node, as §2.3 defines. const WELCOME_APPS = [ ['chat', 'welcome.app_chat'], ['image', 'welcome.app_photos'], ['video', 'welcome.app_media'], ['play', 'welcome.app_video'], ['music', 'welcome.app_music'], ]; +const WELCOME_STEPS = [ + ['home', 'welcome.step_home'], ['globe', 'welcome.step_anywhere'], + ['user', 'welcome.step_share'], +]; const WELCOME_USES = [ ['chat', 'welcome.use_chat'], ['image', 'welcome.use_photos'], ['cast', 'welcome.use_media'], ['pencil', 'welcome.use_apps'], ]; -const WELCOME_NEVER = ['welcome.never_transit', 'welcome.never_stored', 'welcome.never_e2e']; +const WELCOME_BADGES = ['welcome.badge_free', 'welcome.badge_open', + 'welcome.badge_no_ads', 'welcome.badge_no_tracking']; + +const REPO = 'https://git.meshbay.org/meshbay.git/about/'; +const WELCOME_DOCS = [ + ['folder', 'welcome.docs_source', [['welcome.docs_repo', REPO]]], + ['user', 'welcome.docs_user', [ + ['welcome.docs_quickstart', `${REPO}docs/QUICKSTART.md`], + ['welcome.docs_userguide', `${REPO}docs/USERGUIDE.md`]]], + ['gear', 'welcome.docs_devel', [ + ['welcome.docs_design', `${REPO}docs/MESHBAY_DESIGN.md`], + ['welcome.docs_protocol', `${REPO}docs/MESHBAY_NODE_PROTOCOL.md`]]], +]; + +// Under the sign-in form rather than at the foot of the text: on a desktop the +// text column runs far below the form, and these were the last thing on it. +function WelcomeLinks() { + return html` + <div class="welcome-links"> + <a class="welcome-cta" href="https://meshbay.org/downloads/"> + <${Icon} name="download" />${t('welcome.download')}</a> + <a class="welcome-legal" href="https://meshbay.org/legal/">${t('welcome.legal')}</a> + </div> + `; +} function WelcomePitch() { return html` @@ -268,8 +301,13 @@ function WelcomePitch() { ${WELCOME_APPS.map(([icon, key]) => html` <li key=${key}><${Icon} name=${icon} />${t(key)}</li>`)} </ul> - <p>${t('welcome.groups')}</p> - <p class="welcome-e2e"><${Icon} name="lock" /><span>${t('welcome.e2e')}</span></p> + + <h2 class="welcome-h">${t('welcome.how_title')}</h2> + <ol class="welcome-steps"> + ${WELCOME_STEPS.map(([icon, key]) => html` + <li key=${key}><span class="welcome-step-icon"><${Icon} name=${icon} /></span> + <span>${t(key)}</span></li>`)} + </ol> <h2 class="welcome-h">${t('welcome.uses_title')}</h2> <ul class="welcome-uses"> @@ -278,26 +316,51 @@ function WelcomePitch() { <span>${t(key)}</span></li>`)} </ul> - <div class="welcome-hub"> - <h2 class="welcome-h">${t('welcome.hub_title')}</h2> - <p>${t('welcome.hub_body')}</p> - <p class="welcome-hub-never">${t('welcome.hub_never')}</p> - <ul class="welcome-never"> - ${WELCOME_NEVER.map(key => html` - <li key=${key}><${Icon} name="check" /><span>${t(key)}</span></li>`)} - </ul> - <p class="welcome-hub-free">${t('welcome.hub_free')}</p> + <div class="welcome-private"> + <span class="welcome-private-icon"><${Icon} name="shield" /></span> + <div> + <h2 class="welcome-private-title">${t('welcome.private_title')}</h2> + <p>${t('welcome.private_body')}</p> + <ul class="welcome-badges"> + ${WELCOME_BADGES.map(key => html` + <li key=${key}><${Icon} name="check" />${t(key)}</li>`)} + </ul> + </div> </div> - <div class="welcome-links"> - <a class="welcome-cta" href="https://meshbay.org/downloads/"> - <${Icon} name="download" />${t('welcome.download')}</a> - <a class="welcome-legal" href="https://meshbay.org/legal/">${t('welcome.legal')}</a> + <div class="welcome-docs"> + <h2 class="welcome-h">${t('welcome.docs_title')}</h2> + <ul> + ${WELCOME_DOCS.map(([icon, label, links]) => html` + <li key=${label}><${Icon} name=${icon} /> + <span class="welcome-docs-label">${t(label)}</span> + <span class="welcome-docs-links">${links.map(([key, href], i) => html` + ${i > 0 && ' · '}<a key=${key} href=${href} target="_blank" + rel="noopener noreferrer">${t(key)}</a>`)}</span></li>`)} + </ul> </div> + </section> `; } +// The sign-in page's dark gradient backdrop and frosted card, without the +// pitch beside it — so Register (and its verify/recovery/done steps) sits on +// the same background and reads in the same dark theme as Login. A lone +// `.welcome-side` is centred by `.welcome`'s `justify-content`. +function AuthShell({ children }) { + return html` + <div class="page-center"> + <div class="welcome-backdrop" aria-hidden="true"></div> + <div class="welcome"> + <div class="welcome-side"> + ${children} + </div> + </div> + </div> + `; +} + export function RegisterPage() { const [username, setUsername] = useState(''); const [email, setEmail] = useState(''); @@ -312,7 +375,9 @@ export function RegisterPage() { const [recoveryMnemonic, setRecoveryMnemonic] = useState(''); const [recoverySaved, setRecoverySaved] = useState(false); const [recoveryCopied, setRecoveryCopied] = useState(false); - const [emailRecovery, setEmailRecovery] = useState(true); + // Off by default: mailing the recovery key is opt-in — the key is shown on + // screen to save, and sending a copy is the user's own choice to make. + const [emailRecovery, setEmailRecovery] = useState(false); const captcha = useCaptcha(); const onSubmit = async (e) => { @@ -411,7 +476,7 @@ export function RegisterPage() { if (phase === 'done') { return html` - <div class="page-center"> + <${AuthShell}> <div class="card login-card"> <h2>${t('register.verified_title')}</h2> <p style="text-align:center; margin-bottom:16px; color:var(--text-secondary)"> @@ -421,7 +486,7 @@ export function RegisterPage() { <p style="text-align:center; margin-bottom:16px">${t('invite.after_register')}</p>`} <a href="#/login" style="display:block; text-align:center">${t('register.go_login')}</a> </div> - </div> + </${AuthShell}> `; } @@ -434,7 +499,7 @@ export function RegisterPage() { } catch { /* clipboard blocked — the text is on screen to copy by hand */ } }; return html` - <div class="page-center"> + <${AuthShell}> <div class="card login-card"> <h2>${t('register.recovery_title')}</h2> <p style="margin-bottom:12px; color:var(--text-secondary)"> @@ -463,13 +528,13 @@ export function RegisterPage() { ${t('register.recovery_continue')} </button> </div> - </div> + </${AuthShell}> `; } if (phase === 'verify') { return html` - <div class="page-center"> + <${AuthShell}> <div class="card login-card"> <h2>${t('register.success_title')}</h2> <p style="text-align:center; margin-bottom:16px; color:var(--text-secondary)"> @@ -492,12 +557,12 @@ export function RegisterPage() { ${t('register.resend_sent')}</span>`} </div> </div> - </div> + </${AuthShell}> `; } return html` - <div class="page-center"> + <${AuthShell}> <div class="card login-card"> <h2>${t('register.title')}</h2> <form onSubmit=${onSubmit}> @@ -539,7 +604,7 @@ export function RegisterPage() { ${t('register.has_account')} <a href="#/login">${t('register.login_link')}</a> </div> </div> - </div> + </${AuthShell}> `; } |