// views/admin/post.jsx

/** @jsx h */
import { h, renderSSR } from "../../deps.ts"
import Base from '../base.jsx'
  
function PostJsx(props){
  const item = props.config.item
  
  if(!item){
    var content = `
    <form action="/admin/post" name="pform" onSubmit="submitform(event)" method="post">
      <input type="text" name="title" required placeholder="ចំណងជើង" />
      <textarea name="content" id="editor"></textarea>
      <input type="text" name='categories' required placeholder="ជំពូកផ្សេង​ៗ" />
      <div class="wrapper"> 
      <select id="category" onchange="getCategory()">
        <option>ជ្រើសរើស​ជំពូក</option>
        <option>News</option>
        <option>Movie</option>
        <option>Entertainment</option>
        <option>Sport</option>
      </select>
      <input type="text" name="thumb" required placeholder="តំណរ​ភ្ជាប់​រូប​តំណាង" />
      <input type="datetime-local" name="datetime" required />
      <input type="submit" value="បញ្ជូន" />
      <input type="hidden" name="video" value="" />
      </div>
    </form>
    `
    var videos = ``

  }else{
    var content = `
    <form action="/admin/post/edit/${item.id}" name="pform" onSubmit="submitform(event)" method="post">
      <input type="text" name="title" value="${item.title}" required placeholder="ចំណងជើង" />
      <textarea name="content" id="editor">${item.content}</textarea>
      <input type="text" name='categories' value="${item.categories.toString()}" 
      required placeholder="ជំពូកផ្សេង​ៗ" />
      <div class="wrapper"> 
      <select id="category" onchange="getCategory()">
        <option>ជ្រើសរើស​ជំពូក</option>
        <option>News</option>
        <option>Movie</option>
        <option>Entertainment</option>
        <option>Sport</option>
      </select>
      <input type="text" name="thumb" value="${item.thumb}" required 
      placeholder="តំណរ​ភ្ជាប់​រូប​តំណាង" />
      <input type="datetime-local" value="${item.postdate}" name="datetime" required />
      <input type="submit" value="បញ្ជូន" />
      <input type="hidden" name="video" value='${item.video}' />
      </div>
    </form>
    `
    var videos = `
    let is_video = null
    is_video = JSON.parse('${item.video}')

    if((is_video !== '') && (is_video !== '[]')){
      let html = ''
      let episode = is_video.length
    
      for(let video of is_video){
          html += "<div>"
          html += '<input value="'+video.type+'" required />'
          html += '<input value="'+video.id+'" required />'
          html += '<input value="'+video.status+'" required />'
          html += '<p title="Delete" onClick="deleteRow(event)" class="episode">'+(episode--)+'</p>'
          html += "</div>"
      }

      if($('.viddata div').html() === ''){
        $('.viddata div').append('<b>ប្រភេទ​</b>')
        $('.viddata div').append('<b>អត្តសញ្ញាណ​</b>')
        $('.viddata div').append('<b>ចប់ឬ​នៅ?</b>')
        $('.viddata div').append('<b>ភាគ/លុប</b>')
      }
    
      $('.viddata div:eq(0)' ).after(html)
    }
    `
  }

  return(
        <section class="Post">
            <link rel="stylesheet" href="/styles/admin/post.css" />
            <script src="/scripts/ckeditor/ckeditor.js"></script>
            <script src="/scripts/addCategory.js"></script>
            <script src="/scripts/video.js"></script>

            <div class="header">
                <div class="inner region">
                    <div class="logo">{props.config.pageTitle}</div>
                    <form action="/admin/search" method="post">
                        <select name="searchType">
                            <option>ការផ្សាយ</option>
                        </select>
                        <input type="text" name="q" required placeholder="Search" />
                        <input type="submit" value="ស្វែង​រក" />
                    </form>
                    <div class="logout">
                        <a href="/">ទំព័រ​មុខ</a> | <a href="/login/logout">ចេញ​ក្រៅ</a>
                    </div>
                </div>
            </div>

            <div class="main region">
              <div class="sidebar">
                <div class="inner">
                  <a href="/admin/post"><img src="/images/movie.png" /></a>
                  <a class="title" href="/admin/post">ការផ្សាយ</a>

                  <a href="/admin/book"><img src="/images/books.png" /></a>
                  <a class="title" href="/admin/book">សៀវភៅ</a>

                  <a href="/admin/category"><img src="/images/category.png" /></a>
                  <a class="title" href="/admin/category">ជំពូក</a>

                  <a href="/admin/upload"><img src="/images/upload.png" /></a>
                  <a class="title" href="/admin/upload">Upload</a>

                  <a href="/admin/user"><img src="/images/users.png" /></a>
                  <a class="title" href="/admin/user">អ្នក​ប្រើប្រាស់</a>

                  <a href="/admin/setting"><img src="/images/setting.png" /></a>
                  <a class="title" href="/admin/setting">Setting</a>
                </div>
              </div>
              <div class="content" dangerouslySetInnerHTML={{__html: `${content}` }}>
                <div class="wrapper" >
                  <select name="type">
                    <option>YouTube</option>
                    <option>YouTubePL</option>
                    <option>Facebook</option>
                    <option>OK</option>
                  </select>
                  <input type="text" name="videoid" required placeholder="អត្តសញ្ញាណ​វីដេអូ" />
                  <select name="status">
                    <option>ចប់</option>
                    <option>នៅ​មាន​ត</option>
                    <option>~ ចប់</option>
                  </select>
                  <div dangerouslySetInnerHTML={{__html: `
                     <input onclick='genJson()' type="submit" value="បញ្ចូល​វីដេអូ" />
                  `}} />
                </div>
                <div class='viddata'>
                  <div></div>
                </div>

                <script dangerouslySetInnerHTML={{__html: `${videos}`}}/>
                
                <script src="/scripts/ckeditor/config.js"></script>
              </div>
              
            </div>

        </section>
  )
}

