aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Janouch <p@janouch.name>2019-04-14 01:05:05 +0200
committerPřemysl Janouch <p@janouch.name>2019-04-14 01:05:05 +0200
commit7eb84cd937ad65b0941164c5efe6b35a1210f8c3 (patch)
treefc554879abe02c83822fd9b94414336e1469afa8
parentbcfb9fbc2bc035149a71df1ffef96f23e668e815 (diff)
downloadsklad-7eb84cd937ad65b0941164c5efe6b35a1210f8c3.tar.gz
sklad-7eb84cd937ad65b0941164c5efe6b35a1210f8c3.tar.xz
sklad-7eb84cd937ad65b0941164c5efe6b35a1210f8c3.zip
sklad: styling, add a basic view for containers
-rw-r--r--sklad/base.tmpl25
-rw-r--r--sklad/container.tmpl23
-rw-r--r--sklad/login.tmpl2
-rw-r--r--sklad/main.go54
4 files changed, 84 insertions, 20 deletions
diff --git a/sklad/base.tmpl b/sklad/base.tmpl
index 2070d6e..b8487ee 100644
--- a/sklad/base.tmpl
+++ b/sklad/base.tmpl
@@ -7,18 +7,33 @@
html, body { min-height: 100vh; }
body { padding: 1em; box-sizing: border-box;
margin: 0 auto; max-width: 50em;
- border-left: 1px solid gray; border-right: 1px solid gray;
+ border-left: 1px solid #ccc; border-right: 1px solid #ccc;
font-family: sans-serif; }
+ header { display: flex; justify-content: space-between; align-items: center;
+ flex-wrap: wrap; margin: -1em -1em 0 -1em; padding: 0 1em;
+ background: linear-gradient(0deg, #fff, #eee); }
+ header * { display: inline-block; }
+ a { color: inherit; }
</style>
</head>
<body>
-<h1>sklad</h1>
+
+<header>
+ <h1>sklad</h1>
{{ if .LoggedIn }}
-<form method=post action=/logout>
-<input type=submit value="Odhlásit">
-</form>
+ <a href=/>Obaly</a>
+ <a href=/series>Řady</a>
+
+ <form method=get action=/search>
+ <input type=text name=q><input type=submit value="Hledat">
+ </form>
+
+ <form method=post action=/logout>
+ <input type=submit value="Odhlásit">
+ </form>
{{ end }}
+</header>
{{ template "Content" . }}
</body>
diff --git a/sklad/container.tmpl b/sklad/container.tmpl
index 341d19b..b261496 100644
--- a/sklad/container.tmpl
+++ b/sklad/container.tmpl
@@ -1,6 +1,27 @@
{{ define "Title" }}Přehled{{ end }}
{{ define "Content" }}
-<p>TODO
+{{ if .Id }}
+<h2>{{ .Id }}</h2>
+{{ else }}
+<h2>Obaly nejvyšší úrovně</h2>
+{{ end }}
+
+{{ if .Description }}
+<p>{{ .Description }}
+{{ end }}
+
+{{ if .Children }}
+{{ range .Children }}
+<fieldset>
+<h3><a href="/container?id={{ .Id }}">{{ .Id }}</a></h3>
+{{ if .Description }}
+<p>{{ .Description }}
+{{ end }}
+</fieldset>
+{{ end }}
+{{ else }}
+<p>Obal je prázdný.
+{{ end }}
{{ end }}
diff --git a/sklad/login.tmpl b/sklad/login.tmpl
index 4df6c3a..8dbca84 100644
--- a/sklad/login.tmpl
+++ b/sklad/login.tmpl
@@ -1,6 +1,8 @@
{{ define "Title" }}Přihlášení{{ end }}
{{ define "Content" }}
+<h2>Přihlášení</h2>
+
<form method=post>
<label for=password>Heslo:</label>
<input type=password name=password id=password>
diff --git a/sklad/main.go b/sklad/main.go
index 3ceea9f..dee8723 100644
--- a/sklad/main.go
+++ b/sklad/main.go
@@ -11,22 +11,31 @@ import (
"time"
)
-var (
- templates = map[string]*template.Template{}
-)
+var templates = map[string]*template.Template{}
+// TODO: Consider wrapping the data object in something that always contains
+// a LoggedIn member, so that we don't need to duplicate it.
func executeTemplate(name string, w io.Writer, data interface{}) {
if err := templates[name].Execute(w, data); err != nil {
panic(err)
}
}
-func handleLogin(w http.ResponseWriter, r *http.Request) {
- if err := r.ParseForm(); err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
+func wrap(inner func(http.ResponseWriter, *http.Request)) func(
+ http.ResponseWriter, *http.Request) {
+ return func(w http.ResponseWriter, r *http.Request) {
+ if err := r.ParseForm(); err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ if r.Method == http.MethodGet {
+ w.Header().Set("Cache-Control", "no-store")
+ }
+ inner(w, r)
}
+}
+func handleLogin(w http.ResponseWriter, r *http.Request) {
redirect := r.FormValue("redirect")
if redirect == "" {
redirect = "/"
@@ -45,7 +54,7 @@ func handleLogin(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
- w.Header().Set("Cache-Control", "no-store")
+ // We're just going to render the template.
case http.MethodPost:
if r.FormValue("password") == db.Password {
session.LoggedIn = true
@@ -78,10 +87,27 @@ func handleContainer(w http.ResponseWriter, r *http.Request) {
return
}
+ children := []*Container{}
+ id := ContainerId(r.FormValue("id"))
+ description := ""
+
+ if id == "" {
+ children = db.Containers
+ } else if container, ok := indexContainer[id]; ok {
+ children = indexChildren[id]
+ description = container.Description
+ }
+
params := struct {
- LoggedIn bool
+ LoggedIn bool
+ Id ContainerId
+ Description string
+ Children []*Container
}{
- LoggedIn: true,
+ LoggedIn: true,
+ Id: id,
+ Description: description,
+ Children: children,
}
executeTemplate("container.tmpl", w, &params)
@@ -127,11 +153,11 @@ func main() {
// - https://stackoverflow.com/a/33880971/76313
// - POST /label?id=UA1
- http.HandleFunc("/", sessionWrap(handleContainer))
- http.HandleFunc("/container", sessionWrap(handleContainer))
+ http.HandleFunc("/", sessionWrap(wrap(handleContainer)))
+ http.HandleFunc("/container", sessionWrap(wrap(handleContainer)))
- http.HandleFunc("/login", handleLogin)
- http.HandleFunc("/logout", sessionWrap(handleLogout))
+ http.HandleFunc("/login", wrap(handleLogin))
+ http.HandleFunc("/logout", sessionWrap(wrap(handleLogout)))
log.Fatalln(http.ListenAndServe(address, nil))
}