71 lines
1.8 KiB
TypeScript
71 lines
1.8 KiB
TypeScript
import type { ActionArgs, LoaderArgs } from "@remix-run/node";
|
|
import { json, redirect } from "@remix-run/node";
|
|
import {
|
|
Form,
|
|
isRouteErrorResponse,
|
|
useLoaderData,
|
|
useRouteError,
|
|
} from "@remix-run/react";
|
|
import invariant from "tiny-invariant";
|
|
|
|
import { deleteNote, getNote } from "~/models/note.server";
|
|
import { requireUserId } from "~/session.server";
|
|
|
|
export const loader = async ({ params, request }: LoaderArgs) => {
|
|
const userId = await requireUserId(request);
|
|
invariant(params.noteId, "noteId not found");
|
|
|
|
const note = await getNote({ id: params.noteId, userId });
|
|
if (!note) {
|
|
throw new Response("Not Found", { status: 404 });
|
|
}
|
|
return json({ note });
|
|
};
|
|
|
|
export const action = async ({ params, request }: ActionArgs) => {
|
|
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<typeof loader>();
|
|
|
|
return (
|
|
<div>
|
|
<h3 className="text-2xl font-bold">{data.note.title}</h3>
|
|
<p className="py-6">{data.note.body}</p>
|
|
<hr className="my-4" />
|
|
<Form method="post">
|
|
<button
|
|
type="submit"
|
|
className="rounded bg-blue-500 px-4 py-2 text-white hover:bg-blue-600 focus:bg-blue-400"
|
|
>
|
|
Delete
|
|
</button>
|
|
</Form>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function ErrorBoundary() {
|
|
const error = useRouteError();
|
|
|
|
if (error instanceof Error) {
|
|
return <div>An unexpected error occurred: {error.message}</div>;
|
|
}
|
|
|
|
if (!isRouteErrorResponse(error)) {
|
|
return <h1>Unknown Error</h1>;
|
|
}
|
|
|
|
if (error.status === 404) {
|
|
return <div>Note not found</div>;
|
|
}
|
|
|
|
return <div>An unexpected error occurred: {error.statusText}</div>;
|
|
}
|