TV Channel Website: Dashboard Index Page
Tags: webdev, tutorial, python, bottle
Published: 2022-08-26 04:24:00

GitHub: [https://github.com/Sokhavuth/TV-Channel](https://github.com/Sokhavuth/TV-Channel)
Vercel: [https://khmerweb-tv-channel.vercel.app/login](https://khmerweb-tv-channel.vercel.app/login)
<br/>

<p>After the route to the future dashboard was established, we can start to build the dashboard by creating the index page first. This page will be served as the basis of all pages.</p>

```py
# routes/backend/post.py

from bottle import Bottle, get, redirect
from controllers.backend.post import Post
import config


app = Bottle()
post = Post()

@app.get("/")
def getPage():
    if(config.checkLogged()):
        return post.getPage()
    else:
        redirect("/login")
```

```py
# controllers/backend/post.py

import config, copy
from bottle import template, redirect, request

class Post:
    def __init__(self):
        self.setup = copy.deepcopy(config.settings())


    def getPage(self):
        self.setup["pageTitle"] = "POST PAGE"
        self.setup["route"] = "/admin/post"
        user = config.checkLogged()
        if("name" in user):
            self.setup["username"] = user["name"]

        return template("base", data=self.setup)


```

```html
<!--views/backend/index.tpl-->

<link rel="stylesheet" href="/static/styles/backend/index.css" />

<section class="Index">
    <header>
        <div class="inner region">
            <div class="page-title">{{ data["pageTitle"] }}</div>
            <form action="/admin/search" method="post">
                <select name="searchtype">
                    <option>Post</option>
                    <option>Category</option>
                    <option>User</option>
                </select>
                <input type="text" name="q" required />
                <input type="submit" value="Search" />
            </form>
            <div class="logout">
                {{ data["username"]}} | <a href="/">Home</a> | <a href="/login/logout">Logout</a>
            </div>
        </div>
    </header>

    <div class="main region">
        <div class="sidebar">
            <div class="inner">
                <a href="/admin/post"><img src="/static/images/movie.png" /></a>
                <a href="/admin/post">Post</a>

                <a href="/admin/category"><img src="/static/images/category.png" /></a>
                <a href="/admin/category">Category</a>

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

                <a href="/admin/user"><img src="/static/images/users.png" /></a>
                <a href="/admin/user">User</a>

                <a href="/admin/setting"><img src="/static/images/setting.png" /></a>
                <a href="/admin/setting">Settings</a>
            </div>
        </div>
        <div class="content">Content</div>
    </div>

    <div class="footer region">
        <div class="info">Total number of items:</div>
        <ul></ul>
        <div class="pagination">
            <img onclick="paginate(`{{ data['route'] }}`)" src="/static/images/load.png" />
        </div>

        <div class="credit">
            <a href="https://khmerweb.vercel.app/">&copy: Khmer Web 2022</a>
        </div>
    </div>
</section>
```

```css
/* public/styles/backend/index.css */

.Index header{
    background-color: var(--background);
    margin-bottom: 20px;
    border-bottom: 7px solid white;
}

.Index header .inner{
    display: grid;
    grid-template-columns: 25% auto 25%;
    align-items: center;
    padding: 10px 0;
}

.Index header .inner .page-title{
    font: 20px/1.5 Anton;
}

.Index header .inner form{
    display: grid;
    grid-template-columns: 20% auto 20%;
}

.Index header .inner form input,
.Index header .inner form select{
    font: var(--bordy-font);
    padding: 1px 5px;
}

.Index header .inner .logout{
    text-align: right;
}

.Index header .inner .logout a{
    color: white;
}

.Index .main{
    display: grid;
    grid-template-columns: auto 75%;
    grid-gap: 10px;
}

.Index .main .sidebar{
    background-color: var(--background);
    padding: 20px;
}

.Index .main .sidebar .inner{
    display: grid;
    grid-template-columns: 25% auto;
    grid-gap: 15px;
    align-items: center;
}

.Index .main .sidebar .inner img{
    width: 100%;
    float: left;
}

.Index .main .sidebar .inner a{
    font: 18px/1.5 Oswald;
    color: white;
}

.Index .footer{
    padding: 10px 0 30px;
}

.Index .footer .info{
    background-color: var(--background);
    text-align: center;
    padding: 5px 0;
}

.Index .footer ul{
    margin: 10px 0;
}

.Index .footer .pagination{
    background-color: var(--background);
    text-align: center;
}

.Index .footer .pagination img{
    padding-top: 5px;
}

.Index .footer .pagination img:hover{
    cursor: pointer;
    opacity: 0.7;
}

.Index .footer .credit{
    padding-top: 30px;
    text-align: center;
}
```