function Post(config){
  config.page = PostJsx
  const str = renderSSR(<Base config={config} />)
  return `<!DOCTYPE html>${str}`
}

export default Post

 

// routes/admin/post.js

import { Router, verify } from "../../deps.ts"
const router = Router()

import post from '../../controllers/admin/post.js'

router.get('/', async (req, res) => {
  if(await req.session.get("user") === (await verify(req.myjwt, req.mykey)).user){
    post.getItem(req, res)
  }else{
    res.redirect('/login')
  }
})

router.post('/', async (req, res) => {
  if(await req.session.get("user") === (await verify(req.myjwt, req.mykey)).user){
    post.postItem(req, res)
  }else{
    res.redirect('/login')
  }
})

router.get('/edit/:id', async (req, res) => {
  if(await req.session.get("user") === (await verify(req.myjwt, req.mykey)).user){
    post.getItem(req, res)
  }else{
    res.redirect('/login')
  }
})

router.post('/edit/:id', async (req, res) => {
  if(await req.session.get("user") === (await verify(req.myjwt, req.mykey)).user){
    post.editItem(req, res)
  }else{
    res.redirect('/login')
  }
})
  
export default router

 

// controllers/admin/post.js

import config from '../../config.js'
import post from '../../views/admin/post.jsx'
import postdb from '../../models/postdb.ts'

class Post{
    async getItem(req, res){
        this.config = await config()
        this.config.pageTitle = 'ទំព័​រ​ការផ្សាយ'
        this.config.route = '/admin/post'
        this.config.type = 'post'

        this.config.count = await postdb.count(req)
        const {item, items} = await postdb.getItem(req, this.config.adminItemLimit)

        if(item){
            await req.session.set('post-userid', item.userid)
        }

        this.config.item = item
        this.config.items = items
        
        const html = await post(this.config)
        res.send(html)
    }

    async postItem(req, res){
        const user_role = await req.session.get('user-role')
        if(user_role in {'Admin':1,'Editor':1,'Author':1}){
            await postdb.insertPost(req)
        }

        res.redirect('/admin/post')
    }

    async editItem(req, res){
        const user_role = await req.session.get('user-role')
        if(user_role in {'Admin':1,'Editor':1,'Author':1}){

            const user_id = await req.session.get('user-id')
            const post_userid = await req.session.get('post-userid')
            
            if((user_role === 'Admin') || (user_id === post_userid)){
                await postdb.editPost(req)
            }
        }

        res.redirect('/admin/post')
    }
}

export default new Post()

 

// models/postdb.js

interface PostSchema {
    _id: ObjectId;
    id: string; 
    title: string;
    content: string;
    categories: string[];
    thumb: string;
    postdate: string;
    video: string;
    userid: string;
}

class Postdb{
    async count(req, query={}){
        const posts = req.mydb.collection<PostSchema>("posts")
        return await posts.countDocuments(query)
    }

    async insertPost(req){
        const id = Date.now() + Math.round(Math.random() * 1E9).toString()

        if(req.body.categories.includes(',')){
            var categories: string[] = req.body.categories.split(',')
        }else{
            var categories: string[] = [req.body.categories]
        }

        const user_id = await req.session.get('user-id')
        
        let newPost = {
            id: id, 
            title: req.body.title,
            content: req.body.content,
            categories: categories,
            thumb: req.body.thumb,
            postdate: req.body.datetime,
            video: req.body.video,
            userid: user_id,
        }
 
        const posts = req.mydb.collection<PostSchema>("posts")
        await posts.insertOne(newPost)
    }

    async getItem(req, amount, query={}){
        const posts = req.mydb.collection<PostSchema>("posts")
        let item = null

        if(req.params.id){
            item = await posts.findOne({id: req.params.id})
        }

        const items = await posts.find(query).sort({date:-1,_id:-1}).limit(amount).toArray()
        return {item:item, items:items}
    }

    async editPost(req){
        if(req.body.categories.includes(',')){
            var categories: string[] = req.body.categories.split(',')
        }else{
            var categories: string[] = [req.body.categories]
        }

        let editPost = {$set:{
            title: req.body.title,
            content: req.body.content,
            categories: categories,
            thumb: req.body.thumb,
            postdate: req.body.datetime,
            video: req.body.video,
        }}
        
        const posts = req.mydb.collection<PostSchema>("posts")
        await posts.updateOne({id: req.params.id}, editPost)
    }
}

export default new Postdb

 

GitHub: https://github.com/Sokhavuth/khmerweb-deno

Deno Deploy: https://khmerweb-blog.deno.dev/admin/post