Job Announcement Website: Building Login Page
Tags: javascript, webdev, react, opine
Published: 2022-08-12 07:42:00

{% embed https://dev.to/sokhavuth/table-of-contents-2o4e %}
GitHub: [https://github.com/Sokhavuth/opine-job](https://github.com/Sokhavuth/opine-job)
Deno Deploy: [https://khmerweb-job.deno.dev/users](https://khmerweb-job.deno.dev/users)
<br/>
<p>
As Deno hosting platform “Deno Deploy” supports only React template engine and other template engines similar to React, we can use Nano JSX as a template engine to build all kind of HTML pages for our application. To use Nano JSX, we need to include the link to this package in the list of packages inside deps.ts module.
</p>

```ts
// deps.ts
 
export {
    dirname,
    fromFileUrl,
    join,
} from "https://deno.land/std@0.151.0/path/mod.ts";
 
export {
    json,
    opine,
    Router,
    serveStatic,
    urlencoded,
} from "https://deno.land/x/opine@2.2.0/mod.ts";
 
export { config } from "https://deno.land/std@0.147.0/dotenv/mod.ts";
export { Bson, MongoClient } from "https://deno.land/x/mongo@v0.30.1/mod.ts";
export { connect } from 'https://deno.land/x/redis@v0.26.0/mod.ts';
export { OpineSession, RedisStore } from "https://deno.land/x/sessions@v1.5.4/mod.ts";
 
export { h, renderSSR } from "https://deno.land/x/nano_jsx@v0.0.33/mod.ts";
```
<p>To build the login page, we should do as below:</p>

```jsx
// views/users/login.jsx

/** @jsx h */
import { h, renderSSR } from "../../deps.ts";
import Base from "../base.jsx";


function LoginJsx(props){
    return(
        <section class="Login" >
            <link rel="stylesheet" href="/css/users/login.css" />
            <div class="wrapper">
                <div class="title">Log 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.message}</div>
                </form>
            </div>
        </section>
    )
}
   
export default function Login(props){
    props.page = LoginJsx;
    const html = renderSSR(<Base data={props} />);

    return `<!DOCTYPE html>${html}`;
}
```

```jsx
// views/base.jsx

/** @jsx h */
import { h } from "../deps.ts";


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.site_title} | {props.data.page_title}</title>
                <link href="/images/siteLogo.png" rel="icon" />
                <link href="/css/style.css" rel="stylesheet" />
                <link href="/fonts/setup.css" rel="stylesheet" />
                <script src="/js/jquery.js"></script>
            </head>
            <body>
                <Page data={props.data} />
            </body>
        </html>
    )
  }
```

```css
/* public/css/users/login.css */
 
.Login{
    width: 400px;
    margin: 100px auto 0;
}
 
.Login .wrapper{
    background: var(--background);
    margin-bottom: 10px;
}
 
.Login .title{
    text-align: center;
    font: 20px/1.5 StardosStencil, Limonf3;
    padding: 5px;
    border-bottom: 1px solid lightgrey;
}
 
.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);
}
```

```css
/* public/css/style.css */
 
:root{
  --background-light: lightgrey;
  --background: lavender;
  --background-dark: #272727;
  --body-font: 14px/1.5 Vidaloka, OdorMeanChey;
  --link: lavender;
  --color: black;
}
 
*{
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
a{
  text-decoration: none;
  color: var(--link);
}
a:hover{
  opacity: .7;
}
.region{
  max-width: 1100px;
  margin: 0 auto;
}
 
body{
  color: var(--color);
  font: var(--body-font);
  background: var(--background-light);
}
```