add theming
This commit is contained in:
parent
885e7d6e02
commit
8639799f6d
10 changed files with 1069 additions and 287 deletions
|
|
@ -62,6 +62,10 @@ type ReportData struct {
|
|||
// Set when this is a per-day report in split-by-day mode.
|
||||
IndexFile string // non-empty → render "← Back to Index" nav link
|
||||
DayTitle string // e.g. "2024-02-20", shown in the header
|
||||
|
||||
// Theme selects the visual theme (see themes.go). Empty or unrecognized
|
||||
// falls back to DefaultTheme.
|
||||
Theme string
|
||||
}
|
||||
|
||||
// DaySummary is one row in the index page's daily breakdown table.
|
||||
|
|
@ -82,6 +86,10 @@ type IndexData struct {
|
|||
TotalUniqueIPs int
|
||||
TotalBytes int64
|
||||
OverallErrorRate float64
|
||||
|
||||
// Theme selects the visual theme (see themes.go). Empty or unrecognized
|
||||
// falls back to DefaultTheme.
|
||||
Theme string
|
||||
}
|
||||
|
||||
// DayReport bundles one calendar day's fully-computed ReportData with
|
||||
|
|
@ -110,6 +118,7 @@ func GroupByDay(
|
|||
accessEntries []parser.AccessEntry,
|
||||
errorEntries []parser.ErrorEntry,
|
||||
geoPoints map[string]GeoPoint,
|
||||
themeName string,
|
||||
) []DayReport {
|
||||
accessByDay := make(map[string][]parser.AccessEntry)
|
||||
for _, e := range accessEntries {
|
||||
|
|
@ -145,6 +154,7 @@ func GroupByDay(
|
|||
GeneratedAt: time.Now(),
|
||||
AccessEntries: dayAccess,
|
||||
ErrorEntries: dayErrors,
|
||||
Theme: themeName,
|
||||
}
|
||||
ComputeStats(&rd)
|
||||
|
||||
|
|
@ -173,8 +183,21 @@ func GroupByDay(
|
|||
return days
|
||||
}
|
||||
|
||||
// indexRenderData wraps IndexData with the resolved theme's stylesheet for
|
||||
// template execution.
|
||||
type indexRenderData struct {
|
||||
IndexData
|
||||
ThemeCSS template.CSS
|
||||
}
|
||||
|
||||
// GenerateIndexHTML renders the index page from IndexData.
|
||||
func GenerateIndexHTML(idx IndexData) (string, error) {
|
||||
th := themeFor(idx.Theme)
|
||||
view := indexRenderData{
|
||||
IndexData: idx,
|
||||
ThemeCSS: template.CSS(th.CSS),
|
||||
}
|
||||
|
||||
funcMap := template.FuncMap{
|
||||
"formatBytes": func(b int64) string {
|
||||
switch {
|
||||
|
|
@ -206,7 +229,7 @@ func GenerateIndexHTML(idx IndexData) (string, error) {
|
|||
return "", err
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
if err := tmpl.Execute(&buf, idx); err != nil {
|
||||
if err := tmpl.Execute(&buf, view); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return buf.String(), nil
|
||||
|
|
@ -295,8 +318,47 @@ func ComputeStats(data *ReportData) {
|
|||
data.TimeSeriesData = ts
|
||||
}
|
||||
|
||||
// reportRenderData wraps ReportData with the resolved theme's stylesheet and
|
||||
// chart/map color values for template execution.
|
||||
type reportRenderData struct {
|
||||
ReportData
|
||||
ThemeCSS template.CSS
|
||||
ThemeExtraCSS template.CSS
|
||||
ChartFont string
|
||||
ChartText string
|
||||
ChartGrid string
|
||||
Chart1 string
|
||||
Chart2 string
|
||||
Chart2Fill string
|
||||
Chart3 string
|
||||
ChartWarn string
|
||||
ChartErr string
|
||||
MapTileURL string
|
||||
MapAttribution string
|
||||
MarkerColor string
|
||||
}
|
||||
|
||||
// GenerateHTML renders the full HTML report from data.
|
||||
func GenerateHTML(data ReportData) (string, error) {
|
||||
th := themeFor(data.Theme)
|
||||
view := reportRenderData{
|
||||
ReportData: data,
|
||||
ThemeCSS: template.CSS(th.CSS),
|
||||
ThemeExtraCSS: template.CSS(th.ExtraCSS),
|
||||
ChartFont: th.ChartFont,
|
||||
ChartText: th.ChartText,
|
||||
ChartGrid: th.ChartGrid,
|
||||
Chart1: th.Chart1,
|
||||
Chart2: th.Chart2,
|
||||
Chart2Fill: th.Chart2Fill,
|
||||
Chart3: th.Chart3,
|
||||
ChartWarn: th.ChartWarn,
|
||||
ChartErr: th.ChartErr,
|
||||
MapTileURL: th.MapTileURL,
|
||||
MapAttribution: th.MapAttribution,
|
||||
MarkerColor: th.MarkerColor,
|
||||
}
|
||||
|
||||
funcMap := template.FuncMap{
|
||||
"add": func(a, b int) int { return a + b },
|
||||
"formatBytes": func(b int64) string {
|
||||
|
|
@ -428,7 +490,7 @@ func GenerateHTML(data ReportData) (string, error) {
|
|||
return "", err
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
if err := tmpl.Execute(&buf, data); err != nil {
|
||||
if err := tmpl.Execute(&buf, view); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return buf.String(), nil
|
||||
|
|
|
|||
Loading…
Reference in a new issue