diff --git a/cmd/web/main.go b/cmd/web/main.go index 7dcae99..bff4884 100644 --- a/cmd/web/main.go +++ b/cmd/web/main.go @@ -20,6 +20,7 @@ func main() { mux.HandleFunc("/", handlers.Index) mux.HandleFunc("/css/", handlers.CSS) mux.HandleFunc("/fonts/", handlers.Fonts) + mux.HandleFunc("/images/", handlers.Images) loggingMux := middleware.Logging(mux) diff --git a/internal/assets/images/favicon.ico b/internal/assets/images/favicon.ico new file mode 100644 index 0000000..e1cc98a Binary files /dev/null and b/internal/assets/images/favicon.ico differ diff --git a/internal/assets/json/links.json b/internal/assets/json/links.json new file mode 100644 index 0000000..5b17358 --- /dev/null +++ b/internal/assets/json/links.json @@ -0,0 +1,22 @@ +[ + { + "href": "https://youtube.stevanfreeborn.com", + "icon": "fa-brands fa-square-youtube fa-lg", + "text": "YouTube" + }, + { + "href": "https://github.stevanfreeborn.com", + "icon": "fa-brands fa-square-github fa-lg", + "text": "GitHub" + }, + { + "href": "https://blog.stevanfreeborn.com", + "icon": "fa-solid fa-square-rss fa-lg", + "text": "Blog" + }, + { + "href": "https://linkedin.stevanfreeborn.com", + "icon": "fa-brands fa-square-linkedin fa-lg", + "text": "LinkedIn" + } +] diff --git a/internal/assets/main.go b/internal/assets/main.go index ce695cb..6867e41 100644 --- a/internal/assets/main.go +++ b/internal/assets/main.go @@ -12,4 +12,8 @@ var ( CSS embed.FS //go:embed "fonts/*" Fonts embed.FS + //go:embed "json/*" + JSON embed.FS + //go:embed "images/*" + Images embed.FS ) diff --git a/internal/assets/templates/index.gohtml b/internal/assets/templates/index.gohtml index e12222b..21a211a 100644 --- a/internal/assets/templates/index.gohtml +++ b/internal/assets/templates/index.gohtml @@ -9,6 +9,7 @@ integrity="sha512-2SwdPD6INVrV/lHTZbO2nodKhrnDdJK9/kg2XD1r9uGqPo1cUbujc+IYdlYdEErWNu69gVcYgdxlmVmzTWnetw==" crossorigin="anonymous" referrerpolicy="no-referrer" /> + @@ -18,35 +19,20 @@ alt="A man with short brown hair, a grey hoodie, and a white t-shirt smiles at the camera. He has a white earbud in his left ear. The background is a blurred office setting with warm lighting visible through glass partitions." />

Stevan Freeborn

-

I'm a {{ .Age }}-year old dad of 2 who enjoys drinking coffee, lifting weights, and solving problems with code.

+

I'm a {{ .Age }}-year old dad of 2 who enjoys drinking coffee, lifting weights, and solving problems with code. +

diff --git a/internal/handlers/main.go b/internal/handlers/main.go index d55c241..6fd7e0a 100644 --- a/internal/handlers/main.go +++ b/internal/handlers/main.go @@ -2,6 +2,8 @@ package handlers import ( + "encoding/json" + "io/fs" "math" "net/http" "text/template" @@ -10,21 +12,24 @@ import ( "github.com/StevanFreeborn/links.stevanfreeborn.com/internal/assets" ) +const LINKS_JSON_PATH = "json/links.json" const DAYS_IN_YEAR = 365 const HOURS_IN_DAY = 24 var birthday time.Time = time.Date(1993, time.April, 21, 0, 0, 0, 0, time.UTC) +type Link struct { + Href string `json:"href"` + Icon string `json:"icon"` + Text string `json:"text"` +} + type IndexViewModel struct { - Age float64 + Age float64 + Links []Link } func Index(w http.ResponseWriter, r *http.Request) { - // TODO: Links coming in external JSON data - // this could be static file in the repo - // or it could be fetched - // { link: "link", text: "text", "icon": "icon" } - t, err := template.ParseFS(assets.Templates, "templates/index.gohtml") if err != nil { @@ -32,10 +37,25 @@ func Index(w http.ResponseWriter, r *http.Request) { return } + linksFile, err := assets.JSON.Open(LINKS_JSON_PATH) + + if err != nil { + http.Error(w, "Unable to load links", http.StatusInternalServerError) + return + } + + links, err := readLinksFromJSON(linksFile) + + if err != nil { + http.Error(w, "Unable to parse links", http.StatusInternalServerError) + return + } + age := time.Since(birthday).Hours() / HOURS_IN_DAY / DAYS_IN_YEAR viewModel := IndexViewModel{ - Age: math.Floor(age), + Age: math.Floor(age), + Links: links, } t.Execute(w, viewModel) @@ -48,3 +68,22 @@ func CSS(w http.ResponseWriter, r *http.Request) { func Fonts(w http.ResponseWriter, r *http.Request) { http.ServeFileFS(w, r, assets.Fonts, r.URL.Path) } + +func Images(w http.ResponseWriter, r *http.Request) { + http.ServeFileFS(w, r, assets.Images, r.URL.Path) +} + +func readLinksFromJSON(file fs.File) ([]Link, error) { + defer file.Close() + var links []Link + + decoder := json.NewDecoder(file) + + err := decoder.Decode(&links) + + if err != nil { + return nil, err + } + + return links, nil +}