Update web/templates/base.html

This commit is contained in:
Joshua Laymon 2025-08-20 01:50:43 +00:00
parent c604f497fc
commit fa9ec34a90

View File

@ -24,6 +24,7 @@
.nav-btn.danger{background:#b91c1c; border-color:#b91c1c; color:#fff} .nav-btn.danger{background:#b91c1c; border-color:#b91c1c; color:#fff}
.nav-btn.danger:hover{filter:brightness(.95)} .nav-btn.danger:hover{filter:brightness(.95)}
.user-chip{padding:6px 10px; border-radius:999px; border:1px solid var(--nav-border); background:#fff; color:var(--nav-ink-muted); font-size:14px} .user-chip{padding:6px 10px; border-radius:999px; border:1px solid var(--nav-border); background:#fff; color:var(--nav-ink-muted); font-size:14px}
.page{max-width:1100px; margin:18px auto; padding:0 16px} .page{max-width:1100px; margin:18px auto; padding:0 16px}
.messages{margin:12px 0; display:grid; gap:8px} .messages{margin:12px 0; display:grid; gap:8px}
.msg{padding:10px 12px; border-radius:10px; border:1px solid #e5e7eb; background:#fff} .msg{padding:10px 12px; border-radius:10px; border:1px solid #e5e7eb; background:#fff}
@ -77,6 +78,26 @@
.mobile-link.danger{ color:#b91c1c; } .mobile-link.danger{ color:#b91c1c; }
.mobile-user{ padding:10px 14px; color:var(--nav-ink-muted); font-size:14px; } .mobile-user{ padding:10px 14px; color:var(--nav-ink-muted); font-size:14px; }
} }
/* --- user menu (desktop dropdown) --- */
.user-chip{ cursor:pointer; text-decoration:none; }
.user-chip:hover{ background:var(--btn-hover); }
.user-dropdown{ position:relative; }
.user-menu{
position:absolute; right:0; top:calc(100% + 8px);
background:#fff; border:1px solid var(--nav-border);
border-radius:12px; box-shadow:0 8px 30px rgba(0,0,0,.08);
min-width: 160px; padding:6px; display:grid; gap:4px; z-index:60;
}
.user-menu .menu-item{
display:block; width:100%; text-align:left;
padding:10px 12px; border-radius:10px;
text-decoration:none; color:var(--nav-ink);
background:transparent; border:none; cursor:pointer;
}
.user-menu .menu-item:hover{ background:var(--btn-hover); }
.user-menu .danger-btn{ color:#b91c1c; }
</style> </style>
</head> </head>
@ -99,10 +120,19 @@
{% endif %} {% endif %}
{% if user.is_authenticated %} {% if user.is_authenticated %}
<span class="user-chip">Signed in: {{ user.username }}</span> <!-- USER MENU: username button that opens Settings + Logout -->
<form method="post" action="{% url 'logout' %}" style="display:inline;">{% csrf_token %} <div class="user-dropdown">
<button class="nav-btn">Logout</button> <button id="userMenuBtn" class="user-chip" aria-haspopup="true" aria-expanded="false">
{{ user.username }}
</button>
<div id="userMenu" class="user-menu" hidden>
<a class="menu-item" href="{% url 'settings_home' %}">Settings</a>
<form method="post" action="{% url 'logout' %}">
{% csrf_token %}
<button class="menu-item danger-btn" type="submit">Logout</button>
</form> </form>
</div>
</div>
{% else %} {% else %}
<a class="nav-btn primary" href="{% url 'login' %}">Login</a> <a class="nav-btn primary" href="{% url 'login' %}">Login</a>
{% endif %} {% endif %}
@ -126,7 +156,9 @@
{% endif %} {% endif %}
{% if user.is_authenticated %} {% if user.is_authenticated %}
<!-- USER MENU (mobile): show Settings + Logout in the slideout -->
<div class="mobile-user">Signed in: {{ user.username }}</div> <div class="mobile-user">Signed in: {{ user.username }}</div>
<a class="mobile-link" href="{% url 'settings_home' %}" role="menuitem">Settings</a>
<form method="post" action="{% url 'logout' %}" role="menuitem">{% csrf_token %} <form method="post" action="{% url 'logout' %}" role="menuitem">{% csrf_token %}
<button class="mobile-link danger" style="width:100%; text-align:left;">Logout</button> <button class="mobile-link danger" style="width:100%; text-align:left;">Logout</button>
</form> </form>
@ -153,13 +185,13 @@
{% block extra_body %}{% endblock %} {% block extra_body %}{% endblock %}
<!-- tiny toggle script --> <!-- tiny toggles -->
<script> <script>
(function () { (function () {
/* mobile hamburger */
const btn = document.getElementById('hamburger'); const btn = document.getElementById('hamburger');
const menu = document.getElementById('mobileMenu'); const menu = document.getElementById('mobileMenu');
if (!btn || !menu) return; if (btn && menu) {
const open = () => { menu.hidden = false; btn.setAttribute('aria-expanded','true'); }; const open = () => { menu.hidden = false; btn.setAttribute('aria-expanded','true'); };
const close = () => { menu.hidden = true; btn.setAttribute('aria-expanded','false'); }; const close = () => { menu.hidden = true; btn.setAttribute('aria-expanded','false'); };
@ -170,6 +202,22 @@
}); });
document.addEventListener('keydown', (e) => { if (e.key === 'Escape') close(); }); document.addEventListener('keydown', (e) => { if (e.key === 'Escape') close(); });
window.matchMedia('(min-width: 701px)').addEventListener('change', () => close()); window.matchMedia('(min-width: 701px)').addEventListener('change', () => close());
}
/* USER MENU: desktop dropdown */
const userBtn = document.getElementById('userMenuBtn');
const userMenu = document.getElementById('userMenu');
if (userBtn && userMenu) {
const open = () => { userMenu.hidden = false; userBtn.setAttribute('aria-expanded','true'); };
const close = () => { userMenu.hidden = true; userBtn.setAttribute('aria-expanded','false'); };
userBtn.addEventListener('click', (e) => { e.stopPropagation(); userMenu.hidden ? open() : close(); });
document.addEventListener('click', (e) => {
if (userMenu.hidden) return;
if (!userMenu.contains(e.target) && !userBtn.contains(e.target)) close();
});
document.addEventListener('keydown', (e) => { if (e.key === 'Escape') close(); });
window.addEventListener('blur', close);
}
})(); })();
</script> </script>
</body> </body>