Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code for Chapter 11 - Error Handling #178

Merged
merged 52 commits into from
Oct 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
99c150f
Fix loading skeleton bug
delbaoliveira Sep 20, 2023
5aad890
Reduce complexity of table component, move <Search> and <Pagination> …
delbaoliveira Sep 20, 2023
8c0ad11
Use neon's count field instead of fetchInvoiceCountBySearchTerm()
delbaoliveira Sep 20, 2023
fa4a3f6
Update invoice definition
delbaoliveira Sep 20, 2023
c436db9
Update page.tsx
delbaoliveira Sep 20, 2023
d826a37
Update data.ts
delbaoliveira Sep 20, 2023
595337f
Remove image blur
delbaoliveira Sep 20, 2023
1efa9da
Use useSearchParams()
delbaoliveira Sep 20, 2023
866ea7a
Update search.tsx
delbaoliveira Sep 20, 2023
040a588
Remove useTransition, fix types
delbaoliveira Sep 21, 2023
086321d
Consistent naming
delbaoliveira Sep 21, 2023
263d49b
Move logic to fetchFilteredInvoices
delbaoliveira Sep 21, 2023
6836826
Update page.tsx
delbaoliveira Sep 21, 2023
c17ed77
Misc
delbaoliveira Sep 21, 2023
e80620d
Misc
delbaoliveira Sep 22, 2023
2c00604
Use uuid
delbaoliveira Sep 22, 2023
58f3729
Refactor client component form to server component
delbaoliveira Sep 22, 2023
b288d8b
Install zod
delbaoliveira Sep 22, 2023
2401d95
Add create, update, and delete actions
delbaoliveira Sep 22, 2023
15f5ec6
Merge branch 'main' into example-6d7h
delbaoliveira Sep 22, 2023
b000915
Use uuid for customers
delbaoliveira Sep 22, 2023
2317fcd
Update table styles
delbaoliveira Sep 22, 2023
f8d053f
Order invoices by date (not uuid)
delbaoliveira Sep 22, 2023
446f906
Update data fetch for customers table
delbaoliveira Sep 22, 2023
415b09a
Clean up
delbaoliveira Sep 22, 2023
80e08c1
Consistent padding
delbaoliveira Sep 22, 2023
81519eb
Delete utils we don't need
delbaoliveira Sep 22, 2023
4f1afb7
Add create invoice form
delbaoliveira Sep 22, 2023
2c76667
Use past dates
delbaoliveira Sep 22, 2023
816f46a
Add edit invoice form
delbaoliveira Sep 22, 2023
e802b2e
Clean up
delbaoliveira Sep 22, 2023
8bd6d46
Clean up
delbaoliveira Sep 22, 2023
8507afe
Update spelling mistake
delbaoliveira Sep 25, 2023
57b92a6
Improve create form accessibility and add comments
delbaoliveira Sep 25, 2023
34f6eed
Fix error
delbaoliveira Sep 25, 2023
e2f3cfe
Fix errors + disable revalidate
delbaoliveira Sep 25, 2023
d0a3b1e
Remove delay
delbaoliveira Sep 25, 2023
29b5338
Move buttons to the same file
delbaoliveira Sep 26, 2023
64e62c3
Update actions.ts
delbaoliveira Sep 26, 2023
4fc11d5
Misc
delbaoliveira Sep 26, 2023
0e773c6
Fix ts error, update schema
delbaoliveira Sep 26, 2023
0ae44de
More type fixes
delbaoliveira Sep 26, 2023
29e39a0
Add error handling
delbaoliveira Sep 26, 2023
28afda5
Add debouncing
delbaoliveira Sep 26, 2023
3b8d864
Delete .env
delbaoliveira Sep 26, 2023
f1874ae
Update pnpm-lock.yaml
delbaoliveira Sep 26, 2023
07f993e
Add try/catch statements to server actions
delbaoliveira Sep 26, 2023
3ae95d0
Update data.ts
delbaoliveira Sep 26, 2023
5b95d4f
Create not-found.tsx
delbaoliveira Sep 26, 2023
5720bdc
Create error.tsx
delbaoliveira Sep 26, 2023
73c444f
Merge branch 'main' into example-5hoh
delbaoliveira Sep 28, 2023
e0abcbc
Merge branch 'main' into example-5hoh
delbaoliveira Oct 2, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions dashboard/15-final/app/dashboard/invoices/[id]/edit/not-found.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import Link from 'next/link';
import { FaceFrownIcon } from '@heroicons/react/24/outline';

