diff --git a/.gitignore b/.gitignore index 9b818b4..f41ce1f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ /data *.code-workspace .vscode/settings.json +/frontend/public/img/.dev \ No newline at end of file diff --git a/README.md b/README.md index 8e51835..c11b2e8 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,9 @@ # yet-another-blog -A open source blogging website made for both personal blogs and big projects. \ No newline at end of file +A open source blogging website made for both personal blogs and big projects. + +TODO +Setup instructions +Database +S3 +Admin settings diff --git a/backend/page_scripts.js b/backend/page_scripts.js index 032db5c..685cfbc 100644 --- a/backend/page_scripts.js +++ b/backend/page_scripts.js @@ -9,13 +9,21 @@ async function index(request, response) { response.render("index.ejs", { user: request.session.user || null, website_name: process.env.WEBSITE_NAME }); } - function register(request, response) { response.render("register.ejs", { user: request.session.user || null, website_name: process.env.WEBSITE_NAME }); } function login(request, response) { response.render("login.ejs", { user: request.session.user || null, website_name: process.env.WEBSITE_NAME }); } +function author(request, response) { + response.render("author.ejs", { user: request.session.user || null, website_name: process.env.WEBSITE_NAME }); +} +function blogList(request, response) { + response.render("blogList.ejs", { user: request.session.user || null, website_name: process.env.WEBSITE_NAME }); +} +function blogNew(request, response) { + response.render("blogNew.ejs", { user: request.session.user || null, website_name: process.env.WEBSITE_NAME }); +} async function admin(request, response) { const reg_allowed = await settings.userRegistrationAllowed(); response.render("admin.ejs", { user: request.session.user || null, website_name: process.env.WEBSITE_NAME, settings: { registration_enabled: reg_allowed } }); @@ -45,4 +53,4 @@ async function settingPost(request, response) { response.json({ success: true }); } -module.exports = { index, register, login, admin, registerPost, loginPost, settingPost }; +module.exports = { index, register, login, author, blogList, blogNew, admin, registerPost, loginPost, settingPost }; diff --git a/frontend/public/css/blog-list.css b/frontend/public/css/blog-list.css new file mode 100644 index 0000000..811ca4c --- /dev/null +++ b/frontend/public/css/blog-list.css @@ -0,0 +1,53 @@ +.blog-admin { + width: 100%; + background-color: #222; + margin-bottom: 20px; + padding: 5px; + box-sizing: border-box; +} +.blog-admin .horizontal-button-container a { + background-color: #00367b; + color: white; + text-decoration: none; + padding: 5px 10px; + box-sizing: border-box; + border-radius: 5px; +} + +.blog-entry { + width: 100%; + display: grid; + grid-template-columns: 150px auto; + grid-gap: 10px; + margin-bottom: 10px; +} +.blog-entry .thumbnail { + width: 150px; +} +.blog-entry .thumbnail img { + height: 100%; + width: 100%; +} +.blog-entry .blog-info .blog-title { + font-size: 20px; + border-bottom: 1px solid #9f9f9f; + display: flex; +} +.blog-entry .blog-info .blog-title a { + color: white; + text-decoration: none; +} +.blog-entry .blog-info .blog-title .author { + color: #9f9f9f; + font-style: italic; + margin-left: auto; + font-size: 16px; +} +.blog-entry .blog-info .blog-description { + color: #9f9f9f; + margin-top: 10px; +} + +.blog-entry:last-of-type { + margin-bottom: inherit; +} \ No newline at end of file diff --git a/frontend/public/css/blog-list.scss b/frontend/public/css/blog-list.scss new file mode 100644 index 0000000..9ab4eb5 --- /dev/null +++ b/frontend/public/css/blog-list.scss @@ -0,0 +1,63 @@ +$quiet-text: #9f9f9f; + +.blog-admin { + width: 100%; + background-color: #222; + margin-bottom: 20px; + padding: 5px; + box-sizing: border-box; + + .horizontal-button-container { + a { + background-color: #00367b; + color: white; + text-decoration: none; + padding: 5px 10px; + box-sizing: border-box; + border-radius: 5px; + } + } +} + +.blog-entry { + width: 100%; + display: grid; + grid-template-columns: 150px auto; + grid-gap: 10px; + margin-bottom: 10px; + + .thumbnail { + width: 150px; + img { + height: 100%; + width: 100%; + } + } + + .blog-info { + .blog-title { + font-size: 20px; + border-bottom: 1px solid $quiet-text; + display: flex; + a { + color: white; + text-decoration: none; + } + + .author { + color: $quiet-text; + font-style: italic; + margin-left: auto; + font-size: 16px; + } + } + .blog-description { + color: $quiet-text; + margin-top: 10px; + } + } +} + +.blog-entry:last-of-type { + margin-bottom: inherit; +} diff --git a/frontend/public/css/new-blog.css b/frontend/public/css/new-blog.css new file mode 100644 index 0000000..61f419c --- /dev/null +++ b/frontend/public/css/new-blog.css @@ -0,0 +1,107 @@ +.e-header { + width: 100%; + display: grid; + grid-template-columns: 150px auto; + background-color: #222; + padding: 10px; + box-sizing: border-box; + grid-gap: 20px; + margin-bottom: 10px; +} +.e-header .e-thumbnail { + height: 150px; +} +.e-header .e-thumbnail img { + height: 100%; + width: 150px; +} +.e-header .e-description { + width: 100%; + display: flex; + flex-direction: column; +} +.e-header .e-description input { + margin-bottom: 5px; +} +.e-header .e-description textarea { + color: #ccc; + font-size: 16px; + width: 100%; + flex-grow: 1; +} + +.e-image-area { + background-color: #222; + height: 220px; + display: grid; + grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); + grid-template-rows: auto auto; + padding: 5px; + box-sizing: border-box; + width: 100%; + margin-bottom: 10px; +} +.e-image-area .image { + height: 100px; + aspect-ratio: 16/9; + margin: auto; + display: flex; +} +.e-image-area .image img { + height: 100%; + margin: auto; +} +.e-image-area .image:nth-child(odd) { + grid-row: span 1; + grid-column: 1; +} +.e-image-area .image:nth-child(even) { + grid-row: span 1; + grid-column: 2; +} + +.e-content { + background-color: #222; + padding: 5px; + margin-bottom: 10px; +} +.e-content textarea { + font-size: 16px; + color: white; +} + +.e-settings { + height: 40px; + width: 100%; + background-color: #222; + display: flex; + flex-direction: row; + padding: 5px; + box-sizing: border-box; +} +.e-settings .publish-date { + display: flex; +} +.e-settings .publish-date div { + margin: auto 10px auto auto; +} +.e-settings .publish-date input { + margin-right: 5px; +} +.e-settings input, +.e-settings textarea { + width: 200px; +} + +input, +textarea { + width: 100%; + padding: 5px; + box-sizing: border-box; + margin: 0; + border: 0; + background-color: black; + color: white; + font-size: 18px; + resize: vertical; +} \ No newline at end of file diff --git a/frontend/public/css/new-blog.scss b/frontend/public/css/new-blog.scss new file mode 100644 index 0000000..b51b44f --- /dev/null +++ b/frontend/public/css/new-blog.scss @@ -0,0 +1,118 @@ +$background-body: #222; + +.e-header { + width: 100%; + display: grid; + grid-template-columns: 150px auto; + background-color: $background-body; + padding: 10px; + box-sizing: border-box; + grid-gap: 20px; + margin-bottom: 10px; + + .e-thumbnail { + height: 150px; + + img { + height: 100%; + width: 150px; + } + } + + .e-description { + width: 100%; + display: flex; + flex-direction: column; + + input { + margin-bottom: 5px; + } + + textarea { + color: #ccc; + font-size: 16px; + width: 100%; + flex-grow: 1; + } + } +} + +.e-image-area { + background-color: $background-body; + height: 220px; + display: grid; + grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); + grid-template-rows: auto auto; + padding: 5px; + box-sizing: border-box; + width: 100%; + margin-bottom: 10px; + + .image { + height: 100px; + aspect-ratio: 16/9; + margin: auto; + display: flex; + + img { + height: 100%; + margin: auto; + } + } + + .image:nth-child(odd) { + grid-row: span 1; + grid-column: 1; + } + .image:nth-child(even) { + grid-row: span 1; + grid-column: 2; + } +} + +.e-content { + background-color: $background-body; + padding: 5px; + margin-bottom: 10px; + textarea { + font-size: 16px; + color: white; + } +} + +.e-settings { + height: 40px; + width: 100%; + background-color: $background-body; + display: flex; + flex-direction: row; + padding: 5px; + box-sizing: border-box; + .publish-date { + display: flex; + div { + margin: auto 10px auto auto; + } + input { + margin-right: 5px; + } + } + + input, + textarea { + width: 200px; + } +} + +input, +textarea { + width: 100%; + padding: 5px; + box-sizing: border-box; + margin: 0; + border: 0; + background-color: black; + color: white; + font-size: 18px; + resize: vertical; +} diff --git a/frontend/views/author.ejs b/frontend/views/author.ejs new file mode 100644 index 0000000..ff0d0d5 --- /dev/null +++ b/frontend/views/author.ejs @@ -0,0 +1,21 @@ + + + + + + + + + + <%= website_name %> | Author + + + <%- include("partials/header.ejs", {selected: 'home'}) %> + +
+ + <%- include("partials/footer.ejs") %> + + + + diff --git a/frontend/views/blogList.ejs b/frontend/views/blogList.ejs new file mode 100644 index 0000000..d1fbff7 --- /dev/null +++ b/frontend/views/blogList.ejs @@ -0,0 +1,24 @@ + + + + + + + + + + <%= website_name %> | Home + + + <%- include("partials/header.ejs", {selected: 'home'}) %> + +
+ <%- include("partials/blog-admin.ejs") %> <%- include("partials/blog-entry.ejs", {thumbnail: '/img/.dev/square.png', title: 'Title', description: + 'Description', author: 'Author'}) %> +
+ + <%- include("partials/footer.ejs") %> + + + + diff --git a/frontend/views/blogNew.ejs b/frontend/views/blogNew.ejs new file mode 100644 index 0000000..61b14e6 --- /dev/null +++ b/frontend/views/blogNew.ejs @@ -0,0 +1,48 @@ + + + + + + + + + <%= website_name %> | New Blog + + + <%- include("partials/header.ejs", {selected: 'home'}) %> + +
+
+
+ +
+
+ + +
+
+ +
+
+ +
+
+ +
+ +
+ +
+
+
Publish On
+ + +
+
+
+ + <%- include("partials/footer.ejs") %> + + + + diff --git a/frontend/views/index.ejs b/frontend/views/index.ejs index 7e27432..89f6e31 100644 --- a/frontend/views/index.ejs +++ b/frontend/views/index.ejs @@ -5,13 +5,16 @@ + <%= website_name %> | Home <%- include("partials/header.ejs", {selected: 'home'}) %> -
+
+ <%- include("partials/blog-entry.ejs", {thumbnail: '/img/.dev/square.png', title: 'Title', description: 'Description', author: 'Author'}) %> +
<%- include("partials/footer.ejs") %> diff --git a/frontend/views/partials/blog-admin.ejs b/frontend/views/partials/blog-admin.ejs new file mode 100644 index 0000000..7906d8f --- /dev/null +++ b/frontend/views/partials/blog-admin.ejs @@ -0,0 +1,5 @@ +
+
+ New Post +
+
diff --git a/frontend/views/partials/blog-entry.ejs b/frontend/views/partials/blog-entry.ejs new file mode 100644 index 0000000..8d24658 --- /dev/null +++ b/frontend/views/partials/blog-entry.ejs @@ -0,0 +1,9 @@ +
+ + + +
+ +
<%= description %>
+
+
diff --git a/yab.js b/yab.js index ebf2453..9ba8c24 100644 --- a/yab.js +++ b/yab.js @@ -43,7 +43,7 @@ app.post("/register", checkNotAuthenticated, page_scripts.registerPost); // Account Required Endpoints app.post("/setting", checkAuthenticated, page_scripts.settingPost); -// app.get("/blog/new", checkAuthenticated, page_scripts.blogNew); +app.get("/blog/new", checkAuthenticated, page_scripts.blogNew); // app.post("/blog", checkAuthenticated, page_scripts.postBlog); // app.delete("/logout", page_scripts.logout); @@ -52,8 +52,9 @@ app.post("/setting", checkAuthenticated, page_scripts.settingPost); // Endpoints app.get("/", page_scripts.index); +app.get("/author/:author_username", page_scripts.author); app.get("/admin", checkAuthenticated, page_scripts.admin); -// app.get("/blog", page_scripts.blogList); +app.get("/blog", page_scripts.blogList); // app.get("/blog/:id", page_scripts.blogSingle); // app.get("/projects", page_scripts.projectList);