Reorganize the TSX to handle making the pages.
This commit is contained in:
parent
a6fccd61be
commit
c3ddda83db
@ -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>© 2024, Slovocast</p>
|
||||||
|
</footer>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>`;
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Layout;
|
|
||||||
|
31
app/src/frontend/layout/login-form.tsx
Normal file
31
app/src/frontend/layout/login-form.tsx
Normal 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>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
11
app/src/frontend/pages/login.tsx
Normal file
11
app/src/frontend/pages/login.tsx
Normal 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;
|
@ -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;
|
||||||
|
@ -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 };
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user