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 }}
+ {{ .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 @@
+
+
+
+
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