aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorThomas Voss <mail@thomasvoss.com> 2025-08-07 14:44:10 +0200
committerThomas Voss <mail@thomasvoss.com> 2025-08-07 14:44:24 +0200
commit33e94090b10c67ef036803dd14d47af749a5767a (patch)
treecdee04d71f988dea4b98f0dcd927f0e735fd4518
parent3f064cd622d7dd1c74a506eee0766e80a869a94c (diff)
More big improvements to mintage tablesHEADmaster
-rw-r--r--src/dbx/mintages.go8
-rw-r--r--src/dbx/sql/last.sql15
-rw-r--r--src/http.go49
-rw-r--r--src/tables.go108
-rw-r--r--src/templates.go10
-rw-r--r--src/templates/coins-mintages.html.tmpl49
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 -}}
- &nbsp;<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 -}}
+ &nbsp;<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 -}}
- &nbsp;<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 -}}
+ &nbsp;<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>