102 lines
2.5 KiB
Go
102 lines
2.5 KiB
Go
package web
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"html/template"
|
|
"net/http"
|
|
"net/url"
|
|
"path/filepath"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
var (
|
|
counter int = 1
|
|
)
|
|
|
|
func getContacts() map[string]any {
|
|
return map[string]any{
|
|
"Joe": "joe@example.com",
|
|
"Sarah": "sarah@example.com",
|
|
"Fred": "fred@example.com",
|
|
}
|
|
}
|
|
|
|
func makeContacts1(templates *template.Template) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
templates.ExecuteTemplate(w, "contacts", map[string]any{
|
|
"contacts": getContacts(),
|
|
"counter": counter,
|
|
})
|
|
counter++
|
|
}
|
|
}
|
|
|
|
func makeNav(templates *template.Template) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
path := strings.SplitAfterN(r.URL.Path, "/", 3)[2]
|
|
htmlPath := r.Header.Get("Hx-Current-Url")
|
|
u, err := url.Parse(htmlPath)
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
return
|
|
}
|
|
htmlPath = strings.SplitAfterN(u.Path, "/", 2)[1]
|
|
htmlPath = htmlPath[0 : len(htmlPath)-len(filepath.Ext(htmlPath))]
|
|
num, err := strconv.Atoi(htmlPath)
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
return
|
|
}
|
|
switch path {
|
|
case "nav":
|
|
templates.ExecuteTemplate(w, "nav", map[string]any{
|
|
"num": num,
|
|
"prev": fmt.Sprintf("%02d", num-1),
|
|
"curr": fmt.Sprintf("%2d", num),
|
|
"next": fmt.Sprintf("%02d", num+1),
|
|
})
|
|
default:
|
|
http.Error(w, path, http.StatusNotFound)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
func makeSearch4(templates *template.Template) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
q := r.FormValue("q")
|
|
state := r.FormValue("state")
|
|
raw := getContacts()
|
|
filtered := map[string]any{}
|
|
for k, v := range raw {
|
|
if strings.Contains(strings.ToUpper(k), strings.ToUpper(q)) {
|
|
filtered[k] = v
|
|
}
|
|
}
|
|
templates.ExecuteTemplate(w, "contacts", map[string]any{
|
|
"contacts": filtered,
|
|
"state": state,
|
|
})
|
|
}
|
|
}
|
|
|
|
func SetupRoutes(mux *http.ServeMux, templates *template.Template) {
|
|
mux.Handle("/", http.FileServer(http.Dir("./web/public/")))
|
|
mux.HandleFunc("/autonum/", makeNav(templates))
|
|
mux.HandleFunc("/contacts", makeContacts1(templates))
|
|
mux.HandleFunc("/search", makeSearch4(templates))
|
|
}
|
|
|
|
func UI(addr string) error {
|
|
templates := template.Must(template.ParseGlob("./web/public/*.gohtml"))
|
|
mux := http.NewServeMux()
|
|
SetupRoutes(mux, templates)
|
|
if err := http.ListenAndServe(addr, mux); err != nil {
|
|
if !errors.Is(err, http.ErrServerClosed) {
|
|
return fmt.Errorf("http server error %w", err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|