aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src/meshbay_hub/static/auth-page.js
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-09-11 13:05:21 +0200
committerChristophe Besson <cbesson@gmail.com>2026-09-11 13:05:21 +0200
commitcab9ba28cfba9d90d0a6c4c00dbba852825f66c2 (patch)
tree890ce73f8d9d401b779245b851862721810800f0 /packages/meshbay-hub/src/meshbay_hub/static/auth-page.js
parente3c68b3416f8ea2c033d41ac263552833370ba18 (diff)
downloadmeshbay-cab9ba28cfba9d90d0a6c4c00dbba852825f66c2.tar.gz
feat(hub): say what MeshBay is on the sign-in page
The browser sign-in page now carries the project's pitch beside the form: what MeshBay is, the applications, what it is for, and what meshbay.org does and never sees, with links to the downloads and the legal pages. Text on the left and the form on the right on a desktop; one column, form first, below 1000px. Not shown in the desktop application, whose user has already downloaded it. All ten catalogues carry the text. Every claim is held to MESHBAY_DESIGN.md 2.3: the page says content never reaches the hub, not that the hub can read nothing (T3), and "end-to-end" means device to node. Signed out there is no sidebar, so the 960px main column sat at the left of the window and the sign-in, register and reset forms were centred in it (x=290 in 1440). `.page-center` pages now lift that cap. test_welcome_layout_measured.py measures the real stylesheet in Chrome: no horizontal overflow from 320 to 1440px, form first on narrow screens, form right of the text on desktops, pair centred in the window. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D9MCBBWSm9GhBESmqzJxNy
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.js62
1 files changed, 62 insertions, 0 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 4c00137..9ded87b 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/auth-page.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/auth-page.js
@@ -6,6 +6,7 @@ import {
hubFetch, navigate, session, HUB, loadAuth, _storeRecoveryKey,
} from './hub-client.js';
import * as platform from './platform.js';
+import { Icon } from './icon.js';
const PASSWORD_MIN_BITS = 60;
const PASSWORD_MIN_LEN = 12;
@@ -166,6 +167,7 @@ export function LoginPage({ onLogin }) {
return html`
<div class="page-center">
+ <div class="welcome">
<div class="card login-card">
<h2>${t('login.title')}</h2>
<form onSubmit=${onSubmit}>
@@ -192,10 +194,70 @@ export function LoginPage({ onLogin }) {
<a href="#/reset">${t('login.forgot')}</a>
</div>
</div>
+ ${!platform.isNative && html`<${WelcomePitch} />`}
+ </div>
</div>
`;
}
+// What MeshBay is, beside the sign-in form. Browser only: inside the desktop
+// 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.
+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_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'];
+
+function WelcomePitch() {
+ return html`
+ <section class="welcome-pitch" aria-labelledby="welcome-title">
+ <h1 id="welcome-title" class="welcome-title">${t('welcome.title')}</h1>
+ <p class="welcome-lead">${t('welcome.lead')}</p>
+ <ul class="welcome-apps">
+ ${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.uses_title')}</h2>
+ <ul class="welcome-uses">
+ ${WELCOME_USES.map(([icon, key]) => html`
+ <li key=${key}><span class="welcome-use-icon"><${Icon} name=${icon} /></span>
+ <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>
+
+ <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>
+ </section>
+ `;
+}
+
export function RegisterPage() {
const [username, setUsername] = useState('');
const [email, setEmail] = useState('');