mirror of
https://github.com/vercel/next-learn.git
synced 2026-07-09 06:55:12 +00:00
Add table component (#132)
* add table compoennt * format * format * change table type to be a card * update table header and link * update layout and table width * Update dashboard/15-final/app/ui/table.tsx --------- Co-authored-by: Delba de Oliveira <delbabrown@gmail.com> Co-authored-by: Delba de Oliveira <32464864+delbaoliveira@users.noreply.github.com>
This commit is contained in:
@@ -1,3 +1,9 @@
|
|||||||
|
import Table from "@/app/ui/table";
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
return <div>List of invoices</div>
|
return (
|
||||||
|
<div>
|
||||||
|
<Table />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ export type Invoice = {
|
|||||||
id: number
|
id: number
|
||||||
customerId: number
|
customerId: number
|
||||||
amount: number
|
amount: number
|
||||||
|
date: string
|
||||||
status: "pending" | "paid" // In TypeScript, this is called a string union type.
|
status: "pending" | "paid" // In TypeScript, this is called a string union type.
|
||||||
// It means that the "status" property can only be one of the two strings.
|
// It means that the "status" property can only be one of the two strings.
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,24 +38,28 @@ export const invoices: Invoice[] = [
|
|||||||
id: 1,
|
id: 1,
|
||||||
customerId: 1,
|
customerId: 1,
|
||||||
amount: 15795,
|
amount: 15795,
|
||||||
|
date: "2021-01-01",
|
||||||
status: "pending",
|
status: "pending",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 2,
|
id: 2,
|
||||||
customerId: 2,
|
customerId: 2,
|
||||||
amount: 20348,
|
amount: 20348,
|
||||||
|
date: "2021-02-01",
|
||||||
status: "pending",
|
status: "pending",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 3,
|
id: 3,
|
||||||
customerId: 3,
|
customerId: 3,
|
||||||
amount: 3040,
|
amount: 3040,
|
||||||
|
date: "2021-03-01",
|
||||||
status: "paid",
|
status: "paid",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 4,
|
id: 4,
|
||||||
customerId: 4,
|
customerId: 4,
|
||||||
amount: 44800,
|
amount: 44800,
|
||||||
|
date: "2021-04-01",
|
||||||
status: "paid",
|
status: "paid",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
70
dashboard/15-final/app/ui/table.tsx
Normal file
70
dashboard/15-final/app/ui/table.tsx
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
import {invoices, customers} from "../lib/dummy-data";
|
||||||
|
import Link from "next/link";
|
||||||
|
|
||||||
|
export default function Example() {
|
||||||
|
function getNameById(customerId: number) {
|
||||||
|
const customerName = customers.find(customer => customer.id === customerId);
|
||||||
|
return customerName ? customerName.name : null;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div className="w-full">
|
||||||
|
<div className="w-full flex items-center justify-between">
|
||||||
|
<h1 className="text-base font-semibold text-gray-900">Invoices</h1>
|
||||||
|
<Link
|
||||||
|
href="/dashboard/invoices/create"
|
||||||
|
className="block rounded-md bg-indigo-600 px-3 py-2 text-center text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
|
||||||
|
>
|
||||||
|
Add Invoice
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
<div className="mt-8">
|
||||||
|
<div className="overflow-x-auto">
|
||||||
|
<div className="overflow-hidden border rounded-md">
|
||||||
|
<table className="min-w-full divide-y divide-gray-300">
|
||||||
|
<thead className="bg-gray-50">
|
||||||
|
<tr>
|
||||||
|
<th scope="col" className="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">
|
||||||
|
ID
|
||||||
|
</th>
|
||||||
|
<th scope="col" className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
|
||||||
|
Customer Name
|
||||||
|
</th>
|
||||||
|
<th scope="col" className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
|
||||||
|
Amount
|
||||||
|
</th>
|
||||||
|
<th scope="col" className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
|
||||||
|
Status
|
||||||
|
</th>
|
||||||
|
<th scope="col" className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
|
||||||
|
Date
|
||||||
|
</th>
|
||||||
|
<th scope="col" className="relative py-3.5 pl-3 pr-4 sm:pr-6">
|
||||||
|
<span className="sr-only">View</span>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody className="divide-y divide-gray-200 bg-white">
|
||||||
|
{invoices.map((invoice) => (
|
||||||
|
<tr key={invoice.id}>
|
||||||
|
<td className="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6">
|
||||||
|
{invoice.id}
|
||||||
|
</td>
|
||||||
|
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500">{getNameById(invoice.customerId)}</td>
|
||||||
|
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500">{(invoice.amount / 100).toLocaleString("en-US", {style: "currency", currency: "USD"})}</td>
|
||||||
|
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500">{invoice.status}</td>
|
||||||
|
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500">{invoice.date}</td>
|
||||||
|
<td className="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6">
|
||||||
|
<Link href={`/dashboard/invoices/${invoice.id}`} className="text-indigo-600 hover:text-indigo-900">
|
||||||
|
View<span className="sr-only">, {invoice.id}</span>
|
||||||
|
</Link>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user