photo-ui
diff --git a/photos-ui/gallery.html b/photos-ui/gallery.html
new file mode 100644
index 0000000..a8001d0
--- /dev/null
+++ b/photos-ui/gallery.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>Photos</title>
+    </head>
+    <script src="static/photos.js"></script>
+    <body onload="initGallery('gallery')">
+      <div id="gallery" />
+    </body>
+</html>
diff --git a/photos-ui/main.go b/photos-ui/main.go
new file mode 100644
index 0000000..879ef0b
--- /dev/null
+++ b/photos-ui/main.go
@@ -0,0 +1,31 @@
+package main
+
+import (
+	"flag"
+	"fmt"
+	"log"
+	"net/http"
+)
+
+var port = flag.Int("port", 3000, "Port to listen on")
+
+func handle_gallery(w http.ResponseWriter, r *http.Request) {
+	http.ServeFile(w, r, "./gallery.html")
+}
+
+func handle_photo(w http.ResponseWriter, r *http.Request) {
+	http.ServeFile(w, r, "./photo.html")
+}
+
+func handle_graphql(w http.ResponseWriter, r *http.Request) {
+	http.Redirect(w, r, "http://localhost:8080/graphql?query={queryImage(){id objectPath}}", http.StatusMovedPermanently)
+}
+
+func main() {
+	flag.Parse()
+	fs := http.FileServer(http.Dir("./static"))
+	http.Handle("/static/", http.StripPrefix("/static/", fs))
+	http.HandleFunc("/graphql", handle_graphql)
+	http.HandleFunc("/", handle_gallery)
+	log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", *port), nil))
+}
diff --git a/photos-ui/photo.html b/photos-ui/photo.html
new file mode 100644
index 0000000..8628549
--- /dev/null
+++ b/photos-ui/photo.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>Photos</title>
+    </head>
+    <script src="static/photos.js"></script>
+    <body onload="initPhoto('gallery')">
+      <div id="gallery" />
+    </body>
+</html>
diff --git a/photos-ui/static/photos.js b/photos-ui/static/photos.js
new file mode 100644
index 0000000..ccadb4b
--- /dev/null
+++ b/photos-ui/static/photos.js
@@ -0,0 +1,22 @@
+async function fetchAllPhotos() {
+    return await fetch("/graphql?query={queryImage(){objectPath}}")
+	.then(resp => resp.json())
+	.then(resp => resp.data.queryImage)
+	.catch(error => {
+	    alert(error);
+	    return [];
+	});
+    
+}
+
+async function initGallery(gallery_elem_id) {
+    imgs = await fetchAllPhotos();
+    console.log(imgs);
+    img_list = "<ul>";
+    for (img of imgs) {
+	img_list += "<li><a href='/photo/" + img.id + "'><img style='max-width: 300px' src='http://localhost:9000/" + img.objectPath + "' /></a></li>";
+    }
+    img_list += "</ul>";
+    console.log(img_list);
+    document.getElementById(gallery_elem_id).innerHTML = img_list;
+}