foundation for posts

This commit is contained in:
2026-09-06 22:05:10 -04:00
parent 41e5316443
commit 04e66527ca
6 changed files with 116 additions and 14 deletions
+14 -7
View File
@@ -1,10 +1,17 @@
export default function PostRow() { import type { Post } from "../utils/types";
export default function PostRow({ post }: { post: Post }) {
return ( return (
<a href="" className="hover:underline"> <div className="block">
<div> <a href={`/post/${post.slug}`} className="hover:underline">
<h1>This is a test post</h1> <div>
<p>This is a test post description to show how cool it is</p> <h1>{post.title}</h1>
</div> <p>{post.description}</p>
</a> <p className="text-xs opacity-50">
Posted on {new Date(post.createdAt).toLocaleString()}
</p>
</div>
</a>
</div>
); );
} }
+5
View File
@@ -6,6 +6,7 @@ import "./assets/index.css";
import Home from "./pages/home"; import Home from "./pages/home";
import LogIn from "./pages/login"; import LogIn from "./pages/login";
import Post from "./pages/post";
const router = createBrowserRouter([ const router = createBrowserRouter([
{ {
@@ -16,6 +17,10 @@ const router = createBrowserRouter([
path: "/login", path: "/login",
element: <LogIn />, element: <LogIn />,
}, },
{
path: "/post/:slug",
element: <Post />,
},
]); ]);
createRoot(document.getElementById("root")!).render( createRoot(document.getElementById("root")!).render(
+39 -1
View File
@@ -1,7 +1,45 @@
import Layout from "../components/layout"; import Layout from "../components/layout";
import PostRow from "../components/postRow"; import PostRow from "../components/postRow";
import { useEffect, useState } from "react";
import type { Post } from "../utils/types";
export default function Home() { export default function Home() {
const [posts, setPosts] = useState<Post[] | null>(null);
const [loaded, setLoaded] = useState<boolean>(false);
useEffect(() => {
fetch("/api/posts", {
method: "GET",
credentials: "include",
}).then(async (res) => {
if (res.ok) {
const data = await res.json();
setPosts(data);
setLoaded(true);
} else {
console.error("Failed to load posts!");
setLoaded(true);
}
});
}, []);
const PostList = () => {
const mappedPosts = posts?.map((v, k) => {
return <PostRow key={k} post={v} />;
});
if ((loaded && !posts) || posts?.length === 0) {
return (
<div className="my-2 text-center">
<h1 className="text-2xl font-bold">uh oh!</h1>
<p className="opacity-50 text-sm">there's nothing here..</p>
</div>
);
} else if (loaded) {
return mappedPosts;
}
};
return ( return (
<Layout> <Layout>
<div className="mb-4 space-y-1"> <div className="mb-4 space-y-1">
@@ -15,7 +53,7 @@ export default function Home() {
<div className="mt-2"> <div className="mt-2">
<h1 className="font-semibold">Posts</h1> <h1 className="font-semibold">Posts</h1>
<div className="space-y-2"> <div className="space-y-2">
<PostRow /> <PostList />
</div> </div>
</div> </div>
</Layout> </Layout>
+40
View File
@@ -0,0 +1,40 @@
import Layout from "../components/layout";
import { useState, useEffect } from "react";
import { useParams } from "react-router-dom";
import type { Post } from "../utils/types";
export default function Post() {
const [post, setPost] = useState<Post | null>(null);
const params = useParams();
useEffect(() => {
if (params.slug) {
fetch("/api/posts/" + params.slug, {
method: "GET",
credentials: "include",
}).then(async (res) => {
if (res.ok) {
const data = await res.json();
setPost(data);
} else {
console.error("Failed to load post! " + res.status);
}
});
}
}, []);
useEffect(() => {
console.log(post);
}, [post]);
if (post) {
return (
<Layout>
<div className="my-2">
<h1 className="text-2xl font-bold">{post.title}</h1>
<p className="text-sm opacity-50">{post.description}</p>
</div>
</Layout>
);
}
}
+1 -6
View File
@@ -6,12 +6,7 @@ import {
type ReactNode, type ReactNode,
useEffect, useEffect,
} from "react"; } from "react";
import type { User } from "../utils/types";
interface User {
id: number;
email: string;
name: string;
}
interface AuthContextType { interface AuthContextType {
user: User | null; user: User | null;
refetch: () => void; refetch: () => void;
+17
View File
@@ -0,0 +1,17 @@
interface Post {
id: number;
title: string;
description: string;
slug: string;
content: string;
createdAt: string;
updatedAt: string;
userId: number;
}
interface User {
id: number;
email: string;
name: string;
}
export type { Post, User };