Commit Diff


commit - d95718e9ce49029c8c2d565030da7ba34db4a192
commit + c37c785b3570259cde7bdaa2a5133aae4cb0c21b
blob - 9e913e0b55bce0d3a0585f55b2612729ea437a70
blob + d3ffaca7b965399a05cccfa1cff212384af995e4
--- README.md
+++ README.md
@@ -1 +1,7 @@
 ## RSS
+
+Search RSS feeds and collate a feed.
+
+### Build
+
+Run `go run cmd/rss/rss.go` or build `go build cmd/rss/rss.go`
blob - f7b60bdeb99641f615e9dca036f3b2bd4f7fd501
blob + 16dbc589ba4bcf57b0efde168a339eafa8f4f8fc
--- cmd/rss/rss.go
+++ cmd/rss/rss.go
@@ -1,7 +1,34 @@
 package main
 
-import "fmt"
+import (
+	"fmt"
+	"html/template"
+	"log"
+	"net/http"
+)
 
+func render(w http.ResponseWriter, data any, pages ...string) {
+	files := append([]string{"internal/templates/base.tmpl"}, pages...)
+	tmpl := template.Must(template.ParseFiles(files...))
+	tmpl.ExecuteTemplate(w, "base", data)
+}
+
+func homeGET(w http.ResponseWriter, r *http.Request) {
+	render(w, nil, "internal/templates/home.tmpl")
+}
+
+func homePOST(w http.ResponseWriter, r *http.Request) {
+	fmt.Fprintln(w, "Posted to home page")
+}
+
 func main() {
-	fmt.Println("Hello, world!")
+	mux := http.NewServeMux()
+
+	mux.Handle("GET /static/", http.StripPrefix("/static/", http.FileServer(http.Dir("web"))))
+	mux.HandleFunc("GET /", homeGET)
+	mux.HandleFunc("POST /", homePOST)
+
+	addr := ":8080"
+	log.Printf("Server running at %s", addr)
+	log.Fatal(http.ListenAndServe(addr, mux))
 }
