Files
openfsd/internal/web/templates/layout.html
Reese Norris 895dbd8fc8 web: allow Instructor1+ access to airport editor
Move airport-editor HTML routes and validate API from ADM to I1+, matching
sweatbox. Config editor stays Administrator-only. Nav/dashboard use
CanAccessAirportEditor; PE tests cover I1 shell, nav, and validate-apt.
2026-07-27 18:53:44 -04:00

74 lines
4.0 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{{ if .CSRFToken }}<meta name="csrf-token" content="{{ .CSRFToken }}">{{ end }}
{{/*
Theme boot must run before first paint (classic script, not defer/module)
so data-bs-theme matches localStorage / system preference without a flash.
*/}}
<script src="/static/js/openfsd/theme.js"></script>
<link href="/static/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-SgOJa3DmI69IUzQ2PVdRZhwQ+dy64/BUtbMJw1MZ8t5HZApcHrRKUc4W0kG879m7">
<link href="/static/css/openfsd/theme.css" rel="stylesheet">
<script src="/static/js/bootstrap.bundle.min.js" integrity="sha384-k6d4wzSIapyDyv1kpU366/PK5hCdSbCRGRCMv+eplOQJWyd1fbcAu9OCUj5zNLiq"></script>
<script src="/static/js/openfsd/api.js"></script>
<title>openfsd - {{ template "title" . }}</title>
</head>
<body>
<header class="container-fluid p-2 d-flex justify-content-between align-items-center border-bottom border-1 ofs-site-header">
<div class="d-flex align-items-center">
<div>
<svg class="ofs-brand-mark" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" width="32px" height="32px" viewBox="0 0 120.135 120.148" style="enable-background:new 0 0 120.135 120.148;" xml:space="preserve" aria-hidden="true" focusable="false">
<g>
<path d="M105.771,120.147c7.933,0,14.363-6.438,14.363-14.359V14.352C120.134,6.422,113.702,0,105.771,0H14.337 C6.408,0,0,6.422,0,14.352v91.436c0,7.922,6.408,14.359,14.337,14.359H105.771z"/>
<path style="fill:#FFFFFF;" d="M14.337,2.435c-6.564,0-11.908,5.347-11.908,11.917v91.436c0,6.58,5.344,11.926,11.908,11.926 h91.434c6.584,0,11.932-5.346,11.932-11.926V14.352c0-6.57-5.348-11.917-11.932-11.917H14.337z"/>
<path d="M54.82,16.917c0.023-7.053,10.66-7.053,10.66,0.202V46.74l41.453,24.925v10.947l-41.264-13.58v22.129l9.547,7.479v8.641 l-14.723-4.57l-14.719,4.57V98.64l9.45-7.479V69.032l-41.289,13.58V71.665L54.82,46.74V16.917z"/>
</g>
</svg>
</div>
<div class="ms-2">
<a href="/" class="text-decoration-none ofs-brand-link">openfsd</a>
</div>
</div>
<nav class="d-flex align-items-center gap-2" aria-label="Primary">
<button type="button"
class="btn btn-sm btn-outline-secondary ofs-theme-toggle"
data-js="theme-toggle"
aria-pressed="false"
aria-label="Switch to dark mode"
title="Dark mode">
<span class="ofs-theme-icon-light" aria-hidden="true"></span>
<span class="ofs-theme-icon-dark" aria-hidden="true"></span>
</button>
{{ if .User }}
<a class="btn btn-sm btn-outline-secondary" href="/dashboard">Dashboard</a>
<a class="btn btn-sm btn-outline-secondary" href="/account">Account</a>
{{ if .User.CanEditUsers }}
<a class="btn btn-sm btn-outline-secondary" href="/usereditor">Users</a>
{{ end }}
{{ if .User.CanAccessSweatbox }}
<a class="btn btn-sm btn-outline-secondary" href="/sweatbox">Sweatbox</a>
{{ end }}
{{ if .User.CanAccessAirportEditor }}
<a class="btn btn-sm btn-outline-secondary" href="/airport-editor">Airport Editor</a>
{{ end }}
{{ if .User.CanEditConfig }}
<a class="btn btn-sm btn-outline-secondary" href="/configeditor">Config</a>
{{ end }}
<form method="post" action="/logout" class="d-inline m-0">
<input type="hidden" name="csrf_token" value="{{ .CSRFToken }}">
<button type="submit" class="btn btn-sm btn-outline-secondary">Log out</button>
</form>
{{ else }}
<a class="btn btn-sm btn-outline-secondary" href="/login">Login</a>
{{ end }}
</nav>
</header>
{{ template "body" . }}
</body>
</html>