From 1b9ea56423cce2d9bf67293943d0112e64f4bed0 Mon Sep 17 00:00:00 2001 From: Armored Dragon Date: Sat, 6 Apr 2024 17:46:16 -0500 Subject: [PATCH] Theme work Signed-off-by: Armored Dragon --- backend/core/core.js | 20 +- backend/page_scripts.js | 30 ++- frontend/public/css/login.css | 38 ++++ frontend/views/admin.ejs | 56 ----- frontend/views/author.ejs | 32 --- frontend/views/blogList.ejs | 33 --- frontend/views/blogSingle.ejs | 35 ---- frontend/views/index.ejs | 23 -- frontend/views/login.ejs | 2 +- .../views/partials/admin-setting-number.ejs | 15 -- .../views/partials/admin-setting-text.ejs | 15 -- .../views/partials/admin-setting-toggle.ejs | 13 -- frontend/views/partials/blog-admin.ejs | 5 - frontend/views/partials/footer.ejs | 0 frontend/views/partials/header.ejs | 21 -- frontend/views/partials/pagination.ejs | 29 --- frontend/views/themes/default/css/author.css | 52 +++++ frontend/views/themes/default/css/author.scss | 59 ++++++ frontend/views/themes/default/css/generic.css | 154 ++++++++++++++ .../views/themes/default/css/generic.scss | 161 ++++++++++++++ frontend/views/themes/default/css/index.css | 178 ++++++++++++++++ frontend/views/themes/default/css/index.scss | 196 ++++++++++++++++++ frontend/views/themes/default/css/login.css | 38 ++++ frontend/views/themes/default/css/login.scss | 44 ++++ frontend/views/themes/default/css/post.css | 22 ++ frontend/views/themes/default/css/post.scss | 25 +++ .../views/themes/default/css/settings.css | 102 +++++++++ .../views/themes/default/css/settings.scss | 105 ++++++++++ .../themes/default/ejs/admin-settings.ejs | 72 +++++++ frontend/views/themes/default/ejs/author.ejs | 33 +++ frontend/views/themes/default/ejs/index.ejs | 35 ++++ frontend/views/themes/default/ejs/login.ejs | 34 +++ .../themes/default/ejs/partials/footer.ejs | 11 + .../themes/default/ejs/partials/header.ejs | 23 ++ .../default/ejs/partials/pagination.ejs | 23 ++ .../themes/default/ejs/partials/post.ejs | 12 ++ frontend/views/themes/default/ejs/post.ejs | 19 ++ .../views/themes/default/ejs/postSearch.ejs | 37 ++++ .../views/themes/default/img/calendar.svg | 1 + .../views/themes/default/img/hourglass.svg | 1 + frontend/views/themes/default/img/json.svg | 1 + frontend/views/themes/default/img/news.svg | 1 + frontend/views/themes/default/img/rss.svg | 1 + frontend/views/themes/default/img/tag.svg | 1 + frontend/views/themes/default/js/admin.js | 24 +++ frontend/views/themes/default/js/generic.js | 15 ++ frontend/views/themes/default/js/login.js | 17 ++ .../views/themes/default/js/postSearch.js | 4 + frontend/views/themes/default/metadata.json | 14 ++ yab.js | 7 +- 50 files changed, 1589 insertions(+), 300 deletions(-) create mode 100644 frontend/public/css/login.css delete mode 100644 frontend/views/admin.ejs delete mode 100644 frontend/views/author.ejs delete mode 100644 frontend/views/blogList.ejs delete mode 100644 frontend/views/blogSingle.ejs delete mode 100644 frontend/views/index.ejs delete mode 100644 frontend/views/partials/admin-setting-number.ejs delete mode 100644 frontend/views/partials/admin-setting-text.ejs delete mode 100644 frontend/views/partials/admin-setting-toggle.ejs delete mode 100644 frontend/views/partials/blog-admin.ejs delete mode 100644 frontend/views/partials/footer.ejs delete mode 100644 frontend/views/partials/header.ejs delete mode 100644 frontend/views/partials/pagination.ejs create mode 100644 frontend/views/themes/default/css/author.css create mode 100644 frontend/views/themes/default/css/author.scss create mode 100644 frontend/views/themes/default/css/generic.css create mode 100644 frontend/views/themes/default/css/generic.scss create mode 100644 frontend/views/themes/default/css/index.css create mode 100644 frontend/views/themes/default/css/index.scss create mode 100644 frontend/views/themes/default/css/login.css create mode 100644 frontend/views/themes/default/css/login.scss create mode 100644 frontend/views/themes/default/css/post.css create mode 100644 frontend/views/themes/default/css/post.scss create mode 100644 frontend/views/themes/default/css/settings.css create mode 100644 frontend/views/themes/default/css/settings.scss create mode 100644 frontend/views/themes/default/ejs/admin-settings.ejs create mode 100644 frontend/views/themes/default/ejs/author.ejs create mode 100644 frontend/views/themes/default/ejs/index.ejs create mode 100644 frontend/views/themes/default/ejs/login.ejs create mode 100644 frontend/views/themes/default/ejs/partials/footer.ejs create mode 100644 frontend/views/themes/default/ejs/partials/header.ejs create mode 100644 frontend/views/themes/default/ejs/partials/pagination.ejs create mode 100644 frontend/views/themes/default/ejs/partials/post.ejs create mode 100644 frontend/views/themes/default/ejs/post.ejs create mode 100644 frontend/views/themes/default/ejs/postSearch.ejs create mode 100644 frontend/views/themes/default/img/calendar.svg create mode 100644 frontend/views/themes/default/img/hourglass.svg create mode 100644 frontend/views/themes/default/img/json.svg create mode 100644 frontend/views/themes/default/img/news.svg create mode 100644 frontend/views/themes/default/img/rss.svg create mode 100644 frontend/views/themes/default/img/tag.svg create mode 100644 frontend/views/themes/default/js/admin.js create mode 100644 frontend/views/themes/default/js/generic.js create mode 100644 frontend/views/themes/default/js/login.js create mode 100644 frontend/views/themes/default/js/postSearch.js create mode 100644 frontend/views/themes/default/metadata.json diff --git a/backend/core/core.js b/backend/core/core.js index 459272e..501d116 100644 --- a/backend/core/core.js +++ b/backend/core/core.js @@ -21,23 +21,19 @@ let settings = { HIDE_LOGIN: false, BLOG_UPLOADING: false, - CD_RSS: false, - CD_AP: false, + CD_RSS: true, + CD_JSON: true, WEBSITE_NAME: "", PLAUSIBLE_URL: "", USER_MINIMUM_PASSWORD_LENGTH: 7, - BLOG_MINIMUM_TITLE_LENGTH: 7, - BLOG_MINIMUM_DESCRIPTION_LENGTH: 7, - BLOG_MINIMUM_CONTENT_LENGTH: 7, + theme: "default", }; let use_s3_storage = false; -let groups = []; _initS3Storage(); _getSettings(); -_getGroups(); // Checks to see if S3 storage is set function _initS3Storage() { @@ -505,14 +501,16 @@ async function postSetting(key, value) { if (!Object.keys(settings).includes(key)) return { success: false, message: "Setting not valid" }; await prisma.setting.upsert({ where: { id: key }, update: { value: value }, create: { id: key, value: value } }); - settings[key] = JSON.parse(value); + try { + settings[key] = JSON.parse(value); + } catch { + settings[key] = value; + } return { success: true }; } catch (e) { return { success: false, message: e.message }; } } -async function _getGroups() { - const group_list = await prisma.group.findMany(); -} + module.exports = { settings, registerUser, getUser, getAuthorPage, postBlog, updateBlog, getBlog, deleteBlog, deleteImage, postSetting, getSetting }; diff --git a/backend/page_scripts.js b/backend/page_scripts.js index ecd7216..ae075e0 100644 --- a/backend/page_scripts.js +++ b/backend/page_scripts.js @@ -1,6 +1,10 @@ const external = require("./core/external_api"); const core = require("./core/core"); +function getThemePage(page_name) { + return `themes/${core.settings.theme}/ejs/${page_name}.ejs`; +} + function getDefaults(req) { // TODO: Fix reference to website_name return { logged_in_user: req.session.user, website_name: core.settings.WEBSITE_NAME || "Yet-Another-Blog", settings: core.settings }; @@ -8,27 +12,35 @@ function getDefaults(req) { async function index(request, response) { // Check if the master admin has been created - const is_setup_complete = core.settings["SETUP_COMPLETE"]; - if (!is_setup_complete) return response.redirect("/register"); + // const is_setup_complete = core.settings["SETUP_COMPLETE"]; + // if (!is_setup_complete) return response.redirect("/register"); - response.redirect("/blog"); + const blog_list = await core.getBlog({ owner_id: request.session.user?.id, page: request.query.page || 0 }); + response.render(getThemePage("index"), { + ...getDefaults(request), + blog_list: blog_list.data, + pagination: blog_list.pagination, + current_page: request.query.page || 0, + loaded_page: request.path, + }); } function register(request, response) { response.render("register.ejs", getDefaults(request)); } function login(request, response) { - response.render("login.ejs", getDefaults(request)); + response.render(getThemePage("login"), getDefaults(request)); } async function author(req, res) { const user = await core.getUser({ id: req.params.author_id }); // FIXME: Bandage fix for author get error if (!user.success) return res.redirect("/"); const profile = await core.getAuthorPage({ author_id: user.data.id }); - res.render("author.ejs", { ...getDefaults(req), blog_post: profile.data }); + console.log(profile.data); + res.render(getThemePage("author"), { ...getDefaults(req), post: profile.data }); } async function blogList(req, res) { const blog_list = await core.getBlog({ owner_id: req.session.user?.id, page: req.query.page || 0, search: req.query.search, search_tags: true, search_title: true }); - res.render("blogList.ejs", { + res.render(getThemePage("postSearch"), { ...getDefaults(req), blog_list: blog_list.data, pagination: blog_list.pagination, @@ -38,8 +50,8 @@ async function blogList(req, res) { } async function blogSingle(req, res) { const blog = await core.getBlog({ id: req.params.blog_id }); - if (blog.success === false) return res.redirect("/blog"); - res.render("blogSingle.ejs", { ...getDefaults(req), blog_post: blog.data }); + if (blog.success === false) return res.redirect("/"); + res.render(getThemePage("post"), { ...getDefaults(req), blog_post: blog.data }); } function blogNew(request, response) { // TODO: Turn date formatting into function @@ -69,7 +81,7 @@ async function blogEdit(req, res) { res.render("blogNew.ejs", { ...getDefaults(req), existing_blog: existing_blog }); } async function admin(request, response) { - response.render("admin.ejs", { ...getDefaults(request) }); + response.render(getThemePage("admin-settings"), { ...getDefaults(request) }); } async function atom(req, res) { res.type("application/xml"); diff --git a/frontend/public/css/login.css b/frontend/public/css/login.css new file mode 100644 index 0000000..9dcc99d --- /dev/null +++ b/frontend/public/css/login.css @@ -0,0 +1,38 @@ +.page .page-center { + margin-top: 2rem; +} +.page .page-center .page-modal { + width: 400px; + height: 200px; + background-color: white; + margin: auto; + padding: 1rem; + box-sizing: border-box; +} +.page .page-center .page-modal .title { + font-size: 1.4rem; + text-align: center; +} +.page .page-center .page-modal .login-part { + width: 100%; + margin-bottom: 1rem; +} +.page .page-center .page-modal .login-part input { + width: 100%; + padding: 0.25rem; + box-sizing: border-box; +} +.page .page-center .page-modal .action-container { + display: flex; + flex-direction: row-reverse; +} +.page .page-center .page-modal .action-container button { + width: 100px; + padding: 0.25rem; + box-sizing: border-box; + margin-left: auto; + height: 30px; +} +.page .page-center .page-modal .action-container a { + margin: auto auto auto 0; +} \ No newline at end of file diff --git a/frontend/views/admin.ejs b/frontend/views/admin.ejs deleted file mode 100644 index ff02d16..0000000 --- a/frontend/views/admin.ejs +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - <%= website_name %> | Administration - - - <%- include("partials/header.ejs", {selected: 'home'}) %> - -
-
-
- - - - -
-
- - <%- include("partials/admin-setting-toggle.ejs", {setting: {name: 'ACCOUNT_REGISTRATION', name_pretty: 'Account registration', enabled: - settings.ACCOUNT_REGISTRATION}}) %> - - <%- include("partials/admin-setting-toggle.ejs", {setting: {name: 'HIDE_LOGIN', name_pretty: 'Hide Login', enabled: settings.HIDE_LOGIN}}) %> - - <%- include("partials/admin-setting-number.ejs", {setting: {name:'USER_MINIMUM_PASSWORD_LENGTH', name_pretty: 'Minimum Password Length', value: - settings.USER_MINIMUM_PASSWORD_LENGTH}}) %> -
- - - - - -
-
- - <%- include("partials/footer.ejs") %> - - - - diff --git a/frontend/views/author.ejs b/frontend/views/author.ejs deleted file mode 100644 index e423cca..0000000 --- a/frontend/views/author.ejs +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - <%= website_name %> | <%= blog_post.title %> - - - <%- include("partials/header.ejs", {selected: 'home'}) %> - -
- <%if(logged_in_user) {%> -
- -
- - <%}%> -
<%= blog_post.title%>
- - <%- blog_post.content %> -
- - <%- include("partials/footer.ejs") %> - - - - diff --git a/frontend/views/blogList.ejs b/frontend/views/blogList.ejs deleted file mode 100644 index 97b2379..0000000 --- a/frontend/views/blogList.ejs +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - <%= website_name %> | Home - - - <%- include("partials/header.ejs", {selected: 'home'}) %> - -
- <%if(logged_in_user) {%> <%- include("partials/blog-admin.ejs") %> <%}%> - -
- -
- - <% for(post of blog_list) { %> - - <%- include("partials/blog-entry.ejs", {post:post}) %> - - <% } %> <%- include("partials/pagination.ejs") %> -
- - <%- include("partials/footer.ejs") %> - - - - diff --git a/frontend/views/blogSingle.ejs b/frontend/views/blogSingle.ejs deleted file mode 100644 index d458b3f..0000000 --- a/frontend/views/blogSingle.ejs +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - <%= website_name %> | <%= blog_post.title %> - - - <%- include("partials/header.ejs", {selected: 'home'}) %> - -
- - - <%if(logged_in_user) {%> - - - <%}%> -
<%= blog_post.title%>
- - <%- blog_post.content %> -
- - <%- include("partials/footer.ejs") %> - - - - diff --git a/frontend/views/index.ejs b/frontend/views/index.ejs deleted file mode 100644 index 89f6e31..0000000 --- a/frontend/views/index.ejs +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - <%= 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/login.ejs b/frontend/views/login.ejs index 3236416..26b6b1a 100644 --- a/frontend/views/login.ejs +++ b/frontend/views/login.ejs @@ -32,5 +32,5 @@ <%- include("partials/footer.ejs") %> - + diff --git a/frontend/views/partials/admin-setting-number.ejs b/frontend/views/partials/admin-setting-number.ejs deleted file mode 100644 index 7002e4f..0000000 --- a/frontend/views/partials/admin-setting-number.ejs +++ /dev/null @@ -1,15 +0,0 @@ -
-
<%=setting.name_pretty%>
-
- - -
-
diff --git a/frontend/views/partials/admin-setting-text.ejs b/frontend/views/partials/admin-setting-text.ejs deleted file mode 100644 index 989e806..0000000 --- a/frontend/views/partials/admin-setting-text.ejs +++ /dev/null @@ -1,15 +0,0 @@ -
-
<%=setting.name_pretty%>
-
- - -
-
diff --git a/frontend/views/partials/admin-setting-toggle.ejs b/frontend/views/partials/admin-setting-toggle.ejs deleted file mode 100644 index d9def8f..0000000 --- a/frontend/views/partials/admin-setting-toggle.ejs +++ /dev/null @@ -1,13 +0,0 @@ -
-
<%=setting.name_pretty%>
-
- - <% if (!setting.enabled) { %> - - <% } else { %> - - <%}%> -
-
diff --git a/frontend/views/partials/blog-admin.ejs b/frontend/views/partials/blog-admin.ejs deleted file mode 100644 index 405a0de..0000000 --- a/frontend/views/partials/blog-admin.ejs +++ /dev/null @@ -1,5 +0,0 @@ -
-
- New Post -
-
diff --git a/frontend/views/partials/footer.ejs b/frontend/views/partials/footer.ejs deleted file mode 100644 index e69de29..0000000 diff --git a/frontend/views/partials/header.ejs b/frontend/views/partials/header.ejs deleted file mode 100644 index 8199ca9..0000000 --- a/frontend/views/partials/header.ejs +++ /dev/null @@ -1,21 +0,0 @@ -
- -
- -
Blog
-
- <% if (logged_in_user) { %> - -
Profile
-
- <% } else {%> <% if(!settings.HIDE_LOGIN) {%> - -
Login
-
- <% } %> <% } %> -
-
diff --git a/frontend/views/partials/pagination.ejs b/frontend/views/partials/pagination.ejs deleted file mode 100644 index 86d8f3d..0000000 --- a/frontend/views/partials/pagination.ejs +++ /dev/null @@ -1,29 +0,0 @@ - diff --git a/frontend/views/themes/default/css/author.css b/frontend/views/themes/default/css/author.css new file mode 100644 index 0000000..6307c3d --- /dev/null +++ b/frontend/views/themes/default/css/author.css @@ -0,0 +1,52 @@ +.page .page-center { + display: flex; + flex-direction: row; + min-height: 50px; + margin-top: 4rem; +} +.page .page-center .biography { + width: 66.6666666667%; + background-color: white; + min-height: 50px; + box-shadow: rgba(0, 0, 0, 0.1098039216) 0 0px 5px; + padding: 1rem; + box-sizing: border-box; +} +.page .page-center .about { + width: 33.3333333333%; + background-color: white; + min-height: 50px; + margin: 0 1rem; + padding: 1rem; + box-sizing: border-box; + box-shadow: rgba(0, 0, 0, 0.1098039216) 0 0px 5px; +} +.page .page-center .about .profile-picture { + margin: auto auto 1.5rem auto; + display: flex; +} +.page .page-center .about .profile-picture img { + margin: auto; + max-height: 200px; + max-width: 200px; +} +.page .page-center .about .displayname { + font-size: 1.4rem; + text-align: center; +} +.page .page-center .about .stat { + color: gray; + font-size: 1rem; + text-align: center; + margin-top: 0.5rem; +} +.page .page-center .about .sociallist { + display: grid; + grid-template-columns: 1fr 1fr; + grid-template-rows: 3rem; +} +.page .page-center .about .sociallist .link { + text-decoration: none; + color: black; + margin: auto; +} \ No newline at end of file diff --git a/frontend/views/themes/default/css/author.scss b/frontend/views/themes/default/css/author.scss new file mode 100644 index 0000000..0264b3d --- /dev/null +++ b/frontend/views/themes/default/css/author.scss @@ -0,0 +1,59 @@ +.page .page-center { + display: flex; + flex-direction: row; + min-height: 50px; + margin-top: 4rem; + + .biography { + width: calc(100% * (2 / 3)); + background-color: white; + min-height: 50px; + box-shadow: #0000001c 0 0px 5px; + padding: 1rem; + box-sizing: border-box; + } + .about { + width: calc(100% * (1 / 3)); + background-color: white; + min-height: 50px; + margin: 0 1rem; + padding: 1rem; + box-sizing: border-box; + box-shadow: #0000001c 0 0px 5px; + + .profile-picture { + margin: auto auto 1.5rem auto; + display: flex; + + img { + margin: auto; + max-height: 200px; + max-width: 200px; + } + } + + .displayname { + font-size: 1.4rem; + text-align: center; + } + + .stat { + color: gray; + font-size: 1rem; + text-align: center; + margin-top: 0.5rem; + } + + .sociallist { + display: grid; + grid-template-columns: 1fr 1fr; + grid-template-rows: 3rem; + + .link { + text-decoration: none; + color: black; + margin: auto; + } + } + } +} diff --git a/frontend/views/themes/default/css/generic.css b/frontend/views/themes/default/css/generic.css new file mode 100644 index 0000000..74d5564 --- /dev/null +++ b/frontend/views/themes/default/css/generic.css @@ -0,0 +1,154 @@ +body { + background-color: #f9fafc; + margin: 0; + font-family: Verdana, Geneva, Tahoma, sans-serif; +} + +.header { + width: 100%; + height: 50px; + color: black; +} +.header .page-center { + display: flex; + flex-direction: row; + height: 100%; +} +.header .logo { + display: flex; + height: 100%; + width: -moz-fit-content; + width: fit-content; + color: black; + text-decoration: none; +} +.header .logo .logo-icon { + height: 100%; + aspect-ratio: 1/1; +} +.header .logo .logo-icon::before { + background-image: url("../img/news.svg"); + width: 30px; + height: 30px; +} +.header .logo .logo-title { + font-size: 2rem; + text-align: center; + margin: auto; +} +.header .navigation { + margin: 0 0 0 auto; + height: 100%; + display: flex; + flex-direction: row; +} +.header .navigation a { + height: 100%; + display: flex; + flex-direction: row; + padding: 1rem; + box-sizing: border-box; + color: black; + text-decoration: none; +} +.header .navigation a span { + margin: auto; +} + +.page-center { + width: 1080px; + max-width: 1080px; + margin: 0 auto; + display: flex; + flex-direction: column; +} + +.page { + min-height: 700px; +} + +.button { + background-color: #0072ff; + border-radius: 5px; + color: white; + min-width: 130px; + border: transparent; + transition: filter ease-in-out 0.1s; +} + +.button:hover { + cursor: pointer; + filter: brightness(80%); +} + +.button.bad { + background-color: #e70404; +} + +.button.disabled { + filter: contrast(50%); + filter: brightness(50%); + cursor: default; +} + +.atom-feed::before { + background-image: url("/img/rss.svg"); +} + +.json::before { + background-image: url("/img/json.svg"); +} + +.footer .page-center { + display: flex; + flex-direction: row; + text-align: center; + margin-top: 2rem; +} +.footer .page-center * { + width: -moz-fit-content; + width: fit-content; + margin: auto; +} +.footer .page-center * a { + margin-bottom: 0.5rem; + color: black; + text-decoration: none; +} +.footer .page-center .resources { + display: flex; + flex-direction: column; + width: 33.3333333333%; +} +.footer .page-center .info { + display: flex; + flex-direction: column; + width: 33.3333333333%; +} + +.icon { + display: flex; +} + +.icon::before { + content: ""; + display: inline-block; + width: 20px; + height: 20px; + background-size: contain; + margin: auto 5px auto auto; +} + +@media screen and (max-width: 1280px) { + .page-center { + width: 95%; + } +} +@media screen and (max-width: 760px) { + .post-list-container .post-list { + width: 100%; + } + .tag-list { + display: none; + } +} \ No newline at end of file diff --git a/frontend/views/themes/default/css/generic.scss b/frontend/views/themes/default/css/generic.scss new file mode 100644 index 0000000..b0cafab --- /dev/null +++ b/frontend/views/themes/default/css/generic.scss @@ -0,0 +1,161 @@ +body { + background-color: #f9fafc; + margin: 0; + font-family: Verdana, Geneva, Tahoma, sans-serif; +} + +.header { + width: 100%; + height: 50px; + color: black; + + .page-center { + display: flex; + flex-direction: row; + height: 100%; + } + + .logo { + display: flex; + height: 100%; + width: fit-content; + color: black; + text-decoration: none; + + .logo-icon { + height: 100%; + aspect-ratio: 1/1; + } + + .logo-icon::before { + background-image: url("../img/news.svg"); + width: 30px; + height: 30px; + } + + .logo-title { + font-size: 2rem; + text-align: center; + margin: auto; + } + } + + .navigation { + margin: 0 0 0 auto; + height: 100%; + display: flex; + flex-direction: row; + + a { + height: 100%; + display: flex; + flex-direction: row; + padding: 1rem; + box-sizing: border-box; + color: black; + text-decoration: none; + + span { + margin: auto; + } + } + } +} + +.page-center { + width: 1080px; + max-width: 1080px; + margin: 0 auto; + display: flex; + flex-direction: column; +} + +.page { + min-height: 700px; +} + +.button { + background-color: #0072ff; + border-radius: 5px; + color: white; + min-width: 130px; + border: transparent; + transition: filter ease-in-out 0.1s; +} +.button:hover { + cursor: pointer; + filter: brightness(80%); +} +.button.bad { + background-color: #e70404; +} +.button.disabled { + filter: contrast(50%); + filter: brightness(50%); + cursor: default; +} + +.atom-feed::before { + background-image: url("/img/rss.svg"); +} +.json::before { + background-image: url("/img/json.svg"); +} + +.footer { + .page-center { + display: flex; + flex-direction: row; + text-align: center; + margin-top: 2rem; + + * { + width: fit-content; + margin: auto; + a { + margin-bottom: 0.5rem; + color: black; + text-decoration: none; + } + } + + .resources { + display: flex; + flex-direction: column; + width: calc(100% * (1 / 3)); + } + + .info { + display: flex; + flex-direction: column; + width: calc(100% * (1 / 3)); + } + } +} + +.icon { + display: flex; +} +.icon::before { + content: ""; + display: inline-block; + width: 20px; + height: 20px; + background-size: contain; + margin: auto 5px auto auto; +} + +@media screen and (max-width: 1280px) { + .page-center { + width: 95%; + } +} + +@media screen and (max-width: 760px) { + .post-list-container .post-list { + width: 100%; + } + .tag-list { + display: none; + } +} diff --git a/frontend/views/themes/default/css/index.css b/frontend/views/themes/default/css/index.css new file mode 100644 index 0000000..6e6f309 --- /dev/null +++ b/frontend/views/themes/default/css/index.css @@ -0,0 +1,178 @@ +.post-list-container { + margin-top: 2rem; + display: flex; + flex-direction: row; +} +.post-list-container .post-list { + width: 66.6666666667%; + min-height: 200px; +} +.post-list-container .post-list .post { + width: 100%; + background-color: #fff; + border-radius: 10px; + box-shadow: rgba(0, 0, 0, 0.1098039216) 0 0px 5px; + min-height: 200px; + padding: 0.5rem 1rem; + box-sizing: border-box; + display: flex; + flex-direction: column; + margin-bottom: 1rem; +} +.post-list-container .post-list .post .title { + font-size: 2rem; + font-weight: 550; + margin-bottom: 0.5rem; + text-decoration: none; + color: black; +} +.post-list-container .post-list .post .authors { + margin-bottom: 1.5rem; +} +.post-list-container .post-list .post .authors a { + color: black; +} +.post-list-container .post-list .post .description { + margin-bottom: 1rem; +} +.post-list-container .post-list .post .badges { + margin-top: auto; + color: #414141; +} +.post-list-container .post-list .post .badges .tags { + display: flex; + flex-direction: row; + margin-bottom: 0.5rem; +} +.post-list-container .post-list .post .badges .info { + display: flex; + flex-direction: row; +} +.post-list-container .post-list .post .badges .info .info-blip { + margin-right: 1rem; +} +.post-list-container .post-list .post .badges .info .publish-date::before { + background-image: url("../img/calendar.svg"); /* Set the background image */ +} +.post-list-container .post-list .post .badges .info .reading-time::before { + background-image: url("../img/hourglass.svg"); /* Set the background image */ +} +.post-list-container .post-list .post .badges .info .word-count::before { + background-image: url("https://www.svgrepo.com/show/2460/cherry.svg"); /* Set the background image */ +} +.post-list-container .post-list.full { + width: 100%; +} +.post-list-container .tag-list { + width: 33.3333333333%; + max-width: 33.3333333333%; + min-height: 200px; + padding: 0 2rem; + box-sizing: border-box; +} +.post-list-container .tag-list .tag-header { + font-size: 1.2rem; + margin-bottom: 2rem; +} +.post-list-container .tag-list .list { + display: flex; + flex-direction: row; + overflow-wrap: break-word; + flex-wrap: wrap; + width: 100%; +} +.post-list-container .tag-list .list .tag { + height: -moz-fit-content; + height: fit-content; + background-color: lightgray; + margin-bottom: 0.1rem; +} +.post-list-container .tag-list .list .tag::before { + display: none; +} + +.tag { + width: -moz-fit-content; + width: fit-content; + margin-right: 0.1rem; + padding: 0.2rem 0.3rem; + box-sizing: border-box; + border-radius: 4px; +} + +.tag::before { + background-image: url("../img/tag.svg"); /* Set the background image */ +} + +.pagination { + margin-top: auto; + width: 100%; + display: flex; + flex-direction: row; + height: 40px; +} +.pagination .left { + margin-right: 1rem; +} +.pagination .pages { + height: 100%; + margin: auto; + display: flex; + flex-direction: row; +} +.pagination .pages a { + display: flex; + height: 100%; + aspect-ratio: 1/1; + color: black; + text-decoration: none; +} +.pagination .pages a span { + margin: auto; +} +.pagination .pages a.active { + background-color: lightskyblue; + border-radius: 5px; +} +.pagination .right { + margin-left: 1rem; +} +.pagination .left, +.pagination .right { + padding: 0.75rem 1rem; + box-sizing: border-box; + text-decoration: none; + display: flex; +} +.pagination .left span, +.pagination .right span { + margin: auto; +} + +.page { + display: flex; +} + +.search { + margin-top: 2rem; + width: 100%; + height: 3rem; + box-sizing: border-box; +} +.search .title { + font-size: 1.2rem; + font-style: italic; +} +.search .action { + display: flex; + flex-direction: row; +} +.search .action input { + padding: 0.5rem; + box-sizing: border-box; + width: 100%; +} +.search .action button { + margin-left: 1rem; + width: 200px; +} \ No newline at end of file diff --git a/frontend/views/themes/default/css/index.scss b/frontend/views/themes/default/css/index.scss new file mode 100644 index 0000000..5b6e23a --- /dev/null +++ b/frontend/views/themes/default/css/index.scss @@ -0,0 +1,196 @@ +.post-list-container { + margin-top: 2rem; + display: flex; + flex-direction: row; + + .post-list { + width: calc(100% * (2 / 3)); + min-height: 200px; + + .post { + width: 100%; + background-color: #fff; + border-radius: 10px; + box-shadow: #0000001c 0 0px 5px; + min-height: 200px; + padding: 0.5rem 1rem; + box-sizing: border-box; + display: flex; + flex-direction: column; + margin-bottom: 1rem; + + .title { + font-size: 2rem; + font-weight: 550; + margin-bottom: 0.5rem; + text-decoration: none; + color: black; + } + + .authors { + margin-bottom: 1.5rem; + + a { + color: black; + } + } + + .description { + margin-bottom: 1rem; + } + + .badges { + margin-top: auto; + color: #414141; + .tags { + display: flex; + flex-direction: row; + margin-bottom: 0.5rem; + .tag { + } + } + .info { + display: flex; + flex-direction: row; + + .info-blip { + margin-right: 1rem; + } + + .publish-date::before { + background-image: url("../img/calendar.svg"); /* Set the background image */ + } + .reading-time::before { + background-image: url("../img/hourglass.svg"); /* Set the background image */ + } + + .word-count::before { + background-image: url("https://www.svgrepo.com/show/2460/cherry.svg"); /* Set the background image */ + } + } + } + } + } + .post-list.full { + width: 100%; + } + .tag-list { + width: calc(100% * (1 / 3)); + max-width: calc(100% * (1 / 3)); + min-height: 200px; + padding: 0 2rem; + box-sizing: border-box; + + .tag-header { + font-size: 1.2rem; + margin-bottom: 2rem; + } + + .list { + display: flex; + flex-direction: row; + overflow-wrap: break-word; + flex-wrap: wrap; + width: 100%; + .tag { + height: fit-content; + background-color: lightgray; + margin-bottom: 0.1rem; + } + + .tag::before { + display: none; + } + } + } +} + +.tag { + width: fit-content; + margin-right: 0.1rem; + padding: 0.2rem 0.3rem; + box-sizing: border-box; + border-radius: 4px; +} + +.tag::before { + background-image: url("../img/tag.svg"); /* Set the background image */ +} + +.pagination { + margin-top: auto; + width: 100%; + display: flex; + flex-direction: row; + height: 40px; + + .left { + margin-right: 1rem; + } + .pages { + height: 100%; + margin: auto; + display: flex; + flex-direction: row; + + a { + display: flex; + height: 100%; + aspect-ratio: 1/1; + color: black; + text-decoration: none; + + span { + margin: auto; + } + } + + a.active { + background-color: lightskyblue; + border-radius: 5px; + } + } + .right { + margin-left: 1rem; + } + .left, + .right { + padding: 0.75rem 1rem; + box-sizing: border-box; + text-decoration: none; + display: flex; + span { + margin: auto; + } + } +} + +.page { + display: flex; +} +.search { + margin-top: 2rem; + width: 100%; + height: 3rem; + box-sizing: border-box; + + .title { + font-size: 1.2rem; + font-style: italic; + } + + .action { + display: flex; + flex-direction: row; + + input { + padding: 0.5rem; + box-sizing: border-box; + width: 100%; + } + button { + margin-left: 1rem; + width: 200px; + } + } +} diff --git a/frontend/views/themes/default/css/login.css b/frontend/views/themes/default/css/login.css new file mode 100644 index 0000000..9dcc99d --- /dev/null +++ b/frontend/views/themes/default/css/login.css @@ -0,0 +1,38 @@ +.page .page-center { + margin-top: 2rem; +} +.page .page-center .page-modal { + width: 400px; + height: 200px; + background-color: white; + margin: auto; + padding: 1rem; + box-sizing: border-box; +} +.page .page-center .page-modal .title { + font-size: 1.4rem; + text-align: center; +} +.page .page-center .page-modal .login-part { + width: 100%; + margin-bottom: 1rem; +} +.page .page-center .page-modal .login-part input { + width: 100%; + padding: 0.25rem; + box-sizing: border-box; +} +.page .page-center .page-modal .action-container { + display: flex; + flex-direction: row-reverse; +} +.page .page-center .page-modal .action-container button { + width: 100px; + padding: 0.25rem; + box-sizing: border-box; + margin-left: auto; + height: 30px; +} +.page .page-center .page-modal .action-container a { + margin: auto auto auto 0; +} \ No newline at end of file diff --git a/frontend/views/themes/default/css/login.scss b/frontend/views/themes/default/css/login.scss new file mode 100644 index 0000000..2814f87 --- /dev/null +++ b/frontend/views/themes/default/css/login.scss @@ -0,0 +1,44 @@ +.page .page-center { + margin-top: 2rem; + + .page-modal { + width: 400px; + height: 200px; + background-color: white; + margin: auto; + padding: 1rem; + box-sizing: border-box; + + .title { + font-size: 1.4rem; + text-align: center; + } + + .login-part { + width: 100%; + margin-bottom: 1rem; + + input { + width: 100%; + padding: 0.25rem; + box-sizing: border-box; + } + } + + .action-container { + display: flex; + flex-direction: row-reverse; + + button { + width: 100px; + padding: 0.25rem; + box-sizing: border-box; + margin-left: auto; + height: 30px; + } + a { + margin: auto auto auto 0; + } + } + } +} diff --git a/frontend/views/themes/default/css/post.css b/frontend/views/themes/default/css/post.css new file mode 100644 index 0000000..9399d19 --- /dev/null +++ b/frontend/views/themes/default/css/post.css @@ -0,0 +1,22 @@ +.page .page-center { + background-color: white; + min-height: 100px; + box-shadow: rgba(0, 0, 0, 0.1098039216) 0 0px 5px; + margin-top: 2rem; + padding: 1rem; + box-sizing: border-box; + width: 1080px; + max-width: 1080px; + flex-direction: column; + border-radius: 5px; +} +.page .page-center .title { + font-size: 2rem; + font-weight: bold; +} +.page .page-center .image-container { + max-width: 100%; +} +.page .page-center .image-container img { + max-width: 100%; +} \ No newline at end of file diff --git a/frontend/views/themes/default/css/post.scss b/frontend/views/themes/default/css/post.scss new file mode 100644 index 0000000..a7f1557 --- /dev/null +++ b/frontend/views/themes/default/css/post.scss @@ -0,0 +1,25 @@ +.page .page-center { + background-color: white; + min-height: 100px; + box-shadow: #0000001c 0 0px 5px; + margin-top: 2rem; + padding: 1rem; + box-sizing: border-box; + width: 1080px; + max-width: 1080px; + flex-direction: column; + border-radius: 5px; + + .title { + font-size: 2rem; + font-weight: bold; + } + + .image-container { + max-width: 100%; + + img { + max-width: 100%; + } + } +} diff --git a/frontend/views/themes/default/css/settings.css b/frontend/views/themes/default/css/settings.css new file mode 100644 index 0000000..0bd99b9 --- /dev/null +++ b/frontend/views/themes/default/css/settings.css @@ -0,0 +1,102 @@ +.page .page-center { + background-color: white; + width: 700px; + min-height: 50px; + margin-top: 4rem; + padding: 1rem; + box-sizing: border-box; + box-shadow: rgba(0, 0, 0, 0.1098039216) 0 0px 5px; +} +.page .page-center .header { + text-align: center; + font-size: 1.5rem; +} +.page .page-center .setting-list { + display: flex; + flex-direction: column; +} +.page .page-center .setting-list .setting { + width: 100%; + height: 32px; + background-color: rgb(240, 240, 240); + padding: 0.1rem; + box-sizing: border-box; + display: flex; + flex-direction: row; +} +.page .page-center .setting-list .setting .title { + margin: auto auto auto 0; +} +.page .page-center .setting-list .setting .value { + margin: 0 0 0 auto; + display: flex; +} +.page .page-center .setting-list .setting .value input[type=text] { + margin: auto; + font-size: 1rem; + text-align: center; +} +.page .page-center .setting-list .setting .value input[type=number] { + margin: auto; + width: 4rem; + text-align: right; + font-size: 1rem; +} +.page .page-center .setting-list .setting:nth-child(even) { + background-color: rgb(250, 250, 250); +} + +.switch { + position: relative; + display: inline-block; + width: 50px; + height: 28px; +} + +.switch input { + opacity: 0; + width: 0; + height: 0; +} + +.slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #b8b8b8; + transition: 0.4s; +} + +.slider:before { + position: absolute; + content: ""; + height: 20px; + width: 20px; + left: 4px; + bottom: 4px; + background-color: white; + transition: 0.4s; +} + +input:checked + .slider { + background-color: #2196f3; +} + +input:focus + .slider { + box-shadow: 0 0 1px #2196f3; +} + +input:checked + .slider:before { + transform: translateX(20px); +} + +.slider.round { + border-radius: 34px; +} + +.slider.round:before { + border-radius: 50%; +} \ No newline at end of file diff --git a/frontend/views/themes/default/css/settings.scss b/frontend/views/themes/default/css/settings.scss new file mode 100644 index 0000000..0f09d3c --- /dev/null +++ b/frontend/views/themes/default/css/settings.scss @@ -0,0 +1,105 @@ +.page .page-center { + background-color: white; + width: 700px; + min-height: 50px; + margin-top: 4rem; + padding: 1rem; + box-sizing: border-box; + box-shadow: #0000001c 0 0px 5px; + + .header { + text-align: center; + font-size: 1.5rem; + } + + .setting-list { + display: flex; + flex-direction: column; + + .setting { + width: 100%; + height: 32px; + background-color: rgb(240, 240, 240); + padding: 0.1rem; + box-sizing: border-box; + display: flex; + flex-direction: row; + + .title { + margin: auto auto auto 0; + } + + .value { + margin: 0 0 0 auto; + display: flex; + + input[type="text"] { + margin: auto; + font-size: 1rem; + text-align: center; + } + input[type="number"] { + margin: auto; + width: 4rem; + text-align: right; + font-size: 1rem; + } + } + } + + .setting:nth-child(even) { + background-color: rgb(250, 250, 250); + } + } +} + +.switch { + position: relative; + display: inline-block; + width: 50px; + height: 28px; +} +.switch input { + opacity: 0; + width: 0; + height: 0; +} +.slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #b8b8b8; + -webkit-transition: 0.4s; + transition: 0.4s; +} +.slider:before { + position: absolute; + content: ""; + height: 20px; + width: 20px; + left: 4px; + bottom: 4px; + background-color: white; + -webkit-transition: 0.4s; + transition: 0.4s; +} +input:checked + .slider { + background-color: #2196f3; +} +input:focus + .slider { + box-shadow: 0 0 1px #2196f3; +} +input:checked + .slider:before { + -webkit-transform: translateX(20px); + -ms-transform: translateX(20px); + transform: translateX(20px); +} +.slider.round { + border-radius: 34px; +} +.slider.round:before { + border-radius: 50%; +} diff --git a/frontend/views/themes/default/ejs/admin-settings.ejs b/frontend/views/themes/default/ejs/admin-settings.ejs new file mode 100644 index 0000000..d545034 --- /dev/null +++ b/frontend/views/themes/default/ejs/admin-settings.ejs @@ -0,0 +1,72 @@ + + + + + + + + Yet-Another-Blog + + + <%- include("partials/header.ejs") %> +
+
+
<%= website_name %> Admin Settings
+
+
+
User registration
+
+ +
+
+
+
Hide "Login" in navigation bar
+
+ +
+
+
+
Serve ATOM feed
+
+ +
+
+
+
Serve JSON feed
+
+ +
+
+
+
Password minimum length
+
+ +
+
+
+
Website Name
+
+ +
+
+
+
+
+ + <%- include("partials/footer.ejs") %> + + + + diff --git a/frontend/views/themes/default/ejs/author.ejs b/frontend/views/themes/default/ejs/author.ejs new file mode 100644 index 0000000..4ca46a3 --- /dev/null +++ b/frontend/views/themes/default/ejs/author.ejs @@ -0,0 +1,33 @@ + + + + + + + Yet-Another-Blog + + + <%- include("partials/header.ejs") %> + +
+
+
+
<%= post.title %>
+ + <%- post.content %> +
+
+
+
DISPLAYNAME
+
Registered REGISTRATIONDATE
+
NUMPOSTS Posts
+
+ Matrix +
+
+
+
+ + <%- include("partials/footer.ejs") %> + + diff --git a/frontend/views/themes/default/ejs/index.ejs b/frontend/views/themes/default/ejs/index.ejs new file mode 100644 index 0000000..04db330 --- /dev/null +++ b/frontend/views/themes/default/ejs/index.ejs @@ -0,0 +1,35 @@ + + + + + + + Yet-Another-Blog + + + <%- include("partials/header.ejs") %> + +
+
+
+
+ <% for(post of blog_list) { %> + + <%- include("partials/post.ejs", {post:post}) %> + + <% } %> +
+
+
TAGS
+
+
Tag 1
+
+
+
+ <%- include("partials/pagination.ejs") %> +
+
+ + <%- include("partials/footer.ejs") %> + + diff --git a/frontend/views/themes/default/ejs/login.ejs b/frontend/views/themes/default/ejs/login.ejs new file mode 100644 index 0000000..a98be78 --- /dev/null +++ b/frontend/views/themes/default/ejs/login.ejs @@ -0,0 +1,34 @@ + + + + + + + + Yet-Another-Blog + + + <%- include("partials/header.ejs") %> +
+
+
+
Sign in
+ + +
+ + Register +
+
+
+
+ <%- include("partials/footer.ejs") %> + + + diff --git a/frontend/views/themes/default/ejs/partials/footer.ejs b/frontend/views/themes/default/ejs/partials/footer.ejs new file mode 100644 index 0000000..d77de5a --- /dev/null +++ b/frontend/views/themes/default/ejs/partials/footer.ejs @@ -0,0 +1,11 @@ + diff --git a/frontend/views/themes/default/ejs/partials/header.ejs b/frontend/views/themes/default/ejs/partials/header.ejs new file mode 100644 index 0000000..3a6ca0e --- /dev/null +++ b/frontend/views/themes/default/ejs/partials/header.ejs @@ -0,0 +1,23 @@ +
+
+ + + +
+
diff --git a/frontend/views/themes/default/ejs/partials/pagination.ejs b/frontend/views/themes/default/ejs/partials/pagination.ejs new file mode 100644 index 0000000..8dbcea7 --- /dev/null +++ b/frontend/views/themes/default/ejs/partials/pagination.ejs @@ -0,0 +1,23 @@ + diff --git a/frontend/views/themes/default/ejs/partials/post.ejs b/frontend/views/themes/default/ejs/partials/post.ejs new file mode 100644 index 0000000..f114bdd --- /dev/null +++ b/frontend/views/themes/default/ejs/partials/post.ejs @@ -0,0 +1,12 @@ +
+ <%= post.title %> + +
<%= post.description %>
+
+
+
<%= post.publish_date.toLocaleString('en-US', { dateStyle:'medium'}) %>
+
Null minute read
+
Null words
+
+
+
diff --git a/frontend/views/themes/default/ejs/post.ejs b/frontend/views/themes/default/ejs/post.ejs new file mode 100644 index 0000000..dbda94b --- /dev/null +++ b/frontend/views/themes/default/ejs/post.ejs @@ -0,0 +1,19 @@ + + + + + + + Yet-Another-Blog + + + <%- include("partials/header.ejs") %> +
+
+
<%= blog_post.title%>
+ <%- blog_post.content %> +
+
+ <%- include("partials/footer.ejs") %> + + diff --git a/frontend/views/themes/default/ejs/postSearch.ejs b/frontend/views/themes/default/ejs/postSearch.ejs new file mode 100644 index 0000000..9e8d863 --- /dev/null +++ b/frontend/views/themes/default/ejs/postSearch.ejs @@ -0,0 +1,37 @@ + + + + + + + + Yet-Another-Blog + + + <%- include("partials/header.ejs") %> + +
+
+ +
+
+ <% for(post of blog_list) { %> + + <%- include("partials/post.ejs", {post:post}) %> + + <% } %> +
+
+ <%- include("partials/pagination.ejs") %> +
+
+ + <%- include("partials/footer.ejs") %> + + + diff --git a/frontend/views/themes/default/img/calendar.svg b/frontend/views/themes/default/img/calendar.svg new file mode 100644 index 0000000..5d9e723 --- /dev/null +++ b/frontend/views/themes/default/img/calendar.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/views/themes/default/img/hourglass.svg b/frontend/views/themes/default/img/hourglass.svg new file mode 100644 index 0000000..5b6554f --- /dev/null +++ b/frontend/views/themes/default/img/hourglass.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/views/themes/default/img/json.svg b/frontend/views/themes/default/img/json.svg new file mode 100644 index 0000000..8ef5c55 --- /dev/null +++ b/frontend/views/themes/default/img/json.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/views/themes/default/img/news.svg b/frontend/views/themes/default/img/news.svg new file mode 100644 index 0000000..520f031 --- /dev/null +++ b/frontend/views/themes/default/img/news.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/views/themes/default/img/rss.svg b/frontend/views/themes/default/img/rss.svg new file mode 100644 index 0000000..baeeb11 --- /dev/null +++ b/frontend/views/themes/default/img/rss.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/views/themes/default/img/tag.svg b/frontend/views/themes/default/img/tag.svg new file mode 100644 index 0000000..967efed --- /dev/null +++ b/frontend/views/themes/default/img/tag.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/views/themes/default/js/admin.js b/frontend/views/themes/default/js/admin.js new file mode 100644 index 0000000..8acbd17 --- /dev/null +++ b/frontend/views/themes/default/js/admin.js @@ -0,0 +1,24 @@ +async function toggleState(setting_name, element) { + console.log(element.checked); + const form = { + setting_name: setting_name, + value: element.checked, + }; + const response = await request("/setting", "POST", form); + + // TODO: On failure, notify the user + if (response.body.success) { + } +} + +async function changeValue(setting_name, element) { + const form = { + setting_name: setting_name, + value: element.value, + }; + const response = await request("/setting", "POST", form); + + // TODO: On failure, notify the user + if (response.body.success) { + } +} diff --git a/frontend/views/themes/default/js/generic.js b/frontend/views/themes/default/js/generic.js new file mode 100644 index 0000000..6a035a5 --- /dev/null +++ b/frontend/views/themes/default/js/generic.js @@ -0,0 +1,15 @@ +// Quick document selectors +const qs = (selector) => document.querySelector(selector); +const qsa = (selector) => document.querySelectorAll(selector); + +// TODO: Try/Catch for failed requests +async function request(url, method, body) { + const response = await fetch(url, { + method: method, + headers: { + "Content-Type": "application/json", // Set the Content-Type header + }, + body: JSON.stringify(body), + }); + return { status: response.status, body: await response.json() }; +} diff --git a/frontend/views/themes/default/js/login.js b/frontend/views/themes/default/js/login.js new file mode 100644 index 0000000..302a288 --- /dev/null +++ b/frontend/views/themes/default/js/login.js @@ -0,0 +1,17 @@ +async function requestLogin() { + const account_information = { + username: qs("#username").value, + password: qs("#password").value, + }; + + const account_response = await request("/login", "POST", account_information); + + // Check response for errors + + // If success, return to account + console.log(account_response); + + if (account_response.body.success) { + location.href = "/"; + } +} diff --git a/frontend/views/themes/default/js/postSearch.js b/frontend/views/themes/default/js/postSearch.js new file mode 100644 index 0000000..1710603 --- /dev/null +++ b/frontend/views/themes/default/js/postSearch.js @@ -0,0 +1,4 @@ +function search() { + const url_query = `search=${qs("input").value}`; + window.location.href = `${window.location.origin}${window.location.pathname}?${url_query}`; +} diff --git a/frontend/views/themes/default/metadata.json b/frontend/views/themes/default/metadata.json new file mode 100644 index 0000000..696fef9 --- /dev/null +++ b/frontend/views/themes/default/metadata.json @@ -0,0 +1,14 @@ +{ + "author": "Armored Dragon", + "version": "1.0.0", + "comment": "The default theme for Yet-Another-Blog", + "pages": { + "index": "/ejs/index.ejs", + "login": "/ejs/login.ejs", + "register": "/ejs/register.ejs", + "author": "/ejs/author.ejs", + "post": "/ejs/post.ejs", + "settings": "/ejs/login.ejs", + "user-settings": "/ejs/user-settings.ejs" + } +} diff --git a/yab.js b/yab.js index ccbc1fd..4faa196 100644 --- a/yab.js +++ b/yab.js @@ -12,10 +12,13 @@ const internal = require("./backend/core/internal_api"); // Express settings app.set("view-engine", "ejs"); app.set("views", path.join(__dirname, "frontend/views")); -app.use(express.static(path.join(__dirname, "frontend/public"))); app.use(express.json({ limit: "500mb" })); app.use(express.urlencoded({ extended: false })); +// TODO: Does this persist previous themes? May cause security issues! +const refreshTheme = (theme_name) => app.use(express.static(path.join(__dirname, `frontend/views/themes/${theme_name}`))); +refreshTheme("default"); + app.use( session({ secret: require("crypto").randomBytes(128).toString("base64"), @@ -41,7 +44,7 @@ app.get("/login", page_scripts.login); app.get("/register", checkNotAuthenticated, page_scripts.register); app.get("/author/:author_id", page_scripts.author); app.get("/admin", checkAuthenticated, page_scripts.admin); -app.get("/blog", page_scripts.blogList); +app.get("/posts", page_scripts.blogList); app.get("/blog/new", checkAuthenticated, page_scripts.blogNew); app.get("/blog/:blog_id", page_scripts.blogSingle); app.get("/blog/:blog_id/edit", checkAuthenticated, page_scripts.blogEdit);