GitHub: https://github.com/Sokhavuth/opine-job
Deno Deploy: https://khmerweb-job.deno.dev/users/post
To edit a post item, we need to pull that post from MongoDB database to display its entries in the post.jsx template page first. Doing so, we can edit any entries as we want. As a result, we need to define a route with post's id as the parameter to pull the post in question from the database. So, we can use HTTP GET method on the route “/users/post/edit/:id”. To update the post's entries, we can use HTTP POST method on the same route “/users/post/edit/:id”.
// routes/users/post.js
import { Router } from "../../deps.ts";
const router = new Router();
import post from "../../controllers/users/post.js"
router.get("/", async (req, res) => {
if(await req.mysession.get("user")){
post.getPage(req, res);
}else{
res.redirect("/users");
}
});
router.post("/", async (req, res) => {
if(await req.mysession.get("user")){
post.createPost(req, res);
}else{
res.redirect("/users");
}
});
router.get("/edit/:id", async (req, res) => {
if(await req.mysession.get("user")){
post.editPost(req, res);
}else{
res.redirect("/users");
}
});
router.post("/edit/:id", async (req, res) => {
if(await req.mysession.get("user")){
post.updatePost(req, res);
}else{
res.redirect("/users");
}
});
export default router;
// controllers/users/post.js
import post from "../../views/users/post.jsx";
import postdb from "../../models/post.ts";
class Post{
async getPage(req, res){
const config = req.mysetting();
config.page_title = "Post Page";
config.route = "/users/post";
config.username = (await req.mysession.get("user")).title;
config.type = "post";
config.count = await postdb.count(req);
config.items = await postdb.getPosts(req, config.dasPostAmount);
const html = await post(config);
res.send(html);
}
async createPost(req, res){
if((await req.mysession.get("user")).role in {'Admin':1,'Editor':1,'Author':1}){
await postdb.createPost(req);
}
res.redirect("/users/post");
}
async editPost(req, res){
const config = req.mysetting();
config.page_title = "Post Page";
config.route = "/users/post";
config.username = (await req.mysession.get("user")).title;
config.type = "post";
config.count = await postdb.count(req);
config.items = await postdb.getPosts(req, config.dasPostAmount);
config.item = await postdb.editPost(req);
const html = await post(config);
res.send(html);
}
async updatePost(req, res){
const user_role = (await req.mysession.get("user")).role;
const userid = (await req.mysession.get("user")).id;
const post_userid = (await postdb.editPost(req)).userid;
if((user_role === "Admin")||(userid === post_userid)){
await postdb.updatePost(req);
}
res.redirect("/users/post");
}
}
export default new Post();
// models/post.ts
interface PostSchema {
_id: ObjectId;
id: string;
title: string;
content: string;
categories: string[];
location: string;
payable: string;
postdate: Date;
closedate: string;
userid: string;
thumb: string;
}
class Post{
async count(req, query={}){
const posts = req.mydb.collection<PostSchema>("posts");
return await posts.countDocuments(query);
}
async createPost(req){
const id = crypto.randomUUID();
let categories: string[];
if(req.body.categories.includes(',')){
categories = req.body.categories.split(',');
}else{
categories = [req.body.categories]
}
const new_post = {
id: id,
title: req.body.title,
content: req.body.content,
categories: categories,
location: req.body.location,
payable: req.body.payable,
postdate: new Date(),
closedate: req.body.datetime,
userid: (await req.mysession.get("user")).id,
thumb: req.body.thumb,
}
const posts = req.mydb.collection<PostSchema>("posts")
await posts.insertOne(new_post)
}
async getPosts(req, amount, query={}){
const posts = req.mydb.collection<PostSchema>("posts");
return await posts.find(query).sort({date:-1,_id:-1}).limit(amount).toArray();
}
async editPost(req){
const posts = req.mydb.collection<PostSchema>("posts");
return await posts.findOne({id: req.params.id});
}
async updatePost(req){
let categories: string[];
if(req.body.categories.includes(',')){
categories = req.body.categories.split(',');
}else{
categories = [req.body.categories]
}
const edited_post = {$set:{
title: req.body.title,
content: req.body.content,
categories: categories,
location: req.body.location,
payable: req.body.payable,
closedate: req.body.datetime,
thumb: req.body.thumb,
}}
const posts = req.mydb.collection<PostSchema>("posts");
await posts.updateOne({id: req.params.id}, edited_post);
}
}
export default new Post();
// views/users/post.jsx
/** @jsx h */
import { h, renderSSR } from "../../deps.ts";
import Index from "./index.jsx";
function PostJsx(props){
const item = props.data.item;
let editor = ``
if(item){
editor = `
<form action="/users/post/edit/${item.id}" name="form" method="post"
onSubmit="submitForm(event)">
<input type="text" name="title" value="${item.title}" required
placeholder="Post title" />
<textarea id="editor" name="content" >${item.content}</textarea>
<input type="text" name="categories" value="${item.categories.toString()}" required
placeholder="Categories" />
<div class="wrapper">
<select id="category" onChange="getCategory()">
<option>Select a category</option>
<option>ES6</option>
<option>Python</option>
<option>PHP</option>
<option>Video</option>
</select>
<input type="text" name="location" value="${item.location}" required placeholder="Location" />
<input type="text" name="payable" value="${item.payable}" required placeholder="Payable" />
<input type="datetime-local" value="${item.closedate}" name="datetime" required />
<input type="submit" value="Publish" />
</div>
<input type="text" name="thumb" value="${item.thumb}" required placeholder="Thumb" />
</form>
`
}else{
editor = `
<form action="/users/post" name="form" method="post" onSubmit="submitForm(event)">
<input type="text" name="title" required placeholder="Post title" />
<textarea id="editor" name="content"></textarea>
<input type="text" name="categories" required placeholder="Categories" />
<div class="wrapper">
<select id="category" onChange="getCategory()">
<option>Slect a category</option>
<option>ES6</option>
<option>Python</option>
<option>PHP</option>
<option>Video</option>
</select>
<input type="text" name="location" required placeholder="Location" />
<input type="text" name="payable" required placeholder="Payable" />
<input type="datetime-local" name="datetime" required />
<input type="submit" value="Publish" />
</div>
<input type="text" name="thumb" required placeholder="Thumb" />
</form>
`
}
return(
<section class="Post">
<script src="/js/ckeditor/ckeditor.js"></script>
<script src="/js/addCategory.js"></script>
<link rel="stylesheet" href="/css/users/post.css" />
<div dangerouslySetInnerHTML={{__html: `
${editor}
`}}/>
<script src="/js/ckeditor/config.js"></script>
</section>
)
}
export default function Post(props){
props.pageInner = PostJsx;
const html = renderSSR(<Index data={ props } />);
return `<!DOCTYPE html>${ html }`;
}
Top comments (0)