mirror of
https://github.com/PR0M3TH3AN/bitlogin.git
synced 2026-10-27 08:31:21 +00:00
Screen headers with icon back buttons; tidy the sign-in screen
Every pre-auth screen (sign in, create, import, recover, extension and bunker flows) opens with a chevron back button beside its title instead of ending with a dangling 'Back' link after the form. The sign-in screen's 'Forgot password? Recover with phrase' shrinks to a right-aligned 'Forgot password?' under the password field -- the recovery screen itself explains the phrase. Back buttons are 36px icon targets with aria-label; the rollback screen's 'Cancel' keeps its explicit wording. Verified in the browser. Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
1 parent
2e7b1e19e3
commit
14d993d11a
2 files changed
+58
-15
No files matched your search
@@ -58,6 +58,8 @@ const OPTION_ICONS = {
|
||||
|
||||
const CHEVRON_DOWN = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 9l6 6 6-6"/></svg>`;
|
||||
|
||||
const CHEVRON_LEFT = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M15 18l-6-6 6-6"/></svg>`;
|
||||
|
||||
export class BitLoginAuthElement extends HTMLElement {
|
||||
private root: ShadowRoot;
|
||||
private worker: WorkerClient;
|
||||
@@ -1381,6 +1383,17 @@ export class BitLoginAuthElement extends HTMLElement {
|
||||
}, 1100);
|
||||
}
|
||||
|
||||
/** Screen header with an icon back button, replacing the dangling "Back"
|
||||
* link every pre-auth screen used to end with -- back navigation belongs
|
||||
* where the eye starts, not after the form. */
|
||||
private renderScreenHead(title: string, backAction = "goto-welcome"): string {
|
||||
return `
|
||||
<div class="screen-head">
|
||||
<button class="icon-back" type="button" data-action="${backAction}" aria-label="Back">${CHEVRON_LEFT}</button>
|
||||
<h2>${title}</h2>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
private renderError(): string {
|
||||
return this.errorMessage ? `<div class="notice error">${escapeHtml(this.errorMessage)}</div>` : "";
|
||||
}
|
||||
@@ -1439,13 +1452,12 @@ export class BitLoginAuthElement extends HTMLElement {
|
||||
|
||||
case "extension-confirm":
|
||||
return `
|
||||
<h2>Sign in with your extension</h2>
|
||||
${this.renderScreenHead("Sign in with your extension")}
|
||||
<p class="sub">Your Nostr signer extension reports this identity:</p>
|
||||
<div class="credential-box">${escapeHtml(this.extensionPreviewNpub)}</div>
|
||||
<p class="small">Check this is the profile you expect — extensions can hold more than one. BitLogin never sees this identity's private key; your extension signs on its behalf. This session lasts until you log out or leave the page, and BitLogin account features (wallet connections, password rotation, recovery) stay with BitLogin accounts.</p>
|
||||
${this.renderError()}
|
||||
<button class="primary" type="button" data-action="extension-continue">This is me — continue</button>
|
||||
<button class="link" data-action="goto-welcome">Back</button>
|
||||
`;
|
||||
|
||||
case "bunker-connect": {
|
||||
@@ -1461,7 +1473,7 @@ export class BitLoginAuthElement extends HTMLElement {
|
||||
? `<button class="secondary" type="button" data-action="goto-bunker">Generate a new code</button>`
|
||||
: `<p class="sub"><span class="spinner"></span>Preparing connection code…</p>`;
|
||||
return `
|
||||
<h2>Use a remote signer</h2>
|
||||
${this.renderScreenHead("Use a remote signer")}
|
||||
<p class="sub">Scan with a signer app on your phone (Amber, nsec.app, …). Your key stays in the signer; BitLogin only requests signatures.</p>
|
||||
${this.renderError()}
|
||||
${authNotice}
|
||||
@@ -1474,25 +1486,23 @@ export class BitLoginAuthElement extends HTMLElement {
|
||||
${this.busy ? '<span class="spinner"></span>Contacting your signer…' : "Connect"}
|
||||
</button>
|
||||
</form>
|
||||
<button class="link" data-action="goto-welcome">Back</button>
|
||||
`;
|
||||
}
|
||||
|
||||
case "bunker-confirm":
|
||||
return `
|
||||
<h2>Remote signer connected</h2>
|
||||
${this.renderScreenHead("Remote signer connected")}
|
||||
<p class="sub">Your signer reports this identity:</p>
|
||||
<div class="credential-box">${escapeHtml(this.pendingBunker?.npub ?? "")}</div>
|
||||
<p class="small">Check this is the profile you expect. Your private key stays in your signer — each signature is requested over relays, and your signer can require approval or be disconnected at any time. This session lasts until you log out or leave the page; BitLogin account features (wallet connections, password rotation, recovery) stay with BitLogin accounts.</p>
|
||||
${this.renderError()}
|
||||
<button class="primary" type="button" data-action="bunker-continue">This is me — continue</button>
|
||||
<button class="link" data-action="goto-welcome">Back</button>
|
||||
`;
|
||||
|
||||
case "import-key": {
|
||||
const previewed = !!this.importPreviewNpub;
|
||||
return `
|
||||
<h2>Import an existing Nostr key</h2>
|
||||
${this.renderScreenHead("Import an existing Nostr key")}
|
||||
<p class="sub">Wrap a Nostr identity you already control in a BitLogin login name and password. Your key never changes — you just get a friendlier way in.</p>
|
||||
<div class="notice warn">Pasting a private key into any web page is risky. Only do this on a BitLogin build you trust, and clear your clipboard afterward. BitLogin can't secure copies of this key that already exist elsewhere.</div>
|
||||
${this.renderError()}
|
||||
@@ -1510,13 +1520,12 @@ export class BitLoginAuthElement extends HTMLElement {
|
||||
<button class="primary" type="button" data-action="import-continue">This is my identity — continue</button>`
|
||||
: ""
|
||||
}
|
||||
<button class="link" data-action="goto-welcome">Back</button>
|
||||
`;
|
||||
}
|
||||
|
||||
case "create-name":
|
||||
return `
|
||||
<h2>${this.importKey ? "Set up your login" : "Create your BitLogin"}</h2>
|
||||
${this.renderScreenHead(this.importKey ? "Set up your login" : "Create your BitLogin")}
|
||||
<p class="sub">${
|
||||
this.importKey
|
||||
? "Choose a login name for your imported identity. It's a convenience, not a secret."
|
||||
@@ -1528,7 +1537,6 @@ export class BitLoginAuthElement extends HTMLElement {
|
||||
<input type="text" name="loginName" id="loginName" placeholder="adam" autocomplete="off" required minlength="3" maxlength="32" />
|
||||
<button class="primary" type="submit">Continue</button>
|
||||
</form>
|
||||
<button class="link" data-action="goto-welcome">Back</button>
|
||||
`;
|
||||
|
||||
case "create-credential": {
|
||||
@@ -1592,24 +1600,25 @@ export class BitLoginAuthElement extends HTMLElement {
|
||||
|
||||
case "login":
|
||||
return `
|
||||
<h2>Sign in</h2>
|
||||
${this.renderScreenHead("Sign in")}
|
||||
${this.renderError()}
|
||||
<form data-form="login">
|
||||
<label for="loginName">Login name</label>
|
||||
<input type="text" name="loginName" id="loginName" autocomplete="username" required />
|
||||
<label for="password">Password</label>
|
||||
<input type="password" name="password" id="password" autocomplete="current-password" required />
|
||||
<div class="field-hint">
|
||||
<button class="link-inline" type="button" data-action="goto-recover">Forgot password?</button>
|
||||
</div>
|
||||
<button class="primary" type="submit" ${this.busy ? "disabled" : ""}>
|
||||
${this.busy ? '<span class="spinner"></span>Signing in…' : "Sign in"}
|
||||
</button>
|
||||
</form>
|
||||
<button class="link" data-action="goto-recover">Forgot password? Recover with phrase</button>
|
||||
<button class="link" data-action="goto-welcome">Back</button>
|
||||
`;
|
||||
|
||||
case "recover-phrase":
|
||||
return `
|
||||
<h2>Recover with phrase</h2>
|
||||
${this.renderScreenHead("Recover with phrase")}
|
||||
<p class="sub">Enter your 12-word BitLogin recovery phrase.</p>
|
||||
<p class="small">Do not enter a Bitcoin or other cryptocurrency-wallet recovery phrase into BitLogin.</p>
|
||||
${this.renderError()}
|
||||
@@ -1628,7 +1637,6 @@ export class BitLoginAuthElement extends HTMLElement {
|
||||
${this.busy ? '<span class="spinner"></span>Recovering…' : "Continue"}
|
||||
</button>
|
||||
</form>
|
||||
<button class="link" data-action="goto-welcome">Back</button>
|
||||
`;
|
||||
|
||||
case "recover-new-credentials": {
|
||||
|
||||
@@ -205,6 +205,41 @@ button.link {
|
||||
font-size: 13px;
|
||||
}
|
||||
button:focus-visible { outline: 2px solid var(--bl-accent); outline-offset: 2px; }
|
||||
.screen-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin: 0 0 4px -8px; /* negative left margin optically aligns the chevron with the content edge */
|
||||
}
|
||||
.screen-head h2 { margin: 0; }
|
||||
.icon-back {
|
||||
flex: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
border-radius: 9px;
|
||||
background: none;
|
||||
color: var(--bl-muted);
|
||||
}
|
||||
.icon-back:hover { background: var(--bl-input-bg); color: var(--bl-fg); }
|
||||
.icon-back svg { width: 20px; height: 20px; }
|
||||
/* Right-aligned helper link under an input (e.g. "Forgot password?"). */
|
||||
.field-hint { display: flex; justify-content: flex-end; margin-top: 8px; }
|
||||
.field-hint .link-inline {
|
||||
width: auto;
|
||||
margin: 0;
|
||||
padding: 4px 0;
|
||||
border: none;
|
||||
background: none;
|
||||
color: var(--bl-accent);
|
||||
font-size: 12.5px;
|
||||
font-weight: 500;
|
||||
}
|
||||
/* Collapsed disclosure for every non-primary sign-in path (§LM9.1: the
|
||||
password flow stays the visual headline; alternatives are one tap away).
|
||||
Rows are full-bleed buttons with generous minimum height so the menu works
|
||||
|
||||
Reference in new issue
Block a user