Skip to content

Commit 6199129

Browse files
committed
notes update
1 parent 8867f71 commit 6199129

File tree

3 files changed

+127
-177
lines changed

3 files changed

+127
-177
lines changed

app/models/note.server.ts

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,20 @@
11
import type { User, Note } from "@prisma/client";
2-
32
import { prisma } from "~/db.server";
43

54
export function getNote({
65
id,
76
userId,
8-
}: Pick<Note, "id"> & {
9-
userId: User["id"];
10-
}) {
7+
}: Pick<Note, "id"> & { userId: User["id"] }) {
118
return prisma.note.findFirst({
12-
select: { id: true, body: true, title: true, userId: true },
9+
select: { id: true, body: true, title: true },
1310
where: { id, userId },
1411
});
1512
}
1613

1714
export function getNoteListItems({ userId }: { userId: User["id"] }) {
1815
return prisma.note.findMany({
1916
where: { userId },
20-
select: { id: true, title: true, updatedAt: true },
17+
select: { id: true, title: true },
2118
orderBy: { updatedAt: "desc" },
2219
});
2320
}
@@ -26,16 +23,16 @@ export function createNote({
2623
body,
2724
title,
2825
userId,
29-
}: Pick<Note, "body" | "title"> & {
30-
userId: User["id"];
31-
}) {
26+
}: Pick<Note, "body" | "title"> & { userId: User["id"] }) {
3227
return prisma.note.create({
3328
data: {
3429
title,
3530
body,
36-
userId, // Directly set userId instead of using connect for simplicity
37-
createdAt: new Date(),
38-
updatedAt: new Date(),
31+
user: {
32+
connect: {
33+
id: userId,
34+
},
35+
},
3936
},
4037
});
4138
}
@@ -44,12 +41,9 @@ export function deleteNote({
4441
id,
4542
userId,
4643
}: Pick<Note, "id"> & { userId: User["id"] }) {
47-
console.log("Attempting to delete note with id:", id, "for user:", userId);
48-
return prisma.note.delete({
49-
where: { id, userId }, // Changed to delete for single record
50-
}).catch((error) => {
51-
console.error("Error deleting note:", error);
52-
throw new Error("Failed to delete note: " + error.message);
44+
console.log("Deleting note with id:", id, "for user:", userId);
45+
return prisma.note.deleteMany({
46+
where: { id, userId },
5347
});
5448
}
5549

@@ -59,9 +53,9 @@ export function updateNote({
5953
body,
6054
userId,
6155
}: Pick<Note, "id" | "title" | "body"> & { userId: User["id"] }) {
62-
console.log("Attempting to update note with id:", id, "for user:", userId, "title:", title, "body:", body);
56+
console.log("Updating note with id:", id, "title:", title, "body:", body, "userId:", userId);
6357
return prisma.note.update({
64-
where: { id, userId }, // Ensure user owns the note
58+
where: { id }, // Revert to original working state
6559
data: {
6660
title,
6761
body,

app/routes/notes.$noteId.edit.tsx

Lines changed: 0 additions & 124 deletions
This file was deleted.

app/routes/notes.$noteId.tsx

Lines changed: 113 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { Link } from "@remix-run/react";
2-
32
import type { ActionFunctionArgs, LoaderFunctionArgs } from "@remix-run/node";
43
import { json, redirect } from "@remix-run/node";
54
import {
@@ -8,11 +7,13 @@ import {
87
useParams,
98
useLoaderData,
109
useRouteError,
10+
useNavigation,
1111
} from "@remix-run/react";
1212
import invariant from "tiny-invariant";
1313

14-
import { deleteNote, getNote } from "~/models/note.server";
14+
import { deleteNote, getNote, updateNote } from "~/models/note.server";
1515
import { requireUserId } from "~/session.server";
16+
import { useState } from "react";
1617

1718
export const loader = async ({ params, request }: LoaderFunctionArgs) => {
1819
const userId = await requireUserId(request);
@@ -32,48 +33,127 @@ export const action = async ({ params, request }: ActionFunctionArgs) => {
3233
const userId = await requireUserId(request);
3334
invariant(params.noteId, "noteId not found");
3435

35-
console.log('Action: Deleting note with id:', params.noteId, 'for user:', userId);
36+
const formData = await request.formData();
37+
const intent = formData.get("intent");
38+
39+
if (intent === "delete") {
40+
console.log('Action: Deleting note with id:', params.noteId, 'for user:', userId);
41+
try {
42+
await deleteNote({ id: params.noteId, userId });
43+
return redirect("/notes");
44+
} catch (error) {
45+
console.error('Error deleting note:', error);
46+
throw new Response("Failed to delete note", { status: 500 });
47+
}
48+
} else if (intent === "update") {
49+
const title = formData.get("title") as string;
50+
const body = formData.get("body") as string;
51+
52+
if (!title || title.length === 0) {
53+
return json({ errors: { title: "Title is required" } }, { status: 400 });
54+
}
55+
if (!body || body.length === 0) {
56+
return json({ errors: { body: "Body is required" } }, { status: 400 });
57+
}
3658

37-
try {
38-
await deleteNote({ id: params.noteId, userId });
39-
return redirect("/notes");
40-
} catch (error) {
41-
console.error('Error deleting note:', error);
42-
throw new Response("Failed to delete note", { status: 500 });
59+
console.log("Action: Updating note with id:", params.noteId, "title:", title, "body:", body, "userId:", userId);
60+
61+
try {
62+
await updateNote({ id: params.noteId, title, body, userId });
63+
return json({ success: true });
64+
} catch (error) {
65+
console.error("Action Error: Failed to update note:", error);
66+
return json(
67+
{ errors: { server: "Failed to update note. Please try again." } },
68+
{ status: 500 }
69+
);
70+
}
4371
}
72+
73+
return json({ error: "Invalid intent" }, { status: 400 });
4474
};
4575

4676
export default function NoteDetailsPage() {
4777
const params = useParams();
4878
const data = useLoaderData<typeof loader>();
79+
const navigation = useNavigation();
80+
const [isEditing, setIsEditing] = useState(false);
4981

5082
return (
5183
<div className="p-6">
52-
<h3 className="text-3xl font-bold mb-4">{data.note.title}</h3>
53-
<p className="py-6">{data.note.body}</p>
54-
<hr className="my-4" />
55-
<div className="space-y-4">
56-
<Form method="post" onSubmit={(e) => {
57-
if (!confirm("Are you sure you want to delete this note?")) {
58-
e.preventDefault();
59-
}
60-
}}>
61-
<button
62-
type="submit"
63-
className="rounded bg-red-500 px-4 py-2 text-white hover:bg-red-600 focus:bg-red-400"
64-
>
65-
Delete
66-
</button>
84+
{isEditing ? (
85+
<Form method="post" className="space-y-4">
86+
<input type="hidden" name="intent" value="update" />
87+
<div>
88+
<label className="block text-sm font-medium text-gray-700">
89+
Title:
90+
<input
91+
type="text"
92+
name="title"
93+
defaultValue={data.note.title}
94+
required
95+
className="mt-1 block w-full rounded-md border-gray-300 shadow-sm"
96+
/>
97+
</label>
98+
</div>
99+
<div>
100+
<label className="block text-sm font-medium text-gray-700">
101+
Body:
102+
<textarea
103+
name="body"
104+
defaultValue={data.note.body}
105+
required
106+
rows={4}
107+
className="mt-1 block w-full rounded-md border-gray-300 shadow-sm"
108+
/>
109+
</label>
110+
</div>
111+
<div className="flex space-x-4">
112+
<button
113+
type="submit"
114+
disabled={navigation.state === "submitting"}
115+
className="rounded bg-blue-500 px-4 py-2 text-white hover:bg-blue-600 focus:bg-blue-400"
116+
>
117+
{navigation.state === "submitting" ? "Saving..." : "Save"}
118+
</button>
119+
<button
120+
type="button"
121+
onClick={() => setIsEditing(false)}
122+
className="rounded bg-gray-500 px-4 py-2 text-white hover:bg-gray-600 focus:bg-gray-400"
123+
>
124+
Cancel
125+
</button>
126+
</div>
67127
</Form>
68-
<Link to={`/notes/${params.noteId}/edit`} className="inline-block">
69-
<button
70-
type="button"
71-
className="rounded bg-blue-500 px-4 py-2 text-white hover:bg-blue-600 focus:bg-blue-400"
72-
>
73-
Edit
74-
</button>
75-
</Link>
76-
</div>
128+
) : (
129+
<>
130+
<h3 className="text-3xl font-bold mb-4">{data.note.title}</h3>
131+
<p className="py-6">{data.note.body}</p>
132+
<hr className="my-4" />
133+
<div className="space-y-4">
134+
<Form method="post" onSubmit={(e) => {
135+
if (!confirm("Are you sure you want to delete this note?")) {
136+
e.preventDefault();
137+
}
138+
}}>
139+
<input type="hidden" name="intent" value="delete" />
140+
<button
141+
type="submit"
142+
className="rounded bg-red-500 px-4 py-2 text-white hover:bg-red-600 focus:bg-red-400"
143+
>
144+
Delete
145+
</button>
146+
</Form>
147+
<button
148+
type="button"
149+
onClick={() => setIsEditing(true)}
150+
className="rounded bg-blue-500 px-4 py-2 text-white hover:bg-blue-600 focus:bg-blue-400"
151+
>
152+
Edit
153+
</button>
154+
</div>
155+
</>
156+
)}
77157
</div>
78158
);
79159
}

0 commit comments

Comments
 (0)