Manage Profiles: make the login-password state visible (clarity)
The per-member login password was easy to miss — the lock button had no dedicated
styling and nothing showed who was actually stranded. Now, when login mode is on:
- a banner explains every member needs a login password (+ to use the lock button)
- each member row shows a status pill: "⚠ No login password" (red) or "🔒 Login
ready" (green) — so you can see at a glance who can't sign in yet
- the lock button is properly styled (it had none) and pulses red when that member
has no password, so the action you need is obvious
When login mode is off, none of this shows (no noise). Pure UI/clarity — no
behavior change.
This commit is contained in:
parent
5b52d579c5
commit
d9cda0c31c
2 changed files with 81 additions and 1 deletions
|
|
@ -1873,6 +1873,22 @@ async function loadProfileManageList() {
|
|||
const data = await res.json();
|
||||
const profiles = data.profiles || [];
|
||||
|
||||
// Login-mode aware: when it's on, surface which members can't sign in yet
|
||||
// (no login password) so the lock button's purpose is obvious.
|
||||
let loginMode = false;
|
||||
try { loginMode = !!(await (await fetch('/api/profiles/current')).json()).login_mode; } catch (e) { /* ignore */ }
|
||||
|
||||
// Banner when login mode is on (explains the password requirement up front).
|
||||
const banner = document.getElementById('profile-manage-login-banner');
|
||||
if (banner) banner.remove();
|
||||
if (loginMode) {
|
||||
const b = document.createElement('div');
|
||||
b.id = 'profile-manage-login-banner';
|
||||
b.className = 'profile-manage-login-banner';
|
||||
b.textContent = '🔐 Login mode is on — every member needs a login password to sign in. Use the lock button to set one.';
|
||||
list.parentNode.insertBefore(b, list);
|
||||
}
|
||||
|
||||
list.innerHTML = '';
|
||||
profiles.forEach(p => {
|
||||
const item = document.createElement('div');
|
||||
|
|
@ -1896,6 +1912,12 @@ async function loadProfileManageList() {
|
|||
if (p.is_admin) pills.push({ text: 'Admin', cls: 'profile-role-pill--admin' });
|
||||
if (p.can_download === false) pills.push({ text: 'No Downloads', cls: '' });
|
||||
if (p.allowed_pages) pills.push({ text: `${p.allowed_pages.length} pages`, cls: '' });
|
||||
// Login-password status (only meaningful while login mode is on).
|
||||
if (loginMode && !p.is_admin) {
|
||||
pills.push(p.has_password
|
||||
? { text: '🔒 Login ready', cls: 'profile-role-pill--ok' }
|
||||
: { text: '⚠ No login password', cls: 'profile-role-pill--warn' });
|
||||
}
|
||||
if (pills.length) {
|
||||
const roleDiv = document.createElement('div');
|
||||
roleDiv.className = 'role';
|
||||
|
|
@ -1931,7 +1953,9 @@ async function loadProfileManageList() {
|
|||
// used when "Require login" is on). A member with no password can't
|
||||
// sign in and can't self-bootstrap one, so the admin sets it here.
|
||||
const pwBtn = document.createElement('button');
|
||||
pwBtn.className = 'profile-password-btn' + (p.has_password ? ' has-password' : '');
|
||||
// Pulse the button when login's on and this member can't sign in yet.
|
||||
const needsPw = loginMode && !p.has_password;
|
||||
pwBtn.className = 'profile-password-btn' + (p.has_password ? ' has-password' : '') + (needsPw ? ' needs-password' : '');
|
||||
pwBtn.dataset.id = p.id;
|
||||
pwBtn.dataset.name = p.name;
|
||||
pwBtn.dataset.hasPassword = p.has_password ? '1' : '0';
|
||||
|
|
|
|||
|
|
@ -68187,3 +68187,59 @@ body.em-scroll-lock { overflow: hidden; }
|
|||
body.app-locked > *:not(#launch-pin-overlay):not(#login-overlay):not(script):not(style):not(noscript) {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
|
||||
/* Login-password clarity in Manage Profiles (#login-mode) */
|
||||
.profile-manage-login-banner {
|
||||
margin: 0 0 12px;
|
||||
padding: 9px 12px;
|
||||
border-radius: 10px;
|
||||
font-size: 12px;
|
||||
line-height: 1.4;
|
||||
color: #fcd9a8;
|
||||
background: rgba(245, 158, 11, 0.10);
|
||||
border: 1px solid rgba(245, 158, 11, 0.30);
|
||||
}
|
||||
.profile-role-pill--warn {
|
||||
background: rgba(239, 68, 68, 0.16);
|
||||
color: #fca5a5;
|
||||
border-color: rgba(239, 68, 68, 0.40);
|
||||
text-transform: none;
|
||||
}
|
||||
.profile-role-pill--ok {
|
||||
background: rgba(16, 185, 129, 0.14);
|
||||
color: #6ee7b7;
|
||||
border-color: rgba(16, 185, 129, 0.30);
|
||||
text-transform: none;
|
||||
}
|
||||
/* The set-login-password button (lock icon) + an attention pulse when a member
|
||||
can't sign in yet (login on, no password). */
|
||||
.profile-manage-item .profile-password-btn {
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
border: 1px solid rgba(255, 255, 255, 0.07);
|
||||
color: #9ca3af;
|
||||
border-radius: 8px;
|
||||
padding: 6px;
|
||||
cursor: pointer;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all .15s ease;
|
||||
}
|
||||
.profile-manage-item .profile-password-btn svg { width: 15px; height: 15px; }
|
||||
.profile-manage-item .profile-password-btn:hover {
|
||||
background: rgba(99, 102, 241, 0.18);
|
||||
border-color: rgba(99, 102, 241, 0.4);
|
||||
color: #c7d2fe;
|
||||
}
|
||||
.profile-manage-item .profile-password-btn.has-password { color: #6ee7b7; }
|
||||
.profile-manage-item .profile-password-btn.needs-password {
|
||||
color: #fca5a5;
|
||||
border-color: rgba(239, 68, 68, 0.45);
|
||||
background: rgba(239, 68, 68, 0.12);
|
||||
animation: arecPwPulse 1.8s ease-in-out infinite;
|
||||
}
|
||||
@keyframes arecPwPulse {
|
||||
0%, 100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.0); }
|
||||
50% { box-shadow: 0 0 0 4px rgba(239, 68, 68, 0.18); }
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue