From 564d0acca8aea41e9d2d233f64d1cdda6dbcd4ab Mon Sep 17 00:00:00 2001
From: Martin Fischer <martin@push-f.com>
Date: Sun, 13 Apr 2025 21:43:58 +0200
Subject: feat: group countries on start page by level of support

---
 lex-serve/assets/style.css          |  4 +++-
 lex-serve/main.go                   | 43 ++++++++++++++++++++++++++++++++-----
 lex-serve/main_test.go              | 11 +++++++++-
 lex-serve/templates/index.html.tmpl | 18 +++++++++++-----
 4 files changed, 64 insertions(+), 12 deletions(-)

(limited to 'lex-serve')

diff --git a/lex-serve/assets/style.css b/lex-serve/assets/style.css
index 3b064c2..a2d9b2a 100644
--- a/lex-serve/assets/style.css
+++ b/lex-serve/assets/style.css
@@ -10,8 +10,10 @@ body {
     border: 1px solid #ccc;
     border-radius: 5px;
 
-    display: grid;
+    display: inline-grid;
     grid-template-columns: repeat(auto-fit, minmax(50px, 1fr));
+    max-width: calc(9 * 50px);
+    margin-bottom: 1em;
 }
 
 .cc-link {
diff --git a/lex-serve/main.go b/lex-serve/main.go
index 2996aef..cf8e9ae 100644
--- a/lex-serve/main.go
+++ b/lex-serve/main.go
@@ -11,6 +11,7 @@ import (
 	"net/url"
 	"os"
 	"path"
+	"slices"
 	"strings"
 	"sync"
 
@@ -81,9 +82,7 @@ func main() {
 //go:embed templates
 var templates embed.FS
 
-var tpl, _ = template.New("").Funcs(template.FuncMap{
-	"ToUpper": strings.ToUpper,
-}).Option("missingkey=error").ParseFS(templates, "templates/*")
+var tpl, _ = template.New("").Option("missingkey=error").ParseFS(templates, "templates/*")
 
 type handler struct {
 	logger    *slog.Logger
@@ -106,10 +105,29 @@ func (h *handler) handle(w http.ResponseWriter, r *http.Request) {
 			w.Write([]byte("page not found"))
 			return
 		}
+		var firstTier []link
+		var secondTier []link
+		var thirdTier []link
+		for key, country := range h.countries {
+			link := link{
+				URL:  "//" + key + "." + h.domain,
+				Code: strings.ToUpper(key),
+				Name: country.Name,
+			}
+			if len(h.lawsByCC[key]) > 0 {
+				firstTier = append(firstTier, link)
+			} else if country.HasPlaceholder() {
+				secondTier = append(secondTier, link)
+			} else {
+				thirdTier = append(thirdTier, link)
+			}
+		}
 		var html bytes.Buffer
 		err := tpl.ExecuteTemplate(&html, "index.html.tmpl", map[string]any{
-			"Countries": h.countries,
-			"Domain":    r.Host,
+			"FirstTier":  slices.SortedFunc(slices.Values(firstTier), compareLink),
+			"SecondTier": slices.SortedFunc(slices.Values(secondTier), compareLink),
+			"ThirdTier":  slices.SortedFunc(slices.Values(thirdTier), compareLink),
+			"Domain":     r.Host,
 		})
 		if err != nil {
 			h.logger.Error("failed to execute index template", Error(err))
@@ -204,4 +222,19 @@ func (c country) HasPlaceholder() bool {
 	return strings.Contains(c.SearchURL, "%s")
 }
 
+type link struct {
+	URL  string
+	Code string
+	Name string
+}
+
+func compareLink(a, b link) int {
+	if a.Code > b.Code {
+		return 1
+	} else if a.Code < b.Code {
+		return -1
+	}
+	return 0
+}
+
 func Error(value error) slog.Attr { return slog.String("error", value.Error()) }
diff --git a/lex-serve/main_test.go b/lex-serve/main_test.go
index 4783fb3..bd284a8 100644
--- a/lex-serve/main_test.go
+++ b/lex-serve/main_test.go
@@ -47,9 +47,18 @@ func TestStartPage(t *testing.T) {
 <body>
 	<img alt="lex.surf" height=140 class=logo src="/assets/logo.svg">
 	<h2>The portal to&nbsp;national&nbsp;law.</h2>
+	<div>1st tier (autocompletion and short links)</div>
+	<div class=countries>
+	
+</div>
+	<div>2nd tier (search form)</div>
 	<div class=countries>
 	<a class=cc-link href="//zu.lex.example" title="Zubrowka">ZU</a>
-	</div>
+</div>
+	<div>3rd tier (just a link)</div>
+	<div class=countries>
+	
+</div>
 </body>
 </html>
 `
diff --git a/lex-serve/templates/index.html.tmpl b/lex-serve/templates/index.html.tmpl
index 3d8c04f..108bc17 100644
--- a/lex-serve/templates/index.html.tmpl
+++ b/lex-serve/templates/index.html.tmpl
@@ -8,10 +8,18 @@
 <body>
 	<img alt="lex.surf" height=140 class=logo src="/assets/logo.svg">
 	<h2>The portal to&nbsp;national&nbsp;law.</h2>
-	<div class=countries>
-	{{range $key, $c := .Countries -}}
-		<a class=cc-link href="//{{$key}}.{{$.Domain}}" title="{{$c.Name}}">{{$key | ToUpper}}</a>
-	{{- end}}
-	</div>
+	<div>1st tier (autocompletion and short links)</div>
+	{{template "country-links" .FirstTier}}
+	<div>2nd tier (search form)</div>
+	{{template "country-links" .SecondTier}}
+	<div>3rd tier (just a link)</div>
+	{{template "country-links" .ThirdTier}}
 </body>
 </html>
+{{define "country-links" -}}
+<div class=countries>
+	{{range . -}}
+	<a class=cc-link href="{{.URL}}" title="{{.Name}}">{{.Code}}</a>
+	{{- end}}
+</div>
+{{- end -}}
-- 
cgit v1.2.3