From 04e66527cac3d35a0f16c2f649fe5678691c1065 Mon Sep 17 00:00:00 2001 From: Alex Frantz Date: Sun, 6 Sep 2026 22:05:10 -0400 Subject: [PATCH] foundation for posts --- apps/frontend/src/components/postRow.tsx | 21 ++++++---- apps/frontend/src/main.tsx | 5 +++ apps/frontend/src/pages/home.tsx | 40 +++++++++++++++++++- apps/frontend/src/pages/post.tsx | 40 ++++++++++++++++++++ apps/frontend/src/providers/AuthProvider.tsx | 7 +--- apps/frontend/src/utils/types.ts | 17 +++++++++ 6 files changed, 116 insertions(+), 14 deletions(-) create mode 100644 apps/frontend/src/utils/types.ts diff --git a/apps/frontend/src/components/postRow.tsx b/apps/frontend/src/components/postRow.tsx index 2232821..592e471 100644 --- a/apps/frontend/src/components/postRow.tsx +++ b/apps/frontend/src/components/postRow.tsx @@ -1,10 +1,17 @@ -export default function PostRow() { +import type { Post } from "../utils/types"; + +export default function PostRow({ post }: { post: Post }) { return ( - -
-

This is a test post

-

This is a test post description to show how cool it is

-
-
+
+ +
+

{post.title}

+

{post.description}

+

+ Posted on {new Date(post.createdAt).toLocaleString()} +

+
+
+
); } diff --git a/apps/frontend/src/main.tsx b/apps/frontend/src/main.tsx index 26bb8b9..8e3d9e6 100644 --- a/apps/frontend/src/main.tsx +++ b/apps/frontend/src/main.tsx @@ -6,6 +6,7 @@ import "./assets/index.css"; import Home from "./pages/home"; import LogIn from "./pages/login"; +import Post from "./pages/post"; const router = createBrowserRouter([ { @@ -16,6 +17,10 @@ const router = createBrowserRouter([ path: "/login", element: , }, + { + path: "/post/:slug", + element: , + }, ]); createRoot(document.getElementById("root")!).render( diff --git a/apps/frontend/src/pages/home.tsx b/apps/frontend/src/pages/home.tsx index 6e96bd4..98cdaa7 100644 --- a/apps/frontend/src/pages/home.tsx +++ b/apps/frontend/src/pages/home.tsx @@ -1,7 +1,45 @@ import Layout from "../components/layout"; import PostRow from "../components/postRow"; +import { useEffect, useState } from "react"; +import type { Post } from "../utils/types"; export default function Home() { + const [posts, setPosts] = useState(null); + const [loaded, setLoaded] = useState(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 ; + }); + + if ((loaded && !posts) || posts?.length === 0) { + return ( +
+

uh oh!

+

there's nothing here..

+
+ ); + } else if (loaded) { + return mappedPosts; + } + }; + return (
@@ -15,7 +53,7 @@ export default function Home() {

Posts

- +
diff --git a/apps/frontend/src/pages/post.tsx b/apps/frontend/src/pages/post.tsx index e69de29..0798638 100644 --- a/apps/frontend/src/pages/post.tsx +++ b/apps/frontend/src/pages/post.tsx @@ -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(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 ( + +
+

{post.title}

+

{post.description}

+
+
+ ); + } +} diff --git a/apps/frontend/src/providers/AuthProvider.tsx b/apps/frontend/src/providers/AuthProvider.tsx index c3a8552..2d6b47e 100644 --- a/apps/frontend/src/providers/AuthProvider.tsx +++ b/apps/frontend/src/providers/AuthProvider.tsx @@ -6,12 +6,7 @@ import { type ReactNode, useEffect, } from "react"; - -interface User { - id: number; - email: string; - name: string; -} +import type { User } from "../utils/types"; interface AuthContextType { user: User | null; refetch: () => void; diff --git a/apps/frontend/src/utils/types.ts b/apps/frontend/src/utils/types.ts new file mode 100644 index 0000000..d3fc162 --- /dev/null +++ b/apps/frontend/src/utils/types.ts @@ -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 };