feat: show masked UUID in settings with toggle visibility and copy button
This commit is contained in:
@@ -7,6 +7,7 @@ class PageSettings extends HTMLElement {
|
||||
super()
|
||||
this.isLoggedIn = false
|
||||
this.user = null
|
||||
this.uidVisible = false
|
||||
}
|
||||
|
||||
async connectedCallback() {
|
||||
@@ -82,6 +83,29 @@ class PageSettings extends HTMLElement {
|
||||
}
|
||||
})
|
||||
|
||||
// Toggle UUID visibility
|
||||
this.querySelector('#toggle-uid-btn')?.addEventListener('click', () => {
|
||||
this.uidVisible = !this.uidVisible
|
||||
const display = this.querySelector('#user-id-display')
|
||||
const eyeIcon = this.querySelector('#toggle-uid-btn .icon-eye')
|
||||
const eyeOffIcon = this.querySelector('#toggle-uid-btn .icon-eye-off')
|
||||
if (display) {
|
||||
display.textContent = this.uidVisible
|
||||
? this.user?.id
|
||||
: '••••••••-••••-••••-••••-••••••••••••'
|
||||
}
|
||||
if (eyeIcon) eyeIcon.style.display = this.uidVisible ? 'none' : 'block'
|
||||
if (eyeOffIcon) eyeOffIcon.style.display = this.uidVisible ? 'block' : 'none'
|
||||
})
|
||||
|
||||
// Copy UUID
|
||||
this.querySelector('#copy-uid-btn')?.addEventListener('click', async () => {
|
||||
if (this.user?.id) {
|
||||
await navigator.clipboard.writeText(this.user.id)
|
||||
this.showToast(t('auth.copy') + ' ✓')
|
||||
}
|
||||
})
|
||||
|
||||
// Logout
|
||||
this.querySelector('#logout-btn')?.addEventListener('click', () => {
|
||||
auth.logout()
|
||||
@@ -200,7 +224,27 @@ class PageSettings extends HTMLElement {
|
||||
${this.isLoggedIn ? /* html */`
|
||||
<div class="setting-item">
|
||||
<label>${t('settings.userId')}</label>
|
||||
<code class="user-id">${user?.id?.slice(0, 8)}...</code>
|
||||
<div class="user-id-row">
|
||||
<code class="user-id" id="user-id-display">${'•'.repeat(8)}-••••-••••-••••-${'•'.repeat(12)}</code>
|
||||
<div class="user-id-actions">
|
||||
<button class="btn btn-icon btn-icon-sm btn-ghost" id="toggle-uid-btn" title="${t('auth.yourUuid')}">
|
||||
<svg class="icon-eye" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
|
||||
<circle cx="12" cy="12" r="3"></circle>
|
||||
</svg>
|
||||
<svg class="icon-eye-off" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="display:none">
|
||||
<path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"></path>
|
||||
<line x1="1" y1="1" x2="23" y2="23"></line>
|
||||
</svg>
|
||||
</button>
|
||||
<button class="btn btn-icon btn-icon-sm btn-ghost" id="copy-uid-btn" title="${t('auth.copy')}">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
|
||||
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<button id="logout-btn" class="btn btn-outline btn-danger">
|
||||
@@ -355,11 +399,62 @@ style.textContent = /* css */`
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
|
||||
page-settings .user-id-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-xs);
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
page-settings .user-id-actions {
|
||||
display: flex;
|
||||
gap: var(--space-xs);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
page-settings .user-id-row {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
page-settings .user-id-actions {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
|
||||
page-settings .user-id {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
padding: var(--space-xs) var(--space-sm);
|
||||
background: var(--color-bg-tertiary);
|
||||
border-radius: var(--radius-sm);
|
||||
font-size: var(--font-size-sm);
|
||||
word-break: break-all;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
page-settings .btn-icon-sm {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
padding: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
page-settings .btn-ghost {
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: var(--color-text-muted);
|
||||
cursor: pointer;
|
||||
border-radius: var(--radius-sm);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: color var(--transition-fast), background var(--transition-fast);
|
||||
}
|
||||
|
||||
page-settings .btn-ghost:hover {
|
||||
color: var(--color-text);
|
||||
background: var(--color-bg-secondary);
|
||||
}
|
||||
|
||||
page-settings .btn-danger {
|
||||
|
||||
Reference in New Issue
Block a user