// Package templates holds every templ component and the view models they read. // Layout never branches on the stage driver: it renders the binding it is given. // // The generated *_templ.go files are not committed; `make generate` writes them // from the repository root before every build. There is deliberately no // //go:generate directive: templ records the .templ path in its error messages, // so generating from a package directory and generating from the root produce // different files. One entry point keeps the output byte-identical. package templates import ( stdhtml "html" "strings" "github.com/a-h/templ" "gitea.lab.audasmedia.com.au/sam/ai-resume/internal/content" "gitea.lab.audasmedia.com.au/sam/ai-resume/internal/search" "gitea.lab.audasmedia.com.au/sam/ai-resume/internal/stage" ) // NavItem is one left-nav entry. type NavItem struct { Title string Href string Gutter string Current bool } // Crumb is one breadcrumb. type Crumb struct { Label string Href string } // LayoutView is everything the chrome needs. type LayoutView struct { Title string Description string Area string Nav []NavItem Crumbs []Crumb Stage stage.Binding SearchQuery string Year int SkipAI bool // true on Mode A pages, which never need a model } // StageView wraps the binding so the Stage component has one argument. type StageView struct { Binding stage.Binding // Fragment, when set, is rendered into the panel at build time. Fragment *stage.Fragment } // MetricView is one approved chip. type MetricView struct { Label string Value string } // LinkView is a drill-down link. HXGet makes it a stage trigger; Href keeps it // a working link when JavaScript is off. type LinkView struct { Label string Href string HXGet string Kind string Note string Confidence string } // EvidenceRow is one row of an EvidenceTable. type EvidenceRow struct { Label string Href string HXGet string Kind string Confidence string } // EvidenceGroup groups rows by area on the evidence index. type EvidenceGroup struct { AreaTitle string Href string Rows []EvidenceRow } // TimelineItem is one row of a timeline. type TimelineItem struct { Period string Title string Href string Confidence string Claim string } // PillarCardView is one of the six landing cards. type PillarCardView struct { Area content.Area Title string Claim string Href string Metrics []MetricView Tech []string Confidence string Level int Pages int } // Layout of each page kind. type ( // HomeView is the landing page. HomeView struct { Layout LayoutView Positioning string Support string Location string Cards []PillarCardView Artifacts int Pages int Areas int } // DocView is an L1, L2 or L3 content page. DocView struct { Layout LayoutView Doc *content.Document Role string Body templ.Component Metrics []MetricView Tech []string Evidence []LinkView Backlinks []LinkView SubPages []LinkView Timeline []TimelineItem } // EvidenceView is the index of every artefact. EvidenceView struct { Layout LayoutView Groups []EvidenceGroup Total int } // SearchView is the keyword search page. SearchView struct { Layout LayoutView Query string Results []search.Result Total int Indexed int Failed bool // Areas are the six area landings, offered as the way out of an // empty result. Nothing here was ever a search hit. Areas []LinkView } // StreamView is the SSE-driven stage demonstration page. StreamView struct { Layout LayoutView Frames int Fragment []LinkView } // NotFoundView is the 404 page. NotFoundView struct { Layout LayoutView } ) // MarkdownBody wraps pre-rendered Markdown HTML. func MarkdownBody(html string) templ.Component { return templ.Raw(html) } // SafeSnippet escapes a search snippet but keeps the tags the index // inserted. Content is in-repo and trusted; escaping is defence in depth. func SafeSnippet(s string) templ.Component { s = stdhtml.EscapeString(s) s = strings.ReplaceAll(s, "<mark>", "") s = strings.ReplaceAll(s, "</mark>", "") return templ.Raw(s) } // ConfidenceClass maps a confidence value onto a CSS class. The value itself is // always displayed — never softened. func ConfidenceClass(c string) string { switch c { case content.ConfidenceDelivered: return "conf conf-delivered" case content.ConfidenceRunning: return "conf conf-running" case content.ConfidenceInProgress: return "conf conf-in-progress" case content.ConfidenceAbandoned: return "conf conf-abandoned" case content.ConfidenceHistoric: return "conf conf-historic" } return "conf" }