//routes/admin/category.js
import express from 'express'
const category = express.Router()

category.get('/',async function(req,res){
    if(req.session.user){
        const module = await import('../../controllers/admin/category/read.js')
        module.default(req,res)
    }else{
        res.redirect('/admin/login')
    }
})

category.post('/', async function(req,res){
    if(req.session.user){
        const module = await import('../../controllers/admin/category/create.js')
        module.default(req,res)
    }else{
      res.redirect('/admin/login')
    }
})

export default category

 

//controllers/admin/category/read.js
import settings from '../../../settings.js'
import read from '../../../models/category/read.js'
import count from '../../../models/count.js'

export default async (req,res)=>{
    settings.pageTitle = 'ទំព័រ​ជំពូក'
    settings.route = '/admin/category'
    settings.items = await read(req,settings.dItemLimit)
    settings.count = await count(req,'categories')

    res.render('base',{data:settings})
}

 

//models/category/read.js

export default async (req,amount=10,id=false,page=0)=>{
    if(id){
        return await req.mydb.collection("categories").findOne({id:id})
    }else if(page){
        return await req.mydb.collection("categories")
                                .find().skip(amount*page).sort({date:-1,_id:-1}).limit(amount).toArray()
    }else if(amount === 'all'){
        return await req.mydb.collection("categories").find({}, {title:1,_id:0}).sort({title:1}).toArray()
    }else{
        return await req.mydb.collection("categories").find().sort({date:-1,_id:-1}).limit(amount).toArray()
    }
}

 

//models/count.js

export default async (req,col)=>{
    return await req.mydb.collection(col).countDocuments()
}

 

<!--views/admin/index.ejs-->
<link href="/styles/admin/index.css" rel="stylesheet">

<section class="Header">
    <div class="wrapper region">
        <div class="logo"><%= data.pageTitle %></div>
        <form method="post" action="/search">
            <select name="type">
                <option>ការផ្សាយ</option>
                <option>ទំព័រស្តាទិក</option>
                <option>អ្នក​ប្រើប្រាស់</option>
            </select>
            <input type="text" name="q" placeholder="Search" required>
            <input type="submit" value="ស្វែង​រក">
        </form>
        <div class="logout">
            <a href="/">ទំព័រ​មុខ</a> | <a href="/admin/login/logout">ចេញ​ក្រៅ</a>
        </div>
    </div>
</section>

<section class="Body">
    <div class="wrapper region">
        <div class="sidebar">
            <a href='/admin/post'><img src='/images/movie.png' /></a>
            <a href='/admin/post'>ការផ្សាយ</a>
            
            <a href='/admin/category'><img src='/images/category.png' /></a>
            <a href='/admin/category'>ជំពូក</a>
            
            <a href='/admin/book'><img src='/images/books.png' /></a>
            <a href='/admin/book'>សៀវភៅ</a>
            
            <a href='/admin/upload'><img src='/images/upload.png' /></a>
            <a href='/admin/upload'>Upload</a>
            
            <a href='/admin/user'><img src='/images/users.png' /></a>
            <a href='/admin/user'>អ្នក​ប្រើប្រាស់</a>
            
            <a href='/admin/setting'><img src='/images/setting.png' /></a>
            <a href='/admin/setting'>Setting</a>
        </div>
        <div class="Content">
            <% if(data.route.includes('/category')){ %>
                <%- include('category.ejs') %>
            <% } %>
        </div>
    </div>
    <div class="Listing region">
        <div class="info">សរុប​ទាំងអស់​​មាន​ចំនួនៈ <%= data.count %></div>
        <ul class="list">
        <% if('items' in data){ %>
            <% for(let item of data.items) { %>
            <li>
                <div class='thumb'>
                    <a href='<%= data.route %>/<%= item.id %>'><img src='<%= item.thumb %>'/></a>
                    <% if('video' in item){ %>
                        <% if(item.video !== ''){ %>
                            <img class="play-icon" src="/images/play-icon"/>
                        <% } %>
                    <% } %>
                </div>
                <div class="title">
                    <a href="<%= data.route %>/<%= item.id %>"><%= item.title %></a>
                    <div><%= item.date.toLocaleDateString() %></div>
                </div>
                <div class="edit">
                    <a href="<%= data.route %>/edit/<%= item.id %>"><img src="/images/edit.png"/></a>
                    <a href="<%= data.route %>/delete/<%= item.id %>"><img src="/images/delete.png"/></a>
                </div> 
            </li>
            <% } %>
        <% } %>
        </ul>
        <div class="paginate region">
            <img onclick="loadMore('<%= data.route %>')" src="/images/load-more.png"/>
        </div>
    </div>
</section>

 

/* public/styles/admin/index.css */
.Header{
    background: var(--background-dark);
    border-bottom: 8px solid white;
}

.Header .wrapper{
    padding: 10px 0;
    display: grid;
    grid-template-columns: 25% 50% 25%;
    align-items: center;
}

.Header .wrapper .logo{
    font: 22px/1.5 Anton, Limonf3;
}

.Header .wrapper form{
    display: grid;
    grid-template-columns: 20% auto 15%;
}

.Header .wrapper form input,
.Header .wrapper form select{
    font: var(--background-light);
    padding: 0 5px;
}

.Header .wrapper .logout{
    text-align: right;
}

.Body .wrapper{
    display: grid;
    grid-template-columns: 25% auto;
    margin-top: 20px;
}

.Body .wrapper .sidebar{
    max-height: 600px;
    padding: 20px;
    display: grid;
    grid-template-columns: 25% auto;
    grid-gap: 10px;
    align-items: center;
    background: white;
    margin-right: 10px;
}

.Body .wrapper .sidebar a img{
    width: 100%;
}

.Body .wrapper .sidebar a{
    font: 18px/1.5 Koulen, Oswald;
    color: grey;
}

.Listing .info{
    background: var(--item-listing);
    color: var(--item-listing-color);
    text-align: center;
    padding: 10px;
    margin: 10px 0;
}

.Listing ul{
    display: grid;
    grid-template-columns: calc(50% - 5px ) calc(50% - 5px );
    grid-gap: 10px;
}

.Listing ul li{
    display: grid;
    grid-template-columns: 25% auto 20%;
    align-items: center;
    background: var(--item-listing);
    color: var(--item-listing-color);
}

.Listing ul li .thumb{
    position: relative;
    padding-top: 56.25%;
}

.Listing ul li .thumb a{
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}

.Listing ul li .thumb img{
    width: 100%;
    height: 100%;
}

.Listing ul li .title{
    padding-left: 10px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.Listing ul li .title a{
    color: var(--item-listing-color);
}

.Listing ul li .edit{
    text-align: right;
    padding-right: 10px;
    visibility: hidden;
}

.Listing ul li:hover .edit{
    visibility: visible;
}

.Listing ul li .edit img{
    width: 45px;
}

.Listing .paginate{
    text-align: center;
    background: var(--item-listing);
    margin: 10px 0 20px;
    padding: 10px 0 5px;
}

 

GitHub: https://github.com/Sokhavuth/Blog_

Vercel: https://khmerweb-blog.vercel.app/