diff --git a/app/models/recipe.server.ts b/app/models/recipe.server.ts
index b990856..8712f41 100644
--- a/app/models/recipe.server.ts
+++ b/app/models/recipe.server.ts
@@ -18,7 +18,7 @@ export function getRecipe({
export function getRecipeListItems({userId}: UserId) {
return prisma.recipe.findMany({
- select: {title: true, tags: true},
+ select: {title: true, tags: true, id: true},
where: {userId}
})
}
@@ -46,13 +46,15 @@ export function updateRecipe({
title,
source,
steps,
- ingredients
+ ingredients,
+ userId
}: Pick
& {steps?: Step[]}
& {ingredients?: Ingredient[]}
+& UserId
) {
return prisma.recipe.update({
- where: {id},
+ where: {id_userId: { id, userId}},
data: {
title,
source,
diff --git a/app/routes/notes.$noteId.tsx b/app/routes/notes.$noteId.tsx
index 3edd6ff..4ada87b 100644
--- a/app/routes/notes.$noteId.tsx
+++ b/app/routes/notes.$noteId.tsx
@@ -1,5 +1,5 @@
-import type { ActionFunctionArgs, LoaderFunctionArgs } from "@remix-run/node";
-import { json, redirect } from "@remix-run/node";
+import type { LoaderFunctionArgs } from "@remix-run/node";
+import { json, } from "@remix-run/node";
import {
Form,
isRouteErrorResponse,
@@ -8,7 +8,7 @@ import {
} from "@remix-run/react";
import invariant from "tiny-invariant";
-import { deleteNote, getNote } from "~/models/note.server";
+import { getNote } from "~/models/note.server";
import { requireUserId } from "~/session.server";
export const loader = async ({ params, request }: LoaderFunctionArgs) => {
@@ -22,15 +22,6 @@ export const loader = async ({ params, request }: LoaderFunctionArgs) => {
return json({ note });
};
-export const action = async ({ params, request }: ActionFunctionArgs) => {
- const userId = await requireUserId(request);
- invariant(params.noteId, "noteId not found");
-
- await deleteNote({ id: params.noteId, userId });
-
- return redirect("/notes");
-};
-
export default function NoteDetailsPage() {
const data = useLoaderData();
@@ -39,7 +30,7 @@ export default function NoteDetailsPage() {
{data.note.title}
{data.note.body}
-
+ );
+}
diff --git a/app/routes/recipes.delete.$recipeId.tsx b/app/routes/recipes.delete.$recipeId.tsx
new file mode 100644
index 0000000..5ab3979
--- /dev/null
+++ b/app/routes/recipes.delete.$recipeId.tsx
@@ -0,0 +1,14 @@
+import { ActionFunctionArgs, redirect } from "@remix-run/node";
+import invariant from "tiny-invariant";
+
+import { deleteRecipe } from "~/models/recipe.server";
+import { requireUserId } from "~/session.server";
+
+export const action = async ({ params, request }: ActionFunctionArgs) => {
+ const userId = await requireUserId(request);
+ invariant(params.recipeId, "recipeId not found");
+
+ await deleteRecipe({ id: params.recipeId, userId });
+
+ return redirect("/notes");
+ };
\ No newline at end of file
diff --git a/app/routes/recipes.new.tsx b/app/routes/recipes.new.tsx
new file mode 100644
index 0000000..a48c0e1
--- /dev/null
+++ b/app/routes/recipes.new.tsx
@@ -0,0 +1,26 @@
+import { LoaderFunctionArgs, redirect } from "@remix-run/node";
+
+import { createRecipe } from "~/models/recipe.server";
+import { requireUserId } from "~/session.server";
+
+export const action = async ({ request }: LoaderFunctionArgs) => {
+ const userId = await requireUserId(request);
+ // invariant(params.recipeId, "recipeId not found");
+
+ // const formData = await request.formData();
+ // const title = formData.get("title");
+
+ // if (typeof recipe.title !== "string" || recipe.title.length === 0) {
+ // return json(
+ // { errors: { title: "Title is required" } },
+ // { status: 400 },
+ // );
+ // }
+
+ const recipe = await createRecipe({ userId });
+ return redirect(`/recipes/${recipe.id}?edit=true`);
+};
+
+// export default function NewRecipe() {
+
+// }
diff --git a/app/routes/recipes.tsx b/app/routes/recipes.tsx
new file mode 100644
index 0000000..e16827e
--- /dev/null
+++ b/app/routes/recipes.tsx
@@ -0,0 +1,73 @@
+import type { LoaderFunctionArgs } from "@remix-run/node";
+import { json } from "@remix-run/node";
+import { Form, Link, NavLink, Outlet, useLoaderData } from "@remix-run/react";
+
+import { getRecipeListItems } from "~/models/recipe.server";
+import { requireUserId } from "~/session.server";
+import { useUser } from "~/utils";
+
+export const loader = async ({ request }: LoaderFunctionArgs) => {
+ const userId = await requireUserId(request);
+ const recipeListItems = await getRecipeListItems({ userId });
+ return json({ recipeListItems: recipeListItems });
+};
+
+export default function RecipesPage() {
+ const data = useLoaderData();
+ const user = useUser();
+
+ return (
+
+
+
+ Recipes
+
+ Notes
+ {user.email}
+
+
+
+
+
+
+
+
+
+ {data.recipeListItems.length === 0 ? (
+
No recipes yet
+ ) : (
+
+ {data.recipeListItems.map((recipe) => (
+ -
+
+ `block border-b p-4 text-xl ${isActive ? "bg-white" : ""}`
+ }
+ to={recipe.id}
+ >
+ 📝 {recipe.title}
+
+
+ ))}
+
+ )}
+
+
+
+
+
+
+
+ );
+}
diff --git a/app/utils.ts b/app/utils.ts
index f6da6bd..2e25046 100644
--- a/app/utils.ts
+++ b/app/utils.ts
@@ -1,3 +1,4 @@
+import { Recipe } from "@prisma/client";
import { useMatches } from "@remix-run/react";
import { useMemo } from "react";
@@ -74,3 +75,12 @@ export function useUser(): User {
export function validateEmail(email: unknown): email is string {
return typeof email === "string" && email.length > 3 && email.includes("@");
}
+
+export function getRecipeFromForm(formData: FormData) {
+ const values = Object.fromEntries(formData);
+
+ return {
+ title: values.title,
+ source: values.source,
+ } as Recipe;
+}
\ No newline at end of file
diff --git a/prisma/migrations/20231108165715_recipe02/migration.sql b/prisma/migrations/20231108165715_recipe02/migration.sql
new file mode 100644
index 0000000..555d462
--- /dev/null
+++ b/prisma/migrations/20231108165715_recipe02/migration.sql
@@ -0,0 +1,8 @@
+/*
+ Warnings:
+
+ - A unique constraint covering the columns `[id,userId]` on the table `Recipe` will be added. If there are existing duplicate values, this will fail.
+
+*/
+-- CreateIndex
+CREATE UNIQUE INDEX "Recipe_id_userId_key" ON "Recipe"("id", "userId");
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index 4bb8047..143a2c7 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -55,6 +55,7 @@ model Recipe {
userId String
@@unique([userId, title])
+ @@unique([id, userId])
@@index([title, userId])
}