admin page updates

This commit is contained in:
2026-02-13 20:51:39 +11:00
parent f51053212e
commit 295e373f37
34 changed files with 1737 additions and 164 deletions

View File

@@ -2,10 +2,12 @@ package baseview
import "git.haelnorr.com/h/oslstats/internal/view/popup"
import "git.haelnorr.com/h/oslstats/internal/contexts"
import "git.haelnorr.com/h/oslstats/internal/db"
// Global base layout for all pages
templ Layout(title string) {
{{ devInfo := contexts.DevMode(ctx) }}
{{ previewRole := contexts.GetPreviewRole(ctx) }}
<!DOCTYPE html>
<html
lang="en"
@@ -43,6 +45,9 @@ templ Layout(title string) {
class="flex flex-col h-screen justify-between"
>
@Navbar()
if previewRole != nil {
@previewModeBanner(previewRole)
}
<div id="page-content" class="mb-auto md:px-5 md:pt-5">
{ children... }
</div>
@@ -51,3 +56,38 @@ templ Layout(title string) {
</body>
</html>
}
// Preview mode banner (private helper)
templ previewModeBanner(previewRole *db.Role) {
<div class="bg-yellow/20 border-b border-yellow/40 px-4 py-3">
<div class="max-w-7xl mx-auto flex items-center justify-between">
<div class="flex items-center gap-3">
<svg class="w-5 h-5 text-yellow" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"></path>
</svg>
<span class="text-yellow font-semibold">
Preview Mode: Viewing as <span class="font-bold">{ previewRole.DisplayName }</span>
</span>
</div>
<div class="flex items-center gap-2">
<form method="POST" action="/admin/roles/preview-stop?stay=true">
<button
type="submit"
class="px-4 py-1 bg-green text-mantle rounded-lg font-semibold hover:bg-teal transition text-sm"
>
Stop Preview
</button>
</form>
<form method="POST" action="/admin/roles/preview-stop">
<button
type="submit"
class="px-4 py-1 bg-blue text-mantle rounded-lg font-semibold hover:bg-sky transition text-sm"
>
Return to Admin Panel
</button>
</form>
</div>
</div>
</div>
}

View File

@@ -25,13 +25,21 @@ func getNavItems() []NavItem {
}
}
// Profile dropdown items (context-aware for admin)
// Profile dropdown items (context-aware for admin and preview mode)
func getProfileItems(ctx context.Context) []ProfileItem {
items := []ProfileItem{
{Name: "Profile", Href: "/profile"},
{Name: "Account", Href: "/account"},
}
// Check if we're in preview mode
previewRole := contexts.GetPreviewRole(ctx)
if previewRole != nil {
// In preview mode: show stop viewing button instead of admin panel
return items
}
// Not in preview mode: show admin panel if user is admin
cache := contexts.Permissions(ctx)
if cache != nil && cache.Roles["admin"] {
items = append(items, ProfileItem{
@@ -104,6 +112,7 @@ templ userMenu(user *db.User, profileItems []ProfileItem) {
// Profile dropdown (private helper)
templ profileDropdown(user *db.User, items []ProfileItem) {
{{ previewRole := contexts.GetPreviewRole(ctx) }}
<div x-data="{ isActive: false }" class="relative">
<div
class="inline-flex items-center overflow-hidden rounded-lg
@@ -118,7 +127,7 @@ templ profileDropdown(user *db.User, items []ProfileItem) {
</button>
</div>
<div
class="absolute end-0 z-10 mt-2 w-36 divide-y divide-surface2
class="absolute end-0 z-10 mt-2 w-48 divide-y divide-surface2
rounded-lg border border-surface1 bg-surface0 shadow-lg"
role="menu"
x-cloak
@@ -127,6 +136,38 @@ templ profileDropdown(user *db.User, items []ProfileItem) {
x-on:click.away="isActive = false"
x-on:keydown.escape.window="isActive = false"
>
<!-- Preview Mode Stop Buttons -->
if previewRole != nil {
<div class="p-2 bg-yellow/10 border-b border-yellow/30 space-y-2">
<p class="text-xs text-yellow/80 px-2 font-semibold">
Viewing as: { previewRole.DisplayName }
</p>
<div class="flex gap-2">
<form method="POST" action="/admin/roles/preview-stop?stay=true" class="flex-1">
<button
type="submit"
class="w-full rounded-lg px-3 py-2
text-sm text-mantle bg-green font-semibold hover:bg-teal hover:cursor-pointer transition"
role="menuitem"
@click="isActive=false"
>
Stop Preview
</button>
</form>
<form method="POST" action="/admin/roles/preview-stop" class="flex-1">
<button
type="submit"
class="w-full rounded-lg px-3 py-2
text-sm text-mantle bg-blue font-semibold hover:bg-sky hover:cursor-pointer transition"
role="menuitem"
@click="isActive=false"
>
Return to Admin
</button>
</form>
</div>
</div>
}
<!-- Profile links -->
<div class="p-2">
for _, item := range items {