export default function NotFound() {
return (
<main className="flex h-full flex-col items-center justify-center gap-2">
<FaceFrownIcon className="w-12 text-gray-400" />
<h2 className="text-lg font-semibold">Not Found</h2>
<p>Could not find the requested invoice.</p>
<button className="mt-4 rounded-md bg-black px-4 py-2 text-sm text-white">
<Link href="/dashboard/invoices">Go Back</Link>
</button>
</main>
);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { notFound } from 'next/navigation';
import { fetchInvoiceById, fetchAllCustomers } from '@/app/lib/data';
import { updateInvoice } from '@/app/lib/actions';
import { notFound } from 'next/navigation';

export default async function Page({ params }: { params: { id: string } }) {
const id = params.id;
Expand Down
31 changes: 31 additions & 0 deletions dashboard/15-final/app/dashboard/invoices/error.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
'use client';

import { useEffect } from 'react';

export default function Error({
error,
reset,
}: {
error: Error & { digest?: string };
reset: () => void;
}) {
useEffect(() => {
// Optionally log the error to an error reporting service
console.error(error);
}, [error]);

return (
<main className="flex h-full flex-col items-center justify-center">
<h2 className="text-center">Something went wrong!</h2>
<button
className="mt-4 rounded-md bg-black px-4 py-2 text-sm text-white"
onClick={
// Attempt to recover by trying to re-render the invoices route
() => reset()
}
>
Try again
</button>
</main>
);
}
43 changes: 28 additions & 15 deletions dashboard/15-final/app/lib/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,17 @@ export async function createInvoice(formData: FormData) {
const amountInCents = amount * 100;
const date = new Date().toISOString().split('T')[0];

await sql`
INSERT INTO invoices (customer_id, amount, status, date)
VALUES (${customerId}, ${amountInCents}, ${status}, ${date})
`;
try {
await sql`
INSERT INTO invoices (customer_id, amount, status, date)
VALUES (${customerId}, ${amountInCents}, ${status}, ${date})
`;

revalidatePath('/dashboard/invoices');
redirect('/dashboard/invoices');
revalidatePath('/dashboard/invoices');
redirect('/dashboard/invoices');
} catch (error) {
throw new Error('Failed to Create Invoice');
}
}

export async function updateInvoice(formData: FormData) {
Expand All @@ -45,21 +49,30 @@ export async function updateInvoice(formData: FormData) {

const amountInCents = amount * 100;

await sql`
UPDATE invoices
SET customer_id = ${customerId}, amount = ${amountInCents}, status = ${status}
WHERE id = ${id}
`;
try {
await sql`
UPDATE invoices
SET customer_id = ${customerId}, amount = ${amountInCents}, status = ${status}
WHERE id = ${id}
`;

revalidatePath('/dashboard/invoices');
redirect('/dashboard/invoices');
revalidatePath('/dashboard/invoices');
redirect('/dashboard/invoices');
} catch (error) {
throw new Error('Failed to Update Invoice');
}
}

export async function deleteInvoice(formData: FormData) {
const { id } = DeleteInvoice.parse({
id: formData.get('id'),
});

await sql`DELETE FROM invoices WHERE id = ${id}`;
revalidatePath('/dashboard/invoices');
try {
await sql`DELETE FROM invoices WHERE id = ${id}`;
revalidatePath('/dashboard/invoices');
return { message: 'Deleted Invoice' };
} catch (error) {
throw new Error('Failed to Delete Invoice');
}
}
14 changes: 8 additions & 6 deletions dashboard/15-final/app/lib/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,12 +149,14 @@ export async function fetchInvoiceById(id: string) {
amount: invoice.amount / 100,
}));

return invoice[0] as {
id: string;
amount: number;
status: string;
name: string;
};
return invoice[0] as
| {
id: string;
amount: number;
status: string;
name: string;
}
| undefined;
} catch (error) {
console.error('Database Error:', error);
throw new Error('Failed to fetch invoice.');
Expand Down
Loading