diff --git a/react/src/App.tsx b/react/src/App.tsx
index b03050c..069e62e 100644
--- a/react/src/App.tsx
+++ b/react/src/App.tsx
@@ -1,11 +1,24 @@
import { posts } from "./lib/post";
import { BlogPostList } from "./components/BlogPostList";
+import { Link } from "react-router";
export function App() {
return (
<>
+
diff --git a/react/src/components/BlogPostForm.tsx b/react/src/components/BlogPostForm.tsx
new file mode 100644
index 0000000..ac687f5
--- /dev/null
+++ b/react/src/components/BlogPostForm.tsx
@@ -0,0 +1,158 @@
+import { posts, type BlogPost } from "../lib/post";
+import { useState } from "react";
+import { useNavigate } from "react-router";
+import { useSearchParams } from "react-router";
+
+export function BlogPostForm({
+ post,
+ onSubmit,
+}: {
+ post: BlogPost | null;
+ onSubmit: (post: BlogPost) => void;
+}) {
+ const [postState, setPostState] = useState(
+ post ?? {
+ id: posts.length,
+ title: "",
+ summary: "",
+ content: "",
+ author: "",
+ datePosted: new Date().toISOString().split("T")[0],
+ },
+ );
+ const [missing, setMissing] = useState([]);
+
+ const navigate = useNavigate();
+
+ const handleChange = (
+ event: React.ChangeEvent,
+ ) => {
+ const { name, value } = event.target;
+ setPostState((prevState) => ({ ...prevState, [name]: value }));
+ };
+
+ const handleMissing = () => {
+ const missingFields = Object.entries(postState)
+ .map(([key, value]) => (value === "" ? key : null))
+ .filter((key) => key !== null);
+ setMissing(missingFields);
+ };
+
+ const handleSubmit = (event: React.MouseEvent) => {
+ event.preventDefault();
+
+ if (
+ !postState.title ||
+ !postState.summary ||
+ !postState.content ||
+ !postState.author
+ ) {
+ handleMissing();
+ return;
+ }
+
+ onSubmit(postState);
+ navigate("/");
+ };
+
+ return (
+
+ );
+}
+
+export function NewPostLayout() {
+ const searchParams = useSearchParams()[0];
+ const postId = parseInt(searchParams.get("postId") ?? "-1");
+ const post =
+ postId < 0 || postId >= posts.length
+ ? null
+ : posts.find((p) => p.id === postId);
+
+ return (
+
+
New Post
+ {
+ if (post.id < posts.length) {
+ posts[post.id] = post;
+ } else {
+ posts.push(post);
+ }
+ }}
+ />
+
+ );
+}
diff --git a/react/src/components/BlogPostList.tsx b/react/src/components/BlogPostList.tsx
index 65d6839..fc739bb 100644
--- a/react/src/components/BlogPostList.tsx
+++ b/react/src/components/BlogPostList.tsx
@@ -15,7 +15,7 @@ export function BlogPostList({ posts }: { posts: BlogPost[] }) {
.map((post, idx) => (
@@ -13,6 +14,7 @@ createRoot(document.getElementById("root")!).render(
}>
} />
+ } />
,