-
-
-
-
+
+
+
+
+
+ Login
+
+
+ Enter your details below to login to your account
+
+
+
+
-
-
- Don't have an account?{" "}
-
- Sign up
-
-
-
-
+
+
+ Don't have an account?{" "}
+
+ Sign up
+
+
+
+
+
);
}
diff --git a/app/routes/_dashboard.contacts.$contactId._index.tsx b/app/routes/_dashboard.contacts.$contactId._index.tsx
index ed20a99..024e431 100644
--- a/app/routes/_dashboard.contacts.$contactId._index.tsx
+++ b/app/routes/_dashboard.contacts.$contactId._index.tsx
@@ -1,7 +1,6 @@
-import { invariantResponse } from "@epic-web/invariant";
import { Pencil1Icon } from "@radix-ui/react-icons";
import { format, formatDistanceStrict } from "date-fns";
-import { Form, Link } from "react-router";
+import { data, Form, Link } from "react-router";
import { EmptyState } from "~/components/empty-state";
import { Button } from "~/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
@@ -26,11 +25,11 @@ export async function loader({ request, params }: Route.LoaderArgs) {
},
where: { id: params.contactId, userId },
});
- invariantResponse(
- contact,
- `No contact with the id "${params.contactId}" exists.`,
- { status: 404 },
- );
+ if (!contact) {
+ throw data(`No contact with the id "${params.contactId}" exists.`, {
+ status: 404,
+ });
+ }
return { contact };
}
diff --git a/app/routes/_dashboard.contacts.$contactId.notes.tsx b/app/routes/_dashboard.contacts.$contactId.notes.tsx
index 910567b..7354d79 100644
--- a/app/routes/_dashboard.contacts.$contactId.notes.tsx
+++ b/app/routes/_dashboard.contacts.$contactId.notes.tsx
@@ -1,5 +1,4 @@
import { parseWithZod } from "@conform-to/zod";
-import { invariantResponse } from "@epic-web/invariant";
import { DotsHorizontalIcon, UpdateIcon } from "@radix-ui/react-icons";
import { compareAsc, format, isToday, isYesterday } from "date-fns";
import { useState } from "react";
@@ -39,11 +38,11 @@ export async function action({ request, params }: Route.ActionArgs) {
select: { id: true },
where: { id: params.contactId, userId },
});
- invariantResponse(
- contact,
- `No contact with the id "${params.contactId}" exists.`,
- { status: 404 },
- );
+ if (!contact) {
+ throw data(`No contact with the id "${params.contactId}" exists.`, {
+ status: 404,
+ });
+ }
const formData = await request.formData();
@@ -56,6 +55,7 @@ export async function action({ request, params }: Route.ActionArgs) {
}
const { text, date } = submission.value;
+
await db.note.create({
select: { id: true },
data: { text, date, contact: { connect: { id: params.contactId } } },
diff --git a/app/routes/_dashboard.contacts.$contactId.notes_.$noteId.edit.tsx b/app/routes/_dashboard.contacts.$contactId.notes_.$noteId.edit.tsx
index 101c835..2907f35 100644
--- a/app/routes/_dashboard.contacts.$contactId.notes_.$noteId.edit.tsx
+++ b/app/routes/_dashboard.contacts.$contactId.notes_.$noteId.edit.tsx
@@ -1,5 +1,4 @@
import { parseWithZod } from "@conform-to/zod";
-import { invariantResponse } from "@epic-web/invariant";
import { ChevronLeftIcon, TrashIcon } from "@radix-ui/react-icons";
import { data, Form, Link, redirect, useNavigation } from "react-router";
import { NoteForm, NoteFormSchema } from "~/components/note-form";
@@ -20,9 +19,11 @@ export async function loader({ params }: Route.LoaderArgs) {
select: { text: true, date: true },
where: { id: params.noteId },
});
- invariantResponse(note, `No note with the id "${params.noteId}" exists.`, {
- status: 404,
- });
+ if (!note) {
+ throw data(`No note with the id "${params.noteId}" exists.`, {
+ status: 404,
+ });
+ }
return { note };
}
@@ -34,42 +35,51 @@ export async function action({ request, params }: Route.ActionArgs) {
select: { id: true },
where: { id: params.contactId, userId },
});
- invariantResponse(
- contact,
- `No contact with the id "${params.contactId}" exists.`,
- { status: 404 },
- );
+ if (!contact) {
+ throw data(`No contact with the id "${params.contactId}" exists.`, {
+ status: 404,
+ });
+ }
const note = await db.note.findUnique({
select: { id: true },
where: { id: params.noteId },
});
- invariantResponse(note, `No note with the id "${params.noteId}" exists.`, {
- status: 404,
- });
+ if (!note) {
+ throw data(`No note with the id "${params.noteId}" exists.`, {
+ status: 404,
+ });
+ }
const formData = await request.formData();
- if (formData.get("intent") === "deleteNote") {
- await db.note.delete({
- select: { id: true },
- where: { id: params.noteId },
- });
- } else {
- const submission = parseWithZod(formData, { schema: NoteFormSchema });
- if (submission.status !== "success") {
- return data(
- { result: submission.reply() },
- { status: submission.status === "error" ? 400 : 200 },
- );
+ switch (formData.get("intent")) {
+ case "editNote": {
+ const submission = parseWithZod(formData, { schema: NoteFormSchema });
+ if (submission.status !== "success") {
+ return data(
+ { result: submission.reply() },
+ { status: submission.status === "error" ? 400 : 200 },
+ );
+ }
+
+ const updates = submission.value;
+ await db.note.update({
+ select: { id: true },
+ data: updates,
+ where: { id: params.noteId },
+ });
+
+ break;
}
+ case "deleteNote": {
+ await db.note.delete({
+ select: { id: true },
+ where: { id: params.noteId },
+ });
- const updates = submission.value;
- await db.note.update({
- select: { id: true },
- data: updates,
- where: { id: params.noteId },
- });
+ break;
+ }
}
throw redirect(`/contacts/${params.contactId}/notes`);
diff --git a/app/routes/_dashboard.contacts.$contactId.tsx b/app/routes/_dashboard.contacts.$contactId.tsx
index 87d3fa7..47f2ab6 100644
--- a/app/routes/_dashboard.contacts.$contactId.tsx
+++ b/app/routes/_dashboard.contacts.$contactId.tsx
@@ -8,6 +8,7 @@ import {
TrashIcon,
} from "@radix-ui/react-icons";
import {
+ data,
Form,
Link,
NavLink,
@@ -67,39 +68,40 @@ export async function action({ request, params }: Route.ActionArgs) {
select: { id: true },
where: { id: params.contactId, userId },
});
- invariantResponse(
- contact,
- `No contact with the id "${params.contactId}" exists.`,
- { status: 404 },
- );
+ if (!contact) {
+ throw data(`No contact with the id "${params.contactId}" exists.`, {
+ status: 404,
+ });
+ }
const formData = await request.formData();
- if (formData.get("intent") === "favorite") {
- const favorite = formData.get("favorite");
+ switch (formData.get("intent")) {
+ case "favoriteContact": {
+ const favorite = formData.get("favorite");
- await db.contact.update({
- select: { id: true },
- data: { favorite: favorite === "true" },
- where: { id: params.contactId, userId },
- });
-
- return { ok: true };
- }
+ await db.contact.update({
+ select: { id: true },
+ data: { favorite: favorite === "true" },
+ where: { id: params.contactId, userId },
+ });
- if (formData.get("intent") === "delete") {
- await db.contact.delete({
- select: { id: true },
- where: { id: params.contactId, userId },
- });
+ return { ok: true };
+ }
+ case "deleteContact": {
+ await db.contact.delete({
+ select: { id: true },
+ where: { id: params.contactId, userId },
+ });
- return redirect("/contacts");
+ return redirect("/contacts");
+ }
+ default: {
+ throw data(`Invalid intent: ${formData.get("intent") ?? "Missing"}`, {
+ status: 400,
+ });
+ }
}
-
- invariantResponse(
- false,
- `Invalid intent: ${formData.get("intent") ?? "Missing"}`,
- );
}
export function ErrorBoundary() {
@@ -186,7 +188,7 @@ export default function Component({ loaderData }: Route.ComponentProps) {
}
}}
>
-
+