blob - /dev/null
blob + 821d5882fb720dbbab407fe88ebcc2974d748e6b (mode 644)
--- /dev/null
+++ internal/templates/base.tmpl
@@ -0,0 +1,32 @@
+{{ define "base" }}
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <link rel="stylesheet" href="/static/style.css">
+    <link rel="icon" type="image/svg+xml" href="/static/favicon.svg" />
+    <title>RSS</title>
+</head>
+
+<body>
+    <header>
+        <a href="/login">Login</a>
+    </header>
+    <main>
+        {{ block "content" . }}{{ end }}
+    </main>
+    <footer>
+        <a href="https://github.com/StreatCodes/rss">
+            <svg xmlns="http://www.w3.org/2000/svg" aria-label="Github" width="20" height="20" fill="white"
+                class="bi bi-github" viewBox="0 0 16 16">
+                <path
+                    d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27s1.36.09 2 .27c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8" />
+            </svg>
+        </a>
+    </footer>
+</body>
+
+</html>
+{{ end }}
\ No newline at end of file
blob - /dev/null
blob + 7756989b5436336e82e8b6a83d26eaaa449a6393 (mode 644)
--- /dev/null
+++ internal/templates/home.tmpl
@@ -0,0 +1,23 @@
+{{ define "title" }}Home{{ end }}
+
+{{ define "content" }}
+<form>
+    <div class="search-box">
+        <button type="button" aria-label="Filter">
+            <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" fill="currentColor" class="bi bi-filter"
+                viewBox="0 0 16 16">
+                <path
+                    d="M6 10.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5m-2-3a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5m-2-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5" />
+            </svg>
+        </button>
+        <input type="search" autofocus name="search" placeholder="Search for a feed!" />
+        <button type="submit" aria-label="Send">
+            <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" class="bi bi-send"
+                viewBox="0 0 16 16">
+                <path
+                    d="M15.854.146a.5.5 0 0 1 .11.54l-5.819 14.547a.75.75 0 0 1-1.329.124l-3.178-4.995L.643 7.184a.75.75 0 0 1 .124-1.33L15.314.037a.5.5 0 0 1 .54.11ZM6.636 10.07l2.761 4.338L14.13 2.576zm6.787-8.201L1.591 6.602l4.339 2.76z" />
+            </svg>
+        </button>
+    </div>
+</form>
+{{ end }}
\ No newline at end of file
blob - /dev/null
blob + 5d28b006bc0515bf54ae1cbe2a900c7ad8e8dbf0 (mode 644)
--- /dev/null
+++ web/favicon.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256" viewBox="0 0 100 100"><rect width="100" height="100" rx="20" fill="#ee8695"></rect><path fill="#fff" d="M12.17 68.20L6.66 68.20L6.66 31.80L18.57 31.80Q22.83 31.80 25.61 33.26Q28.39 34.71 29.77 37.18Q31.15 39.65 31.15 42.77L31.15 42.77Q31.15 46.31 29.36 49.04Q27.56 51.77 23.87 53.02L23.87 53.02L31.51 68.20L25.12 68.20L18.15 53.80L12.17 53.80L12.17 68.20ZM12.17 36.74L12.17 48.80L18.25 48.80Q22.00 48.80 23.74 47.14Q25.48 45.48 25.48 42.77L25.48 42.77Q25.48 40.02 23.77 38.38Q22.05 36.74 18.20 36.74L18.20 36.74L12.17 36.74ZM49.92 68.82L49.92 68.82Q46.07 68.82 43.19 67.42Q40.30 66.02 38.66 63.42Q37.03 60.82 36.97 57.23L36.97 57.23L42.80 57.23Q42.85 59.98 44.70 61.93Q46.54 63.88 49.87 63.88L49.87 63.88Q52.94 63.88 54.65 62.45Q56.37 61.02 56.37 58.74L56.37 58.74Q56.37 56.81 55.36 55.54Q54.34 54.26 52.21 53.25Q50.08 52.24 46.70 51.14L46.70 51.14Q42.17 49.69 40.04 47.11Q37.91 44.54 37.91 40.80L37.91 40.80Q37.91 36.48 41.03 33.83Q44.15 31.18 49.61 31.18L49.61 31.18Q54.91 31.18 58.14 33.91Q61.36 36.64 61.47 41.47L61.47 41.47L55.59 41.47Q55.59 40.17 54.86 38.95Q54.13 37.73 52.78 36.92Q51.43 36.12 49.45 36.12L49.45 36.12Q47.01 36.06 45.35 37.29Q43.68 38.51 43.68 40.59L43.68 40.59Q43.68 43.14 45.71 44.57Q47.74 46.00 52.31 47.50L52.31 47.50Q55.17 48.44 57.38 49.77Q59.59 51.09 60.87 53.15Q62.14 55.20 62.14 58.37L62.14 58.37Q62.14 61.28 60.69 63.65Q59.23 66.02 56.50 67.42Q53.77 68.82 49.92 68.82ZM81.12 68.82L81.12 68.82Q77.27 68.82 74.39 67.42Q71.50 66.02 69.86 63.42Q68.23 60.82 68.17 57.23L68.17 57.23L74.00 57.23Q74.05 59.98 75.90 61.93Q77.74 63.88 81.07 63.88L81.07 63.88Q84.14 63.88 85.85 62.45Q87.57 61.02 87.57 58.74L87.57 58.74Q87.57 56.81 86.56 55.54Q85.54 54.26 83.41 53.25Q81.28 52.24 77.90 51.14L77.90 51.14Q73.37 49.69 71.24 47.11Q69.11 44.54 69.11 40.80L69.11 40.80Q69.11 36.48 72.23 33.83Q75.35 31.18 80.81 31.18L80.81 31.18Q86.11 31.18 89.34 33.91Q92.56 36.64 92.67 41.47L92.67 41.47L86.79 41.47Q86.79 40.17 86.06 38.95Q85.33 37.73 83.98 36.92Q82.63 36.12 80.65 36.12L80.65 36.12Q78.21 36.06 76.55 37.29Q74.88 38.51 74.88 40.59L74.88 40.59Q74.88 43.14 76.91 44.57Q78.94 46.00 83.51 47.50L83.51 47.50Q86.37 48.44 88.58 49.77Q90.79 51.09 92.07 53.15Q93.34 55.20 93.34 58.37L93.34 58.37Q93.34 61.28 91.89 63.65Q90.43 66.02 87.70 67.42Q84.97 68.82 81.12 68.82Z"></path></svg>
\ No newline at end of file
blob - /dev/null
blob + 438ab5ca5437aa9776fed711062553da4c7ba2fc (mode 644)
--- /dev/null
+++ web/style.css
@@ -0,0 +1,86 @@
+:root {
+    --white: #c8c8c8;
+    --peach: #fbbbad;
+    --pink: #ee8695;
+    --blue: #468fb9;
+    --dark-blue: #333f58;
+    --black: #292831;
+}
+
+* {
+    box-sizing: border-box;
+}
+
+body {
+    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
+    background-color: var(--black);
+    color: var(--white);
+    font-size: 1.2em;
+    margin: 0;
+    padding: 0;
+    min-height: 100vh;
+    display: flex;
+    flex-direction: column;
+}
+
+a {
+    text-decoration: none;
+    cursor: pointer;
+    color: var(--peach);
+}
+
+a:hover {
+    text-decoration: underline;
+}
+
+header {
+    margin: 2rem;
+    display: flex;
+    justify-content: end;
+}
+
+main {
+    flex: 1;
+    padding: 1rem;
+}
+
+footer {
+    text-align: center;
+    margin-top: auto;
+    margin: 2rem;
+}
+
+.search-box {
+    background-color: #212024;
+    border-radius: 100px;
+    padding: 0.5rem 0.65rem;
+    box-shadow: rgba(50, 50, 93, 0.25) 0px 2px 5px -1px, rgba(0, 0, 0, 0.3) 0px 1px 3px -1px;
+    display: flex;
+    align-items: center;
+    max-width: 640px;
+    margin: 20vh auto;
+    transition: margin 300ms;
+
+    &.results {
+        margin: 0 auto;
+    }
+
+    input {
+        all: unset;
+        width: 100%;
+        color: var(--white);
+        margin: 0 0.25rem;
+    }
+
+    button {
+        all: unset;
+        cursor: pointer;
+        color: var(--blue);
+        line-height: 0;
+        padding: 0.6rem;
+    }
+
+    button:focus, button:hover {
+        color: white;
+    }
+}
\ No newline at end of file