main
Ethan Niser 2023-09-21 15:54:10 +00:00 committed by GitHub
parent fbc91a664c
commit f1c5467009
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 66 additions and 17 deletions

Binary file not shown.

@ -41,7 +41,7 @@
"@lucia-auth/adapter-sqlite": "^2.0.0",
"@t3-oss/env-core": "^0.6.1",
"@tlscipher/holt": "1.1.0",
"beth-stack": "0.0.22",
"beth-stack": "0.0.24",
"drizzle-orm": "^0.28.6",
"drizzle-typebox": "^0.1.1",
"elysia": "0.7.4",

@ -2,8 +2,13 @@ import { liveReloadScript } from "beth-stack/dev";
import { type PropsWithChildren } from "beth-stack/jsx";
import { config } from "../config";
const safeScript =
config.env.NODE_ENV === "development" ? liveReloadScript() : "";
config.env.NODE_ENV === "development"
? liveReloadScript({
url: "https://upgraded-orbit-qw9457vrwv39669-3001.app.github.dev/ws",
})
: "";
export const BaseHtml = ({ children }: PropsWithChildren) => (
<html>
@ -25,4 +30,4 @@ export const BaseHtml = ({ children }: PropsWithChildren) => (
{children}
</body>
</html>
);
);

@ -1,24 +1,44 @@
import { db } from "../db";
import { tweets, type Tweet } from "../db/schema/tweets";
import { tweets } from "../db/schema/tweets";
export function TweetCard({ authorId, createdAt, content }: Tweet) {
export function TweetCard({
author: { handle },
createdAt,
content,
}: {
createdAt: Date;
content: string;
author: {
handle: string;
};
}) {
return (
<div class="rounded-lg border p-4 shadow-md">
<h2 class="text-xl font-bold" safe>
{authorId}
@{handle}
</h2>
<p class="text-gray-700" safe>
{content}
</p>
<span class="text-sm text-gray-500">
{new Date(createdAt).toLocaleString()}
{createdAt.toLocaleString()}
</span>
</div>
);
}
export async function TweetList() {
const tweetData = await db.select().from(tweets).limit(10);
const tweetData = await db.query.tweets.findMany({
limit: 10,
orderBy: (tweets, { desc }) => [desc(tweets.createdAt)],
with: {
author: {
columns: {
handle: true,
},
},
},
});
return (
<div class="space-y-4" id="tweetList">
@ -33,17 +53,15 @@ export function TweetCreationForm() {
return (
<div class="rounded-lg border p-4 shadow-md">
<h2 class="mb-4 text-xl font-bold">Create a new Tweet</h2>
<form hx-post="/api/tweets" hx-swap="afterend" hx-target="#tweetList">
<form hx-post="/api/tweets" hx-swap="afterbegin" hx-target="#tweetList" _="on submit target.reset()">
<label class="mb-2 block text-sm font-bold" for="content">
Tweet:
</label>
<textarea
<input
class="w-full appearance-none rounded border px-3 py-2 leading-tight text-gray-700 shadow"
name="content"
rows="3"
required="true"
_="on submit reset me"
></textarea>
/>
<button
class="rounded bg-blue-500 px-4 py-2 font-bold text-white hover:bg-blue-700"
type="submit"

@ -56,7 +56,7 @@ export const authController = new Elysia({
body: t.Object({
handle: t.String({
minLength: 1,
maxLength: 10,
maxLength: 20,
}),
password: t.String({
minLength: 4,
@ -67,7 +67,10 @@ export const authController = new Elysia({
signin: "signin",
}), // Enum to validate action type
}),
error({ code, error, set }) {
error({ code, error, set, log }) {
log.error(error);
let errorMessage = "";
if (code === "VALIDATION") {

@ -35,7 +35,13 @@ export const tweetsController = new Elysia({
throw new Error("Failed to create tweet");
}
return <TweetCard {...tweet} />;
return (
<TweetCard
content={tweet.content}
createdAt={tweet.createdAt}
author={{ handle: session.user.handle }}
/>
);
},
{
body: t.Object({

@ -1,2 +1,18 @@
import { relations } from "drizzle-orm";
import { user } from "./auth";
import { tweets } from "./tweets";
export { tweets } from "./tweets";
export * from "./auth";
export { key, session, user } from "./auth";
export const userRelations = relations(user, ({ many }) => ({
tweets: many(tweets),
}));
export const tweetsRelations = relations(tweets, ({ one }) => ({
author: one(user, {
fields: [tweets.authorId],
references: [user.id],
}),
}));

@ -1,5 +1,6 @@
import { index, integer, sqliteTable, text } from "drizzle-orm/sqlite-core";
import { createInsertSchema, createSelectSchema } from "drizzle-typebox";
import { user } from ".";
export const tweets = sqliteTable(
"tweet",