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)} + - - - +