From 4c9b51b8c6b2ebeea0481d219df89ed4fec1e360 Mon Sep 17 00:00:00 2001 From: Julien Dessaux Date: Mon, 25 Mar 2024 13:58:48 +0100 Subject: feat(ods): implement basic ods functionality --- index.html | 29 ++++++++++++++++ main.go | 75 +++++++++++++++++++++++++++++++++++++++++ static/favicon.svg | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ static/index4.css | 57 ++++++++++++++++++++++++++++++++ 4 files changed, 258 insertions(+) create mode 100644 index.html create mode 100644 main.go create mode 100644 static/favicon.svg create mode 100644 static/index4.css diff --git a/index.html b/index.html new file mode 100644 index 0000000..f98fd30 --- /dev/null +++ b/index.html @@ -0,0 +1,29 @@ + + + + + + + + + ODS + + +
+
+ +
+ + {{ if .HasQuery }} + + {{ end }} +
+
+

+ {{ if .HasQuery }} + {{ .Query }} est un mot IN{{ else }}valid">{{ end }}VALIDE au scrabble. + {{ end }} +

+
+ + diff --git a/main.go b/main.go new file mode 100644 index 0000000..3afc7cc --- /dev/null +++ b/main.go @@ -0,0 +1,75 @@ +package main + +import ( + "embed" + "html/template" + "log/slog" + "net/http" + "strings" +) + +// Variables to customise the search behaviour +const ( + listenStr = "0.0.0.0:8090" +) + +//go:embed ods.txt +var ods string + +//go:embed index.html +var templatesFS embed.FS + +//go:embed static/* +var static embed.FS + +// html templates +var indexTemplate = template.Must(template.New("index").ParseFS(templatesFS, "index.html")) + +type IndexData struct { + HasQuery bool + Query string + Invalid bool +} + +func getIndex() http.Handler { + data := IndexData{ + HasQuery: false, + Query: "", + Invalid: true, + } + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Cache-Control", "no-store, no-cache") + indexTemplate.ExecuteTemplate(w, "index.html", data) + }) +} + +func postIndex() http.Handler { + words := strings.Split(ods,"\n") + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + data := IndexData{ + HasQuery: true, + Query: r.FormValue("query"), + Invalid: true, + } + query := strings.ToUpper(data.Query) + for _, w := range words { + if w == query { + data.Invalid = false + break + } + } + w.Header().Set("Cache-Control", "no-store, no-cache") + indexTemplate.ExecuteTemplate(w, "index.html", data) + }) +} + +// The main function +func main() { + http.Handle("GET /static/", http.FileServer(http.FS(static))) + http.Handle("GET /", getIndex()) + http.Handle("POST /", postIndex()) + slog.Info("listening", "addr", listenStr) + if err := http.ListenAndServe(listenStr, nil); err != nil && err != http.ErrServerClosed { + slog.Error("error listening and serving", "error", err) + } +} diff --git a/static/favicon.svg b/static/favicon.svg new file mode 100644 index 0000000..971d573 --- /dev/null +++ b/static/favicon.svg @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + A + 1 + + diff --git a/static/index4.css b/static/index4.css new file mode 100644 index 0000000..34637fe --- /dev/null +++ b/static/index4.css @@ -0,0 +1,57 @@ +* { + box-sizing: border-box; + scrollbar-gutter: stable both-edges; +} + +body { + background: #009E60; + display: grid; + grid-template-rows: auto 1fr auto; + font-family: -apple-system, BlinkMacSystemFont, + "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", + "Fira Sans", "Droid Sans", "Helvetica Neue", + sans-serif; + font-feature-settings: "kern" 1; + font-kerning: normal; +} + +form { + align-items: center; + display: flex; + flex-wrap: wrap; + justify-content: start; +} + +input,.btn-group { + margin-top: 1em; + margin-right: 1.5em; +} + +main { + background: #F6F7EB; + padding-left: 1em; + padding-right: 1em; +} + +@media only screen and (min-width: 48rem) { + body { + max-width:48rem; + margin-left: auto; + margin-right: auto; + } +} + +span { + font-weight: bold; + padding-bottom: 0.1em; + padding-left: 0.5em; + padding-right: 0.5em; + padding-top: 0.1em; +} +.valid { + background: #009E60; + color: #F6F7EB; +} +.invalid { + background: #E94F37; +} -- cgit v1.2.3