diff --git a/dashboard/15-final/app/lib/utils.ts b/dashboard/15-final/app/lib/utils.ts
index 3b9582d..b694c1a 100644
--- a/dashboard/15-final/app/lib/utils.ts
+++ b/dashboard/15-final/app/lib/utils.ts
@@ -1,4 +1,4 @@
-import { Invoice, Revenue, Customer, LatestInvoice } from './definitions';
+import { Invoice, Revenue, Customer } from './definitions';
export const formatCurrency = (amount: number) => {
return (amount / 100).toLocaleString('en-US', {
@@ -7,6 +7,20 @@ export const formatCurrency = (amount: number) => {
});
};
+export const formatDateToLocal = (
+ dateStr: string,
+ locale: string = 'en-US',
+) => {
+ const date = new Date(dateStr);
+ const options: Intl.DateTimeFormatOptions = {
+ day: 'numeric',
+ month: 'short',
+ year: 'numeric',
+ };
+ const formatter = new Intl.DateTimeFormat(locale, options);
+ return formatter.format(date);
+};
+
export function findLatestInvoices(invoices: Invoice[], customers: Customer[]) {
// Sort the invoices by date in descending order and take the top 5
const latestInvoices = [...invoices]
diff --git a/dashboard/15-final/app/ui/invoices/add-button.tsx b/dashboard/15-final/app/ui/invoices/add-button.tsx
new file mode 100644
index 0000000..7113cd1
--- /dev/null
+++ b/dashboard/15-final/app/ui/invoices/add-button.tsx
@@ -0,0 +1,11 @@
+import Link from 'next/link';
+export default function AddInvoice() {
+ return (
+
+ Add Invoice
+
+ );
+}
diff --git a/dashboard/15-final/app/ui/invoices/edit-button.tsx b/dashboard/15-final/app/ui/invoices/edit-button.tsx
new file mode 100644
index 0000000..a7352ec
--- /dev/null
+++ b/dashboard/15-final/app/ui/invoices/edit-button.tsx
@@ -0,0 +1,12 @@
+import { PencilSquareIcon } from '@heroicons/react/24/outline';
+import Link from 'next/link';
+export default function EditInvoice({ id }: { id: number }) {
+ return (
+
+
+
+ );
+}
diff --git a/dashboard/15-final/app/ui/invoices/table-search.tsx b/dashboard/15-final/app/ui/invoices/search.tsx
similarity index 96%
rename from dashboard/15-final/app/ui/invoices/table-search.tsx
rename to dashboard/15-final/app/ui/invoices/search.tsx
index 546c214..d6e6584 100644
--- a/dashboard/15-final/app/ui/invoices/table-search.tsx
+++ b/dashboard/15-final/app/ui/invoices/search.tsx
@@ -3,7 +3,7 @@
import { MagnifyingGlassIcon } from '@heroicons/react/24/outline';
import { usePathname, useRouter } from 'next/navigation';
-export default function TableSearch({
+export default function Search({
searchParams,
}: {
searchParams: { query: string; page: string };
diff --git a/dashboard/15-final/app/ui/invoices/status.tsx b/dashboard/15-final/app/ui/invoices/status.tsx
new file mode 100644
index 0000000..ce2534c
--- /dev/null
+++ b/dashboard/15-final/app/ui/invoices/status.tsx
@@ -0,0 +1,27 @@
+import { CheckCircleIcon, ClockIcon } from '@heroicons/react/24/outline';
+import clsx from 'clsx';
+
+export default function InvoiceStatus({ status }: { status: string }) {
+ return (
+
+ {status === 'pending' ? (
+ <>
+ Pending
+ >
+ ) : null}
+ {status === 'paid' ? (
+ <>
+ Paid
+ >
+ ) : null}
+
+ );
+}
diff --git a/dashboard/15-final/app/ui/invoices/table.tsx b/dashboard/15-final/app/ui/invoices/table.tsx
index 63f25da..f8ea07a 100644
--- a/dashboard/15-final/app/ui/invoices/table.tsx
+++ b/dashboard/15-final/app/ui/invoices/table.tsx
@@ -1,48 +1,15 @@
-import Link from 'next/link';
import Image from 'next/image';
-import {
- PencilSquareIcon,
- ClockIcon,
- CheckCircleIcon,
-} from '@heroicons/react/24/outline';
import DeleteInvoice from '@/app/ui/invoices/delete-button';
-import TableSearch from './table-search';
-import PaginationButtons from './pagination';
+import EditInvoice from '@/app/ui/invoices/edit-button';
+import AddInvoice from '@/app/ui/invoices/add-button';
+import Search from '@/app/ui/invoices/search';
+import PaginationButtons from '@/app/ui/invoices/pagination';
+import InvoiceStatus from '@/app/ui/invoices/status';
import {
fetchFilteredInvoices,
fetchInvoiceCountBySearchTerm,
} from '@/app/lib/data';
-
-const ITEMS_PER_PAGE = 10;
-
-function renderInvoiceStatus(status: string) {
- if (status === 'pending') {
- return (
-
-
- Pending
-
- );
- } else {
- return (
-
-
- Paid
-
- );
- }
-}
-
-function formatDateToLocal(dateStr: string, locale: string = 'en-US') {
- const date = new Date(dateStr);
- const options: Intl.DateTimeFormatOptions = {
- day: 'numeric',
- month: 'short',
- year: 'numeric',
- };
- const formatter = new Intl.DateTimeFormat(locale, options);
- return formatter.format(date);
-}
+import { formatDateToLocal, formatCurrency } from '@/app/lib/utils';
export default async function InvoicesTable({
searchParams,
@@ -52,6 +19,7 @@ export default async function InvoicesTable({
page: string;
};
}) {
+ const ITEMS_PER_PAGE = 10;
const searchTerm = searchParams.query ?? '';
let currentPage = 1;
if (!searchTerm) {
@@ -71,15 +39,10 @@ export default async function InvoicesTable({
Invoices
-
- Add Invoice
-
+
-
+
- {(invoice.amount / 100).toLocaleString('en-US', {
- style: 'currency',
- currency: 'USD',
- })}
+ {formatCurrency(invoice.amount)}
|
{formatDateToLocal(invoice.date)}
|
- {renderInvoiceStatus(invoice.status)}
+
|
-
-
-
+
|