sklad: styling, add a basic view for containers
This commit is contained in:
parent
bcfb9fbc2b
commit
7eb84cd937
|
@ -7,18 +7,33 @@
|
||||||
html, body { min-height: 100vh; }
|
html, body { min-height: 100vh; }
|
||||||
body { padding: 1em; box-sizing: border-box;
|
body { padding: 1em; box-sizing: border-box;
|
||||||
margin: 0 auto; max-width: 50em;
|
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; }
|
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>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
<header>
|
||||||
<h1>sklad</h1>
|
<h1>sklad</h1>
|
||||||
|
|
||||||
{{ if .LoggedIn }}
|
{{ if .LoggedIn }}
|
||||||
|
<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>
|
<form method=post action=/logout>
|
||||||
<input type=submit value="Odhlásit">
|
<input type=submit value="Odhlásit">
|
||||||
</form>
|
</form>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
</header>
|
||||||
|
|
||||||
{{ template "Content" . }}
|
{{ template "Content" . }}
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -1,6 +1,27 @@
|
||||||
{{ define "Title" }}Přehled{{ end }}
|
{{ define "Title" }}Přehled{{ end }}
|
||||||
{{ define "Content" }}
|
{{ 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 }}
|
{{ end }}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
{{ define "Title" }}Přihlášení{{ end }}
|
{{ define "Title" }}Přihlášení{{ end }}
|
||||||
{{ define "Content" }}
|
{{ define "Content" }}
|
||||||
|
|
||||||
|
<h2>Přihlášení</h2>
|
||||||
|
|
||||||
<form method=post>
|
<form method=post>
|
||||||
<label for=password>Heslo:</label>
|
<label for=password>Heslo:</label>
|
||||||
<input type=password name=password id=password>
|
<input type=password name=password id=password>
|
||||||
|
|
|
@ -11,22 +11,31 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var templates = map[string]*template.Template{}
|
||||||
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{}) {
|
func executeTemplate(name string, w io.Writer, data interface{}) {
|
||||||
if err := templates[name].Execute(w, data); err != nil {
|
if err := templates[name].Execute(w, data); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleLogin(w http.ResponseWriter, r *http.Request) {
|
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 {
|
if err := r.ParseForm(); err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
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")
|
redirect := r.FormValue("redirect")
|
||||||
if redirect == "" {
|
if redirect == "" {
|
||||||
redirect = "/"
|
redirect = "/"
|
||||||
|
@ -45,7 +54,7 @@ func handleLogin(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
switch r.Method {
|
switch r.Method {
|
||||||
case http.MethodGet:
|
case http.MethodGet:
|
||||||
w.Header().Set("Cache-Control", "no-store")
|
// We're just going to render the template.
|
||||||
case http.MethodPost:
|
case http.MethodPost:
|
||||||
if r.FormValue("password") == db.Password {
|
if r.FormValue("password") == db.Password {
|
||||||
session.LoggedIn = true
|
session.LoggedIn = true
|
||||||
|
@ -78,10 +87,27 @@ func handleContainer(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
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 {
|
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, ¶ms)
|
executeTemplate("container.tmpl", w, ¶ms)
|
||||||
|
@ -127,11 +153,11 @@ func main() {
|
||||||
// - https://stackoverflow.com/a/33880971/76313
|
// - https://stackoverflow.com/a/33880971/76313
|
||||||
// - POST /label?id=UA1
|
// - POST /label?id=UA1
|
||||||
|
|
||||||
http.HandleFunc("/", sessionWrap(handleContainer))
|
http.HandleFunc("/", sessionWrap(wrap(handleContainer)))
|
||||||
http.HandleFunc("/container", sessionWrap(handleContainer))
|
http.HandleFunc("/container", sessionWrap(wrap(handleContainer)))
|
||||||
|
|
||||||
http.HandleFunc("/login", handleLogin)
|
http.HandleFunc("/login", wrap(handleLogin))
|
||||||
http.HandleFunc("/logout", sessionWrap(handleLogout))
|
http.HandleFunc("/logout", sessionWrap(wrap(handleLogout)))
|
||||||
|
|
||||||
log.Fatalln(http.ListenAndServe(address, nil))
|
log.Fatalln(http.ListenAndServe(address, nil))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue