Files
oslstats/internal/view/baseview/layout.templ
2026-03-07 13:24:36 +11:00

103 lines
3.3 KiB
Plaintext

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"
>
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>{ title }</title>
<link rel="icon" type="image/x-icon" href="/static/assets/favicon.ico"/>
<link href="/static/css/output.css" rel="stylesheet"/>
<script src="/static/vendored/htmx@2.0.8.min.js"></script>
<script src="/static/vendored/htmx-ext-ws.min.js"></script>
<script src="/static/vendored/alpinejs@3.15.4.min.js" defer></script>
<script src="/static/js/localtime.js" defer></script>
if devInfo.HTMXLog {
<script>
htmx.logAll();
</script>
}
</head>
<body
class="bg-base dark text-text ubuntu-mono-regular overflow-hidden h-screen"
hx-ext="ws"
ws-connect={ devInfo.WebsocketBase + "/ws/notifications" }
>
@popup.ErrorModalContainer()
@popup.ToastContainer()
@popup.ConfirmModal()
<div
id="main-content"
class="flex flex-col h-screen"
>
if devInfo.StagingBanner {
@stagingBanner()
}
@Navbar()
if previewRole != nil {
@previewModeBanner(previewRole)
}
<div id="page-viewport" class="flex-1 overflow-y-auto overflow-x-hidden">
<div id="page-content" class="min-h-full flex flex-col justify-between">
<div class="mb-auto md:px-5 md:pt-5">
{ children... }
</div>
@Footer()
</div>
</div>
</div>
</body>
</html>
}
templ stagingBanner() {
<div class="bg-peach text-crust text-center text-xs font-bold py-1 tracking-wider uppercase">
Staging Environment - For Testing Only
</div>
}
// 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>
}