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> | ||||||
| <h1>sklad</h1> | 
 | ||||||
|  | <header> | ||||||
|  | 	<h1>sklad</h1> | ||||||
| 
 | 
 | ||||||
| {{ if .LoggedIn }} | {{ if .LoggedIn }} | ||||||
| <form method=post action=/logout> | 	<a href=/>Obaly</a> | ||||||
| <input type=submit value="Odhlásit"> | 	<a href=/series>Řady</a> | ||||||
| </form> | 
 | ||||||
|  | 	<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 }} | {{ 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( | ||||||
| 	if err := r.ParseForm(); err != nil { | 	http.ResponseWriter, *http.Request) { | ||||||
| 		http.Error(w, err.Error(), http.StatusInternalServerError) | 	return func(w http.ResponseWriter, r *http.Request) { | ||||||
| 		return | 		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") | 	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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user