
25 | 26 | Grunge Stack 27 | 28 |
29 |30 | Check the README.md file for instructions on how to get this 31 | project deployed. 32 |
33 |30 | Check the README.md file for instructions on how to get this 31 | project deployed. 32 |
33 |{data.note.body}
41 |6 | No note selected. Select a note on the left, or{" "} 7 | 8 | create a new note. 9 | 10 |
11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /app/routes/notes.new.tsx: -------------------------------------------------------------------------------- 1 | import type { ActionFunctionArgs } from "@remix-run/node"; 2 | import { json, redirect } from "@remix-run/node"; 3 | import { Form, useActionData } from "@remix-run/react"; 4 | import { useEffect, useRef } from "react"; 5 | 6 | import { createNote } from "~/models/note.server"; 7 | import { requireUserId } from "~/session.server"; 8 | 9 | export const action = async ({ request }: ActionFunctionArgs) => { 10 | const userId = await requireUserId(request); 11 | 12 | const formData = await request.formData(); 13 | const title = formData.get("title"); 14 | const body = formData.get("body"); 15 | 16 | if (typeof title !== "string" || title.length === 0) { 17 | return json( 18 | { errors: { body: null, title: "Title is required" } }, 19 | { status: 400 }, 20 | ); 21 | } 22 | 23 | if (typeof body !== "string" || body.length === 0) { 24 | return json( 25 | { errors: { body: "Body is required", title: null } }, 26 | { status: 400 }, 27 | ); 28 | } 29 | 30 | const note = await createNote({ body, title, userId }); 31 | 32 | return redirect(`/notes/${note.id}`); 33 | }; 34 | 35 | export default function NewNotePage() { 36 | const actionData = useActionData{user.email}
26 | 34 |No notes yet
46 | ) : ( 47 |