Files
fit/internal/web/templates/day.html
scott faf73c8be5 Track five things a day for seventy-five days
The workout, the protein, the calories, the water, and three lines of
gratitude. One page per day, a card of seventy-five tiles that fill by
how many of the five landed, and a missed day left as a gap rather than
a reset.

Single Go binary with no dependencies. The log is one JSON file on a
mounted volume, written atomically and never silently replaced when it
fails to parse, since it is the one thing here that cannot be recreated.
Auth is Traefik basic auth at the ingress; the app has no login of its
own, so every POST checks Sec-Fetch-Site to stop another origin posting
with those credentials.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-01 21:59:01 -07:00

94 lines
3.4 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{{template "head" .}}
<main class="page">
<header class="masthead">
<nav class="masthead-nav">
{{if .PrevDate}}
<a class="step" href="/d/{{.PrevDate}}" rel="prev" aria-label="The day before"></a>
{{else}}
<span class="step is-spent" aria-hidden="true"></span>
{{end}}
<div class="masthead-day">
<p class="eyebrow">Day</p>
{{if .View.Number}}
<p class="masthead-count">{{.View.Number}}</p>
<p class="masthead-of">of {{.Settings.Length}}</p>
{{else}}
<p class="masthead-count is-spent">·</p>
<p class="masthead-of">outside the {{.Settings.Length}}</p>
{{end}}
</div>
{{if .NextDate}}
<a class="step" href="/d/{{.NextDate}}" rel="next" aria-label="The day after"></a>
{{else}}
<span class="step is-spent" aria-hidden="true"></span>
{{end}}
</nav>
<p class="masthead-date">
{{if .View.IsToday}}<b>Today</b> · {{end}}{{dateLong .View.Time}}
{{if not .View.IsToday}}<a class="masthead-back" href="/">Back to today</a>{{end}}
</p>
{{if eq .Status "before"}}
<p class="notice">Day 1 is {{dateLong .Settings.Start}}. Nothing counts until then.</p>
{{else if eq .Status "after"}}
<p class="notice">The {{.Settings.Length}} days are done. {{.Stats.Complete}} of them were perfect.</p>
{{end}}
</header>
<form class="log" method="post" action="/d/{{.View.Date}}" data-log>
<label class="band band-toggle{{if .Day.Workout}} is-met{{end}}" data-band="workout">
<input class="band-check" type="checkbox" name="workout" value="1" {{if .Day.Workout}}checked{{end}}>
<span class="band-label">Workout</span>
<span class="band-state">
<span class="state-off">Not yet</span>
<span class="state-on">Done</span>
</span>
<span class="band-tick" aria-hidden="true"></span>
</label>
{{range .Meters}}
<div class="band band-meter{{if .Met}} is-met{{end}}{{if .Over}} is-over{{end}}"
style="--fill:{{.Pct}}%" data-band="{{.Key}}" data-target="{{.Target}}" data-mode="{{.Mode}}">
<span class="band-track" aria-hidden="true"><span class="band-fill"></span></span>
<label class="band-label" for="f-{{.Key}}">{{.Label}}</label>
<span class="band-entry">
<input class="band-input" id="f-{{.Key}}" name="{{.Key}}" type="number"
inputmode="numeric" min="0" step="1" value="{{num .Value}}" placeholder="—">
<span class="band-unit">{{.Unit}}</span>
</span>
<span class="band-note">{{.Note}}</span>
<span class="band-tick" aria-hidden="true"></span>
</div>
{{end}}
<fieldset class="gratitude{{if .View.Marks.Gratitude}} is-met{{end}}" data-band="gratitude">
<legend>Gratitude</legend>
<p class="gratitude-hint">Three lines. Any size.</p>
<ol class="gratitude-lines">
{{range $i, $line := .Day.Gratitude}}
<li>
<input class="gratitude-input" type="text" name="gratitude{{add $i 1}}"
value="{{$line}}" maxlength="280" autocomplete="off"
aria-label="Gratitude {{add $i 1}} of 3">
</li>
{{end}}
</ol>
</fieldset>
<div class="log-foot">
<button class="save save-day" type="submit">Save the day</button>
<p class="log-status" data-status role="status">{{.Flash}}</p>
</div>
</form>
{{template "card" .}}
</main>
{{template "foot" .}}