Files
felhom-controller/controller/internal/web/templates/app_guide.html
T
admin d170a2aecf
gates / gates (push) Successful in 52s
v0.319.0: the app page in panels, the login in one place, a password the box never had is said in words
- style A (operator 2026-10-16): hero, tab bar and every section are panels on --bg-1, one width, 16px apart;
  the install page's form groups use the same rule; the settings tab's 700px inner wrapper is gone
- „Belépés az alkalmazásba": name + password side by side, fetched on demand (R-254, R-709); pairing in app_login.go
- the empty-value rule: no stored value -> a sentence, never an eye; page and reveal endpoint share storedValuePresent
- „Cím és kulcsok" is rows (no Domain input, no disabled storage select, no install form); hint under the title
- tests red-proved: app_page_tuning_test.go (4); 36 app-page parity fixtures re-captured, 4 new; install fixtures unchanged

Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb
2026-10-16 12:12:06 +02:00

124 lines
4.5 KiB
HTML

{{define "app_guide"}}
{{template "layout_start" .}}
<div class="app-page">
{{template "app_shell_start" .}}
{{/* „UTMUTATO" — the app's own copy, and the WHOLE page for an app that is not installed yet.
It replaces the old details page: description and screenshots, what it is for, the first steps,
the guide the catalog carries, the questions people ask, and the official documentation.
THE GUIDE RENDERS ONLY WHEN ITS AUTHOR NAMED THE VERSION THEY CHECKED IT AGAINST
(AppGuide.Rendered). A guide walking the household through a screen two releases old is worse
than no guide, so an unchecked one is not shown and the page says a guide is still to come.
Everything here is PLAIN TEXT through html/template. No markdown, no raw HTML: a step that
contains a tag is shown as the characters the author typed. */}}
<script>
// Defined BEFORE the images: an error event can fire as soon as an <img> is parsed.
function appShotGone(img) {
img.style.display = 'none';
var box = img.parentNode, left = false;
box.querySelectorAll('img').forEach(function (i) { if (i.style.display !== 'none') { left = true; } });
if (!left) { box.closest('.app-section').style.display = 'none'; }
}
</script>
<!-- Screenshots (graceful — each hidden if its asset does not exist, and the section with the last
one, so a panel is never drawn around nothing) -->
<div class="app-section" data-screenshots-section="1">
<div class="app-screenshots" id="screenshots">
<img src="{{screenshotURL .Meta.Slug 1}}" alt="" class="app-screenshot"
onerror="appShotGone(this)">
<img src="{{screenshotURL .Meta.Slug 2}}" alt="" class="app-screenshot"
onerror="appShotGone(this)">
<img src="{{screenshotURL .Meta.Slug 3}}" alt="" class="app-screenshot"
onerror="appShotGone(this)">
</div>
</div>
{{if not .Deployed}}
{{/* The install button lives on this tab, because this tab IS the page for a not-installed app.
The server refuses a non-installable template regardless; hiding the button keeps the page
from offering an action that would be rejected. */}}
<div class="app-section">
{{if canInstall .Meta}}
<a href="/apps/{{.Meta.Slug}}/install" class="btn btn-primary" data-install-cta="1"
onclick="return checkBeforeDeploy(event, '{{.Stack.Name}}')">{{T "app_info.telepites"}}</a>
{{else}}
<p class="form-hint" data-not-installable="1">{{T "app_page.not_installable"}}</p>
{{end}}
</div>
{{end}}
<div class="app-sections">
{{if .AppInfo.UseCases}}
<div class="app-section">
<h3>{{T "app_info.mire_hasznalhato"}}</h3>
<ul class="app-info-list">
{{range .AppInfo.UseCases}}<li>{{.}}</li>{{end}}
</ul>
</div>
{{end}}
{{if .AppInfo.FirstSteps}}
<div class="app-section">
<h3>{{T "app_info.elso_lepesek"}}</h3>
<ol class="app-info-list">
{{range .AppInfo.FirstSteps}}<li>{{.}}</li>{{end}}
</ol>
</div>
{{end}}
{{if .AppInfo.Prerequisites}}
<div class="app-section">
<h3>{{T "app_info.elofeltetelek"}}</h3>
<ul class="app-info-list">
{{range .AppInfo.Prerequisites}}<li>{{.}}</li>{{end}}
</ul>
</div>
{{end}}
</div>
{{/* THE GUIDE. */}}
{{if .AppInfo.Guide.Rendered}}
<div class="app-guide" data-guide="1" data-guide-checked="{{.AppInfo.Guide.CheckedVersion}}">
{{- range .AppInfo.Guide.Sections}}
<div class="app-section" data-guide-section="1">
<h3>{{.Title}}</h3>
{{if .Intro}}<p>{{.Intro}}</p>{{end}}
{{if .Steps}}
<ol class="app-info-list">
{{- range .Steps}}<li>{{.}}</li>{{end}}
</ol>
{{end}}
</div>
{{- end}}
{{- if .AppInfo.Guide.FAQ}}
<div class="app-section" data-guide-faq="1">
<h3>{{T "app_page.faq"}}</h3>
<dl class="app-faq">
{{- range .AppInfo.Guide.FAQ}}
<dt>{{.Q}}</dt>
<dd>{{.A}}</dd>
{{- end}}
</dl>
</div>
{{- end}}
</div>
{{else}}
<div class="app-section" data-guide-missing="1"><p>{{T "app_page.guide_missing"}}</p></div>
{{end}}
<div class="app-sections">
{{if .AppInfo.DocsURL}}
<div class="app-section">
<h3>{{T "app_info.dokumentacio"}}</h3>
<p><a href="{{.AppInfo.DocsURL}}" target="_blank" class="app-info-link">{{T "app_info.hivatalos_dokumentacio"}}</a></p>
</div>
{{end}}</div>
{{template "app_press_script" .}}
</div>{{/* .app-page */}}
{{template "layout_end" .}}
{{end}}