Here’s a clean, modern React-based dashboard for managing online orders, using Tailwind CSS and ShadCN UI components. This design includes summary cards, a sortable order table, and filters for managing order data efficiently.
tsx// File: OnlineOrdersDashboard.tsx
import { Card, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Badge } from "@/components/ui/badge";
import { Search } from "lucide-react";
import { useState } from "react";
const orders = [
{ id: "ORD001", customer: "Alice Smith", status: "Pending", total: "$120.00", date: "2025-05-15" },
{ id: "ORD002", customer: "John Doe", status: "Shipped", total: "$85.00", date: "2025-05-14" },
{ id: "ORD003", customer: "Emma Johnson", status: "Delivered", total: "$99.00", date: "2025-05-13" },
{ id: "ORD004", customer: "Michael Brown", status: "Cancelled", total: "$47.00", date: "2025-05-12" },
];
export default function OnlineOrdersDashboard() {
const [search, setSearch] = useState("");
const filteredOrders = orders.filter(order =>
order.customer.toLowerCase().includes(search.toLowerCase()) ||
order.id.toLowerCase().includes(search.toLowerCase())
);
return (
<div className="p-6 space-y-6">
<h1 className="text-2xl font-bold">Online Orders Dashboard</h1>
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 gap-4">
<Card><CardContent className="p-4"><p className="text-sm text-gray-500">Total Orders</p><p className="text-xl font-bold">134</p></CardContent></Card>
<Card><CardContent className="p-4"><p className="text-sm text-gray-500">Pending</p><p className="text-xl font-bold">23</p></CardContent></Card>
<Card><CardContent className="p-4"><p className="text-sm text-gray-500">Delivered</p><p className="text-xl font-bold">89</p></CardContent></Card>
<Card><CardContent className="p-4"><p className="text-sm text-gray-500">Cancelled</p><p className="text-xl font-bold">22</p></CardContent></Card>
</div>
<div className="flex items-center gap-4">
<div className="relative w-full max-w-sm">
<Input
placeholder="Search by customer or order ID"
value={search}
onChange={(e) => setSearch(e.target.value)}
className="pl-10"
/>
<Search className="absolute left-3 top-2.5 w-5 h-5 text-gray-400" />
</div>
<Tabs defaultValue="all">
<TabsList>
<TabsTrigger value="all">All</TabsTrigger>
<TabsTrigger value="pending">Pending</TabsTrigger>
<TabsTrigger value="shipped">Shipped</TabsTrigger>
<TabsTrigger value="delivered">Delivered</TabsTrigger>
</TabsList>
</Tabs>
</div>
<Table>
<TableHeader>
<TableRow>
<TableHead>Order ID</TableHead>
<TableHead>Customer</TableHead>
<TableHead>Status</TableHead>
<TableHead>Total</TableHead>
<TableHead>Date</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{filteredOrders.map((order) => (
<TableRow key={order.id}>
<TableCell>{order.id}</TableCell>
<TableCell>{order.customer}</TableCell>
<TableCell>
<Badge variant={getStatusVariant(order.status)}>{order.status}</Badge>
</TableCell>
<TableCell>{order.total}</TableCell>
<TableCell>{order.date}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
);
}
function getStatusVariant(status: string) {
switch (status.toLowerCase()) {
case "pending": return "secondary";
case "shipped": return "default";
case "delivered": return "success";
case "cancelled": return "destructive";
default: return "outline";
}
}
Would you like a version of this with chart analytics or export functionality too?
Share this Page your favorite way: Click any app below to share.