mirror of
https://github.com/Akif9748/akf-forum.git
synced 2024-12-22 15:49:08 +03:00
Added categories to front end
This commit is contained in:
parent
0ed4a34c8c
commit
035b2b7184
12 changed files with 144 additions and 15 deletions
3
index.js
3
index.js
|
@ -22,8 +22,7 @@ app.use(
|
|||
session({ secret: 'secret', resave: true, saveUninitialized: true }),
|
||||
express.static("public"), express.json(), ipBlock(app.ips),
|
||||
async (req, res, next) => {
|
||||
if (req.session.userID)
|
||||
req.user = await UserModel.findOneAndUpdate({ id: req.session.userID }, { lastSeen: Date.now() });
|
||||
req.user = req.session.userID ? await UserModel.findOneAndUpdate({ id: req.session.userID }, { lastSeen: Date.now() }) : null;
|
||||
|
||||
res.reply = (page, options = {}, status = 200) => res.status(status)
|
||||
.render(page, { user: req.user, theme: req.user?.theme || def_theme, forum_name, desp, ...options });
|
||||
|
|
|
@ -11,6 +11,11 @@ schema.methods.takeId = async function () {
|
|||
this.id = String(await model.count() || 0);
|
||||
return this;
|
||||
}
|
||||
|
||||
schema.methods.getLink = function (id = this.id) {
|
||||
return "/categories/" + this.id;
|
||||
}
|
||||
|
||||
const model = mongoose.model('category', schema);
|
||||
|
||||
module.exports = model;
|
|
@ -40,8 +40,8 @@ app.post("/", async (req, res) => {
|
|||
if (!name) return res.error(400, "You have to give a name for the category.");
|
||||
|
||||
if (await CategoryModel.exists({ name })) return res.error(400, "This category is already opened.");
|
||||
|
||||
res.complate(await CategoryModel.create({ name, desp, authorID: req.user.id }).then(c => c.takeId()));
|
||||
const category = await new CategoryModel({ name, desp, authorID: req.user.id }).takeId();
|
||||
res.complate(await category.save());
|
||||
|
||||
});
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ app.get("/:id/messages/", async (req, res) => {
|
|||
app.post("/", async (req, res) => {
|
||||
|
||||
const { title, content } = req.body;
|
||||
|
||||
return console.log(req.body)
|
||||
if (!content || !title) return res.error(400, "Missing content/title in request body.");
|
||||
|
||||
const { user } = req;
|
||||
|
|
25
routes/categories.js
Normal file
25
routes/categories.js
Normal file
|
@ -0,0 +1,25 @@
|
|||
const { CategoryModel,ThreadModel } = require("../models");
|
||||
|
||||
const { Router } = require("express");
|
||||
|
||||
const app = Router();
|
||||
app.get("/", async (req, res) => {
|
||||
const categories = await CategoryModel.find({});
|
||||
res.reply("categories", { categories });
|
||||
});
|
||||
|
||||
app.get("/create",(req,res)=>res.reply("create_category"));
|
||||
app.get("/:id", async (req, res) => {
|
||||
const category = await CategoryModel.findOne({ id: req.params.id });
|
||||
if (!category) return res.error(404, "Category not found.");
|
||||
const page = Number(req.query.page) || 0;
|
||||
const query = { categoryID: category.id };
|
||||
if (!req.user?.admin) query.deleted= false;
|
||||
|
||||
let threads = await ThreadModel.find(query).limit(10).skip(page * 10);
|
||||
threads = await Promise.all(threads.map(thread => thread.get_author()));
|
||||
|
||||
res.reply("threads", { threads, page, title: `Threads in ${category.name}`, desp: category.desp, pages: Math.ceil(await ThreadModel.count(query) / 10) });
|
||||
});
|
||||
|
||||
module.exports = app;
|
|
@ -42,8 +42,7 @@ app.get("/threads", async (req, res) => {
|
|||
if (req.query.authorID) query.authorID = req.query.authorID;
|
||||
const threads = await ThreadModel.find(query, null, req.so)
|
||||
res.reply("threads", {
|
||||
threads,
|
||||
page: null, page: req.page,
|
||||
threads, page: req.page, title: "Threads with query " + req.query.q,
|
||||
pages: Math.ceil(await ThreadModel.count(query) / 10)
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const { Router } = require("express");
|
||||
const app = Router();
|
||||
const { clearContent } = require("../lib");
|
||||
const { ThreadModel, MessageModel } = require("../models")
|
||||
const { ThreadModel, MessageModel, CategoryModel } = require("../models")
|
||||
|
||||
app.get("/", async (req, res) => {
|
||||
const page = Number(req.query.page) || 0;
|
||||
|
@ -9,11 +9,11 @@ app.get("/", async (req, res) => {
|
|||
let threads = await ThreadModel.find(query).limit(10).skip(page * 10);
|
||||
threads = await Promise.all(threads.map(thread => thread.get_author()));
|
||||
|
||||
return res.reply("threads", { threads, page, pages: Math.ceil(await ThreadModel.count(query) / 10) });
|
||||
return res.reply("threads", { threads, page, title: "Threads", desp: threads.length + " thread listed", pages: Math.ceil(await ThreadModel.count(query) / 10) });
|
||||
});
|
||||
|
||||
|
||||
app.get("/create/", (req, res) => res.reply("create_thread"));
|
||||
app.get("/create/", async (req, res) => res.reply("create_thread", { categories: await CategoryModel.find() }));
|
||||
|
||||
app.get("/:id/", async (req, res) => {
|
||||
|
||||
|
|
58
views/categories.ejs
Normal file
58
views/categories.ejs
Normal file
|
@ -0,0 +1,58 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<%- include("extra/meta", {title: "Thread list!" }) %>
|
||||
|
||||
<body>
|
||||
<link href='https://unpkg.com/boxicons@2.1.2/css/boxicons.min.css' rel='stylesheet'>
|
||||
|
||||
<link rel="stylesheet" href="/css/threads.css" />
|
||||
<link rel="stylesheet" href="/css/pages.css" />
|
||||
|
||||
<%- include("extra/navbar") %>
|
||||
<div class="threads">
|
||||
<%if(user?.admin) {%>
|
||||
<a href="/categories/create" class="btn-primary">Create Category</a>
|
||||
<% }; %>
|
||||
<% categories.forEach(category=>{ %>
|
||||
<a href="<%= category.getLink() %>" >
|
||||
<div class="threads-box">
|
||||
<div class="thread-box-title">
|
||||
<%= category.name %>
|
||||
</div>
|
||||
|
||||
<div class="box-username"> <%if(user?.admin) {%>
|
||||
<a class="btn-danger" onclick="fetch('/api/categories/<%= category.id %>/',{method:'DELETE'})"><i class="bx bx-trash bx-sm"></i></a>
|
||||
<% }; %><%= category.desp %>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</a>
|
||||
<br>
|
||||
<% }); %>
|
||||
|
||||
</div>
|
||||
<% if(typeof page === "number"){ %>
|
||||
|
||||
<div class="pagination">
|
||||
<div class="back">
|
||||
<% if (page > 0){ %>
|
||||
<a href="/threads?page=<%= page-1 %>" class='bx bxs-chevron-left'></a>
|
||||
<% } %>
|
||||
</div>
|
||||
|
||||
<div class="numbers">
|
||||
<% for(let i=0; i < pages; i++){ %>
|
||||
<a class="number <%= i==page?'active':'' %>" href="/threads?page=<%= i %>"><%= i+1 %></a>
|
||||
<% } %>
|
||||
</div>
|
||||
|
||||
<div class="after">
|
||||
<% if (pages-1 > page) { %>
|
||||
<a href="/threads?page=<%= page +1 %>" class='bx bxs-chevron-right'></a>
|
||||
<% } %>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<% } %>
|
||||
|
||||
</body>
|
38
views/create_category.ejs
Normal file
38
views/create_category.ejs
Normal file
|
@ -0,0 +1,38 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<%- include("extra/meta", {title: "Create Category!" }) %>
|
||||
|
||||
<body>
|
||||
<link rel="stylesheet" href="/css/create_thread.css" />
|
||||
|
||||
<%- include("extra/navbar") %>
|
||||
|
||||
<form>
|
||||
<h2 class="title" style="align-self: baseline;">Name:</h2>
|
||||
<input name="name" class="input"></input>
|
||||
<h2 class="title" style="align-self: baseline;">Description:</h2>
|
||||
<textarea rows="4" cols="50" name="desp" class="input"></textarea>
|
||||
<button class="btn-primary" style="width:100%" type="submit">Create Category!</button>
|
||||
</form>
|
||||
|
||||
|
||||
<script type="module">
|
||||
import request from "../../js/request.js";
|
||||
|
||||
document.addEventListener("submit", async e => {
|
||||
e.preventDefault();
|
||||
const data = new FormData(e.target);
|
||||
|
||||
const response = await request("/api/categories/", "POST", {
|
||||
name: data.get("name"),
|
||||
desp: data.get("desp")
|
||||
});
|
||||
|
||||
if (response)
|
||||
window.location.href = "/categories/" + response.id;
|
||||
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
|
@ -12,11 +12,13 @@
|
|||
<form>
|
||||
<h2 class="title" style="align-self: baseline;">Title:</h2>
|
||||
<input name="title" class="input"></input>
|
||||
|
||||
|
||||
<h2 class="title" style="align-self: baseline;">Content:</h2>
|
||||
<textarea rows="4" cols="50" name="content" class="input"></textarea>
|
||||
|
||||
<select name="category">
|
||||
<% for (const category of categories) { %>
|
||||
<option name="<%= category.id %>" value="<%= category.name %>"><%= category.name %></option>
|
||||
<% } %>
|
||||
</select>
|
||||
|
||||
<button class="btn-primary" style="width:100%" type="submit">Create Thread!</button>
|
||||
</form>
|
||||
|
@ -32,7 +34,8 @@
|
|||
|
||||
const response = await request("/api/threads/", "POST", {
|
||||
title: data.get("title"),
|
||||
content: data.get("content")
|
||||
content: data.get("content"),
|
||||
categord: data.get("category")
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
</div>
|
||||
<div class="menu">
|
||||
<a href="/threads/create/" class="menu-item">Create Thread</a>
|
||||
<a href="/categories" class="menu-item">Categories</a>
|
||||
<a href="/threads" class="menu-item">Threads</a>
|
||||
<a href="/users" class="menu-item">Users</a>
|
||||
<a href="/search" class="menu-item">Search</a>
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
<link rel="stylesheet" href="/css/pages.css" />
|
||||
|
||||
<%- include("extra/navbar") %>
|
||||
|
||||
<h1><%= title || "Threads" %></h1>
|
||||
<h2><%= desp %></h2>
|
||||
<div class="threads">
|
||||
|
||||
<% threads.forEach(thread=>{ %>
|
||||
|
|
Loading…
Reference in a new issue