aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBobby <[email protected]>2022-03-21 01:28:56 -0400
committerBobby <[email protected]>2022-03-21 01:28:56 -0400
commit6a43cd05abf6be7d30e405f2e797738ffeaf659a (patch)
tree1d89ba30395fc82e7b41a30610007363af79de26
parentb38eaa1a814769d93b7cd8348804fc1241098189 (diff)
downloadluciferreeves.github.io-6a43cd05abf6be7d30e405f2e797738ffeaf659a.tar.xz
luciferreeves.github.io-6a43cd05abf6be7d30e405f2e797738ffeaf659a.zip
update posts function
-rw-r--r--public/views/dashboard.html15
-rw-r--r--public/views/editPost.html137
-rw-r--r--routes/admin.js31
-rw-r--r--routes/blog.js49
-rw-r--r--routes/index.js3
-rw-r--r--routes/posts.js1
-rw-r--r--static/assets/js/pages/publish.js75
7 files changed, 294 insertions, 17 deletions
diff --git a/public/views/dashboard.html b/public/views/dashboard.html
index 8692bb4..03dd653 100644
--- a/public/views/dashboard.html
+++ b/public/views/dashboard.html
@@ -18,13 +18,13 @@
<div class="container">
<button type="button" class="btn btn-navbar" data-toggle="collapse"
data-target=".nav-collapse"></button>
- <a class="brand" href="../">That Computer Scientist</a>
+ <a class="brand" href="/">That Computer Scientist</a>
<div class="nav-collapse collapse">
<ul class="nav">
- <li><a href="../">Home</a></li>
- <li><a href="../about">About</a></li>
- <li><a href="../repos">Repositories</a></li>
- <li class="active"><a href="./">Administration</a></li>
+ <li><a href="/">Home</a></li>
+ <li><a href="/about">About</a></li>
+ <li><a href="/repos">Repositories</a></li>
+ <li class="active"><a href="/admin">Administration</a></li>
</ul>
</div>
</div>
@@ -35,7 +35,7 @@
<div class="row">
<div class="span3 bs-docs-sidebar">
<ul class="nav nav-list bs-docs-sidenav affix-top">
- <li class="active"><a href="../admin/dashboard">All Posts</a></li>
+ <li class="active"><a href="/admin/dashboard">All Posts</a></li>
<li><a href="/admin/dashboard/new">Add Post</a></li>
<li><a href="#">Manage Comments</a></li>
<li><a href="#">Manage Users</a></li>
@@ -87,6 +87,7 @@
editButton.className = 'btn btn-primary';
editButton.innerHTML = 'Edit Post';
editButton.style.marginRight = '15px';
+ editButton.href = `/admin/dashboard/edit/${post.slug}`;
const deleteButton = document.createElement('a');
deleteButton.className = 'btn btn-danger';
deleteButton.innerHTML = 'Delete Post';
@@ -101,7 +102,7 @@
leadParagraphCotainer.appendChild(editButtonContainer);
posts.appendChild(leadParagraphCotainer);
})
- },
+ },
error: (err) => {
console.log(err);
}
diff --git a/public/views/editPost.html b/public/views/editPost.html
new file mode 100644
index 0000000..371b455
--- /dev/null
+++ b/public/views/editPost.html
@@ -0,0 +1,137 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+ <meta charset="UTF-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link href="/static/assets/css/bootstrap.css" rel="stylesheet">
+ <link href="/static/assets/css/bootstrap-responsive.css" rel="stylesheet">
+ <link rel="stylesheet"
+ href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.5.0/styles/base16/seti-ui.min.css">
+ <link rel="preconnect" href="https://fonts.googleapis.com">
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+ <link href="https://fonts.googleapis.com/css2?family=Fira+Code&display=swap" rel="stylesheet">
+ <link href="/static/assets/css/custom.css" rel="stylesheet">
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css"
+ integrity="sha384-KiWOvVjnN8qwAZbuQyWDIbfCLFhLXNETzBQjA/92pIowpC0d2O3nppDGQVgwd2nB" crossorigin="anonymous">
+ <link rel="shortcut icon" href="/static/images/favicon.png">
+ <title>Dashboard - Add New Post</title>
+ <style type="text/css">
+ input,
+ textarea {
+ width: 100%;
+ }
+
+ code,
+ pre {
+ font-family: 'Fira Code', monospace !important;
+ font-size: 14px;
+ background-color: #1c1c1c;
+ color: #D4D4D5;
+ }
+
+ pre {
+ padding: 10px;
+ }
+ </style>
+</head>
+
+<body>
+ <div class="navbar navbar-inverse navbar-fixed-top">
+ <div class="navbar-inner">
+ <div class="container">
+ <button type="button" class="btn btn-navbar" data-toggle="collapse"
+ data-target=".nav-collapse"></button>
+ <a class="brand" href="/">That Computer Scientist</a>
+ <div class="nav-collapse collapse">
+ <ul class="nav">
+ <li><a href="/">Home</a></li>
+ <li><a href="/about">About</a></li>
+ <li><a href="/repos">Repositories</a></li>
+ <li class="active"><a href="/admin">Administration</a></li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="container margin-top-375" style="margin-top: 3.75rem;">
+ <div class="container">
+ <div class="row">
+ <div class="span3 bs-docs-sidebar">
+ <ul class="nav nav-list bs-docs-sidenav affix-top">
+ <li><a href="/admin/dashboard">All Posts</a></li>
+ <li><a href="/admin/dashboard/new">Add Post</a></li>
+ <li><a href="#">Manage Comments</a></li>
+ <li><a href="#">Manage Users</a></li>
+ <li><a id="logout">Logout</a></li>
+ </ul>
+ </div>
+ <div class="span9">
+ <header class="page-header">
+ <h1>Editing Post</h1>
+ </header>
+ <div class="span9" style="padding: 0; margin: 0;">
+ <div id="createPost" class="form">
+ <div class="form-group">
+ <label for="title">Title</label>
+ <input type="text" class="form-control" id="title" name="title" placeholder="Title"
+ style=" margin-left: 0;">
+ </div>
+ <div class="form-group">
+ <label for="content">Content</label>
+ <textarea class="form-control" id="content" name="content" rows="10"
+ placeholder="Content"></textarea>
+ </div>
+ <div class="container">
+ <h1 style="margin-left: 0; padding-left: 0; transform: translate(-20px, 0px);">Render
+ Preview</h1>
+ <div class="span9" id="renderPreview"
+ style="padding: 10px 0px; margin: 20px 0px 20px -20px"></div>
+ </div>
+ <div class="form-group">
+ <label for="tags">Tags</label>
+ <input type="text" class="form-control" id="tags" name="tags" placeholder="Tags"
+ style=" margin-left: 0;">
+ </div>
+ <div class="form-group">
+ <label for="publishDate">Publish Date</label>
+ <input type="date" class="form-control" id="publishDate" name="publishDate"
+ placeholder="Publish Date" style=" margin-left: 0;">
+ </div>
+ <div id="error" class="alert alert-error hidden">
+ <strong>Error!</strong> Please fill out all fields.
+ </div>
+ <div class="control-group">
+ <div class="controls">
+ <button type="submit" class="btn btn-primary" id="publishPost">Update
+ Post</button>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <script src="https://www.gstatic.com/firebasejs/7.14.1/firebase-app.js"></script>
+ <script src="https://www.gstatic.com/firebasejs/7.14.1/firebase-auth.js"></script>
+ <script src="/static/assets/js/jquery.js"></script>
+ <script src="/static/assets/js/bootstrap-transition.js"></script>
+ <script src="/static/assets/js/bootstrap-collapse.js"></script>
+ <script src="/static/assets/js/pages/config.js"></script>
+ <script src="/static/assets/js/pages/authCheck.js"></script>
+ <script src="/static/assets/js/marked.js"></script>
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.5.0/highlight.min.js"></script>
+ <script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.js"
+ integrity="sha384-0fdwu/T/EQMsQlrHCCHoH10pkPLlKA1jL5dFyUOvB3lfeT2540/2g6YgSi2BL14p"
+ crossorigin="anonymous"></script>
+ <script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/contrib/auto-render.min.js"
+ integrity="sha384-+XBljXPPiv+OzfbB3cVmLHf4hdUFHlWNZN5spNQ7rmHTXpd7WvJum6fIACpNNfIR"
+ crossorigin="anonymous"></script>
+ <script>
+
+ </script>
+</body>
+
+</html> \ No newline at end of file
diff --git a/routes/admin.js b/routes/admin.js
index b6afab7..260f343 100644
--- a/routes/admin.js
+++ b/routes/admin.js
@@ -1,5 +1,8 @@
const express = require("express");
const router = express.Router();
+const cheerio = require("cheerio");
+const fs = require("fs");
+const firebase = require("../firebase");
router.get("/dashboard", function (req, res) {
res.render("dashboard.html");
@@ -7,7 +10,33 @@ router.get("/dashboard", function (req, res) {
router.get("/dashboard/new", function (req, res) {
res.render("createPost.html");
-})
+});
+
+router.get("/dashboard/edit/:slug", function (req, res) {
+ var html = fs.readFileSync(
+ __dirname + "/../public/views/editPost.html",
+ "utf8"
+ );
+ var $ = cheerio.load(html);
+ const store = firebase.firestore();
+ let query = store.collection("posts");
+ query = query.where("slug", "==", req.params.slug);
+ query
+ .get()
+ .then(function (querySnapshot) {
+ querySnapshot.forEach(function (doc) {
+ $("#title").val(doc.data().title);
+ $("#content").val(Buffer.from(doc.data().content, "base64").toString());
+ $("#tags").val(doc.data().tags);
+ $("#publishDate").val(doc.data().publishDate);
+ });
+ })
+ .then(() => {
+ const publishScript = `<script src="/static/assets/js/pages/publish.js"></script>`;
+ $("body").append(publishScript);
+ res.send($.html());
+ });
+});
router.get("/", (req, res) => {
// Send admin.html from public folder
diff --git a/routes/blog.js b/routes/blog.js
index fbdc1f2..8a8cb19 100644
--- a/routes/blog.js
+++ b/routes/blog.js
@@ -7,13 +7,50 @@ router.get("/posts", (req, res) => {
const posts = [];
let query = store.collection("posts");
query = query.select("slug", "tags", "title", "shortText", "publishDate");
- query.get().then(function (querySnapshot) {
- querySnapshot.forEach(function (doc) {
- posts.push(doc.data());
+ query
+ .get()
+ .then(function (querySnapshot) {
+ querySnapshot.forEach(function (doc) {
+ posts.push(doc.data());
+ });
+ })
+ .then(() => {
+ res.json(posts);
+ });
+});
+
+router.put("/update/:slug", (req, res) => {
+ const store = firebase.firestore();
+ const { title, content, tags, publishDate, shortText, slug } = req.body;
+ const base64 = Buffer.from(content).toString("base64");
+ const post = {
+ title,
+ content: base64,
+ tags: String(tags).split(",").length > 0 ? String(tags).split(",") : [],
+ publishDate,
+ shortText,
+ slug,
+ };
+ let query = store.collection("posts");
+ query = query.where("slug", "==", slug);
+ query
+ .get()
+ .then(function (querySnapshot) {
+ querySnapshot.forEach(function (doc) {
+ doc.ref.update({
+ title: post.title,
+ content: post.content,
+ tags: post.tags,
+ publishDate: post.publishDate,
+ });
+ });
+ })
+ .then(() => {
+ res.json({ success: true });
+ })
+ .catch((err) => {
+ res.json({ success: false, err });
});
- }).then(() => {
- res.json(posts);
- });
});
router.post("/new", (req, res) => {
diff --git a/routes/index.js b/routes/index.js
index 659d50d..605f6ad 100644
--- a/routes/index.js
+++ b/routes/index.js
@@ -13,8 +13,8 @@ const home = require("./home");
router.use("/admin", admin);
router.use("/api/blog", blog);
router.use("/", repositories);
-router.use("/", posts);
router.use("/", home);
+router.use("/", posts);
// Create the routes
@@ -22,6 +22,5 @@ router.get("/about", (req, res) => {
res.render("about.html");
});
-
// Export the routes
module.exports = router;
diff --git a/routes/posts.js b/routes/posts.js
index bc22670..00b092f 100644
--- a/routes/posts.js
+++ b/routes/posts.js
@@ -6,7 +6,6 @@ const router = express.Router();
const marked = require("marked");
const hljs = require("highlight.js");
-
router.get("/posts/:id", function (req, res) {
const id = req.params.id;
// get single document where slug === id
diff --git a/static/assets/js/pages/publish.js b/static/assets/js/pages/publish.js
new file mode 100644
index 0000000..7349fac
--- /dev/null
+++ b/static/assets/js/pages/publish.js
@@ -0,0 +1,75 @@
+window.addEventListener("DOMContentLoaded", () => {
+ const content = document.getElementById("content");
+ const renderPreview = document.getElementById("renderPreview");
+ marked.setOptions({
+ highlight: function (code) {
+ return hljs.highlightAuto(code).value;
+ },
+ });
+ content.addEventListener("input", () => {
+ renderPreview.innerHTML = marked.parse(content.value);
+ renderMathInElement(renderPreview, {
+ // customised options
+ // • auto-render specific keys, e.g.:
+ delimiters: [
+ { left: "$$", right: "$$", display: true },
+ { left: "$", right: "$", display: false },
+ { left: "\\(", right: "\\)", display: false },
+ { left: "\\[", right: "\\]", display: true },
+ ],
+ // • rendering keys, e.g.:
+ throwOnError: false,
+ });
+ });
+});
+$(document).on("click", "#publishPost", () => {
+ document.getElementById("error").classList.add("hidden");
+ const content = $("#content").val();
+ const title = $("#title").val();
+ const publishDate = $("#publishDate").val();
+ const slug = title
+ .toLowerCase()
+ .replace(/ /g, "-")
+ .replace(/[^\w-]+/g, "");
+ const tags = $("#tags").val();
+ if (title === "" || publishDate === "") {
+ document.getElementById("error").classList.remove("hidden");
+ return;
+ } else {
+ // Publish post to api/blog/new
+ const body = {
+ title: title,
+ publishDate: publishDate,
+ tags: tags,
+ content: content,
+ shortText: marked.parse(content.substring(0, 120) + "..."),
+ slug: slug,
+ };
+ if (window.location.href.includes(slug)) {
+ // Update post
+ $.ajax({
+ url: `/api/blog/update/${slug}`,
+ type: "PUT",
+ data: body,
+ success: function (data) {
+ window.location.href = `/posts/${slug}`;
+ },
+ error: function (err) {
+ console.log(err);
+ },
+ });
+ } else {
+ $.ajax({
+ url: "/api/blog/new",
+ type: "POST",
+ data: body,
+ success: (data) => {
+ window.location.href = "/admin/dashboard";
+ },
+ error: (err) => {
+ console.log(err);
+ },
+ });
+ }
+ }
+});