124 lines
4.4 KiB
TypeScript
124 lines
4.4 KiB
TypeScript
"use client"
|
|
|
|
import { Eye, Pencil, Trash2 } from "lucide-react"
|
|
|
|
import { Badge } from "@/components/ui/badge"
|
|
import { DataTable, type DataTableColumn } from "@/components/ui/data-table"
|
|
|
|
const orders = [
|
|
{ id: "#3210", customer: "John Martinez", date: "Jul 4, 2026", status: "Paid", items: 3, amount: 245.0 },
|
|
{ id: "#3209", customer: "Aisha Khan", date: "Jul 3, 2026", status: "Pending", items: 1, amount: 89.5 },
|
|
{ id: "#3208", customer: "Liam Chen", date: "Jul 3, 2026", status: "Paid", items: 5, amount: 512.2 },
|
|
{ id: "#3207", customer: "Sofia Rossi", date: "Jul 2, 2026", status: "Cancelled", items: 2, amount: 64.0 },
|
|
{ id: "#3206", customer: "Noah Williams", date: "Jul 1, 2026", status: "Paid", items: 4, amount: 178.9 },
|
|
{ id: "#3205", customer: "Emma Garcia", date: "Jun 30, 2026", status: "Paid", items: 2, amount: 132.4 },
|
|
{ id: "#3204", customer: "Yuki Tanaka", date: "Jun 30, 2026", status: "Pending", items: 6, amount: 340.75 },
|
|
{ id: "#3203", customer: "Priya Patel", date: "Jun 29, 2026", status: "Paid", items: 1, amount: 42.0 },
|
|
{ id: "#3202", customer: "Lucas Silva", date: "Jun 28, 2026", status: "Cancelled", items: 3, amount: 97.6 },
|
|
{ id: "#3201", customer: "Olivia Brown", date: "Jun 27, 2026", status: "Paid", items: 4, amount: 210.3 },
|
|
{ id: "#3200", customer: "Mateo Alvarez", date: "Jun 26, 2026", status: "Paid", items: 2, amount: 88.0 },
|
|
{ id: "#3199", customer: "Grace Kim", date: "Jun 25, 2026", status: "Pending", items: 5, amount: 265.5 },
|
|
] as const
|
|
|
|
type Order = (typeof orders)[number]
|
|
|
|
const statusStyles: Record<Order["status"], string> = {
|
|
Paid: "bg-emerald-50 text-emerald-700",
|
|
Pending: "bg-amber-50 text-amber-700",
|
|
Cancelled: "bg-rose-50 text-rose-700",
|
|
}
|
|
|
|
const currency = new Intl.NumberFormat(undefined, {
|
|
style: "currency",
|
|
currency: "USD",
|
|
})
|
|
|
|
const columns: DataTableColumn<Order>[] = [
|
|
{
|
|
key: "id",
|
|
header: "Order",
|
|
cell: (order) => <span className="font-medium text-slate-900">{order.id}</span>,
|
|
},
|
|
{
|
|
key: "customer",
|
|
header: "Customer",
|
|
cell: (order) => order.customer,
|
|
},
|
|
{
|
|
key: "date",
|
|
header: "Date",
|
|
cell: (order) => order.date,
|
|
headerClassName: "hidden sm:table-cell",
|
|
cellClassName: "hidden text-muted-foreground sm:table-cell",
|
|
},
|
|
{
|
|
key: "items",
|
|
header: "Items",
|
|
cell: (order) => order.items,
|
|
headerClassName: "hidden md:table-cell",
|
|
cellClassName: "hidden text-muted-foreground md:table-cell",
|
|
},
|
|
{
|
|
key: "status",
|
|
header: "Status",
|
|
cell: (order) => <Badge className={statusStyles[order.status]}>{order.status}</Badge>,
|
|
},
|
|
{
|
|
key: "amount",
|
|
header: "Amount",
|
|
cell: (order) => currency.format(order.amount),
|
|
headerClassName: "text-right",
|
|
cellClassName: "text-right font-medium text-slate-900",
|
|
},
|
|
]
|
|
|
|
export function RecentOrdersTable() {
|
|
return (
|
|
<div className="rounded-2xl bg-white p-5 shadow-sm ring-1 ring-black/5">
|
|
<h2 className="mb-4 text-lg font-bold tracking-tight text-slate-900">Recent Orders</h2>
|
|
|
|
<DataTable
|
|
data={orders}
|
|
columns={columns}
|
|
getRowId={(order) => order.id}
|
|
searchAccessor={(order) => `${order.id} ${order.customer}`}
|
|
searchPlaceholder="Search orders..."
|
|
filters={[
|
|
{
|
|
key: "status",
|
|
label: "Status",
|
|
options: ["Paid", "Pending", "Cancelled"],
|
|
accessor: (order) => order.status,
|
|
},
|
|
]}
|
|
pageSize={5}
|
|
actions={(order) => (
|
|
<div className="flex items-center justify-end gap-1">
|
|
<button
|
|
type="button"
|
|
aria-label={`View ${order.id}`}
|
|
className="flex size-8 items-center justify-center rounded-full text-slate-500 hover:bg-slate-50 hover:text-slate-700"
|
|
>
|
|
<Eye className="size-4" />
|
|
</button>
|
|
<button
|
|
type="button"
|
|
aria-label={`Edit ${order.id}`}
|
|
className="flex size-8 items-center justify-center rounded-full text-slate-500 hover:bg-slate-50 hover:text-slate-700"
|
|
>
|
|
<Pencil className="size-4" />
|
|
</button>
|
|
<button
|
|
type="button"
|
|
aria-label={`Delete ${order.id}`}
|
|
className="flex size-8 items-center justify-center rounded-full text-rose-500 hover:bg-rose-50"
|
|
>
|
|
<Trash2 className="size-4" />
|
|
</button>
|
|
</div>
|
|
)}
|
|
/>
|
|
</div>
|
|
)
|
|
}
|