Bläddra i källkod

i have changed almost everything lol but the UI looks way better and functions way better as well

aeth 2 månader sedan
förälder
incheckning
ad3535e3fd

+ 1 - 0
cmd/seed/seed.go

@@ -7,6 +7,7 @@ import (
 
 	"git.aetherial.dev/aeth/keiji/pkg/env"
 	"git.aetherial.dev/aeth/keiji/pkg/helpers"
+	_ "github.com/mattn/go-sqlite3"
 )
 
 

+ 21 - 0
cmd/webserver/webserver.go

@@ -12,6 +12,8 @@ import (
 	"git.aetherial.dev/aeth/keiji/pkg/env"
 	"git.aetherial.dev/aeth/keiji/pkg/routes"
 	"git.aetherial.dev/aeth/keiji/pkg/helpers"
+
+	_ "github.com/mattn/go-sqlite3"
 )
 
 var WEB_ROOT string
@@ -30,10 +32,12 @@ func main() {
 	renderer.AddFromFiles(
 		"home",
 		fmt.Sprintf("%s/templates/home.html", WEB_ROOT),
+		fmt.Sprintf("%s/templates/writing.html", WEB_ROOT),
 		fmt.Sprintf("%s/templates/navigation.html", WEB_ROOT),
 		fmt.Sprintf("%s/templates/menu.html", WEB_ROOT),
 		fmt.Sprintf("%s/templates/link.html", WEB_ROOT),
 		fmt.Sprintf("%s/templates/listing.html", WEB_ROOT),
+		fmt.Sprintf("%s/templates/head.html", WEB_ROOT),
 	)
 	renderer.AddFromFiles(
 		"blogpost",
@@ -102,6 +106,23 @@ func main() {
 		fmt.Sprintf("%s/templates/navigation.html", WEB_ROOT),
 		fmt.Sprintf("%s/templates/listing.html", WEB_ROOT),
 	)
+	renderer.AddFromFiles(
+		"writing",
+		/*
+		fmt.Sprintf("%s/templates/listing.html", WEB_ROOT),
+		fmt.Sprintf("%s/templates/navigation.html", WEB_ROOT),
+		fmt.Sprintf("%s/templates/head.html", WEB_ROOT),
+		*/
+		fmt.Sprintf("%s/templates/writing.html", WEB_ROOT),
+	)
+	renderer.AddFromFiles(
+		"listing",
+		fmt.Sprintf("%s/templates/listing.html", WEB_ROOT),
+		)
+	renderer.AddFromFiles(
+		"head",
+		fmt.Sprintf("%s/templates/head.html", WEB_ROOT),
+		)
 	e := gin.Default()
 	dbfile := "sqlite.db"
 	db, err := sql.Open("sqlite3", dbfile)

+ 1 - 1
go.mod

@@ -32,7 +32,7 @@ require (
 	github.com/leodido/go-urn v1.2.4 // indirect
 	github.com/mailru/easyjson v0.7.6 // indirect
 	github.com/mattn/go-isatty v0.0.20 // indirect
-	github.com/mattn/go-sqlite3 v1.14.22 // indirect
+	github.com/mattn/go-sqlite3 v1.14.24 // indirect
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 	github.com/modern-go/reflect2 v1.0.2 // indirect
 	github.com/patrickmn/go-cache v2.1.0+incompatible // indirect

+ 2 - 0
go.sum

@@ -89,6 +89,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
 github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
 github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
 github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
+github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
+github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=

+ 13 - 0
html/custom.css

@@ -23,6 +23,19 @@
 
   }
 
+/*This is modifying the btn-primary colors but you could create your own .btn-something class as well*/
+.btn-primary {
+  color: #fff;
+  background-color: rgba(38, 41, 50, 0.9);
+  border-color: #9dadbb; /*set the color you want here*/
+}
+.btn-primary:hover, .btn-primary:focus, .btn-primary:active, .btn-primary.active, .open>.dropdown-toggle.btn-primary {
+  color: #8a3b3b;
+  background-color: rgba(58, 20, 20, 0.9);
+  border-color: rgb(142, 40, 40); /*set the color you want here*/
+}
+
+
   /* When you mouse over the navigation links, change their color */
   .sidenav a:hover {
     color: #f1f1f1;

+ 10 - 8
html/slide.js

@@ -1,11 +1,13 @@
 /* Set the width of the side navigation to 250px and the left margin of the page content to 250px */
-function openNav() {
-  document.getElementById("mySidenav").style.width = "400px";
-  document.getElementById("main").style.marginLeft = "400px";
+function toggleNav() {
+  if (document.getElementById("mySidenav").style.width === "400px"){
+      document.getElementById("mySidenav").style.width = "0px";
+      document.getElementById("main").style.marginLeft = "0px";
+      return;
+  } else {
+      document.getElementById("mySidenav").style.width = "400px";
+      document.getElementById("main").style.marginLeft = "400px";
+      return;
+  }
 }
 
-/* Set the width of the side navigation to 0 and the left margin of the page content to 0 */
-function closeNav() {
-  document.getElementById("mySidenav").style.width = "0px";
-  document.getElementById("main").style.marginLeft = "0px";
-}

+ 3 - 4
html/templates/admin.html

@@ -18,16 +18,15 @@
 
     {{ template "navigation.html" .navigation }}
     <div class="container-fluid row">
-        {{ range .Tables }}
+        {{ range $key, $value := .Tables }}
             <div class="col">
-                <div class="col container h-2 p-2" style="background-color: rgb(22, 22, 22); color: white; height: fit-content; font-size: larger; font-family: monospace;">
-                    {{ .TableName }}
+                <div class="col container h-2 p-2" style="background-color: rgb(22, 22, 22); color: white; height: fit-content; font-size: larger; font-family: monospace;">{{ $key }}
                 </div>
                     <table class="table table-dark table-hover">
                         <thead>
                         </thead>
                     <tbody>
-                    {{ range .TableData }}
+                    {{ range $value }}
                         <tr>
                             <th scope="row" style="color: white; height: fit-content; font-size: larger; font-family: monospace;">
                                 <a href="{{ .Link }}">{{ .DisplayName }}</a></th>

+ 2 - 25
html/templates/blogpost.html

@@ -1,23 +1,12 @@
 {{ define "blogpost.html" }}
 <!DOCTYPE html>
 <html lang="en">
-    <head>
-        <meta http-equiv="content-type" content="text/html; charset=UTF-8">
-        <meta name="viewport" content="width=device-width, initial-scale=1">
-        <link rel="stylesheet" href="/api/v1/style/bootstrap.min.css">
-        <link rel="stylesheet" href="/api/v1/style/mdb/mdb.min.css">
-        <link rel="stylesheet" href="/api/v1/cdn/custom.css">
 
-    </head>
-    <body style="background-color: rgb(56, 56, 56);">
-        <div id="main">
-
-        {{ template "navigation.html" .navigation }}
         <div class="container-fluid row">
             <div class="col"></div>
             <div class="col-auto p-3 m-3" style="max-width: 80vw;">
                 <div class="row" style="background-color: rgb(22, 22, 22); color: white; height: fit-content; font-family: monospace; white-space: pre-wrap;">
-                    <p class="text-center">{{ .Ident }}</p>
+                    <p class="text-center">{{ .Title }}</p>
                 </div>
                 <div class="row" style="background-color: rgb(22, 22, 22); color: white; height: fit-content; font-family: monospace; white-space: pre-wrap">
                     <p class="text-left">{{ .Created }}</p>
@@ -28,18 +17,6 @@
             </div>
             <div class="col"></div>
         </div>
-        <div id="mySidenav" class="sidenav">
-            <a href="javascript:void(0)" class="closebtn" onclick="closeNav()">&times;</a>
-            {{ range .menu.MenuLinks }}
-                <a href="{{ .MenuLink }}" style="font-family: monospace;">{{ .LinkText }}</a>
-            {{ end }}
-          </div>
-        </div>
-        <script type="text/javascript" src="/api/v1/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
-        <script src="/api/v1/cdn/slide.js"></script>
-        <script src="/api/v1/htmx/htmx.min.js"></script>
-        <script src="/api/v1/htmx/json-enc.js"></script>
-    </body>
 
 </html>
-{{ end }}
+{{ end }}

+ 2 - 2
html/templates/centered_image.html

@@ -3,7 +3,7 @@
 <html lang="en">
     <div class="row container-fluid m-0 p-0">
         <div class="col container-fluid" style="background-color: black;"></div>
-        <img src="{{ .ApiPath }}" loading="lazy" class="img-fluid m-0 p-0 col-auto" style="background-color: black; max-height: 70vh;">
+        <img src="/api/v1/images/{{ .Ident }}" loading="lazy" class="img-fluid m-0 p-0 col-auto" style="background-color: black; max-height: 70vh;">
         <div class="col container-fluid" style="background-color: black;"></div>
     </div>
     <a href="#">
@@ -23,4 +23,4 @@
         </div>
     </a>
 </html>
-{{ end }}
+{{ end }}

+ 1 - 12
html/templates/digital_art.html

@@ -12,7 +12,6 @@
     <body style="background-color: rgb(56, 56, 56);">
     <div id="main">
 
-        {{ template "navigation.html" .navigation }}
         <div class="container-fluid row">
             {{ range .images }}
                 <div class="col-sm hover-overlay" data-mdb-ripple-init data-mdb-ripple-color="light">
@@ -25,17 +24,7 @@
                 </div>
             {{ end }}
             </div>
-        <div id="mySidenav" class="sidenav">
-            <a href="javascript:void(0)" class="closebtn" onclick="closeNav()">&times;</a>
-            {{ range .menu.MenuLinks }}
-                <a href="{{ .MenuLink }}" style="font-family: monospace;">{{ .LinkText }}</a>
-            {{ end }}
-          </div>
         </div>
-        <script type="text/javascript" src="/api/v1/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
-        <script src="/api/v1/cdn/slide.js"></script>
-        <script src="/api/v1/htmx/htmx.min.js"></script>
-        <script src="/api/v1/htmx/json-enc.js"></script>
     </body>
 </html>
-{{ end }}
+{{ end }}

+ 4 - 3
html/templates/head.html

@@ -4,8 +4,9 @@
     <head>
         <meta http-equiv="content-type" content="text/html; charset=UTF-8">
         <meta name="viewport" content="width=device-width, initial-scale=1">
-        <link rel="stylesheet" href="/api/v1/style/bootstrap.min.css">
-        <link rel="stylesheet" href="/api/v1/style/mdb/mdb.min.css">
+        <link rel="stylesheet" href="/api/v1/cdn/bootstrap.min.css">
+        <link rel="stylesheet" href="/api/v1/cdn/mdb.min.css">
+        <link rel="stylesheet" href="/api/v1/cdn/custom.css">
     </head>
 </html>
-{{ end }}
+{{ end }}

+ 10 - 28
html/templates/home.html

@@ -1,35 +1,17 @@
 {{ define "home.html" }}
 <!DOCTYPE html>
 <html lang="en">
-    <head>
-        <meta http-equiv="content-type" content="text/html; charset=UTF-8">
-        <meta name="viewport" content="width=device-width, initial-scale=1">
-        <link rel="stylesheet" href="/api/v1/cdn/bootstrap.min.css">
-        <link rel="stylesheet" href="/api/v1/cdn/mdb.min.css">
-        <link rel="stylesheet" href="/api/v1/cdn/custom.css">
-    </head>
-
-    <body style="background-color: rgb(56, 56, 56);">
-    <div id="main">
-
-        {{ template "navigation.html" .navigation }}
-        <div class="container-fluid row">
-        {{ range .listings }}
-            <div class="col-sm hover-overlay" data-mdb-ripple-init data-mdb-ripple-color="light">
-                <div class="col-auto">
-                {{ template "listing.html" . }}
-                </div>
-            </div>
+    {{ template "head.html" }}
+    <body style="background-color: #191a1b;">
+    {{ template "navigation.html" .navigation }}
+    <div id="main"></div>
+    <div id="mySidenav" class="sidenav row">
+        {{ range .menu}}
+            <button class="btn-primary" hx-get="{{ .MenuLink }}" style="font-family: monospace;" hx-target="#main">
+                {{ .LinkText }}
+            </button>
         {{ end }}
-        </div>
-
-        <div id="mySidenav" class="sidenav">
-            <a href="javascript:void(0)" class="closebtn" onclick="closeNav()">&times;</a>
-            {{ range .menu}}
-                <a href="{{ .MenuLink }}" style="font-family: monospace;">{{ .LinkText }}</a>
-            {{ end }}
-          </div>
-        </div>
+    </div>
         <script type="text/javascript" src="/api/v1/cdn/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
         <script src="/api/v1/cdn/slide.js"></script>
         <script src="/api/v1/cdn/htmx.min.js"></script>

+ 6 - 4
html/templates/listing.html

@@ -1,10 +1,11 @@
 {{ define "listing.html" }}
 <!DOCTYPE html>
 <html>
+{{ range . }}
         <div class="row position-relative shadow-lg p-3 m-3 rounded justify-content-center"
             style="width: 80vh; max-width: 95%; background-color: rgb(22, 22, 22);">
             <div class="row" style="background-color: rgb(22, 22, 22); color: white; height: fit-content;font-family: monospace;">
-                <p class="text-center">{{ .Ident }}</p>
+                <p class="text-center">{{ .Title }}</p>
             </div>
             <div class="row" style="background-color: rgb(22, 22, 22); color: white; height: fit-content; font-family: monospace;">
                 <p class="text-left">{{ .Created }}</p>
@@ -12,9 +13,10 @@
             <div class="row" style="background-color: rgb(22, 22, 22); color: white; height: fit-content; font-family: monospace;">
                 <p class="text-left">{{ .Sample }}</p>
             </div>
-            <a href="/writing/{{ .Ident }}">
+            <button hx-get="/writing/{{ .Ident }}" hx-target="#main">
                 <div class="mask" style="background-color: hsla(0, 0%, 98%, 0.2)"></div>
-            </a>
+            </button>
         </div>
+{{ end }}
 </html>
-{{ end }}
+{{ end }}

+ 5 - 14
html/templates/login.html

@@ -4,20 +4,11 @@
     <head>
         <meta http-equiv="content-type" content="text/html; charset=UTF-8">
         <meta name="viewport" content="width=device-width, initial-scale=1">
-        <link rel="stylesheet" href="/api/v1/style/bootstrap.min.css">
-        <link rel="stylesheet" href="/api/v1/style/mdb/mdb.min.css">
+        <link rel="stylesheet" href="/api/v1/cdn/bootstrap.min.css">
+        <link rel="stylesheet" href="/api/v1/cdn/mdb.min.css">
     </head>
 
     <body style="background-color: rgb(56, 56, 56);">
-        <div class="container-fluid sticky-top pb-0">
-            <div class="row align-items-center justify-content-center bg-dark h-100 shadow-lg p-0 mb-0 rounded">
-                <div class="col-sm-8 p-3">
-                    <div style="color: whitesmoke; font-size: xx-large; font-family: monospace;">
-                        <a style="color:whitesmoke">{{ .heading }}</a>
-                    </div>
-                </div>
-            </div>
-        </div>
         <div class="container-fluid p-5 position-relative">
             <div class="container">
                 <div class="row">
@@ -39,7 +30,7 @@
             </div>
         </div>
     </body>
-    <script src="/api/v1/htmx/htmx.min.js"></script>
-    <script src="/api/v1/htmx/json-enc.js"></script>
+    <script src="/api/v1/cdn/htmx.min.js"></script>
+    <script src="/api/v1/cdn/json-enc.js"></script>
 </html>
-{{ end }}
+{{ end }}

+ 2 - 3
html/templates/menu.html

@@ -6,13 +6,12 @@
                 id="dropdownMenuButton" data-bs-toggle="dropdown"
                 data-mdb-ripple-init
                 data-mdb-ripple-color="light">
-                <span onclick="openNav()">
+                <span onclick="toggleNav()">
                 <img src="/api/v1/assets/menu.png" style="max-height: 5vh;"/>
                     <div class="mask" style="background-color: hsla(0, 0%, 98%, 0.2)"></div>
                 </span>
-            </div>
-
         </div>
+
     </div>
 </html>
 {{ end }}

+ 14 - 6
html/templates/navigation.html

@@ -1,26 +1,34 @@
 {{ define "navigation.html" }}
 <div class="container-fluid sticky-top pb-0">
-    <div class="row align-items-center justify-content-center bg-dark h-100 shadow-lg p-0 mb-0 rounded">
+    <div class="row align-items-center justify-content-center h-100 shadow-lg p-0 mb-0 rounded" style="background-color: #2a2e2f;">
         <div class="col-sm-8 p-3">
             <div style="color: whitesmoke; font-size: xx-large; font-family: monospace;">
-                <a href="/home" style="color:whitesmoke">aetherial.dev homepage</a>
+                <a href="/" style="color:whitesmoke">aetherial.dev homepage</a>
             </div>
         </div>
         <div class="col-sm">
             <div class="row">
                 {{ range .headers }}
-                    {{ template "link.html" . }}
+                    <div class="col-2">
+                        <div class="bg-image hover-overlay shadow-1-strong rounded d-inline-flex p-0"
+                            data-mdb-ripple-init
+                            data-mdb-ripple-color="light">
+                            <img src="/api/v1/assets/{{ .Link}}" style="max-height: 5vh;"/>
+                            <a href="{{ .Redirect}}" target="_blank">
+                              <div class="mask" style="background-color: hsla(0, 0%, 98%, 0.2)"></div>
+                            </a>
+                        </div>
+                    </div>
                 {{ end }}
                 <div class="col-2">
-                    <div class="bg-image hover-overlay shadow-1-strong d-inline-flex p-0"
+                    <div class="bg-image hover-overlay shadow-1-strong d-inline-flex p-0 row"
                             id="dropdownMenuButton" data-bs-toggle="dropdown"
                             data-mdb-ripple-init
                             data-mdb-ripple-color="light">
-                            <span onclick="openNav()">
+                            <span onclick="toggleNav()">
                             <img src="/api/v1/assets/menu.png" style="max-height: 5vh;"/>
                                 <div class="mask" style="background-color: hsla(0, 0%, 98%, 0.2)"></div>
                             </span>
-                        </div>
                     </div>
                 </div>
             </div>

+ 8 - 8
html/templates/new_blogpost.html

@@ -4,8 +4,8 @@
 <head>
     <meta http-equiv="content-type" content="text/html; charset=UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1">
-    <link rel="stylesheet" href="/api/v1/style/bootstrap.min.css">
-    <link rel="stylesheet" href="/api/v1/style/mdb/mdb.min.css">
+    <link rel="stylesheet" href="/api/v1/cdn/bootstrap.min.css">
+    <link rel="stylesheet" href="/api/v1/cdn/mdb.min.css">
 </head>
 
 <body style="background-color: rgb(56, 56, 56);">
@@ -21,8 +21,8 @@
                         <form method="post" hx-post="/admin/posts" hx-ext="json-enc" hx-target="#response" hx-swap="innerHTML">
                             <div class="row"
                                 style="background-color: rgb(22, 22, 22); color: white; height: fit-content; font-size: larger; font-family: monospace;">
-                                <a>Post ID:</a>
-                                <textarea name="identifier"
+                                <a>Title:</a>
+                                <textarea name="title"
                                     style="background-color: rgb(73, 73, 73); color: white;">{{ .Ident }}</textarea>
                             </div>
                             <div class="row"
@@ -56,9 +56,9 @@
             </div>
         </div>
     </div>
-    <script type="text/javascript" src="/api/v1/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
-    <script src="/api/v1/htmx/htmx.min.js"></script>
-    <script src="/api/v1/htmx/json-enc.js"></script>
+    <script type="text/javascript" src="/api/v1/cdn/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
+    <script src="/api/v1/cdn/htmx.min.js"></script>
+    <script src="/api/v1/cdn/json-enc.js"></script>
 </body>
 </html>
-{{ end }}
+{{ end }}

+ 17 - 14
html/templates/writing.html

@@ -1,19 +1,22 @@
 {{ define "writing.html" }}
-<!DOCTYPE html>
-<html lang="en">
-{{ template "centered-image.html" .image }}
-{{ range .listings }}
-<div class="container-fluid p-5 position-relative">
-    <div class="container">
-        <div class="row">
-            <div class="col-sm"></div>
-            <div class="col-sm hover-overlay" data-mdb-ripple-init data-mdb-ripple-color="light">
-                {{ template "listing.html" . }}
+<div class="container-fluid row">
+    {{ range . }}
+        <div class="col hover-overlay" data-mdb-ripple-init data-mdb-ripple-color="light">
+            <div class="row position-relative shadow-lg p-3 m-3 rounded justify-content-center" style="width: 80vh; max-width: 95%; background-color: rgb(22, 22, 22);">
+                <div class="row" style="background-color: rgb(22, 22, 22); color: white; height: fit-content;font-family: monospace;">
+                    <p class="text-center">{{ .Title }}</p>
+                </div>
+                <div class="row" style="background-color: rgb(22, 22, 22); color: white; height: fit-content; font-family: monospace;">
+                    <p class="text-left">{{ .Created }}</p>
+                </div>
+                <div class="row" style="background-color: rgb(22, 22, 22); color: white; height: fit-content; font-family: monospace;">
+                    <p class="text-left">{{ .Sample }}</p>
+                </div>
+                <button hx-get="/writing/{{ .Ident }}" hx-target="#main">
+                    <div class="mask" style="background-color: hsla(0, 0%, 98%, 0.2)"></div>
+                </button>
             </div>
-            <div class="col-sm"></div>
         </div>
-    </div>
+    {{ end }}
 </div>
 {{ end }}
-</html>
-{{ end }}

+ 81 - 28
pkg/controller/admin_handlers.go

@@ -9,33 +9,6 @@ import (
 
 const AUTH_COOKIE_NAME = "X-Server-Auth"
 
-// AddDocument uploads a document to redis
-// @Description AddDocument uploads a document to redis
-// @Tags admin
-// @Success 200
-// @Param doc body helpers.DocumentUpload true "Redis Document Upload"
-// @Router	/api/v1/admin/add-document [post]
-func (c *Controller) AddDocument(ctx *gin.Context) {
-
-	var upload helpers.DocumentUpload
-
-	err := ctx.BindJSON(&upload)
-	if err != nil {
-		ctx.JSON(400, map[string]string{
-			"Error": err.Error(),
-		})
-		return
-	}
-	newPost := helpers.NewDocument(upload.Name, nil, upload.Text, upload.Category)
-	err = helpers.AddDocument(newPost, c.RedisConfig)
-	if err != nil {
-		ctx.JSON(400, map[string]string{
-			"Error": err.Error(),
-		})
-		return
-	}
-
-}
 
 // @Name ServeLogin
 // @Summary serves the HTML login page
@@ -80,6 +53,86 @@ func (c *Controller) Auth(ctx *gin.Context) {
 
 }
 
+
+/*
+@Name AddAdminTableEntry 
+@Summary add an entry to the admin table
+@Tags admin
+@Router /admin/panel
+*/
+func (c *Controller) AddAdminTableEntry(ctx *gin.Context) {
+	tables := make(map[string][]helpers.TableData)
+	adminPage := helpers.AdminPage{Tables: tables}
+	err := ctx.ShouldBind(&adminPage)
+	if err != nil {
+		ctx.JSON(400, map[string]string{
+			"Error": err.Error(),
+		})
+		return
+	}
+	for category := range adminPage.Tables {
+		for entry := range adminPage.Tables[category] {
+			err := c.database.AddAdminTableEntry(adminPage.Tables[category][entry], category)
+			if err != nil {
+				ctx.JSON(400, map[string]string{
+					"Error": err.Error(),
+				})
+				return
+			}
+
+		}
+	}
+	ctx.Data(200, "text", []byte("Categories populated."))
+}
+
+/*
+@Name AddMenuItem
+@Summary add an entry to the sidebar menu
+@Tags admin
+@Router /admin/menu
+*/
+func (c *Controller) AddMenuItem(ctx *gin.Context) {
+	var item helpers.MenuLinkPair
+	err := ctx.ShouldBind(&item); if err != nil {
+		ctx.JSON(400, map[string]string{
+			"Error": err.Error(),
+		})
+		return
+	}
+	err = c.database.AddMenuItem(item); if err != nil {
+		ctx.JSON(400, map[string]string{
+			"Error": err.Error(),
+		})
+		return
+	}
+	ctx.Data(200, "text", []byte("menu item added."))
+}
+
+/*
+@Name AddNavbarItem
+@Summary add an entry to the navbar
+@Tags admin
+@Router /admin/navbar
+*/
+func (c *Controller) AddNavbarItem(ctx *gin.Context) {
+
+	var item helpers.NavBarItem
+	err := ctx.ShouldBind(&item); if err != nil {
+		ctx.JSON(400, map[string]string{
+			"Error": err.Error(),
+		})
+		return
+	}
+	err = c.database.AddNavbarItem(item); if err != nil {
+		ctx.JSON(400, map[string]string{
+			"Error": err.Error(),
+		})
+		return
+	}
+	ctx.Data(200, "text", []byte("navbar item added."))
+}
+
+
 // @Name AdminPanel
 // @Summary serve the admin panel page
 // @Tags admin
@@ -91,7 +144,7 @@ func (c *Controller) AdminPanel(ctx *gin.Context) {
 			"headers": c.database.GetNavBarLinks(),
 			"menu":    c.database.GetDropdownElements(),
 		},
-		"Tables": c.AdminTables().Tables,
+		"Tables": c.database.GetAdminTables().Tables,
 	})
 
 }

+ 1 - 1
pkg/controller/cdn_handlers.go

@@ -77,7 +77,7 @@ func (c *Controller) ServeGeneric(ctx *gin.Context) {
 		ctype = "text/css"
 	case fext == "js":
 		ctype = "text/javascript"
-	case fext == "json":
+	case fext == "json" || fext == "map":
 		ctype = "application/json"
 	case fext == "png":
 		ctype = "image/png"

+ 32 - 15
pkg/controller/content_handlers.go

@@ -1,8 +1,10 @@
 package controller
 
 import (
-	"os"
 	"time"
+	"io"
+	"bytes"
+	"log"
 
 	"git.aetherial.dev/aeth/keiji/pkg/helpers"
 	"github.com/gin-gonic/gin"
@@ -15,7 +17,7 @@ func (c *Controller) ServeBlogDirectory(ctx *gin.Context) {
 			"menu": c.database.GetDropdownElements(),
 			"headers": c.database.GetNavBarLinks(),
 		},
-		"Tables": c.FormatDocTable().Tables,
+		"Tables": c.database.GetAdminTables().Tables,
 
 	})
 
@@ -23,15 +25,14 @@ func (c *Controller) ServeBlogDirectory(ctx *gin.Context) {
 
 
 func (c *Controller) GetBlogPostEditor(ctx *gin.Context) {
-	rds := helpers.NewRedisClient(c.RedisConfig)
-	post, exist := ctx.Params.Get("post-name")
+	post, exist := ctx.Params.Get("id")
 	if !exist {
 		ctx.JSON(404, map[string]string{
 			"Error": "the requested file could not be found",
 		})
 		return
 	}
-	doc, err := rds.GetItem(post)
+	doc, err := c.database.GetDocument(helpers.Identifier(post))
 	if err != nil {
 		ctx.JSON(500, map[string]string{
 			"Error": err.Error(),
@@ -60,8 +61,7 @@ func (c *Controller) UpdateBlogPost(ctx *gin.Context) {
 		ctx.HTML(500, "upload_status", gin.H{"UpdateMessage": "Update Failed!", "Color": "red"})
 		return
 	}
-	rds := helpers.NewRedisClient(helpers.RedisConf{Addr: os.Getenv("REDIS_ADDR"), Port: os.Getenv("REDIS_PORT")})
-	err = rds.UpdatePost(doc.Ident, doc); if err != nil {
+	err = c.database.UpdateDocument(doc); if err != nil {
 		ctx.HTML(400, "upload_status", gin.H{"UpdateMessage": "Update Failed!", "Color": "red"})
 		return
 	}
@@ -93,8 +93,7 @@ func (c *Controller) MakeBlogPost(ctx *gin.Context) {
 		ctx.HTML(500, "upload_status", gin.H{"UpdateMessage": "Update Failed!", "Color": "red"})
 		return
 	}
-	rds := helpers.NewRedisClient(helpers.RedisConf{Addr: os.Getenv("REDIS_ADDR"), Port: os.Getenv("REDIS_PORT")})
-	err = rds.AddDoc(doc); if err != nil {
+	err = c.database.AddDocument(doc); if err != nil {
 		ctx.HTML(400, "upload_status", gin.H{"UpdateMessage": "Update Failed!", "Color": "red"})
 		return
 	}
@@ -115,19 +114,37 @@ func (c *Controller) ServeFileUpload(ctx *gin.Context) {
 
 
 func (c *Controller) SaveFile(ctx *gin.Context) {
-	var img helpers.ImageStoreItem
+	var img helpers.Image
 	err := ctx.ShouldBind(&img); if err != nil {
 		ctx.HTML(500, "upload_status", gin.H{"UpdateMessage": err, "Color": "red"})
 		return
 	}
-	savedImg := helpers.NewImageStoreItem(img.Title, img.Desc)
-	err = c.database.AddImage(savedImg); if err != nil {
+	file, err := ctx.FormFile("file")
+	if err != nil {
+		ctx.HTML(500, "upload_status", gin.H{"UpdateMessage": err, "Color": "red"})
+		return
+	}
+	fh, err := file.Open()
+	if err != nil {
+		ctx.HTML(500, "upload_status", gin.H{"UpdateMessage": err, "Color": "red"})
+		return
+	}
+	fb := make([]byte, file.Size)
+	var output bytes.Buffer
+	for {
+		n, err := fh.Read(fb)
+		if err == io.EOF {
+			break
+		}
+		if err != nil {
+			log.Fatal(err)
+		}
+		output.Write(fb[:n])
+	}
+	err = c.database.AddImage(fb, img.Title, img.Desc); if err != nil {
 		ctx.HTML(500, "upload_status", gin.H{"UpdateMessage": err, "Color": "red"})
 		return
 	}
-
-
-	// Upload the file to specific dst.
 
 	ctx.HTML(200, "upload_status", gin.H{"UpdateMessage": "Update Successful!", "Color": "green"})
 }

+ 0 - 37
pkg/controller/controller.go

@@ -1,8 +1,6 @@
 package controller
 
 import (
-	"fmt"
-	"log"
 
 	"git.aetherial.dev/aeth/keiji/pkg/helpers"
 )
@@ -17,41 +15,6 @@ type Controller struct{
 
 
 
-/*
-Retrieve the administrator table configuration from redis
-*/
-func (c *Controller) AdminTables() *helpers.AdminTables {
-	tables, err := helpers.GetAdminTables(c.RedisConfig)
-	if err != nil {
-		log.Fatal(err, "Administrator tables couldnt be couldnt be loaded. Exiting.")
-	}
-	return tables
-}
-
-
-/*
-Retrieve the post data and format it for the post management page
-*/
-func (c *Controller) FormatDocTable() *helpers.AdminTables {
-	var postTables helpers.AdminTables
-	for i := range helpers.Topics {
-		docs, err := helpers.GetAllDocuments(helpers.Topics[i], c.RedisConfig)
-		if err != nil {
-			log.Fatal(err, "Post tables couldnt be couldnt be loaded. Exiting.")
-		}
-		var categoryTable helpers.Table
-		categoryTable.TableName = helpers.Topics[i]
-		for idx := range docs {
-			categoryTable.TableData = append(categoryTable.TableData, helpers.TableData{
-				DisplayName: docs[idx].Ident,
-				Link: fmt.Sprintf("/admin/posts/%s", docs[idx].Ident),
-			})
-		}
-		postTables.Tables = append(postTables.Tables, categoryTable)
-	}
-	return &postTables
-
-}
 
 
 

+ 21 - 12
pkg/controller/html_handlers.go

@@ -3,6 +3,7 @@ package controller
 import (
 	"html/template"
 	"net/http"
+	
 
 	"git.aetherial.dev/aeth/keiji/pkg/helpers"
 	"github.com/gin-gonic/gin"
@@ -11,17 +12,16 @@ import (
 // @Name ServePost
 // @Summary serves HTML files out of the HTML directory
 // @Tags webpages
-// @Router /writing/:post-name [get]
+// @Router /writing/:id [get]
 func (c *Controller) ServePost(ctx *gin.Context) {
-	rds := helpers.NewRedisClient(c.RedisConfig)
-	post, exist := ctx.Params.Get("post-name")
+	post, exist := ctx.Params.Get("id")
 	if !exist {
 		ctx.JSON(404, map[string]string{
 			"Error": "the requested file could not be found",
 		})
 		return
 	}
-	doc, err := rds.GetItem(post)
+	doc, err := c.database.GetDocument(helpers.Identifier(post))
 	if err != nil {
 		ctx.JSON(500, map[string]string{
 			"Error": err.Error(),
@@ -36,7 +36,7 @@ func (c *Controller) ServePost(ctx *gin.Context) {
 		"navigation": gin.H{
 			"headers": c.database.GetNavBarLinks(),
 		},
-		"title":   doc.Ident,
+		"Title":   doc.Title,
 		"Ident":   doc.Ident,
 		"Created": doc.Created,
 		"Body":    template.HTML(helpers.MdToHTML([]byte(doc.Body))),
@@ -48,25 +48,33 @@ func (c *Controller) ServePost(ctx *gin.Context) {
 // @Name ServeBlogHome
 // @Summary serves the HTML file for the blog post homepage
 // @Tags webpages
-// @Router /blog [get]
-func (c *Controller) ServeBlogHome(ctx *gin.Context) {
-	docs := c.database.GetByCategory(helpers.BLOG)
+// @Router / [get]
+func (c *Controller) ServeHome(ctx *gin.Context) {
 	ctx.HTML(http.StatusOK, "home", gin.H{
 		"navigation": gin.H{
 			"headers": c.database.GetNavBarLinks(),
 		},
-		"listings": docs,
 		"menu":     c.database.GetDropdownElements(),
+		"listings": c.database.GetByCategory(helpers.BLOG),
 	})
 }
 
+// @Name ServeBlog
+// @Summary serves the HTML for written post listings
+// @Tags webpages
+// @Router /blog [get]
+func (c *Controller) ServeBlog(ctx *gin.Context) {
+	ctx.HTML(http.StatusOK, "writing", c.database.GetByCategory(helpers.BLOG))
+}
+
+
 // @Name ServeDigitalArt
 // @Summary serves the HTML file for the digital art homepage
 // @Tags webpages
 // @Router /digital [get]
 func (c *Controller) ServeDigitalArt(ctx *gin.Context) {
-	rds := helpers.NewRedisClient(c.RedisConfig)
-	fnames, err := helpers.GetImageData(rds)
+	images := c.database.GetAllImages()
+	/*
 	if err != nil {
 		ctx.HTML(http.StatusInternalServerError, "unhandled_error",
 			gin.H{
@@ -76,11 +84,12 @@ func (c *Controller) ServeDigitalArt(ctx *gin.Context) {
 		)
 		return
 	}
+	*/
 	ctx.HTML(http.StatusOK, "digital_art", gin.H{
 		"navigation": gin.H{
 			"headers": c.database.GetNavBarLinks(),
 		},
-		"images": fnames,
+		"images": images,
 		"menu":   c.database.GetDropdownElements(),
 	})
 }

+ 4 - 125
pkg/helpers/helpers.go

@@ -1,14 +1,12 @@
 package helpers
 
 import (
-	"encoding/json"
 
 	"time"
 
 	"github.com/gomarkdown/markdown"
 	"github.com/gomarkdown/markdown/html"
 	"github.com/gomarkdown/markdown/parser"
-	"github.com/redis/go-redis/v9"
 )
 
 const HEADER_KEY = "header-links"
@@ -54,21 +52,17 @@ type MenuElement struct {
 }
 
 type DocumentOld struct {
-	Ident    string `json:"identifier"`
+	Ident    Identifier`json:"identifier"`
 	Created  string `json:"created"`
 	Body     string `json:"body"`
 	Category string `json:"category"`
 	Sample   string
 }
 
-type AdminTables struct {
-	Tables []Table `json:"tables"`
+type AdminPage struct {
+	Tables map[string][]TableData `json:"tables"`
 }
 
-type Table struct {
-	TableName string      `json:"table_name"`
-	TableData []TableData `json:"table_data"`
-}
 
 type TableData struct { // TODO: add this to the database io interface 
 	DisplayName string `json:"display_name"`
@@ -86,7 +80,7 @@ func NewDocument(ident string, created *time.Time, body string, category string)
 		ts = *created
 	}
 
-	return Document{Ident: ident, Created: ts.String(), Body: body, Category: category}
+	return Document{Ident: Identifier(ident), Created: ts.String(), Body: body, Category: category}
 }
 
 type DocumentUpload struct {
@@ -101,121 +95,6 @@ type HeaderIo interface {
 	GetMenuLinks() (*MenuElement, error)
 }
 
-/*
-Retrieves the header data from the redis database
-*/
-func GetHeaders(redisCfg RedisConf) (*HeaderCollection, error) {
-	rds := NewRedisClient(redisCfg)
-	d, err := rds.Client.Get(rds.ctx, HEADER_KEY).Result()
-	if err != nil {
-		if err == redis.Nil {
-			return nil, nil
-		}
-		return nil, err
-	}
-	header := &HeaderCollection{}
-	err = json.Unmarshal([]byte(d), header)
-	if err != nil {
-		return nil, err
-	}
-	return header, nil
-}
-
-/*
-Retrieves the menu elements from the database
-*/
-func GetMenuLinks(redisCfg RedisConf) (*MenuElement, error) {
-	rds := NewRedisClient(redisCfg)
-	d, err := rds.Client.Get(rds.ctx, MENU_KEY).Result()
-	if err != nil {
-		if err == redis.Nil {
-			return nil, nil
-		}
-		return nil, err
-	}
-	header := &MenuElement{}
-	err = json.Unmarshal([]byte(d), header)
-	if err != nil {
-		return nil, err
-	}
-	return header, nil
-}
-
-/*
-retreives the admin table config from the database
-*/
-func GetAdminTables(redisCfg RedisConf) (*AdminTables, error) {
-	rds := NewRedisClient(redisCfg)
-	d, err := rds.Client.Get(rds.ctx, ADMIN_TABLE_KEY).Result()
-	if err != nil {
-		if err == redis.Nil {
-			return nil, nil
-		}
-		return nil, err
-	}
-	tables := &AdminTables{}
-	err = json.Unmarshal([]byte(d), tables)
-	if err != nil {
-		return nil, err
-	}
-	return tables, nil
-}
-
-/*
-Place holder func to create the header element in redis
-*/
-func AddHeaders(h HeaderCollection, redisCfg RedisConf) error {
-	rdc := NewRedisClient(redisCfg)
-	data, err := json.Marshal(&h)
-	if err != nil {
-		return err
-	}
-	err = rdc.Client.Set(rdc.ctx, HEADER_KEY, data, 0).Err()
-	if err != nil {
-		return err
-	}
-	return nil
-}
-
-/*
-Retrieve all documents from the category specified in the argument category
-
-	:param category: the category to get documents from
-*/
-func GetAllDocuments(category string, redisCfg RedisConf) ([]*Document, error) {
-	rdc := NewRedisClient(redisCfg)
-	ids, err := rdc.AllDocIds()
-	if err != nil {
-		return nil, err
-	}
-	var docs []*Document
-	for idx := range ids {
-		doc, err := rdc.GetItem(ids[idx])
-		if err != nil {
-			return nil, err
-		}
-		if doc.Category != category {
-			continue
-		}
-		docs = append(docs, &Document{
-			Ident:   doc.Ident,
-			Created: doc.Created,
-			Body:    doc.Body,
-			Sample:  doc.MakeSample(),
-		})
-	}
-	return docs, nil
-
-}
-
-/*
-adds a text post document to the redis database
-*/
-func AddDocument(d Document, redisCfg RedisConf) error {
-	rdc := NewRedisClient(redisCfg)
-	return rdc.AddDoc(d)
-}
-
 /*
 	 convert markdown to html
 		:param md: the byte array containing the Markdown to convert

+ 4 - 4
pkg/helpers/redis.go

@@ -76,14 +76,14 @@ func (r *RedisCaller) AddDoc(doc Document) error {
 		return &InvalidTopic{Topic: doc.Category}
 	}
 
-	val, err := r.Client.Get(r.ctx, doc.Ident).Result()
+	val, err := r.Client.Get(r.ctx, string(doc.Ident)).Result()
 	if err == redis.Nil {
 		data, err := json.Marshal(&doc)
 		if err != nil {
 			return err
 		}
 
-		err = r.Client.Set(r.ctx, doc.Ident, data, 0).Err()
+		err = r.Client.Set(r.ctx, string(doc.Ident), data, 0).Err()
 		if err != nil {
 			return err
 		}
@@ -91,7 +91,7 @@ func (r *RedisCaller) AddDoc(doc Document) error {
     } else if err != nil {
         return err
     }
-	return &DocAlreadyExists{Key: doc.Ident, Value: val}
+	return &DocAlreadyExists{Key: string(doc.Ident), Value: val}
 }
 
 
@@ -240,4 +240,4 @@ func (r *RedisCaller) UpdateHeader(id string, new HeaderCollection) error {
 
 func (r *RedisCaller) UpdateMenu(id string, new MenuElement) error {
 	return r.editVal(id, new)
-}
+}

+ 154 - 30
pkg/helpers/storage.go

@@ -10,6 +10,7 @@ import (
 	"os"
 	"strings"
 	"time"
+	"mime/multipart"
 
 	"git.aetherial.dev/aeth/keiji/pkg/env"
 	"github.com/google/uuid"
@@ -44,7 +45,7 @@ type Identifier string
 
 type Document struct {
 	Row int
-	Ident   string   `json:"id"`
+	Ident   Identifier   `json:"id"`
 	Title    string `json:"title"`
 	Created  string `json:"created"`
 	Body     string `json:"body"`
@@ -70,9 +71,10 @@ func (d *Document) MakeSample() string {
 }
 
 type Image struct {
-	Ident string
-	Location string
-	Title    string
+	Ident Identifier `json:"identifier"`
+	Location string  `json:"title" form:"title"`
+	Title    string  `json:"description" form:"description"`
+	File        *multipart.FileHeader `form:"file"`
 	Desc     string
 	Created string
 	Category string
@@ -82,15 +84,20 @@ type Image struct {
 type DocumentIO interface {
 	GetDocument(id Identifier) (Document, error)
 	GetImage(id Identifier) (Image, error)
+	GetAllImages() []Image
 	UpdateDocument(doc Document) error
 	DeleteDocument(id Identifier) error
 	AddDocument(doc Document) error
-	AddImage(img Image) error
+	AddImage(data []byte, title, desc string) error
+	AddAdminTableEntry(TableData, string) error
+	AddNavbarItem(NavBarItem) error
+	AddMenuItem(MenuLinkPair) error
 	GetByCategory(category string) []Document
 	AllDocuments() []Document
 	GetDropdownElements() []MenuLinkPair
 	GetNavBarLinks() []NavBarItem
 	GetAssets() []Asset
+	GetAdminTables() AdminPage
 }
 
 var (
@@ -117,10 +124,10 @@ func (r *SQLiteRepo) Migrate() error {
 	postsTable := `
     CREATE TABLE IF NOT EXISTS posts(
         row INTEGER PRIMARY KEY AUTOINCREMENT,
-		id TEXT NOT NULL,
+		id TEXT NOT NULL UNIQUE,
 		title TEXT NOT NULL,
         created TEXT NOT NULL,
-        body TEXT NOT NULL UNIQUE,
+        body TEXT NOT NULL,
         category TEXT NOT NULL,
 		sample TEXT NOT NULL
     );
@@ -131,9 +138,8 @@ func (r *SQLiteRepo) Migrate() error {
 		id TEXT NOT NULL,
 		title TEXT NOT NULL,
 		location TEXT NOT NULL,
-		description TEXT NOT NULL,
-		created TEXT NOT NULL,
-		category TEXT NOT NULL
+		desc TEXT NOT NULL,
+		created TEXT NOT NULL
 	);
 	`
 	menuItemsTable := `
@@ -157,7 +163,15 @@ func (r *SQLiteRepo) Migrate() error {
 		data BLOB NOT NULL
 	);
 	`
-	seedQueries := []string{postsTable, imagesTable, menuItemsTable, navbarItemsTable, assetTable}
+	adminTable := `
+	CREATE TABLE IF NOT EXISTS admin(
+		row INTEGER PRIMARY KEY AUTOINCREMENT,
+		display_name TEXT NOT NULL,
+		link TEXT NOT NULL,
+		category TEXT NOT NULL
+	);
+	`
+	seedQueries := []string{postsTable, imagesTable, menuItemsTable, navbarItemsTable, assetTable, adminTable}
     for i := range seedQueries {
 	    _, err := r.db.Exec(seedQueries[i])
 	    if err != nil {
@@ -168,8 +182,13 @@ func (r *SQLiteRepo) Migrate() error {
 }
 
 
-
-func (s *SQLiteRepo) Seed(menu string, pngs string, dir string) {
+/*
+Seed the database with the necessary configuration items to function properly
+	:param menu: the text file containing the k/v pair for the navigation menu
+	:param pngs: the text file containing the k/v pair for the icon names -> redirect links
+	:param dir: the directory that the PNG assets are in (note: the k/v pair in pngs will read from this dir)
+*/
+func (s *SQLiteRepo) Seed(menu string, pngs string, dir string) { // TODO: make a bootstrap file with a comprehensive unmarshalling sequence for tighter control of the seeing procedute
 	b, err := os.ReadFile(menu)
 
 	if err != nil {log.Fatal(err)}
@@ -210,11 +229,12 @@ func (s *SQLiteRepo) Seed(menu string, pngs string, dir string) {
 		}
 
 	}
+	
 }
 
 
 /*
-Get all dropdown menu elements
+Get all dropdown menu elements. Returns a list of MenuLinkPair structs with the text and redirect location
 */
 func (s *SQLiteRepo) GetDropdownElements() []MenuLinkPair {
 	rows, err := s.db.Query("SELECT * FROM menu")
@@ -236,7 +256,7 @@ func (s *SQLiteRepo) GetDropdownElements() []MenuLinkPair {
 
 
 /*
-Get all nav bar items
+Get all nav bar items. Returns a list of NavBarItem structs with the png data, the file name, and the redirect location of the icon
 */
 func (s *SQLiteRepo) GetNavBarLinks() []NavBarItem {
 
@@ -277,6 +297,26 @@ func (s *SQLiteRepo) GetAssets() []Asset {
 
 }
 
+/*
+get all assets from the asset table
+*/
+func (s *SQLiteRepo) GetAdminTables() AdminPage {
+	rows, err := s.db.Query("SELECT * FROM admin")
+	adminPage := AdminPage{Tables: map[string][]TableData{}}
+	defer rows.Close()
+	for rows.Next() {
+		var item TableData
+		var id int
+		var category string
+		err = rows.Scan(&id, &item.DisplayName, &item.Link, &category)
+		if err != nil {
+			log.Fatal(err)
+		}
+		adminPage.Tables[category] = append(adminPage.Tables[category], item)
+	}
+	return adminPage 
+
+}
 
 
 /*
@@ -288,7 +328,8 @@ func (s *SQLiteRepo) GetDocument(id Identifier) (Document, error) {
 	row := s.db.QueryRow("SELECT * FROM posts WHERE id = ?", id)
 
 	var post Document
-	if err := row.Scan(&post); err != nil {
+	var rowNum int
+	if err := row.Scan(&rowNum, &post.Ident, &post.Title, &post.Created, &post.Body, &post.Category, &post.Sample); err != nil {
 		if errors.Is(err, sql.ErrNoRows) {
 			return post, ErrNotExists
 		}
@@ -298,8 +339,12 @@ func (s *SQLiteRepo) GetDocument(id Identifier) (Document, error) {
 
 }
 
+
+
+
 /*
 Get all documents by category
+	:param category: the category to retrieve all docs from
 */
 func (s *SQLiteRepo) GetByCategory(category string) []Document {
 	rows, err := s.db.Query("SELECT * FROM posts WHERE category = ?", category)
@@ -330,12 +375,12 @@ get image data from the images table
 */
 func (s *SQLiteRepo) GetImage(id Identifier) (Image, error) {
 	row := s.db.QueryRow("SELECT * FROM images WHERE id = ?", id)
+	var rowNum int
 	var title string
 	var location string
 	var desc string
-	var category string
 	var created string
-	if err := row.Scan(&title, &location, &desc, &created, &category); err != nil {
+	if err := row.Scan(&rowNum, &title, &location, &desc, &created); err != nil {
 		if errors.Is(err, sql.ErrNoRows) {
 			return Image{}, ErrNotExists
 		}
@@ -345,9 +390,40 @@ func (s *SQLiteRepo) GetImage(id Identifier) (Image, error) {
 	if err != nil {
 		return Image{}, err
 	}
-	return Image{Title: title, Location: location, Desc: desc, Data: data, Created: created, Category: category}, nil
+	return Image{Ident: id, Title: title, Location: location, Desc: desc, Data: data, Created: created}, nil
 }
 
+/*
+Get all of the images from the datastore
+*/
+func (s *SQLiteRepo) GetAllImages() []Image {
+	rows, err := s.db.Query("SELECT * FROM images")
+	if err != nil {
+		log.Fatal(err)
+	}
+	imgs := []Image{}
+	for rows.Next() {
+		var img Image
+		var rowNum int
+		err := rows.Scan(&rowNum, &img.Ident, &img.Title, &img.Location, &img.Desc, &img.Created)
+		if err != nil {
+			log.Fatal(err)
+		}
+		b, err := os.ReadFile(img.Location)
+		if err != nil {
+			log.Fatal(err)
+		}
+		imgs = append(imgs, Image{Ident: img.Ident, Title: img.Title, Location: img.Location, Desc: img.Desc, Data: b, Created: img.Created})
+	}
+	err = rows.Err()
+	if err != nil {
+		log.Fatal(err)
+	}
+	return imgs
+}
+
+
+
 /*
 Add an image to the database
 	:param title: the title of the image
@@ -355,12 +431,14 @@ Add an image to the database
 	:param desc: the description of the image, if any
 	:param data: the binary data for the image
 */
-func (s *SQLiteRepo) AddImage(img Image) error {
-	err := os.WriteFile(path.Join(img.Location, img.Ident), img.Data, os.ModeAppend) 
+func (s *SQLiteRepo) AddImage(data []byte, title string, desc string) error {
+	id := newIdentifier()
+	fsLoc := path.Join(GetImageStore(), string(id))
+	err := os.WriteFile(fsLoc, data, os.ModePerm) 
 	if err != nil {
 		return err
 	}
-	_, err = s.db.Exec("INSERT INTO images (id, title, location, desc, created, category) VALUES (?,?,?,?,?,?,?)", img.Ident, img.Title, img.Location, img.Desc, img.Created, img.Category)
+	_, err = s.db.Exec("INSERT INTO images (id, title, location, desc, created) VALUES (?,?,?,?,?)", string(id), title, fsLoc, desc, time.Now().String())
 	if err != nil {
 		return err
 	}
@@ -368,7 +446,10 @@ func (s *SQLiteRepo) AddImage(img Image) error {
 }
 
 
-
+/*
+Updates a document in the database with the supplied. Only changes the title, the body, category. Keys off of the documents Identifier
+	:param doc: the Document to upload into the database
+*/
 func (s *SQLiteRepo) UpdateDocument(doc Document) error {
 	tx, err := s.db.Begin()
 	if err != nil {
@@ -383,7 +464,10 @@ func (s *SQLiteRepo) UpdateDocument(doc Document) error {
 	tx.Commit()
 	return nil
 }
-
+/*
+Adds a MenuLinkPair to the menu database table
+	:param item: the MenuLinkPair to upload
+*/
 func (s *SQLiteRepo) AddMenuItem(item MenuLinkPair) error {
 	tx, err := s.db.Begin()
 	if err != nil {
@@ -400,6 +484,10 @@ func (s *SQLiteRepo) AddMenuItem(item MenuLinkPair) error {
 	
 }
 
+/*
+Adds an item to the navbar database table
+	:param item: the NavBarItem to upload
+*/
 func (s *SQLiteRepo) AddNavbarItem(item NavBarItem) error {
 	tx, err := s.db.Begin()
 	if err != nil {
@@ -416,6 +504,12 @@ func (s *SQLiteRepo) AddNavbarItem(item NavBarItem) error {
 	
 }
 
+
+/*
+Adds an asset to the asset database table asset
+	:param name: the name of the asset (filename)
+	:param data: the byte array of the PNG to upload TODO: limit this to 256kb
+	*/
 func (s *SQLiteRepo) AddAsset(name string, data []byte) error {
 	tx, err := s.db.Begin()
 	if err != nil {
@@ -431,14 +525,18 @@ func (s *SQLiteRepo) AddAsset(name string, data []byte) error {
 	return nil
 }	
 
-
+/*
+Adds a document to the database (for text posts)
+	:param doc: the Document to add
+*/
 func (s *SQLiteRepo) AddDocument(doc Document) error {
+	id := uuid.New()
 	tx, err := s.db.Begin()
 	if err != nil {
 		return err
 	}
-	stmt,_ := tx.Prepare("INSERT INTO posts (id, title, created, body, category,sample) VALUES (?,?,?,?,?,?)")
-	_, err = stmt.Exec(doc.Ident, doc.Title, doc.Created, doc.Body, doc.Category, doc.Sample)
+	stmt,_ := tx.Prepare("INSERT INTO posts(id, title, created, body, category, sample) VALUES (?,?,?,?,?,?)")
+	_, err = stmt.Exec(id.String(), doc.Title, doc.Created, doc.Body, doc.Category, doc.MakeSample())
 	if err != nil {
 		tx.Rollback()
 		return err
@@ -447,6 +545,26 @@ func (s *SQLiteRepo) AddDocument(doc Document) error {
 	return nil
 
 }
+/*
+Add an entry to the 'admin' table in the database
+	:param item: an admin table k/v text to redirect pair
+	:param tableName: the name of the table to populate the link in on the UI
+*/
+func (s *SQLiteRepo) AddAdminTableEntry(item TableData, category string) error {
+	tx, err := s.db.Begin()
+	if err != nil {
+		return err
+	}
+	stmt,_ := tx.Prepare("INSERT INTO admin (display_name, link, category) VALUES (?,?,?)")
+	_, err = stmt.Exec(item.DisplayName, item.Link, category)
+	if err != nil {
+		tx.Rollback()
+		return err
+	}
+	tx.Commit()
+
+	return nil
+}
 
 /*
 Delete a document from the db
@@ -476,7 +594,7 @@ func (s *SQLiteRepo) AllDocuments() []Document {
 	}
 	defer rows.Close()
 
-	var all []Document
+	all := []Document{}
 	for rows.Next() {
 		var post Document
 		if err := rows.Scan(&post.Ident, &post.Title, &post.Created, &post.Body, &post.Sample); err != nil {
@@ -515,9 +633,9 @@ Create a new ImageStoreItem
 	:param desc: the description to associate to the image
 */
 func NewImageStoreItem(title string, desc string) Image {
-	id := uuid.New()
+	id := newIdentifier()
 	img := Image{
-		Ident:   id.String(),
+		Ident:   id,
 		Title:        title,
 		Category:     DIGITAL_ART,
 		Location: GetImageStore(),
@@ -535,6 +653,12 @@ func GetImageStore() string {
 	return os.Getenv(env.IMAGE_STORE)
 }
 
+// Wrapping the new id call in a function to make refactoring easier
+func newIdentifier() Identifier {
+	return Identifier(uuid.NewString())
+}
+
+
 /*
 Return database entries of the images that exist in the imagestore
 

+ 7 - 5
pkg/routes/register.go

@@ -9,10 +9,10 @@ import (
 func Register(e *gin.Engine, root string, domain string, redisPort string, redisAddr string, database helpers.DocumentIO) {
 	c := controller.NewController(root, domain, redisPort, redisAddr, database)
 	web := e.Group("")
-	web.GET("/", c.ServeBlogHome)
-	web.GET("/blog", c.ServeBlogHome)
+	web.GET("/", c.ServeHome)
+	web.GET("/blog", c.ServeBlog)
 	web.GET("/digital", c.ServeDigitalArt)
-	web.GET("/writing/:post-name", c.ServePost)
+	web.GET("/writing/:id", c.ServePost)
 	web.GET("/login", c.ServeLogin)
 	web.POST("/login", c.Auth)
 
@@ -29,9 +29,11 @@ func Register(e *gin.Engine, root string, domain string, redisPort string, redis
 	priv.GET("/upload", c.ServeFileUpload)
 	priv.POST("/upload", c.SaveFile)
 	priv.GET("/panel", c.AdminPanel)
-	priv.POST("/add-document", c.AddDocument)
+	priv.POST("/panel", c.AddAdminTableEntry)
+	priv.POST("/menu", c.AddMenuItem)
+	priv.POST("/navbar", c.AddNavbarItem)
 	priv.POST("/images/upload", c.SaveFile)
-	priv.GET("/posts/:post-name", c.GetBlogPostEditor)
+	priv.GET("/posts/:id", c.GetBlogPostEditor)
 	priv.POST("/posts", c.MakeBlogPost)
 	priv.GET("/posts/all", c.ServeBlogDirectory)
 	priv.GET("/posts", c.ServeNewBlogPage)