mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
Updated `js/ui/loginModalController.js` to resolve QR code colors from CSS variables (`--color-white`, `--color-black`) instead of hardcoding hex values, ensuring compatibility with the design system. Updated `components/login-modal.html` to use Tailwind utility classes (`bg-white`, `text-black`, `p-6`) instead of inline styles, improving maintainability and readability. This ensures the QR code remains scannable (high contrast) while respecting the codebase's tokenized styling approach.
421 lines
15 KiB
HTML
421 lines
15 KiB
HTML
<div
|
|
id="loginModal"
|
|
class="bv-modal hidden p-0 sm:p-0 lg:p-8 lg:items-start lg:justify-center overflow-hidden"
|
|
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 w-full h-full max-w-none rounded-none border-0 lg:max-h-modal-shell lg:max-w-5xl lg:rounded-modal-xl lg:border lg:h-auto flex min-h-0 flex-col 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 flex-1 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
|
|
></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-generate-dialog>
|
|
<div
|
|
data-generate-view
|
|
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">Create a new Nostr key</h3>
|
|
<p class="text-sm text-text-muted">
|
|
Save your keys somewhere safe. We'll only enable login after you
|
|
confirm you've backed them up.
|
|
</p>
|
|
</div>
|
|
<div class="space-y-3">
|
|
<div class="space-y-2">
|
|
<label class="block text-sm font-medium text-text">
|
|
Public key (npub)
|
|
</label>
|
|
<div class="space-y-2 sm:flex sm:items-start sm:gap-2 sm:space-y-0">
|
|
<div
|
|
data-generate-npub
|
|
class="min-w-0 flex-1 break-all rounded-lg border border-border bg-overlay-panel px-3 py-2 text-sm text-text"
|
|
></div>
|
|
<button
|
|
type="button"
|
|
class="btn-ghost text-sm"
|
|
data-generate-copy-npub
|
|
>
|
|
Copy npub
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="space-y-2">
|
|
<label class="block text-sm font-medium text-text" for="generatedNsec">
|
|
Secret key (nsec)
|
|
</label>
|
|
<div class="space-y-2 sm:flex sm:items-start sm:gap-2 sm:space-y-0">
|
|
<input
|
|
id="generatedNsec"
|
|
type="password"
|
|
class="input min-w-0 flex-1"
|
|
readonly
|
|
data-generate-nsec
|
|
/>
|
|
<div class="flex flex-wrap items-center gap-2">
|
|
<button
|
|
type="button"
|
|
class="btn-ghost text-sm"
|
|
data-generate-reveal-nsec
|
|
>
|
|
Reveal
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="btn-ghost text-sm"
|
|
data-generate-copy-nsec
|
|
>
|
|
Copy nsec
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<button
|
|
type="button"
|
|
class="btn-link text-sm"
|
|
data-generate-download
|
|
>
|
|
Download backup
|
|
</button>
|
|
</div>
|
|
<label class="inline-flex items-center gap-2 text-sm text-text">
|
|
<input type="checkbox" class="checkbox" data-generate-confirm />
|
|
<span>I saved these keys and understand they're private.</span>
|
|
</label>
|
|
</div>
|
|
<div class="flex justify-end gap-2">
|
|
<button type="button" class="btn-ghost" data-generate-cancel>
|
|
Cancel
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="btn"
|
|
data-generate-login
|
|
disabled
|
|
>
|
|
Continue
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</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 (like Amber or NsecBunker) to login.
|
|
</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-6">
|
|
<div class="flex flex-col items-center gap-6">
|
|
<div
|
|
class="flex aspect-square w-full max-w-xs items-center justify-center rounded-2xl border border-border-strong bg-white text-black p-6 shadow-sm"
|
|
data-nip46-qr
|
|
aria-hidden="true"
|
|
>
|
|
<div class="w-full text-center text-sm text-text-muted animate-pulse">
|
|
Generating code...
|
|
</div>
|
|
</div>
|
|
|
|
<div class="w-full space-y-4 text-center">
|
|
<!-- Hidden input for copy functionality -->
|
|
<input
|
|
type="text"
|
|
class="sr-only"
|
|
data-nip46-handshake-uri
|
|
readonly
|
|
aria-hidden="true"
|
|
>
|
|
|
|
<button
|
|
type="button"
|
|
class="btn w-full sm:max-w-xs"
|
|
data-nip46-copy-uri
|
|
disabled
|
|
>
|
|
Copy Connect Link
|
|
</button>
|
|
|
|
<details class="text-sm text-text-muted">
|
|
<summary class="cursor-pointer hover:text-text hover:underline">Trouble scanning?</summary>
|
|
<div class="mt-2 p-2 bg-overlay-panel border border-border rounded-lg break-all text-xs font-mono text-left select-all" data-nip46-debug-uri>
|
|
<!-- Raw URI injected here for debugging/manual copy -->
|
|
</div>
|
|
</details>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div
|
|
data-nip46-status
|
|
class="hidden rounded-lg border border-info/40 bg-info/10 px-4 py-3 text-sm text-info font-medium text-center"
|
|
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="flex justify-between items-center pt-2">
|
|
<button
|
|
type="button"
|
|
class="btn-link text-sm hidden"
|
|
data-nip46-reuse
|
|
>
|
|
Reconnect saved
|
|
</button>
|
|
<button type="button" class="btn-ghost" data-nip46-cancel>Cancel</button>
|
|
</div>
|
|
<!-- Hidden submit to satisfy form semantics if needed, though we trigger via logic -->
|
|
<button type="submit" class="hidden" data-nip46-submit></button>
|
|
</form>
|
|
</template>
|
|
</div>
|
|
</div>
|
|
</div>
|