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()
|
super()
|
||||||
this.isLoggedIn = false
|
this.isLoggedIn = false
|
||||||
this.user = null
|
this.user = null
|
||||||
|
this.uidVisible = false
|
||||||
}
|
}
|
||||||
|
|
||||||
async connectedCallback() {
|
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
|
// Logout
|
||||||
this.querySelector('#logout-btn')?.addEventListener('click', () => {
|
this.querySelector('#logout-btn')?.addEventListener('click', () => {
|
||||||
auth.logout()
|
auth.logout()
|
||||||
@@ -200,7 +224,27 @@ class PageSettings extends HTMLElement {
|
|||||||
${this.isLoggedIn ? /* html */`
|
${this.isLoggedIn ? /* html */`
|
||||||
<div class="setting-item">
|
<div class="setting-item">
|
||||||
<label>${t('settings.userId')}</label>
|
<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>
|
||||||
<div class="setting-item">
|
<div class="setting-item">
|
||||||
<button id="logout-btn" class="btn btn-outline btn-danger">
|
<button id="logout-btn" class="btn btn-outline btn-danger">
|
||||||
@@ -355,11 +399,62 @@ style.textContent = /* css */`
|
|||||||
font-size: var(--font-size-sm);
|
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 {
|
page-settings .user-id {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
padding: var(--space-xs) var(--space-sm);
|
padding: var(--space-xs) var(--space-sm);
|
||||||
background: var(--color-bg-tertiary);
|
background: var(--color-bg-tertiary);
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
font-size: var(--font-size-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 {
|
page-settings .btn-danger {
|
||||||
|
|||||||
Reference in New Issue
Block a user