parent
50f30f227d
commit
1b9ea56423
|
@ -21,23 +21,19 @@ let settings = {
|
||||||
HIDE_LOGIN: false,
|
HIDE_LOGIN: false,
|
||||||
BLOG_UPLOADING: false,
|
BLOG_UPLOADING: false,
|
||||||
|
|
||||||
CD_RSS: false,
|
CD_RSS: true,
|
||||||
CD_AP: false,
|
CD_JSON: true,
|
||||||
|
|
||||||
WEBSITE_NAME: "",
|
WEBSITE_NAME: "",
|
||||||
PLAUSIBLE_URL: "",
|
PLAUSIBLE_URL: "",
|
||||||
|
|
||||||
USER_MINIMUM_PASSWORD_LENGTH: 7,
|
USER_MINIMUM_PASSWORD_LENGTH: 7,
|
||||||
|
|
||||||
BLOG_MINIMUM_TITLE_LENGTH: 7,
|
theme: "default",
|
||||||
BLOG_MINIMUM_DESCRIPTION_LENGTH: 7,
|
|
||||||
BLOG_MINIMUM_CONTENT_LENGTH: 7,
|
|
||||||
};
|
};
|
||||||
let use_s3_storage = false;
|
let use_s3_storage = false;
|
||||||
let groups = [];
|
|
||||||
_initS3Storage();
|
_initS3Storage();
|
||||||
_getSettings();
|
_getSettings();
|
||||||
_getGroups();
|
|
||||||
|
|
||||||
// Checks to see if S3 storage is set
|
// Checks to see if S3 storage is set
|
||||||
function _initS3Storage() {
|
function _initS3Storage() {
|
||||||
|
@ -505,14 +501,16 @@ async function postSetting(key, value) {
|
||||||
if (!Object.keys(settings).includes(key)) return { success: false, message: "Setting not valid" };
|
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 } });
|
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 };
|
return { success: true };
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return { success: false, message: e.message };
|
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 };
|
module.exports = { settings, registerUser, getUser, getAuthorPage, postBlog, updateBlog, getBlog, deleteBlog, deleteImage, postSetting, getSetting };
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
const external = require("./core/external_api");
|
const external = require("./core/external_api");
|
||||||
const core = require("./core/core");
|
const core = require("./core/core");
|
||||||
|
|
||||||
|
function getThemePage(page_name) {
|
||||||
|
return `themes/${core.settings.theme}/ejs/${page_name}.ejs`;
|
||||||
|
}
|
||||||
|
|
||||||
function getDefaults(req) {
|
function getDefaults(req) {
|
||||||
// TODO: Fix reference to website_name
|
// 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 };
|
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) {
|
async function index(request, response) {
|
||||||
// Check if the master admin has been created
|
// Check if the master admin has been created
|
||||||
const is_setup_complete = core.settings["SETUP_COMPLETE"];
|
// const is_setup_complete = core.settings["SETUP_COMPLETE"];
|
||||||
if (!is_setup_complete) return response.redirect("/register");
|
// 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) {
|
function register(request, response) {
|
||||||
response.render("register.ejs", getDefaults(request));
|
response.render("register.ejs", getDefaults(request));
|
||||||
}
|
}
|
||||||
function login(request, response) {
|
function login(request, response) {
|
||||||
response.render("login.ejs", getDefaults(request));
|
response.render(getThemePage("login"), getDefaults(request));
|
||||||
}
|
}
|
||||||
async function author(req, res) {
|
async function author(req, res) {
|
||||||
const user = await core.getUser({ id: req.params.author_id });
|
const user = await core.getUser({ id: req.params.author_id });
|
||||||
// FIXME: Bandage fix for author get error
|
// FIXME: Bandage fix for author get error
|
||||||
if (!user.success) return res.redirect("/");
|
if (!user.success) return res.redirect("/");
|
||||||
const profile = await core.getAuthorPage({ author_id: user.data.id });
|
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) {
|
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 });
|
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),
|
...getDefaults(req),
|
||||||
blog_list: blog_list.data,
|
blog_list: blog_list.data,
|
||||||
pagination: blog_list.pagination,
|
pagination: blog_list.pagination,
|
||||||
|
@ -38,8 +50,8 @@ async function blogList(req, res) {
|
||||||
}
|
}
|
||||||
async function blogSingle(req, res) {
|
async function blogSingle(req, res) {
|
||||||
const blog = await core.getBlog({ id: req.params.blog_id });
|
const blog = await core.getBlog({ id: req.params.blog_id });
|
||||||
if (blog.success === false) return res.redirect("/blog");
|
if (blog.success === false) return res.redirect("/");
|
||||||
res.render("blogSingle.ejs", { ...getDefaults(req), blog_post: blog.data });
|
res.render(getThemePage("post"), { ...getDefaults(req), blog_post: blog.data });
|
||||||
}
|
}
|
||||||
function blogNew(request, response) {
|
function blogNew(request, response) {
|
||||||
// TODO: Turn date formatting into function
|
// 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 });
|
res.render("blogNew.ejs", { ...getDefaults(req), existing_blog: existing_blog });
|
||||||
}
|
}
|
||||||
async function admin(request, response) {
|
async function admin(request, response) {
|
||||||
response.render("admin.ejs", { ...getDefaults(request) });
|
response.render(getThemePage("admin-settings"), { ...getDefaults(request) });
|
||||||
}
|
}
|
||||||
async function atom(req, res) {
|
async function atom(req, res) {
|
||||||
res.type("application/xml");
|
res.type("application/xml");
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -1,56 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<link rel="stylesheet" type="text/css" href="/css/admin.css" />
|
|
||||||
<link rel="stylesheet" type="text/css" href="/css/theme.css" />
|
|
||||||
<script src="/js/generic.js"></script>
|
|
||||||
<title><%= website_name %> | Administration</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<%- include("partials/header.ejs", {selected: 'home'}) %>
|
|
||||||
|
|
||||||
<div class="page">
|
|
||||||
<div class="container">
|
|
||||||
<div class="category-navigation">
|
|
||||||
<button id="accounts-nav-btn" class="active" onclick="toggleActiveCategory('accounts')"><span>Accounts</span></button>
|
|
||||||
<button id="content-delivery-nav-btn" onclick="toggleActiveCategory('content-delivery')"><span>Content Delivery</span></button>
|
|
||||||
<button id="groups-nav-btn" onclick="toggleActiveCategory('groups')"><span>Groups</span></button>
|
|
||||||
<button id="yab-master-nav-btn" onclick="toggleActiveCategory('yab-master')"><span>YAB</span></button>
|
|
||||||
</div>
|
|
||||||
<div id="accounts" class="category-page">
|
|
||||||
<!-- Account registration -->
|
|
||||||
<%- include("partials/admin-setting-toggle.ejs", {setting: {name: 'ACCOUNT_REGISTRATION', name_pretty: 'Account registration', enabled:
|
|
||||||
settings.ACCOUNT_REGISTRATION}}) %>
|
|
||||||
<!-- Hide login -->
|
|
||||||
<%- include("partials/admin-setting-toggle.ejs", {setting: {name: 'HIDE_LOGIN', name_pretty: 'Hide Login', enabled: settings.HIDE_LOGIN}}) %>
|
|
||||||
<!-- Minimum password length -->
|
|
||||||
<%- include("partials/admin-setting-number.ejs", {setting: {name:'USER_MINIMUM_PASSWORD_LENGTH', name_pretty: 'Minimum Password Length', value:
|
|
||||||
settings.USER_MINIMUM_PASSWORD_LENGTH}}) %>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="content-delivery" class="category-page hidden">
|
|
||||||
<!-- RSS -->
|
|
||||||
<%- include("partials/admin-setting-toggle.ejs", {setting: {name: 'CD_RSS', name_pretty: 'RSS Feed', enabled: settings.CD_RSS}}) %>
|
|
||||||
<!-- ActivityPub -->
|
|
||||||
<%- include("partials/admin-setting-toggle.ejs", {setting: {name: 'CD_AP', name_pretty: 'Activity Pub Feed', enabled: settings.CD_AP}}) %>
|
|
||||||
<!-- TODO: Add these option automatically to footer on active -->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="groups" class="category-page hidden">TODO</div>
|
|
||||||
<div id="yab-master" class="category-page hidden">
|
|
||||||
<!-- Website title -->
|
|
||||||
<%- include("partials/admin-setting-text.ejs", {setting: {name: 'WEBSITE_NAME', name_pretty: 'Website Title', value: settings.WEBSITE_NAME}}) %>
|
|
||||||
<!-- Placeholder thumbnail -->
|
|
||||||
<!-- Plausible analytics -->
|
|
||||||
<%- include("partials/admin-setting-text.ejs", {setting: {name: 'PLAUSIBLE_URL', name_pretty: 'Plausible URL', value: settings.PLAUSIBLE_URL}}) %>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<%- include("partials/footer.ejs") %>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
<script defer src="/js/admin.js"></script>
|
|
|
@ -1,32 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<link rel="stylesheet" type="text/css" href="/css/blogSingle.css" />
|
|
||||||
<link rel="stylesheet" type="text/css" href="/css/theme.css" />
|
|
||||||
<script src="/js/generic.js"></script>
|
|
||||||
<title><%= website_name %> | <%= blog_post.title %></title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<%- include("partials/header.ejs", {selected: 'home'}) %>
|
|
||||||
|
|
||||||
<div class="page">
|
|
||||||
<%if(logged_in_user) {%>
|
|
||||||
<div class="blog-admin">
|
|
||||||
<div class="horizontal-button-container">
|
|
||||||
<a class="yellow" href=""><span>Edit Profile</span></a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<%}%>
|
|
||||||
<div class="title"><%= blog_post.title%></div>
|
|
||||||
|
|
||||||
<%- blog_post.content %>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<%- include("partials/footer.ejs") %>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
<script defer src="/js/blogSingle.js"></script>
|
|
|
@ -1,33 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<link rel="stylesheet" type="text/css" href="/css/index.css" />
|
|
||||||
<link rel="stylesheet" type="text/css" href="/css/theme.css" />
|
|
||||||
<link rel="stylesheet" type="text/css" href="/css/blog-list.css" />
|
|
||||||
<script src="/js/generic.js"></script>
|
|
||||||
<title><%= website_name %> | Home</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<%- include("partials/header.ejs", {selected: 'home'}) %>
|
|
||||||
|
|
||||||
<div class="page">
|
|
||||||
<%if(logged_in_user) {%> <%- include("partials/blog-admin.ejs") %> <%}%>
|
|
||||||
<!-- Search area -->
|
|
||||||
<div class="search-area">
|
|
||||||
<input type="text" placeholder="Search..." /><button id="search-btn"><span>Search</span></button>
|
|
||||||
</div>
|
|
||||||
<!-- -->
|
|
||||||
<% for(post of blog_list) { %>
|
|
||||||
<!-- -->
|
|
||||||
<%- include("partials/blog-entry.ejs", {post:post}) %>
|
|
||||||
<!-- -->
|
|
||||||
<% } %> <%- include("partials/pagination.ejs") %>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<%- include("partials/footer.ejs") %>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
<script defer src="/js/postList.js"></script>
|
|
|
@ -1,35 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<link rel="stylesheet" type="text/css" href="/css/blogSingle.css" />
|
|
||||||
<link rel="stylesheet" type="text/css" href="/css/theme.css" />
|
|
||||||
<script src="/js/generic.js"></script>
|
|
||||||
<title><%= website_name %> | <%= blog_post.title %></title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<%- include("partials/header.ejs", {selected: 'home'}) %>
|
|
||||||
|
|
||||||
<div class="page">
|
|
||||||
<!-- TODO: Check if user is the owner or an admin -->
|
|
||||||
<!-- TODO: Confirmation before deleting post -->
|
|
||||||
<%if(logged_in_user) {%>
|
|
||||||
<div class="blog-admin">
|
|
||||||
<div class="horizontal-button-container">
|
|
||||||
<a id="delete-post" href="#" class="bad"><span>Delete Post</span></a>
|
|
||||||
<a class="yellow" href="/blog/<%=blog_post.id %>/edit"><span>Edit Post</span></a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<%}%>
|
|
||||||
<div class="title"><%= blog_post.title%></div>
|
|
||||||
|
|
||||||
<%- blog_post.content %>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<%- include("partials/footer.ejs") %>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
<script defer src="/js/blogSingle.js"></script>
|
|
|
@ -1,23 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<link rel="stylesheet" type="text/css" href="/css/index.css" />
|
|
||||||
<link rel="stylesheet" type="text/css" href="/css/theme.css" />
|
|
||||||
<link rel="stylesheet" type="text/css" href="/css/blog-list.css" />
|
|
||||||
<script src="/js/generic.js"></script>
|
|
||||||
<title><%= website_name %> | Home</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<%- include("partials/header.ejs", {selected: 'home'}) %>
|
|
||||||
|
|
||||||
<div class="page">
|
|
||||||
<%- include("partials/blog-entry.ejs", {thumbnail: '/img/.dev/square.png', title: 'Title', description: 'Description', author: 'Author'}) %>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<%- include("partials/footer.ejs") %>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
<script defer src="/js/login.js"></script>
|
|
|
@ -32,5 +32,5 @@
|
||||||
<%- include("partials/footer.ejs") %>
|
<%- include("partials/footer.ejs") %>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
<script src="/js/generic.js"></script>
|
||||||
<script defer src="/js/login.js"></script>
|
<script defer src="/js/login.js"></script>
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
<div class="setting-row">
|
|
||||||
<div class="setting-title"><%=setting.name_pretty%></div>
|
|
||||||
<div class="setting-toggleable">
|
|
||||||
<div class="spinner hidden">
|
|
||||||
<div>↺</div>
|
|
||||||
</div>
|
|
||||||
<input
|
|
||||||
type="number"
|
|
||||||
id="<%=setting.name%>"
|
|
||||||
onkeydown="updateValue(event.keyCode, '<%=setting.name%>', this.value, this.id)"
|
|
||||||
placeholder="<%=setting.name_pretty%>"
|
|
||||||
value="<%=setting.value%>"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,15 +0,0 @@
|
||||||
<div class="setting-row">
|
|
||||||
<div class="setting-title"><%=setting.name_pretty%></div>
|
|
||||||
<div class="setting-toggleable">
|
|
||||||
<div class="spinner hidden">
|
|
||||||
<div>↺</div>
|
|
||||||
</div>
|
|
||||||
<input
|
|
||||||
id="<%=setting.name%>"
|
|
||||||
type="text"
|
|
||||||
onkeydown="updateValue(event.keyCode, '<%=setting.name%>', this.value, this.id)"
|
|
||||||
placeholder="<%=setting.name_pretty%>"
|
|
||||||
value="<%=setting.value%>"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,13 +0,0 @@
|
||||||
<div class="setting-row">
|
|
||||||
<div class="setting-title"><%=setting.name_pretty%></div>
|
|
||||||
<div class="setting-toggleable">
|
|
||||||
<div class="spinner hidden">
|
|
||||||
<div>↺</div>
|
|
||||||
</div>
|
|
||||||
<% if (!setting.enabled) { %>
|
|
||||||
<button id="<%=setting.name%>_toggle" onclick="toggleState('<%=setting.name%>', true, this.id)" class="bad"><div>Disabled</div></button>
|
|
||||||
<% } else { %>
|
|
||||||
<button id="<%=setting.name%>_toggle" onclick="toggleState('<%=setting.name%>', false, this.id)" class="good"><div>Enabled</div></button>
|
|
||||||
<%}%>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,5 +0,0 @@
|
||||||
<div class="blog-admin">
|
|
||||||
<div class="horizontal-button-container">
|
|
||||||
<a href="/blog/new"><span>New Post</span></a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,21 +0,0 @@
|
||||||
<div class="header">
|
|
||||||
<div class="left">
|
|
||||||
<a class="nav-button" href="/">
|
|
||||||
<div><%= website_name %></div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="right">
|
|
||||||
<a class="nav-button" href="/blog">
|
|
||||||
<div>Blog</div>
|
|
||||||
</a>
|
|
||||||
<% if (logged_in_user) { %>
|
|
||||||
<a class="nav-button" href="/author/<%= logged_in_user.username %>">
|
|
||||||
<div>Profile</div>
|
|
||||||
</a>
|
|
||||||
<% } else {%> <% if(!settings.HIDE_LOGIN) {%>
|
|
||||||
<a class="nav-button" href="/login">
|
|
||||||
<div>Login</div>
|
|
||||||
</a>
|
|
||||||
<% } %> <% } %>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,29 +0,0 @@
|
||||||
<div class="pagination">
|
|
||||||
<% if(pagination.includes(Number(current_page) - 1)) {%>
|
|
||||||
<a href="<%= loaded_page %>?page=<%= Number(current_page) - 1 %>">
|
|
||||||
<span>Previous</span>
|
|
||||||
</a>
|
|
||||||
<% } else {%>
|
|
||||||
<a class="disabled">
|
|
||||||
<span>Previous</span>
|
|
||||||
</a>
|
|
||||||
<%}%>
|
|
||||||
|
|
||||||
<div class="page-list">
|
|
||||||
<% for(page of pagination) { %> <% if (page == current_page) {%>
|
|
||||||
<a href="#" class="active"><span><%=page + 1%></span></a>
|
|
||||||
<% } else { %>
|
|
||||||
<a href="<%= loaded_page %>?page=<%=page %>" class=""><span><%=page + 1%></span></a>
|
|
||||||
<% } %> <% } %>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<% if(pagination.includes(Number(current_page) + 1)) {%>
|
|
||||||
<a href="<%= loaded_page %>?page=<%= Number(current_page) + 1 %>">
|
|
||||||
<span>Next</span>
|
|
||||||
</a>
|
|
||||||
<% } else {%>
|
|
||||||
<a class="disabled">
|
|
||||||
<span>Next</span>
|
|
||||||
</a>
|
|
||||||
<%}%>
|
|
||||||
</div>
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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%;
|
||||||
|
}
|
|
@ -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%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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%;
|
||||||
|
}
|
|
@ -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%;
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="../css/settings.css" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="../css/generic.css" />
|
||||||
|
<script src="/js/generic.js"></script>
|
||||||
|
<title>Yet-Another-Blog</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<%- include("partials/header.ejs") %>
|
||||||
|
<div class="page">
|
||||||
|
<div class="page-center">
|
||||||
|
<div class="header"><%= website_name %> Admin Settings</div>
|
||||||
|
<div class="setting-list">
|
||||||
|
<div class="setting">
|
||||||
|
<div class="title">User registration</div>
|
||||||
|
<div class="value">
|
||||||
|
<label class="switch">
|
||||||
|
<input <% if(settings.ACCOUNT_REGISTRATION) {%> checked <% } %> id="ACCOUNT_REGISTRATION" onchange="toggleState(this.id, this)" type="checkbox" />
|
||||||
|
<span class="slider round"></span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="setting">
|
||||||
|
<div class="title">Hide "Login" in navigation bar</div>
|
||||||
|
<div class="value">
|
||||||
|
<label class="switch">
|
||||||
|
<input <% if(settings.HIDE_LOGIN) {%> checked <% } %> id="HIDE_LOGIN" onchange="toggleState(this.id, this)" type="checkbox" />
|
||||||
|
<span class="slider round"></span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="setting">
|
||||||
|
<div class="title">Serve ATOM feed</div>
|
||||||
|
<div class="value">
|
||||||
|
<label class="switch">
|
||||||
|
<input <% if(settings.CD_RSS) {%> checked <% } %> id="CD_RSS" onchange="toggleState(this.id, this)" type="checkbox" />
|
||||||
|
<span class="slider round"></span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="setting">
|
||||||
|
<div class="title">Serve JSON feed</div>
|
||||||
|
<div class="value">
|
||||||
|
<label class="switch">
|
||||||
|
<input <% if(settings.CD_JSON) {%> checked <% } %> id="CD_JSON" onchange="toggleState(this.id, this)" type="checkbox" />
|
||||||
|
<span class="slider round"></span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="setting">
|
||||||
|
<div class="title">Password minimum length</div>
|
||||||
|
<div class="value">
|
||||||
|
<input id="USER_MINIMUM_PASSWORD_LENGTH" value="<%- settings.USER_MINIMUM_PASSWORD_LENGTH -%>" onchange="changeValue(this.id, this)" type="number" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="setting">
|
||||||
|
<div class="title">Website Name</div>
|
||||||
|
<div class="value">
|
||||||
|
<input id="WEBSITE_NAME" value="<%- settings.WEBSITE_NAME -%>" onchange="changeValue(this.id, this)" type="text" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%- include("partials/footer.ejs") %>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
<script defer src="/js/admin.js"></script>
|
|
@ -0,0 +1,33 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="../css/author.css" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="../css/generic.css" />
|
||||||
|
<title>Yet-Another-Blog</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<%- include("partials/header.ejs") %>
|
||||||
|
|
||||||
|
<div class="page">
|
||||||
|
<div class="page-center">
|
||||||
|
<div class="biography">
|
||||||
|
<div class="title"><%= post.title %></div>
|
||||||
|
|
||||||
|
<%- post.content %>
|
||||||
|
</div>
|
||||||
|
<div class="about">
|
||||||
|
<div class="profile-picture"><img src="" /></div>
|
||||||
|
<div class="displayname">DISPLAYNAME</div>
|
||||||
|
<div class="stat">Registered REGISTRATIONDATE</div>
|
||||||
|
<div class="stat">NUMPOSTS Posts</div>
|
||||||
|
<div class="sociallist">
|
||||||
|
<a class="link" href="#">Matrix</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%- include("partials/footer.ejs") %>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,35 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="/css/index.css" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="/css/generic.css" />
|
||||||
|
<title>Yet-Another-Blog</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<%- include("partials/header.ejs") %>
|
||||||
|
|
||||||
|
<div class="page">
|
||||||
|
<div class="page-center">
|
||||||
|
<div class="post-list-container">
|
||||||
|
<div class="post-list">
|
||||||
|
<% for(post of blog_list) { %>
|
||||||
|
<!-- -->
|
||||||
|
<%- include("partials/post.ejs", {post:post}) %>
|
||||||
|
<!-- -->
|
||||||
|
<% } %>
|
||||||
|
</div>
|
||||||
|
<div class="tag-list">
|
||||||
|
<div class="tag-header">TAGS</div>
|
||||||
|
<div class="list">
|
||||||
|
<div class="tag icon">Tag 1</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<%- include("partials/pagination.ejs") %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%- include("partials/footer.ejs") %>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,34 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="/css/login.css" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="/css/generic.css" />
|
||||||
|
<script src="/js/generic.js"></script>
|
||||||
|
<title>Yet-Another-Blog</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<%- include("partials/header.ejs") %>
|
||||||
|
<div class="page">
|
||||||
|
<div class="page-center">
|
||||||
|
<div class="page-modal">
|
||||||
|
<div class="title">Sign in</div>
|
||||||
|
<div class="login-part">
|
||||||
|
<div class="name">Username:</div>
|
||||||
|
<input id="username" type="text" />
|
||||||
|
</div>
|
||||||
|
<div class="login-part">
|
||||||
|
<div class="name">Password:</div>
|
||||||
|
<input id="password" type="password" />
|
||||||
|
</div>
|
||||||
|
<div class="action-container">
|
||||||
|
<button onclick="requestLogin()" class="button"><span>Login</span></button>
|
||||||
|
<a href="/register">Register</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<%- include("partials/footer.ejs") %>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
<script defer src="/js/login.js"></script>
|
|
@ -0,0 +1,11 @@
|
||||||
|
<div class="footer">
|
||||||
|
<div class="page-center">
|
||||||
|
<div class="resources">
|
||||||
|
<a class="atom-feed icon" href="#"><span>ATOM Feed</span> </a>
|
||||||
|
<a class="json icon" href="#"><span>JSON Feed</span></a>
|
||||||
|
</div>
|
||||||
|
<div class="info">
|
||||||
|
<a class="json icon" href="https://github.com/armored-dragon/yet-another-blog">Built using Yet-Another-Blog</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,23 @@
|
||||||
|
<div class="header">
|
||||||
|
<div class="page-center">
|
||||||
|
<a class="logo" href="/">
|
||||||
|
<span class="logo-icon icon"></span>
|
||||||
|
<span class="logo-title"><%= website_name %></span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="navigation">
|
||||||
|
<a href="/posts">
|
||||||
|
<span>Posts</span>
|
||||||
|
</a>
|
||||||
|
<% if (logged_in_user) { %>
|
||||||
|
<a href="/author/<%= logged_in_user.id %>">
|
||||||
|
<span>Account</span>
|
||||||
|
</a>
|
||||||
|
<% } else {%> <% if(!settings.HIDE_LOGIN) {%>
|
||||||
|
<a href="/login">
|
||||||
|
<span>Login</span>
|
||||||
|
</a>
|
||||||
|
<% } %> <% } %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,23 @@
|
||||||
|
<div class="pagination">
|
||||||
|
<% if(pagination.includes(Number(current_page) - 1)) {%>
|
||||||
|
<a href="<%= loaded_page %>?page=<%= Number(current_page) - 1 %>">
|
||||||
|
<a href="<%= loaded_page %>?page=<%= Number(current_page) - 1 %>" class="left button"><span>< Previous</span></a>
|
||||||
|
</a>
|
||||||
|
<% } else {%>
|
||||||
|
<a href="#" class="left button disabled"><span>< Previous</span></a>
|
||||||
|
<%}%>
|
||||||
|
<!-- -->
|
||||||
|
<div class="pages">
|
||||||
|
<% for(page of pagination) { %> <% if (page == current_page) {%>
|
||||||
|
<a class="active" href="#"><span><%=page + 1%></span></a>
|
||||||
|
<% } else { %>
|
||||||
|
<a ref="<%= loaded_page %>?page=<%=page %>"><span><%=page + 1%></span></a>
|
||||||
|
<% } %> <% } %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<% if(pagination.includes(Number(current_page) + 1)) {%>
|
||||||
|
<a href="<%= loaded_page %>?page=<%= Number(current_page) + 1 %>" class="right button"><span>Next ></span></a>
|
||||||
|
<% } else {%>
|
||||||
|
<a href="#" class="right button disabled"><span>Next ></span></a>
|
||||||
|
<%}%>
|
||||||
|
</div>
|
|
@ -0,0 +1,12 @@
|
||||||
|
<div class="post">
|
||||||
|
<a href="/blog/<%= post.id %>" class="title"><%= post.title %></a>
|
||||||
|
<div class="authors">By <a href="/author/<%= post.owner.id %>"><%= post.owner.username %></a></div>
|
||||||
|
<div class="description"><%= post.description %></div>
|
||||||
|
<div class="badges">
|
||||||
|
<div class="info">
|
||||||
|
<div class="info-blip icon publish-date"><%= post.publish_date.toLocaleString('en-US', { dateStyle:'medium'}) %></div>
|
||||||
|
<div class="info-blip icon reading-time">Null minute read</div>
|
||||||
|
<div class="info-blip icon word-count">Null words</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,19 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="../css/post.css" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="../css/generic.css" />
|
||||||
|
<title>Yet-Another-Blog</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<%- include("partials/header.ejs") %>
|
||||||
|
<div class="page">
|
||||||
|
<div class="page-center">
|
||||||
|
<div class="title"><%= blog_post.title%></div>
|
||||||
|
<%- blog_post.content %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<%- include("partials/footer.ejs") %>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,37 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="/css/index.css" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="/css/generic.css" />
|
||||||
|
<script src="/js/generic.js"></script>
|
||||||
|
<title>Yet-Another-Blog</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<%- include("partials/header.ejs") %>
|
||||||
|
|
||||||
|
<div class="page">
|
||||||
|
<div class="page-center">
|
||||||
|
<div class="search">
|
||||||
|
<div class="action">
|
||||||
|
<input type="text" placeholder="Search..." />
|
||||||
|
<button class="button" onclick="search()"><span>Search</span></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="post-list-container">
|
||||||
|
<div class="post-list full">
|
||||||
|
<% for(post of blog_list) { %>
|
||||||
|
<!-- -->
|
||||||
|
<%- include("partials/post.ejs", {post:post}) %>
|
||||||
|
<!-- -->
|
||||||
|
<% } %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<%- include("partials/pagination.ejs") %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%- include("partials/footer.ejs") %>
|
||||||
|
</body>
|
||||||
|
<script defer src="/js/postSearch.js"></script>
|
||||||
|
</html>
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48"><path d="M306-394q-17 0-28.5-11.5T266-434q0-17 11.5-28.5T306-474q17 0 28.5 11.5T346-434q0 17-11.5 28.5T306-394Zm177 0q-17 0-28.5-11.5T443-434q0-17 11.5-28.5T483-474q17 0 28.5 11.5T523-434q0 17-11.5 28.5T483-394Zm170 0q-17 0-28.5-11.5T613-434q0-17 11.5-28.5T653-474q17 0 28.5 11.5T693-434q0 17-11.5 28.5T653-394ZM180-80q-24 0-42-18t-18-42v-620q0-24 18-42t42-18h65v-60h65v60h340v-60h65v60h65q24 0 42 18t18 42v620q0 24-18 42t-42 18H180Zm0-60h600v-430H180v430Zm0-490h600v-130H180v130Zm0 0v-130 130Z"/></svg>
|
After Width: | Height: | Size: 591 B |
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48"><path d="M308-140h344v-127q0-72-50-121.5T480-438q-72 0-122 49.5T308-267v127Zm172-382q72 0 122-50t50-122v-126H308v126q0 72 50 122t122 50ZM160-80v-60h88v-127q0-71 40-129t106-84q-66-27-106-85t-40-129v-126h-88v-60h640v60h-88v126q0 71-40 129t-106 85q66 26 106 84t40 129v127h88v60H160Zm320-60Zm0-680Z"/></svg>
|
After Width: | Height: | Size: 391 B |
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M320-240 80-480l240-240 57 57-184 184 183 183-56 56Zm320 0-57-57 184-184-183-183 56-56 240 240-240 240Z"/></svg>
|
After Width: | Height: | Size: 209 B |
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48"><path d="M140-120q-24 0-42-18t-18-42v-489h60v489h614v60H140Zm169-171q-24 0-42-18t-18-42v-489h671v489q0 24-18 42t-42 18H309Zm0-60h551v-429H309v429Zm86-131h168v-215H395v215Zm211 0h168v-88H606v88Zm0-127h168v-88H606v88ZM309-351v-429 429Z"/></svg>
|
After Width: | Height: | Size: 330 B |
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48"><path d="M194.956-120Q164-120 142-142.044q-22-22.045-22-53Q120-226 142.044-248q22.045-22 53-22Q226-270 248-247.956q22 22.045 22 53Q270-164 247.956-142q-22.045 22-53 22ZM710-120q0-123-46-229.5T537-537q-81-81-187.575-127Q242.85-710 120-710v-90q142 0 265 53t216 146q93 93 146 216t53 265h-90Zm-258 0q0-70-25.798-131.478Q400.404-312.956 355-360q-45-47-105.027-73.5Q189.945-460 120-460v-90q89 0 165.5 33.5t133.643 92.425q57.143 58.924 90 137Q542-209 542-120h-90Z"/></svg>
|
After Width: | Height: | Size: 553 B |
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48"><path d="m239-160 40-159H120l15-60h159l51-202H186l15-60h159l39-159h59l-39 159h203l39-159h59l-39 159h159l-15 60H666l-51 202h159l-15 60H600l-40 159h-59l40-159H338l-40 159h-59Zm114-219h203l51-202H404l-51 202Z"/></svg>
|
After Width: | Height: | Size: 302 B |
|
@ -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) {
|
||||||
|
}
|
||||||
|
}
|
|
@ -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() };
|
||||||
|
}
|
|
@ -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 = "/";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
function search() {
|
||||||
|
const url_query = `search=${qs("input").value}`;
|
||||||
|
window.location.href = `${window.location.origin}${window.location.pathname}?${url_query}`;
|
||||||
|
}
|
|
@ -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"
|
||||||
|
}
|
||||||
|
}
|
7
yab.js
7
yab.js
|
@ -12,10 +12,13 @@ const internal = require("./backend/core/internal_api");
|
||||||
// Express settings
|
// Express settings
|
||||||
app.set("view-engine", "ejs");
|
app.set("view-engine", "ejs");
|
||||||
app.set("views", path.join(__dirname, "frontend/views"));
|
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.json({ limit: "500mb" }));
|
||||||
app.use(express.urlencoded({ extended: false }));
|
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(
|
app.use(
|
||||||
session({
|
session({
|
||||||
secret: require("crypto").randomBytes(128).toString("base64"),
|
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("/register", checkNotAuthenticated, page_scripts.register);
|
||||||
app.get("/author/:author_id", page_scripts.author);
|
app.get("/author/:author_id", page_scripts.author);
|
||||||
app.get("/admin", checkAuthenticated, page_scripts.admin);
|
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/new", checkAuthenticated, page_scripts.blogNew);
|
||||||
app.get("/blog/:blog_id", page_scripts.blogSingle);
|
app.get("/blog/:blog_id", page_scripts.blogSingle);
|
||||||
app.get("/blog/:blog_id/edit", checkAuthenticated, page_scripts.blogEdit);
|
app.get("/blog/:blog_id/edit", checkAuthenticated, page_scripts.blogEdit);
|
||||||
|
|
Loading…
Reference in New Issue