Files
bitvid/components/login-modal.html
T

349 lines
13 KiB
HTML

<div
id="loginModal"
class="bv-modal hidden items-start justify-center"
role="dialog"
aria-modal="true"
aria-labelledby="loginModalTitle"
aria-describedby="loginModalDescription"
data-ds="new"
>
<div class="bv-modal-backdrop" data-dismiss></div>
<div class="modal-sheet max-h-modal-shell overflow-hidden" tabindex="-1">
<!-- Header with the special exit button (unchanged) -->
<div class="modal-header">
<h2 id="loginModalTitle" class="text-xl font-bold text-text">
Login Options
</h2>
<button
id="closeLoginModal"
class="modal-close"
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M6 18L18 6M6 6l12 12"
/>
</svg>
</button>
</div>
<!-- Body -->
<div id="loginModalDescription" class="modal-body space-y-6 overflow-y-auto">
<div class="space-y-2 text-left">
<p class="text-sm text-text-muted">
Choose how you'd like to sign in. Connect a browser extension, link a
remote signer, or work directly with your keys when you need to.
</p>
</div>
<section
class="space-y-5 rounded-3xl border border-border bg-overlay-panel-soft/90 p-4 shadow-lg backdrop-blur-sm sm:p-5"
>
<div class="space-y-1">
<h3 class="text-base font-semibold text-text">Available methods</h3>
<p class="text-sm text-text-muted">
Pick the option that matches how you manage your Nostr identity.
</p>
</div>
<!-- Login provider buttons are rendered dynamically -->
<div
data-login-providers
class="grid auto-rows-fr gap-4 sm:grid-cols-2 xl:grid-cols-3"
></div>
</section>
<div class="space-y-3">
<div class="space-y-1 text-left">
<h3 class="text-sm font-semibold uppercase tracking-wide text-text-muted">
Need an invite?
</h3>
<p class="text-sm text-text-muted">
Submit an application and we'll send you updates when new slots open.
</p>
</div>
<button
id="openApplicationModal"
class="btn w-full"
type="button"
>
Application Form
</button>
</div>
<template data-login-provider-template>
<button
class="login-option"
type="button"
data-provider-button
>
<span class="login-option__header">
<span class="login-option__copy">
<span
data-provider-eyebrow
class="login-option__eyebrow hidden"
></span>
<span data-provider-label class="login-option__label"></span>
<span
data-provider-description
class="login-option__description"
></span>
</span>
<span aria-hidden="true" class="login-option__chevron">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
class="h-5 w-5"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 5l7 7-7 7"
/>
</svg>
</span>
</span>
<div data-provider-status-row class="login-option__status hidden">
<span data-provider-status class="truncate"></span>
<button
type="button"
class="btn-link text-sm hidden"
data-provider-disconnect
>
Disconnect
</button>
</div>
<span
data-provider-capabilities
class="login-option__capabilities hidden"
></span>
</button>
</template>
<template data-login-nsec-dialog>
<form
data-nsec-form
class="space-y-4 rounded-xl border border-border bg-overlay-panel-soft px-5 py-4"
>
<div class="space-y-2">
<h3 class="text-lg font-semibold text-text">Direct key login</h3>
<p class="text-sm text-text-muted" data-nsec-warning>
"Unsafe by default" — imported keys stay decrypted only for this session
unless you protect them with a passphrase.
</p>
</div>
<div
data-nsec-error
class="hidden rounded-lg border border-danger/60 bg-danger/10 px-4 py-2 text-sm text-danger"
role="alert"
></div>
<fieldset data-nsec-unlock-section class="space-y-3 hidden">
<legend class="text-sm font-semibold text-text">Unlock saved key</legend>
<label class="inline-flex items-center gap-2 text-sm text-text">
<input
type="radio"
name="nsec-mode"
value="unlock"
class="radio"
data-nsec-mode="unlock"
/>
<span>Use the encrypted key stored on this device</span>
</label>
<div class="space-y-2 pl-6" data-nsec-unlock-fields>
<label class="block text-sm font-medium text-text" for="nsecUnlockPassphrase">
Passphrase
</label>
<input
id="nsecUnlockPassphrase"
type="password"
class="input"
autocomplete="current-password"
data-nsec-unlock-passphrase
required
/>
</div>
</fieldset>
<fieldset data-nsec-import-section class="space-y-3">
<legend class="text-sm font-semibold text-text">Import a new secret</legend>
<label class="inline-flex items-center gap-2 text-sm text-text">
<input
type="radio"
name="nsec-mode"
value="import"
class="radio"
data-nsec-mode="import"
checked
/>
<span>Paste an nsec, hex key, or mnemonic seed</span>
</label>
<div class="space-y-3 pl-6" data-nsec-import-fields>
<label class="block text-sm font-medium text-text" for="nsecSecretInput">
Secret
</label>
<textarea
id="nsecSecretInput"
class="input"
rows="3"
spellcheck="false"
autocomplete="off"
data-nsec-secret
required
></textarea>
<label class="inline-flex items-center gap-2 text-sm text-text">
<input type="checkbox" class="checkbox" data-nsec-remember />
<span>Remember this key on this device</span>
</label>
<div class="space-y-2" data-nsec-passphrase-fields hidden>
<label class="block text-sm font-medium text-text" for="nsecPassphraseInput">
Passphrase
</label>
<input
id="nsecPassphraseInput"
type="password"
class="input"
autocomplete="new-password"
data-nsec-passphrase
/>
<label class="block text-sm font-medium text-text" for="nsecPassphraseConfirm">
Confirm passphrase
</label>
<input
id="nsecPassphraseConfirm"
type="password"
class="input"
autocomplete="new-password"
data-nsec-passphrase-confirm
/>
</div>
</div>
</fieldset>
<div class="flex justify-end gap-2">
<button type="button" class="btn-ghost" data-nsec-cancel>Cancel</button>
<button type="submit" class="btn" data-nsec-submit>Continue</button>
</div>
</form>
</template>
<template data-login-nip46-dialog>
<form
data-nip46-form
class="space-y-4 rounded-xl border border-border bg-overlay-panel-soft px-5 py-4"
>
<div class="space-y-2">
<h3 class="text-lg font-semibold text-text">Pair a remote signer</h3>
<p class="text-sm text-text-muted">
Scan the QR code with your signer or share the connect link to start a
Nostr Connect session.
</p>
</div>
<div
data-nip46-error
class="hidden rounded-lg border border-danger/60 bg-danger/10 px-4 py-2 text-sm text-danger"
role="alert"
></div>
<div data-nip46-handshake-panel class="space-y-3">
<div class="flex flex-col gap-4 sm:flex-row sm:items-start">
<div
class="flex aspect-square w-full max-w-xs items-center justify-center rounded-xl border border-border-strong bg-surface p-4 sm:max-w-sm sm:flex-none sm:p-6"
data-nip46-qr
aria-hidden="true"
>
<div class="w-full text-center text-sm text-text-muted">
Generating connect code…
</div>
</div>
<div class="flex-1 space-y-2">
<label class="block text-sm font-medium text-text" for="nip46HandshakeUri">
Connect URI
</label>
<textarea
id="nip46HandshakeUri"
class="input"
rows="3"
spellcheck="false"
autocomplete="off"
data-nip46-handshake-uri
readonly
></textarea>
<div class="flex flex-wrap items-center gap-2">
<button type="button" class="btn-ghost text-sm" data-nip46-copy-uri disabled>
Copy link
</button>
</div>
<p
data-nip46-secret
class="hidden text-xs text-text-muted"
></p>
</div>
</div>
</div>
<div
data-nip46-status
class="hidden rounded-lg border border-info/40 bg-info/10 px-4 py-2 text-sm text-info"
role="status"
></div>
<div
data-nip46-auth
class="hidden rounded-lg border border-warning/50 bg-warning/10 px-4 py-2 text-sm text-warning"
role="alert"
>
<p data-nip46-auth-message class="mb-2"></p>
<button type="button" class="btn-link text-sm" data-nip46-auth-open>
Open signer challenge
</button>
</div>
<div class="space-y-2">
<button type="button" class="btn-link text-sm" data-nip46-toggle-manual>
Paste a signer-provided bunker link instead
</button>
<div class="hidden space-y-2" data-nip46-manual-fields>
<label class="block text-sm font-medium text-text" for="nip46LegacyUri">
Signer link
</label>
<textarea
id="nip46LegacyUri"
class="input"
rows="2"
spellcheck="false"
autocomplete="off"
placeholder="bunker://…"
data-nip46-legacy-uri
></textarea>
<p class="text-xs text-text-muted">
Use this fallback when your signer cannot scan QR codes.
</p>
</div>
</div>
<div class="space-y-2">
<label class="inline-flex items-center gap-2 text-sm text-text">
<input type="checkbox" class="checkbox" data-nip46-remember checked />
<span>Remember this signer for future logins</span>
</label>
<button
type="button"
class="btn-link text-sm hidden"
data-nip46-reuse
>
Reconnect using the saved session
</button>
</div>
<div class="flex justify-end gap-2">
<button type="button" class="btn-ghost" data-nip46-cancel>Cancel</button>
<button type="submit" class="btn" data-nip46-submit>Connect</button>
</div>
</form>
</template>
</div>
</div>
</div>