WIP all the things
This commit is contained in:
parent
0fc6b1b8a8
commit
17ae95e3fe
34
components/Page.tsx
Normal file
34
components/Page.tsx
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
import { JSX } from "preact";
|
||||||
|
|
||||||
|
const NAV_ITEMS = {
|
||||||
|
"/note": "Notes",
|
||||||
|
"/register": "Register",
|
||||||
|
"/login": "Login",
|
||||||
|
};
|
||||||
|
|
||||||
|
const navItem = ([url, text]: [string, string]) => {
|
||||||
|
return (
|
||||||
|
<a class="px-4 py-2 text-blue-500 hover:bg-gray-900" href={url}>{text}</a>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function Page(props: JSX.HTMLAttributes<HTMLDivElement>) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<header>
|
||||||
|
<h1>
|
||||||
|
<a href="/">LyricScreen</a>
|
||||||
|
</h1>
|
||||||
|
<nav class="flex">
|
||||||
|
{Object.entries(NAV_ITEMS).map(navItem)}
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
<main>
|
||||||
|
{props.children}
|
||||||
|
</main>
|
||||||
|
<footer>
|
||||||
|
"It's a bit much, really..."
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
10
fresh.gen.ts
10
fresh.gen.ts
|
@ -14,8 +14,9 @@ import * as $7 from "./routes/countdown.tsx";
|
||||||
import * as $8 from "./routes/github/[username].tsx";
|
import * as $8 from "./routes/github/[username].tsx";
|
||||||
import * as $9 from "./routes/index.tsx";
|
import * as $9 from "./routes/index.tsx";
|
||||||
import * as $10 from "./routes/note.tsx";
|
import * as $10 from "./routes/note.tsx";
|
||||||
import * as $11 from "./routes/route-config-example.tsx";
|
import * as $11 from "./routes/register.tsx";
|
||||||
import * as $12 from "./routes/search.tsx";
|
import * as $12 from "./routes/route-config-example.tsx";
|
||||||
|
import * as $13 from "./routes/search.tsx";
|
||||||
import * as $$0 from "./islands/Countdown.tsx";
|
import * as $$0 from "./islands/Countdown.tsx";
|
||||||
import * as $$1 from "./islands/Counter.tsx";
|
import * as $$1 from "./islands/Counter.tsx";
|
||||||
|
|
||||||
|
@ -32,8 +33,9 @@ const manifest = {
|
||||||
"./routes/github/[username].tsx": $8,
|
"./routes/github/[username].tsx": $8,
|
||||||
"./routes/index.tsx": $9,
|
"./routes/index.tsx": $9,
|
||||||
"./routes/note.tsx": $10,
|
"./routes/note.tsx": $10,
|
||||||
"./routes/route-config-example.tsx": $11,
|
"./routes/register.tsx": $11,
|
||||||
"./routes/search.tsx": $12,
|
"./routes/route-config-example.tsx": $12,
|
||||||
|
"./routes/search.tsx": $13,
|
||||||
},
|
},
|
||||||
islands: {
|
islands: {
|
||||||
"./islands/Countdown.tsx": $$0,
|
"./islands/Countdown.tsx": $$0,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { ErrorPageProps } from "$fresh/server.ts";
|
import { ErrorPageProps } from "$fresh/server.ts";
|
||||||
|
|
||||||
export default function Error500Page({ error }: ErrorPageProps) {
|
export default function Error500Page(_props: ErrorPageProps) {
|
||||||
return <p>500 internal error: {(error as Error).message}</p>;
|
return <p>500 internal error</p>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,15 @@
|
||||||
import Counter from "../islands/Counter.tsx";
|
import Counter from "../islands/Counter.tsx";
|
||||||
|
import { Page } from "../components/Page.tsx";
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
return (
|
return (
|
||||||
<div class="p-4 mx-auto max-w-screen-md">
|
<Page>
|
||||||
<img
|
<img
|
||||||
src="/logo.svg"
|
src="/logo.svg"
|
||||||
class="w-32 h-32"
|
class="w-32 h-32"
|
||||||
alt="the fresh logo: a sliced lemon dripping with juice"
|
alt="the fresh logo: a sliced lemon dripping with juice"
|
||||||
/>
|
/>
|
||||||
<p class="my-6">
|
|
||||||
Welcome to `fresh`. Try updating this message in the ./routes/index.tsx
|
|
||||||
file, and refresh.
|
|
||||||
</p>
|
|
||||||
<Counter start={3} />
|
<Counter start={3} />
|
||||||
</div>
|
</Page>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Handlers, PageProps } from "$fresh/server.ts";
|
import { Handlers, PageProps } from "$fresh/server.ts";
|
||||||
import { query, type QueryObjectResult } from "../db.ts";
|
import { query } from "../db.ts";
|
||||||
|
|
||||||
interface Note {
|
interface Note {
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -12,34 +12,24 @@ export const handler: Handlers<Note[] | null> = {
|
||||||
console.debug({ request, context });
|
console.debug({ request, context });
|
||||||
const result = await query("select * from notes");
|
const result = await query("select * from notes");
|
||||||
if (result == null) throw "unable to fetch from database";
|
if (result == null) throw "unable to fetch from database";
|
||||||
const notes = result.rows;
|
const notes = result.rows as Note[];
|
||||||
console.debug(notes);
|
console.debug(notes);
|
||||||
return await context.render(notes);
|
return await context.render(notes);
|
||||||
},
|
},
|
||||||
async POST(request, context) {
|
|
||||||
console.debug({ request, context });
|
|
||||||
if (request.headers.get("content-type") != "application/json") {
|
|
||||||
throw "content-type must be application/json";
|
|
||||||
}
|
|
||||||
const body = await request.json();
|
|
||||||
console.log({ body });
|
|
||||||
if (!("content" in body)) {
|
|
||||||
throw "no content field present in body";
|
|
||||||
}
|
|
||||||
const result = await query(
|
|
||||||
"insert into notes (content) values ($1) returning id",
|
|
||||||
body.content,
|
|
||||||
);
|
|
||||||
if (result == null) throw "failed to fetch notes";
|
|
||||||
const { rows: [{ id }] } = result as QueryObjectResult<Note>;
|
|
||||||
console.debug(id);
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function Page({ data }: PageProps<Note[] | null>) {
|
export default function Page({ data }: PageProps<Note[] | null>) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<p>Yo!</p>
|
<h1>List of Notes</h1>
|
||||||
|
<nav>
|
||||||
|
<a href="/" class="text-blue-500 p-2">Back to Index</a>
|
||||||
|
</nav>
|
||||||
|
<p>Create a note:</p>
|
||||||
|
<form action="./create" method="POST">
|
||||||
|
<textarea name="content"></textarea>
|
||||||
|
<button>Post</button>
|
||||||
|
</form>
|
||||||
<pre>
|
<pre>
|
||||||
{JSON.stringify(data, null, 2)}
|
{JSON.stringify(data, null, 2)}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
11
routes/register.tsx
Normal file
11
routes/register.tsx
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
export default function Register() {
|
||||||
|
return (
|
||||||
|
<form class="flex flex-col max-w-lg" method="post">
|
||||||
|
<label for="username">Username</label>
|
||||||
|
<input type="text" name="username" />
|
||||||
|
<label for="password">Password</label>
|
||||||
|
<input type="password" name="password" />
|
||||||
|
<input class="mt-2" type="submit" value="Register" />
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
Loading…
Reference in a new issue