diff options
-rw-r--r-- | src/dbx/mintages.go | 8 | ||||
-rw-r--r-- | src/dbx/sql/last.sql | 15 | ||||
-rw-r--r-- | src/http.go | 49 | ||||
-rw-r--r-- | src/tables.go | 108 | ||||
-rw-r--r-- | src/templates.go | 10 | ||||
-rw-r--r-- | src/templates/coins-mintages.html.tmpl | 49 |
6 files changed, 180 insertions, 59 deletions
diff --git a/src/dbx/mintages.go b/src/dbx/mintages.go index c612a92..2223eff 100644 --- a/src/dbx/mintages.go +++ b/src/dbx/mintages.go @@ -100,8 +100,8 @@ func GetMintagesByYear(year int, typ MintageType) (YearMintageData, error) { loop: msr := MSYearRow{ - Country: x.Country, - Mintmark: x.Mintmark, + Country: x.Country, + Mintmark: x.Mintmark, } i := denomToIdx(x.Denomination) msr.Mintages[i] = x.Mintage @@ -164,8 +164,8 @@ func GetMintagesByCountry(country string, typ MintageType) (CountryMintageData, loop: msr := MSCountryRow{ - Year: x.Year, - Mintmark: x.Mintmark, + Year: x.Year, + Mintmark: x.Mintmark, } i := denomToIdx(x.Denomination) msr.Mintages[i] = x.Mintage diff --git a/src/dbx/sql/last.sql b/src/dbx/sql/last.sql index 0f70bcc..22ebab8 100644 --- a/src/dbx/sql/last.sql +++ b/src/dbx/sql/last.sql @@ -133,6 +133,21 @@ INSERT INTO mintages_c ( mintage, reference ) VALUES + ('de', 0, 2015, C_('Hessen', 'CC Name'), 1, 'A', 6000000, NULL), + ('de', 0, 2015, C_('German Reunification', 'CC Name'), 2, 'A', 6000000, NULL), + ('de', 0, 2015, C_('EU Flag', 'CC Name'), 3, 'A', 6000000, NULL), + ('de', 0, 2015, C_('Hessen', 'CC Name'), 1, 'D', 6300000, NULL), + ('de', 0, 2015, C_('German Reunification', 'CC Name'), 2, 'D', 6300000, NULL), + ('de', 0, 2015, C_('EU Flag', 'CC Name'), 3, 'D', 6300000, NULL), + ('de', 0, 2015, C_('Hessen', 'CC Name'), 1, 'F', 7200000, NULL), + ('de', 0, 2015, C_('German Reunification', 'CC Name'), 2, 'F', 7200000, NULL), + ('de', 0, 2015, C_('EU Flag', 'CC Name'), 3, 'F', 7200000, NULL), + ('de', 0, 2015, C_('Hessen', 'CC Name'), 1, 'G', 4200000, NULL), + ('de', 0, 2015, C_('German Reunification', 'CC Name'), 2, 'G', 4200000, NULL), + ('de', 0, 2015, C_('EU Flag', 'CC Name'), 3, 'G', 4200000, NULL), + ('de', 0, 2015, C_('Hessen', 'CC Name'), 1, 'J', 6300000, NULL), + ('de', 0, 2015, C_('German Reunification', 'CC Name'), 2, 'J', 6300000, NULL), + ('de', 0, 2015, C_('EU Flag', 'CC Name'), 3, 'J', 6300000, NULL), ('sk', 0, 2014, C_('Slovak Republic to the EU', 'CC Name'), 1, NULL, 1000000, NULL), ('sk', 0, 2015, C_('Ľudovít Štúr', 'CC Name'), 1, NULL, 1000000, NULL), ('sk', 0, 2015, C_('EU Flag', 'CC Name'), 2, NULL, 1000000, NULL), diff --git a/src/http.go b/src/http.go index 241ddcc..fce82ba 100644 --- a/src/http.go +++ b/src/http.go @@ -14,8 +14,6 @@ import ( "time" . "git.thomasvoss.com/euro-cash.eu/pkg/try" - "golang.org/x/text/collate" - "golang.org/x/text/language" "git.thomasvoss.com/euro-cash.eu/src/dbx" "git.thomasvoss.com/euro-cash.eu/src/email" @@ -155,7 +153,6 @@ func mintageHandler(next http.Handler) http.Handler { td.FilterBy = "country" } - var err error mt := dbx.NewMintageType(td.Type) switch td.FilterBy { @@ -166,45 +163,25 @@ func mintageHandler(next http.Handler) http.Handler { }) { td.Code = td.Countries[0].Code } - td.CountryMintages, err = dbx.GetMintagesByCountry(td.Code, mt) + + m, err := dbx.GetMintagesByCountry(td.Code, mt) + if err != nil { + throwError(http.StatusInternalServerError, err, w, r) + return + } + td.CountryMintages = makeCountryMintageTable(m, td.Printer) case "year": + var err error td.Year, err = strconv.Atoi(r.FormValue("year")) if err != nil || td.Year < 1999 { td.Year = 1999 } - td.YearMintages, err = dbx.GetMintagesByYear(td.Year, mt) - - /* NOTE: It’s safe to use MustParse() here, because by this - point we know that all BCPs are valid. */ - c := collate.New(language.MustParse(td.Printer.Bcp)) - for i, r := range td.YearMintages.Standard { - name := td.Printer.GetC( - countryCodeToName[r.Country], "Place Name") - td.YearMintages.Standard[i].Country = name - } - for i, r := range td.YearMintages.Commemorative { - name := td.Printer.GetC( - countryCodeToName[r.Country], "Place Name") - td.YearMintages.Commemorative[i].Country = name + m, err := dbx.GetMintagesByYear(td.Year, mt) + if err != nil { + throwError(http.StatusInternalServerError, err, w, r) + return } - slices.SortFunc(td.YearMintages.Standard, func(x, y dbx.MSYearRow) int { - Δ := c.CompareString(x.Country, y.Country) - if Δ == 0 { - Δ = c.CompareString(x.Mintmark.V, y.Mintmark.V) - } - return Δ - }) - slices.SortFunc(td.YearMintages.Commemorative, func(x, y dbx.MCommemorative) int { - Δ := c.CompareString(x.Country, y.Country) - if Δ == 0 { - Δ = c.CompareString(x.Mintmark.V, y.Mintmark.V) - } - return Δ - }) - } - if err != nil { - throwError(http.StatusInternalServerError, err, w, r) - return + td.YearMintages = makeYearMintageTable(m, td.Printer) } next.ServeHTTP(w, r) diff --git a/src/tables.go b/src/tables.go new file mode 100644 index 0000000..f99630b --- /dev/null +++ b/src/tables.go @@ -0,0 +1,108 @@ +package app + +import ( + "database/sql" + "slices" + + "golang.org/x/text/collate" + "golang.org/x/text/language" + + "git.thomasvoss.com/euro-cash.eu/src/dbx" + "git.thomasvoss.com/euro-cash.eu/src/i18n" +) + +type YearCCsPair struct { + Year int + Mintmark sql.Null[string] + CCs []dbx.MCommemorative +} + +type CountryMintageTable struct { + Standard []dbx.MSCountryRow + Commemorative []YearCCsPair +} + +type CountryCCsPair struct { + Country string + Mintmark sql.Null[string] + CCs []dbx.MCommemorative +} + +type YearMintageTable struct { + Standard []dbx.MSYearRow + Commemorative []CountryCCsPair +} + +func makeCountryMintageTable(data dbx.CountryMintageData, p i18n.Printer) CountryMintageTable { + ccdata := data.Commemorative + ccs := make([]YearCCsPair, 0, len(ccdata)) + + for len(ccdata) > 0 { + x := ccdata[0] + i := len(ccdata) + for j, y := range ccdata[1:] { + if x.Year != y.Year || x.Mintmark != y.Mintmark { + i = j + 1 + break + } + } + ccs = append(ccs, YearCCsPair{ + Year: x.Year, + Mintmark: x.Mintmark, + CCs: ccdata[:i], + }) + ccdata = ccdata[i:] + } + + return CountryMintageTable{data.Standard, ccs} +} + +func makeYearMintageTable(data dbx.YearMintageData, p i18n.Printer) YearMintageTable { + ccdata := data.Commemorative + ccs := make([]CountryCCsPair, 0, len(ccdata)) + + for len(ccdata) > 0 { + x := ccdata[0] + i := len(ccdata) + for j, y := range ccdata[1:] { + if x.Country != y.Country || x.Mintmark != y.Mintmark { + i = j + 1 + break + } + } + ccs = append(ccs, CountryCCsPair{ + Country: x.Country, + Mintmark: x.Mintmark, + CCs: ccdata[:i], + }) + ccdata = ccdata[i:] + } + + /* NOTE: It’s safe to use MustParse() here, because by this + point we know that all BCPs are valid. */ + c := collate.New(language.MustParse(p.Bcp)) + for i, r := range data.Standard { + name := countryCodeToName[r.Country] + data.Standard[i].Country = p.GetC(name, "Place Name") + } + for i, r := range ccs { + name := countryCodeToName[r.Country] + ccs[i].Country = p.GetC(name, "Place Name") + } + slices.SortFunc(data.Standard, func(x, y dbx.MSYearRow) int { + Δ := c.CompareString(x.Country, y.Country) + if Δ == 0 { + Δ = c.CompareString(x.Mintmark.V, y.Mintmark.V) + } + return Δ + }) + slices.SortFunc(ccs, func(x, y CountryCCsPair) int { + Δ := c.CompareString(x.Country, y.Country) + if Δ == 0 { + Δ = c.CompareString(x.Mintmark.V, y.Mintmark.V) + } + return Δ + }) + + return YearMintageTable{data.Standard, ccs} +} diff --git a/src/templates.go b/src/templates.go index 076f8dc..6a43fcb 100644 --- a/src/templates.go +++ b/src/templates.go @@ -10,7 +10,6 @@ import ( . "git.thomasvoss.com/euro-cash.eu/pkg/try" "git.thomasvoss.com/euro-cash.eu/pkg/watch" - "git.thomasvoss.com/euro-cash.eu/src/dbx" "git.thomasvoss.com/euro-cash.eu/src/i18n" ) @@ -20,8 +19,8 @@ type templateData struct { Printers map[string]i18n.Printer Code, Type, FilterBy string Year int - CountryMintages dbx.CountryMintageData - YearMintages dbx.YearMintageData + CountryMintages CountryMintageTable + YearMintages YearMintageTable Countries []country } @@ -30,6 +29,7 @@ var ( errorTmpl *template.Template templates map[string]*template.Template funcmap = map[string]any{ + "evenp": evenp, "ifElse": ifElse, "locales": i18n.Locales, "map": templateMakeMap, @@ -132,6 +132,10 @@ func templateMakeMap(args ...any) map[string]any { return m } +func evenp(n int) bool { + return n&1 == 0 +} + func ifElse(b bool, x, y any) any { if b { return x diff --git a/src/templates/coins-mintages.html.tmpl b/src/templates/coins-mintages.html.tmpl index a70a8ea..e5fa5f1 100644 --- a/src/templates/coins-mintages.html.tmpl +++ b/src/templates/coins-mintages.html.tmpl @@ -9,6 +9,10 @@ position: sticky; left: 0; } + + .striped :is(th, td) { + background-color: var(--pico-table-row-stripped-background-color); + } } label[for="country-dd"] { display: none; } @@ -180,7 +184,7 @@ {{ if ne (len .CountryMintages.Commemorative) 0 }} <figure> <figcaption>{{ .Get "Commemorative Coins" }}</figcaption> - <table class="mintage-table striped" role="grid"> + <table class="mintage-table" role="grid"> <thead> <th>{{ .GetC "Year" "Header/Label" }}</th> <th>{{ .GetC "Commemorated Topic" "Header/Label" }}</th> @@ -188,18 +192,25 @@ </thead> <tbody> {{ $p := .Printer }} - {{ range .CountryMintages.Commemorative }} - <tr> - <th scope="row"> - {{- .Year -}} - {{- if .Mintmark.Valid -}} - <sub><small>{{ .Mintmark.V }}</small></sub> + {{ range $i, $ := .CountryMintages.Commemorative }} + {{ $y := .Year }} + {{ $mm := .Mintmark }} + {{ $ccs := .CCs }} + {{ range $j, $cc := .CCs }} + <tr {{ if evenp $i }}class="striped"{{ end }}> + {{ if eq $j 0 }} + <th scope="row" rowspan="{{ len $ccs }}"> + {{- $y -}} + {{- if $mm.Valid -}} + <sub><small>{{ $mm.V }}</small></sub> {{- end -}} </th> + {{ end }} <td>{{ $p.GetC .Name "CC Name" }}</td> {{ template "mintages/mintage-cell" (tuple .Mintage $p) }} </tr> {{ end }} + {{ end }} </tbody> </table> </figure> @@ -210,7 +221,7 @@ {{ if ne (len .YearMintages.Commemorative) 0 }} <figure> <figcaption>{{ .Get "Commemorative Coins" }}</figcaption> - <table class="mintage-table striped" role="grid"> + <table class="mintage-table" role="grid"> <thead> <th>{{ .GetC "Country" "Header/Label" }}</th> <th>{{ .GetC "Commemorated Topic" "Header/Label" }}</th> @@ -218,19 +229,25 @@ </thead> <tbody> {{ $p := .Printer }} - {{ range .YearMintages.Commemorative }} - <tr> - <th scope="row"> - {{- .Country -}} - {{- if .Mintmark.Valid -}} - <sub><small>{{ .Mintmark.V }}</small></sub> + {{ range $i, $ := .YearMintages.Commemorative }} + {{ $c := .Country }} + {{ $mm := .Mintmark }} + {{ $ccs := .CCs }} + {{ range $j, $cc := .CCs }} + <tr {{ if evenp $i }}class="striped"{{ end }}> + {{ if eq $j 0 }} + <th scope="row" rowspan="{{ len $ccs }}"> + {{- $c -}} + {{- if $mm.Valid -}} + <sub><small>{{ $mm.V }}</small></sub> {{- end -}} </th> - <!-- TODO: Translate commemorative names --> - <td>{{ .Name }}</td> + {{ end }} + <td>{{ $p.GetC .Name "CC Name" }}</td> {{ template "mintages/mintage-cell" (tuple .Mintage $p) }} </tr> {{ end }} + {{ end }} </tbody> </table> </figure> |