Blog Engine with Fresh: Building Login Page
Tags: javascript, webdev, react, fresh
Published: 2022-08-09 05:06:00

{% embed https://dev.to/sokhavuth/table-of-contents-41pd %}
GitHub: [https://github.com/Sokhavuth/deno-fresh](https://github.com/Sokhavuth/deno-fresh)
Deno Deploy: [https://khmerweb-fresh.deno.dev/login](https://khmerweb-fresh.deno.dev/login)
<br/>

```js
// routes/login.jsx

/** @jsx h */
import { h } from "preact";
import VLogin from '../components/front/login.jsx';
import CLogin from "../controllers/front/login.js";


export const handler = {
  async GET(req, ctx){
      return await CLogin.getForm(req, ctx);
  },  

  async POST(req, ctx){
      //return await CLogin.checkUser(req, ctx);
  },
}


export default function Template(props){
    return (
        <VLogin data={props.data} />
    )
}
```

```js
// controllers/front/login.js

import { setCookie, getCookies, deleteCookie } from "cookies";
import { setting, secret_key, myredis } from 'setting';
import { create, verify, getNumericDate } from "jwt";
import userdb from "../../models/user.ts";
import { bcrypt } from "bcrypt";


class Login{
    async getForm(req, ctx){
        const cookies = getCookies(req.headers);

        if((cookies)&&(cookies.session_id)){
            const jwt = await myredis.get(cookies.session_id);
            try{
                const payload = await verify(jwt, secret_key, "HS512");
                if(payload.user){
                    return new Response(undefined, { headers: {location: `/admin/post`}, status: 302 });
                }
            }catch(error){
                console.log(error);
                const config = setting();
                config.page_title = "Login Page";
                const resp = new Response();
                deleteCookie(resp.headers, "session_id");
                return await ctx.render({"setting": config});
            }
        }   

        const config = setting();
        config.page_title = "Login Page";
        return await ctx.render({"setting": config});
    }
}

export default new Login();
```

```js
// components/front/login.jsx
 
/** @jsx h */
import { h } from "preact";
import Base from "../base.jsx";
 
function LoginJsx(props){
 
  return(
      <section class="Login" >
          <link rel="stylesheet" href="/styles/front/login.css" />
          <div class="wrapper">
              <div class="title">Login into the Dashboard</div>
              <form action="/login" method="post" >
                  <a>Email:</a><input type="email" name="email" value="guest@khmerweb.app" 
                      required />
                  <a>Password:</a><input type="password" name="password" 
                      value="rdagfyhows"  required />
                  <a></a><input type="submit" value="Submit" />
                  <a></a><div class="info">{props.data.setting.message}</div>
              </form>
        </div>
      </section>
  )
}
 
export default function Login(props){
  props.data.page = LoginJsx
  return(
    <Base data={props.data} />
  )
}
```

```js
// components/base.jsx

/** @jsx h */
import { h } from "preact";


export default function Base(props){
    const Page = props.data.page
    return(
        <html>
          <head>
            <meta charSet="UTF-8"/>
            <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
            <title>{props.data.setting.site_title} | {props.data.setting.page_title}</title>
            <link href="/styles/base.css" rel="stylesheet" />
            <link href="/fonts/setup.css" rel="stylesheet" />
            <script src="/scripts/jquery.js"></script>
          </head>
          <body>
            <Page data={props.data} />
          </body>
        </html>
    )
  }
```

```css
/* static/styles/front/login.css */

.Login{
    width: 400px;
    margin: 100px auto 0;
}

.Login .wrapper{
    background: var(--background-light);
    margin-bottom: 10px;
}

.Login .title{
    text-align: center;
    font: 20px/1.5 StardosStencil, Limonf3;
    padding: 5px;
    background: var(--background-dark);
    color: white;
}

.Login form{
    padding: 20px;
    display: grid;
    grid-template-columns: 20% auto;
    grid-gap: 5px;
    align-items: center;
}

.Login form a{
    text-align: right;
    color: black;
}

.Login form input{
    font: var(--body-font);
    padding: 2px 5px;
}

.Login form .info{
    text-align: center;
    font: var(--body-font);
}
```