package main
import (
"fmt"
"strconv"
"strings"
"time"
)
// Finnish weekday and month names. Go formats dates in English only, and this
// app has exactly one locale (PRD §5).
var (
weekdaysFI = [...]string{"sunnuntai", "maanantai", "tiistai", "keskiviikko",
"torstai", "perjantai", "lauantai"}
weekdayAbbrFI = [...]string{"su", "ma", "ti", "ke", "to", "pe", "la"}
monthsFI = [...]string{"", "tammikuu", "helmikuu", "maaliskuu", "huhtikuu",
"toukokuu", "kesäkuu", "heinäkuu", "elokuu", "syyskuu", "lokakuu",
"marraskuu", "joulukuu"}
)
func longDateFI(t time.Time) string {
return weekdaysFI[t.Weekday()] + " " + t.Format("2.1.2006")
}
func dayLabelFI(t time.Time) string {
return weekdayAbbrFI[t.Weekday()] + " " + t.Format("2.1.")
}
func monthFI(t time.Time) string {
return monthsFI[int(t.Month())]
}
func isoDate(t time.Time) string {
return t.Format(dateLayout)
}
// dayURL links to a specific day, leaving today as the bare path.
func dayURL(base string, d, now time.Time) string {
if d.Equal(now) {
return base
}
return base + "?pvm=" + isoDate(d)
}
// pickSeparator joins a dish onto a day URL, which already carries ?pvm= for
// any day but today.
func pickSeparator(v logView) string {
if v.Date.Equal(v.Today) {
return "?"
}
return "&"
}
// categoryLabels lists a dish's categories in Finnish, for the catalog rows.
func categoryLabels(d Dish) string {
names := make([]string, 0, len(d.Categories))
for _, c := range d.Categories {
names = append(names, categoryFI[c])
}
return strings.Join(names, ", ")
}
// countFI renders "1 pääruoka" but "16 pääruokaa": Finnish takes the partitive
// after every number except one.
func countFI(n int, one, many string) string {
if n == 1 {
return fmt.Sprintf("%d %s", n, one)
}
return fmt.Sprintf("%d %s", n, many)
}
templ page(title, current string) {
// Dark is the default, set here so it holds even before theme.js runs and
// for anyone without JavaScript.
{ title }
@brandbar()
{ children... }
@tabbar(current)
}
templ brandbar() {
Foodster
@themeSwitch()
}
// themeSwitch marks the active theme rather than labelling itself with the one
// a click would produce. aria-pressed is set by theme.js on load, because only
// the device knows what was chosen.
// themeSwitch shows the theme that is on right now — moon while dark, sun
// while light — and clicking swaps it. Both icons are in the markup and CSS
// picks one, so the server never has to know the device's choice.
// theme.js writes the label, which names the state and then the action.
templ themeSwitch() {
}
templ iconSun() {
}
templ iconMoon() {
}
templ tabbar(current string) {
}
templ tab(href, label, current string) {
if href == current {
{ label }
} else {
{ label }
}
}
// ---------------------------------------------------------------- Kirjaa
templ logPage(v logView) {
@page("Foodster", "/") {
}
if len(v.Dishes) == 0 {
@quickAddCard(v)
}
}
// quickAddCard turns a search that found nothing into the thing to do next.
// Adding a dish here creates it and goes straight to logging it, so the user
// never leaves Kirjaa mid-thought.
templ quickAddCard(v logView) {
if v.Search == "" {
Lisää ensimmäinen ruoka
Ruokalista on tyhjä. Lisää ruoka tästä, tai tuo koko lista kerralla Ruoat-välilehdeltä.