All Taste components
App screens
Store orders
An online store’s order list with today’s numbers, status tabs, bulk actions and payment and fulfilment badges.
sidebar · stat strip · tabs · bulk-action bar · selectable table · 7 statuses
Orders
Search orders⌘K
Orders
2 orders are waiting to be packed for today’s 4 pm pickup.
Orders today
38
↑ 6 vs yesterday
To fulfil
14
2 selected
Revenue today
₹61,820
↑ 8.4%
Returns
3
1.1% of orders
2 selected
| Order | Date | Customer | Payment | Fulfilment | Total | |
|---|---|---|---|---|---|---|
| #3291 | Today, 10:42 | Priya Menon · Bengaluru | Paid | Unfulfilled | ₹2,340 | |
| #3290 | Today, 09:15 | Arjun Kapoor · Pune | Paid | Unfulfilled | ₹1,180 | |
| #3289 | Today, 08:03 | Fatima Shaikh · Mumbai | COD | Packed | ₹860 | |
| #3288 | Yesterday | Rohan Das · Kolkata | Paid | Shipped | ₹4,520 | |
| #3287 | Yesterday | Neha Iyer · Chennai | Refunded | Returned | ₹1,640 | |
| #3286 | Yesterday | Vikram Singh · Jaipur | Paid | Delivered | ₹3,075 | |
| #3285 | 13 Oct | Ananya Bose · Delhi | Pending | Unfulfilled | ₹990 |
"use client";
import { useState } from "react";
import { Bell, Download, Globe, Home, Inbox, LineChart, Package, Percent, Plus, Search, Settings, Tag, Users } from "lucide-react";
import { cn } from "@/lib/utils";
const nav = [
{ label: "Home", icon: Home },
{ label: "Orders", icon: Inbox, count: 14, current: true },
{ label: "Products", icon: Tag },
{ label: "Customers", icon: Users },
{ label: "Discounts", icon: Percent },
{ label: "Analytics", icon: LineChart },
{ label: "Settings", icon: Settings },
];
const stats = [
{ label: "Orders today", value: "38", note: "↑ 6 vs yesterday" },
{ label: "To fulfil", value: "14", note: "Pickup at 4 pm" },
{ label: "Revenue today", value: "₹61,820", note: "↑ 8.4%" },
{ label: "Returns", value: "3", note: "1.1% of orders" },
];
const tabs = ["All", "Unfulfilled · 14", "Unpaid · 4", "Returns", "Archived"];
type Tone = "success" | "warning" | "info" | "danger" | "neutral";
const tone: Record<Tone, string> = {
success: "bg-success-soft text-success-fg",
warning: "bg-warning-soft text-warning-fg",
info: "bg-info-soft text-info-fg",
danger: "bg-danger-soft text-danger-fg",
neutral: "bg-surface-2 text-fg-muted",
};
const orders: { id: string; date: string; customer: string; city: string; payment: [string, Tone]; fulfilment: [string, Tone]; total: string }[] = [
{ id: "#3291", date: "Today, 10:42", customer: "Priya Menon", city: "Bengaluru", payment: ["Paid", "success"], fulfilment: ["Unfulfilled", "warning"], total: "₹2,340" },
{ id: "#3290", date: "Today, 09:15", customer: "Arjun Kapoor", city: "Pune", payment: ["Paid", "success"], fulfilment: ["Unfulfilled", "warning"], total: "₹1,180" },
{ id: "#3289", date: "Today, 08:03", customer: "Fatima Shaikh", city: "Mumbai", payment: ["COD", "neutral"], fulfilment: ["Packed", "info"], total: "₹860" },
{ id: "#3288", date: "Yesterday", customer: "Rohan Das", city: "Kolkata", payment: ["Paid", "success"], fulfilment: ["Shipped", "info"], total: "₹4,520" },
{ id: "#3287", date: "Yesterday", customer: "Neha Iyer", city: "Chennai", payment: ["Refunded", "danger"], fulfilment: ["Returned", "neutral"], total: "₹1,640" },
{ id: "#3286", date: "Yesterday", customer: "Vikram Singh", city: "Jaipur", payment: ["Paid", "success"], fulfilment: ["Delivered", "success"], total: "₹3,075" },
{ id: "#3285", date: "13 Oct", customer: "Ananya Bose", city: "Delhi", payment: ["Pending", "warning"], fulfilment: ["Unfulfilled", "warning"], total: "₹990" },
];
export default function OrdersPage() {
const [tab, setTab] = useState(0);
const [selected, setSelected] = useState<string[]>(["#3291", "#3290"]);
const toggle = (id: string) => setSelected((s) => (s.includes(id) ? s.filter((x) => x !== id) : [...s, id]));
return (
<div className="flex min-h-screen bg-bg font-sans text-sm text-fg">
<aside aria-label="Main" className="hidden w-56 shrink-0 flex-col gap-0.5 border-r border-border bg-surface p-3 lg:flex">
<p className="mb-2 flex h-8 items-center gap-2 px-1.5 font-medium">
<span className="grid size-6 place-items-center rounded-sm bg-primary text-xs font-semibold text-primary-fg">K</span>Kaveri Store
</p>
<nav className="grid gap-0.5">
{nav.map(({ label, icon: Icon, current, count }) => (
<a key={label} href="#" aria-current={current ? "page" : undefined}
className={cn("flex h-8 items-center gap-2.5 rounded px-2 font-medium text-fg-muted hover:bg-surface-2 hover:text-fg",
current && "bg-bg text-fg shadow-sm ring-1 ring-border")}>
<Icon className="size-4" aria-hidden />{label}
{count && <span className="ml-auto text-xs tabular-nums text-fg-subtle">{count}</span>}
</a>
))}
</nav>
<p className="px-2 pb-1 pt-4 text-[11px] font-medium text-fg-subtle">Sales channels</p>
<a href="#" className="flex h-8 items-center gap-2.5 rounded px-2 font-medium text-fg-muted hover:bg-surface-2"><Globe className="size-4" aria-hidden />Online store</a>
<a href="#" className="flex h-8 items-center gap-2.5 rounded px-2 font-medium text-fg-muted hover:bg-surface-2"><Package className="size-4" aria-hidden />Wholesale</a>
</aside>
<div className="flex min-w-0 flex-1 flex-col">
<header className="flex h-14 items-center gap-3 border-b border-border px-4 sm:px-6">
<p className="font-medium">Orders</p>
<label className="ml-auto hidden h-9 w-64 items-center gap-2 rounded border border-border bg-surface px-2.5 text-fg-subtle md:flex">
<Search className="size-4" aria-hidden />
<input placeholder="Search orders" className="w-full bg-transparent text-[13px] text-fg outline-none placeholder:text-fg-subtle" />
</label>
<button type="button" aria-label="Notifications" className="grid size-9 place-items-center rounded text-fg-muted hover:bg-surface-2"><Bell className="size-4" aria-hidden /></button>
</header>
<main className="grid gap-4 p-4 sm:p-6">
<div className="flex flex-wrap items-end justify-between gap-3">
<div>
<h1 className="text-xl font-medium tracking-tight">Orders</h1>
<p className="text-fg-muted">2 orders are waiting to be packed for today’s 4 pm pickup.</p>
</div>
<div className="flex gap-2">
<button type="button" className="inline-flex h-9 items-center gap-1.5 rounded border border-border-strong px-3 font-medium hover:bg-surface"><Download className="size-4" aria-hidden /> Export</button>
<button type="button" className="inline-flex h-9 items-center gap-1.5 rounded bg-primary px-3 font-medium text-primary-fg hover:bg-primary-hover"><Plus className="size-4" aria-hidden /> Create order</button>
</div>
</div>
<section aria-label="Today" className="grid grid-cols-2 gap-3 xl:grid-cols-4">
{stats.map((s) => (
<div key={s.label} className="rounded-lg border border-border px-4 py-3">
<p className="text-xs text-fg-muted">{s.label}</p>
<p className="mt-0.5 text-xl font-medium tabular-nums">{s.value}</p>
<p className="text-xs text-fg-subtle">{s.note}</p>
</div>
))}
</section>
<section aria-label="Order list" className="overflow-hidden rounded-lg border border-border">
<div role="tablist" className="flex gap-4 overflow-x-auto border-b border-border px-4">
{tabs.map((t, i) => (
<button key={t} role="tab" type="button" aria-selected={tab === i} onClick={() => setTab(i)}
className="-mb-px h-10 whitespace-nowrap border-b-2 border-transparent text-[13px] font-medium text-fg-muted aria-selected:border-primary aria-selected:text-fg">{t}</button>
))}
</div>
{selected.length > 0 && (
<div className="flex items-center gap-2 border-b border-border bg-primary-soft px-4 py-2 text-[13px] text-primary-soft-fg">
<span className="font-medium">{selected.length} selected</span>
<button type="button" className="ml-2 h-7 rounded border border-border-strong bg-bg px-2.5 text-xs font-medium text-fg">Mark as packed</button>
<button type="button" className="h-7 rounded border border-border-strong bg-bg px-2.5 text-xs font-medium text-fg">Print labels</button>
<button type="button" onClick={() => setSelected([])} className="ml-auto text-xs font-medium">Clear</button>
</div>
)}
<div className="overflow-x-auto">
<table className="w-full text-[13px]">
<thead className="bg-surface text-left text-xs text-fg-subtle">
<tr>
<th className="w-10 px-4 py-2"><input type="checkbox" aria-label="Select all" className="size-4 accent-primary"
checked={selected.length === orders.length} onChange={(e) => setSelected(e.target.checked ? orders.map((o) => o.id) : [])} /></th>
<th className="px-4 py-2 font-medium">Order</th><th className="px-4 py-2 font-medium">Date</th><th className="px-4 py-2 font-medium">Customer</th>
<th className="px-4 py-2 font-medium">Payment</th><th className="px-4 py-2 font-medium">Fulfilment</th><th className="px-4 py-2 text-right font-medium">Total</th>
</tr>
</thead>
<tbody className="divide-y divide-border">
{orders.map((o) => (
<tr key={o.id} className={cn("whitespace-nowrap hover:bg-surface", selected.includes(o.id) && "bg-surface")}>
<td className="px-4 py-2.5"><input type="checkbox" className="size-4 accent-primary" aria-label={"Select order " + o.id} checked={selected.includes(o.id)} onChange={() => toggle(o.id)} /></td>
<td className="px-4 py-2.5 font-medium tabular-nums">{o.id}</td>
<td className="px-4 py-2.5 text-fg-muted">{o.date}</td>
<td className="px-4 py-2.5"><span className="font-medium">{o.customer}</span> <span className="text-fg-subtle">· {o.city}</span></td>
<td className="px-4 py-2.5"><span className={cn("rounded-full px-2 py-0.5 text-xs font-medium", tone[o.payment[1]])}>{o.payment[0]}</span></td>
<td className="px-4 py-2.5"><span className={cn("inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-xs font-medium", tone[o.fulfilment[1]])}><span className="size-1.5 rounded-full bg-current" />{o.fulfilment[0]}</span></td>
<td className="px-4 py-2.5 text-right font-medium tabular-nums">{o.total}</td>
</tr>
))}
</tbody>
</table>
</div>
</section>
</main>
</div>
</div>
);
}
The code uses the Taste Tailwind preset. Make yours on the Taste page with Export my system.