//controllers/backend/category.js

import category from '../../models/category.js'

class Category{
    async getPage(req,res){
        if(req.session.user){
            req.settings.pageTitle = 'ទំព័រ​ជំពូក'
            req.settings.message = ''
            req.settings.route = '/admin/category'
            req.settings.type = 'category'

            req.settings.items = await category.getItem(req,req.settings.dItemLimit)
            req.settings.count = await category.countItem(req)
  
            res.render('base', {data:req.settings})
        }else{
            res.redirect('/admin/login')
        }
    }

    async createItem(req,res){
        if(req.session.user){
            if(req.session.user.role == 'Admin'){
                category.createItem(req)
            }

            res.redirect('/admin/category')
        }else{
            res.redirect('/admin/login')
        }
    }
}

export default new Category()

 

//models/category.js

class Category{
    async createItem(req){
        const id = Date.now() + Math.round(Math.random() * 1E9).toString()
 
        let myCategory = {
            id: id, 
            title: req.body.label,
            thumb: req.body.thumb,
            date: req.body.datetime
        }
 
        req.mydb.collection("categories").insertOne(myCategory)
    }

    async countItem(req){
        return await req.mydb.collection('categories').countDocuments()
    }

    async getItem(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()
        }
    }
}

export default new Category()

 

<!--views/backend/index.ejs-->

<link href="/styles/backend/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>
        
        <% if(data.route == '/admin/post'){ %>
            <%- include('./post.ejs') %>
        <% } else if(data.route == '/admin/category'){ %>
            <%- include('./category.ejs') %>
        <% } %>

    </div>
</section>

<section class="Footer region">
    <div class="info">សរុប​ទាំងអស់​មាន​ចំនួនៈ <%= data.count %></div>

    <ul>
        <% if('items' in data){ %>
            <% for(let item of data.items) { %>
            <li>
                <div class='thumb'>
                    <a href='<%= data.type %>/<%= 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.type %>/<%= item.id %>"><%= item.title %></a>
                    <div><%= (new Date(item.date)).toLocaleDateString('it-IT') %></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"><img src='/images/load-more.png' /></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-wrapper{
    background: white;
    margin-right: 10px;
}

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

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

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

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

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

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

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

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

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

.Footer ul li .thumb .play-icon{
    position: absolute;
    top: 50%;
    left: 50%;
    width: 25%;
    height: auto;
    transform: translate(-50%,-50%);
}

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

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

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

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

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

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

.Footer .paginate img:hover{
    cursor: pointer;
}

 

GitHub: https://github.com/Sokhavuth/Node.js_backend

Vercel: https://vercel.com/sokhavuth/node-js-backend