diff --git a/README.md b/README.md index 5d4a55f..0d6e926 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,8 @@ # Cal An open-source shared calendar + + +## Acknowledgements + - [SmolCSS](https://smolcss.dev/) for the stylings + - [git-pr](https://pr.pico.sh/) for an example of how to implement http + functions with Go 1.22.5 diff --git a/main.go b/main.go index 9c00e75..8305ada 100644 --- a/main.go +++ b/main.go @@ -1,7 +1,62 @@ package main -import "fmt" +import ( + "embed" + "fmt" + "html/template" + "io" + "io/fs" + "mime" + "net/http" + "path/filepath" +) + +//go:embed static +var staticFiles embed.FS func main() { - fmt.Println("Saluton, mondo") + staticFS := fs.FS(staticFiles) + http.HandleFunc("GET /", index) + http.Handle("GET /static/{file}", http.FileServer(http.FS(staticFS))) + + if err := http.ListenAndServe(":4321", nil); err != nil { + fmt.Printf("Unable to serve: %v\n", err) + } +} + +func serveFile(system fs.FS) func(w http.ResponseWriter, r http.Request) { + return func(w http.ResponseWriter, r http.Request) { + file := r.PathValue("file") + reader, err := system.Open(file) + + if err != nil { + http.Error(w, "File not found", 404) + return + } + defer reader.Close() + + cont, err := io.ReadAll(reader) + handleHTTPError("Error reading file", err, w) + contType := mime.TypeByExtension(filepath.Ext(file)) + w.Header().Add("Content-Type", contType) + _, err = w.Write(cont) + handleHTTPError("Error writing HTTP resp", err, w) + } +} + +func index(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "text/html; charset=utf8") + tmpl, err := template.ParseFiles("./tmpl/index.html", "./tmpl/base.html") + handleHTTPError("Error parsing template", err, w) + + err = tmpl.Execute(w, nil) + handleHTTPError("Error executing on template", err, w) +} + +func handleHTTPError(msg string, err error, w http.ResponseWriter) { + if err != nil { + fmt.Printf("%v: %v", msg, err) + http.Error(w, "Internal server error", 500) + return + } } diff --git a/static/smol.css b/static/smol.css new file mode 100644 index 0000000..5f752c4 --- /dev/null +++ b/static/smol.css @@ -0,0 +1,57 @@ +* { + box-sizing: border-box; + margin: 0; +} + +body { + background-color: var(--bg-colour); + color: var(--text-colour) !important; + display: flex; + flex-direction: column; + min-height: 100vh; + padding: 5vh clamp(1rem, 5vw, 3rem) 1rem; + font-family: system-ui, sans-serif; + line-height: 1.5; + color: #222; +} + +body > * { + --layout-spacing: max(8vh, 3rem); + --max-width: 70ch; + width: min(100%, var(--max-width)); + margin-left: auto; + margin-right: auto; +} + +main { + margin-top: var(--layout-spacing); +} + +footer { + margin-top: auto; + padding-top: var(--layout-spacing); +} + +footer p { + border-top: 1px solid #ccc; + padding-top: 0.25em; + font-size: 0.9rem; + color: #767676; +} + +:is(h1, h2, h3) { + line-height: 1.2; +} + +:is(h2, h3):not(:first-child) { + margin-top: 2em; +} + +article * + * { + margin-top: 1em; +} + +a { + color: navy; + text-underline-offset: 0.15em; +} diff --git a/static/vars.css b/static/vars.css new file mode 100644 index 0000000..87ae991 --- /dev/null +++ b/static/vars.css @@ -0,0 +1,12 @@ + +:root { + --bg-colour: #ffffff; + --text-colour: #282a36; +} + +@media (prefers-color-scheme: dark) { + :root { + --bg-colour: #282a36; + --text-colour: #ffffff; + } +} diff --git a/tmpl/base.html b/tmpl/base.html new file mode 100644 index 0000000..788fce9 --- /dev/null +++ b/tmpl/base.html @@ -0,0 +1,16 @@ +{{define "base"}} + + + + + + {{template "title" .}} + {{template "meta" .}} + + + + + {{template "body" .}} + + +{{end}} diff --git a/tmpl/index.html b/tmpl/index.html new file mode 100644 index 0000000..918ffcb --- /dev/null +++ b/tmpl/index.html @@ -0,0 +1,13 @@ +{{template "base" .}} + +{{define "title"}}Calendar{{end}} + +{{define "meta"}} {{end}} + +{{define "body"}} + +
+

Cal

+
+ +{{end}}