tracker/templates/layout.html
{{define "layout"}}<!doctype html>
<html lang="th">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="color-scheme" content="light dark">
<script>/* apply the saved theme before first paint */try{var t=localStorage.getItem("tracker-theme");if(t==="light"||t==="dark")document.documentElement.dataset.theme=t}catch(e){}</script>
<title>{{.Title}} | ติดตามความคืบหน้างาน TNSU EMS</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Bai+Jamjuree:wght@500;600;700&family=IBM+Plex+Sans+Thai:wght@400;500;600&display=swap">
<link rel="stylesheet" href="{{asset "style.css"}}">
<script src="{{asset "live.js"}}" defer></script>
<script src="{{asset "theme.js"}}" defer></script>
<script src="{{asset "timeline.js"}}" defer></script>
<script src="{{asset "usecases.js"}}" defer></script>
<script src="{{asset "usecase-groups.js"}}" defer></script>
<script src="{{asset "usecase-export.js"}}" defer></script>
<link rel="stylesheet" href="{{asset "usecases.css"}}">
<link rel="stylesheet" href="{{asset "usecase-review.css"}}">
<link rel="stylesheet" href="{{asset "mockups.css"}}">
<script src="{{asset "mockups.js"}}" defer></script>
<script src="{{asset "mockup-groups.js"}}" defer></script>
</head>
<body>
<div class="shell">
<aside class="side" id="side">
<a class="brand" href="/">
<span class="brand-mark" aria-hidden="true"><svg viewBox="0 0 32 32" width="32" height="32"><rect x="3" y="6" width="26" height="4" rx="2"/><rect x="3" y="14" width="18" height="4" rx="2"/><rect x="3" y="22" width="10" height="4" rx="2"/></svg></span>
<span class="brand-text"><b>ความคืบหน้างาน</b><span>โครงการ TNSU EMS</span></span>
</a>
<nav class="nav" aria-label="เมนูหลัก">
{{template "navlink" (navItem . "/" "overview" "หน้าภาพรวม" "")}}
{{template "navlink" (navItem . "/milestones" "milestones" "Milestone & Tasks" (printf "%d" .Counts.Total))}}
{{if .Milestones}}<div class="nav-subs">{{range .Milestones}}<a class="nav-sub{{if and $.Milestone (eq $.Milestone.ID .ID)}} is-on{{end}}" href="{{milestoneHref .ID}}"{{if and $.Milestone (eq $.Milestone.ID .ID)}} aria-current="page"{{end}}><span class="nav-sub-no">{{.No}}</span><span class="nav-sub-name">{{.Title}}</span><span class="nav-sub-pct">{{.Counts.Percent}}%</span></a>{{end}}</div>{{end}}
{{template "navlink" (navItem . "/use-cases" "usecases" "Use cases" "")}}
{{template "navlink" (navItem . "/mockup" "mockup" "Mockup" "")}}
<div class="nav-subs mock-nav"><a class="nav-sub{{if and .Mockups (eq .Mockups.Tab "sitemap")}} is-on{{end}}" href="/mockup/sitemap">Sitemap</a><a class="nav-sub{{if and .Mockups (eq .Mockups.Tab "flow")}} is-on{{end}}" href="/mockup/page-flow">Page flow</a><a class="nav-sub{{if and .Mockups (eq .Mockups.Tab "screens")}} is-on{{end}}" href="/mockup/screens">Screen Listing</a></div>
{{template "navlink" (navItem . "/timeline" "timeline" "Timeline" "")}}
{{template "navlink" (navItem . "/checkpoints" "checkpoints" "ประวัติ Checkpoint" (printf "%d" (len .Checkpoints)))}}
{{template "navlink" (navItem . "/tests" "tests" "ผลตรวจ Test" (testBadge .))}}
{{template "navlink" (navItem . "/problems" "problems" "Problem solving" (problemBadge .))}}
{{template "navlink" (navItem . "/reviews" "reviews" "Wait for review" (printf "%d" (len .Reviews)))}}
</nav>
<div class="theme" role="group" aria-label="ธีมสี">
<button type="button" data-theme-choice="system" aria-pressed="true">ตามระบบ</button>
<button type="button" data-theme-choice="light" aria-pressed="false">สว่าง</button>
<button type="button" data-theme-choice="dark" aria-pressed="false">มืด</button>
</div>
<p class="live" id="live" data-state="connecting"><span class="live-dot" aria-hidden="true"></span><span class="live-text">กำลังเชื่อมต่อ</span></p>
<p class="side-note">อัปเดตข้อมูลล่าสุด <time id="loaded-at" datetime="{{.LoadedAt.Format "2006-01-02T15:04:05Z07:00"}}">{{thaiDateTime .LoadedAt}}</time></p>
</aside>
<main class="main{{if or (eq .Active "timeline") (eq .Active "usecases") (eq .Active "mockup")}} is-wide{{end}}" id="main" tabindex="-1">
{{if .LoadErr}}
<div class="alert" role="alert">
<b>อ่านข้อมูลล่าสุดไม่สำเร็จ หน้าจอกำลังแสดงข้อมูลชุดก่อนหน้า</b>
<p>{{.LoadErr}}</p>
<p>แก้ไฟล์ใน <code>tracker/data/</code> แล้วบันทึก หน้านี้จะอัปเดตเอง</p>
</div>
{{end}}
{{template "content" .}}
</main>
</div>
</body>
</html>{{end}}
{{define "navlink"}}<a href="{{.Href}}" class="nav-link{{if .On}} is-on{{end}}"{{if .On}} aria-current="page"{{end}}><span>{{.Label}}</span>{{if .Badge}}<span class="badge{{if .Alert}} badge-alert{{end}}">{{.Badge}}</span>{{end}}</a>{{end}}