Reorganize the TSX to handle making the pages.

This commit is contained in:
Dave Smith-Hayes 2024-03-03 21:28:33 -05:00
parent a6fccd61be
commit c3ddda83db
6 changed files with 81 additions and 25 deletions

View File

@ -1,20 +1,23 @@
import { FC } from 'hono/jsx'; import { html } from 'hono/html';
import Header from './layout/header';
import Footer from './layout/footer';
const Layout: FC = (props) => { export const Layout = (props: { title: string, children?: any }) => {
return ( return html`<!DOCTYPE html>
<html> <html>
<head> <head>
<title>{props.siteData.title}</title> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>${props.title}</title>
</head> </head>
<body> <body>
<Header title={props.siteData.title} /> <header>
{props.children} <h1>Slovocast</h1>
<Footer title={props.siteData.copyright} /> </header>
<main>${props.children}</main>
<footer>
<p>&copy; 2024, Slovocast</p>
</footer>
</body> </body>
</html> </html>`;
)
} }
export default Layout;

View File

@ -0,0 +1,31 @@
import { FC } from "hono/jsx"
const Error: FC = (props) => {
return (
<div class="form-error">
{props.message}
</div>
);
};
export const LoginForm: FC = (props) => {
return (
<>
{props.error ? <Error message={props.error.message} /> : null}
<form action="/login" method="POST">
<label for="email">
<div>Email</div>
<input type="text" name="email" required />
</label>
<label for="password">
<div>Password</div>
<input type="password" name="password" required />
</label>
<div>
<input type="submit" name="login" value="Login" />
</div>
</form>
</>
);
};

View File

@ -0,0 +1,11 @@
import { Layout } from '../layout';
const LoginPage = (props: { error?: any }) => {
return (
<Layout title="Login">
<LoginForm action="/login" error=error />
</Layout>
);
};
export default LoginPage;

View File

@ -1,17 +1,18 @@
import { Hono } from 'hono'; import { Hono } from 'hono';
import Layout from './frontend/layout'; import Layout from './frontend/layout';
import { SiteConfig, configMiddleware } from './middleware/config'; import { SiteConfig, configMiddleware } from './middleware/config';
import LoginForm from './frontend/user/login';
const app = new Hono(); const app = new Hono();
app.use(configMiddleware); app.use(configMiddleware);
app.get('/', async (c) => { app.get('/', async (c) => {
const siteData: SiteConfig = await c.get('config'); const siteData: SiteConfig = c.get('config');
const layout = ( const layout = (
<Layout siteData={siteData}> <Layout siteData={siteData}>
<main> <main>
<h1>Slovocast</h1> <h1>Welcome to Slovocast</h1>
</main> </main>
</Layout> </Layout>
); );
@ -19,4 +20,16 @@ app.get('/', async (c) => {
return c.html(layout); return c.html(layout);
}); });
app.get('/login', async (c) => {
const config: SiteConfig = c.get('config');
return c.html(
<Layout siteData={config}>
<main>
<LoginForm action="/login" />
</main>
</Layout>
);
});
export default app; export default app;

View File

@ -1,16 +1,10 @@
import { Hono } from 'hono'; import { Hono } from 'hono';
import { Context } from 'hono'; import { Context } from 'hono';
import SiteData from '../model/SiteData';
type SiteConfig = {
name: string,
description: string,
baseUrl: string
copyright: string,
};
const currentYear = new Date().getFullYear(); const currentYear = new Date().getFullYear();
const config: SiteConfig = { const config: SiteData = {
name: "Slovocast", name: "Slovocast",
description: "A no-nonesense Podcast hosting platform.", description: "A no-nonesense Podcast hosting platform.",
baseUrl: "dev.slovocast.com", baseUrl: "dev.slovocast.com",
@ -22,4 +16,4 @@ const configMiddleware = async function(c: Context, next) {
await next(); await next();
}; };
export { SiteConfig, configMiddleware }; export { configMiddleware };

View File

@ -1,4 +1,8 @@
export default interface SiteData { type SiteData = {
title: string, name: string,
description: string, description: string,
baseUrl: string
copyright: string,
}; };
export default SiteData;