'use client' import { useState, useEffect, useCallback } from 'react' import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { Badge } from '@/components/ui/badge' import { Checkbox } from '@/components/ui/checkbox' import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '@/components/ui/table' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select' import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu' import { Search, Download, MoreHorizontal, Eye, Package, Truck, CheckCircle, XCircle, Clock, CreditCard, Filter } from 'lucide-react' import { toast } from 'sonner' import Link from 'next/link' import { motion } from 'framer-motion' interface Order { id: string total: number status: 'PENDING' | 'PAID' | 'SHIPPED' | 'DELIVERED' | 'CANCELLED' createdAt: string razorpayOrderId: string | null razorpayPaymentId: string | null user: { id: string name: string email: string } orderItems: { id: string quantity: number price: number product: { id: string name: string images: string[] } }[] } const statusConfig = { PENDING: { label: 'Pending', color: 'bg-gradient-to-r from-yellow-400 to-orange-500', icon: Clock, description: 'Awaiting payment' }, PAID: { label: 'Paid', color: 'bg-gradient-to-r from-blue-500 to-indigo-600', icon: CreditCard, description: 'Payment confirmed' }, SHIPPED: { label: 'Shipped', color: 'bg-gradient-to-r from-purple-500 to-pink-600', icon: Truck, description: 'Order shipped' }, DELIVERED: { label: 'Delivered', color: 'bg-gradient-to-r from-green-500 to-emerald-600', icon: CheckCircle, description: 'Successfully delivered' }, CANCELLED: { label: 'Cancelled', color: 'bg-gradient-to-r from-red-500 to-pink-600', icon: XCircle, description: 'Order cancelled' } } export default function AdminOrdersPage() { const [orders, setOrders] = useState([]) const [loading, setLoading] = useState(true) const [search, setSearch] = useState('') const [statusFilter, setStatusFilter] = useState('all') const [selectedOrders, setSelectedOrders] = useState([]) const [bulkActionLoading, setBulkActionLoading] = useState(false) const fetchOrders = useCallback(async () => { try { setLoading(true) const params = new URLSearchParams() if (search) params.append('search', search) if (statusFilter && statusFilter !== 'all') params.append('status', statusFilter) const response = await fetch(`/api/admin/orders?${params}`) const data = await response.json() setOrders(data || []) } catch (error) { console.error('Error fetching orders:', error) toast.error('Failed to load orders') } finally { setLoading(false) } }, [search, statusFilter]) useEffect(() => { fetchOrders() }, [fetchOrders]) const handleSelectAll = (checked: boolean) => { if (checked) { setSelectedOrders(orders.map(o => o.id)) } else { setSelectedOrders([]) } } const handleSelectOrder = (orderId: string, checked: boolean) => { if (checked) { setSelectedOrders(prev => [...prev, orderId]) } else { setSelectedOrders(prev => prev.filter(id => id !== orderId)) } } const handleBulkStatusUpdate = async (newStatus: string) => { if (selectedOrders.length === 0) { toast.error('Please select at least one order') return } setBulkActionLoading(true) try { const response = await fetch('/api/admin/orders/bulk', { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ orderIds: selectedOrders, status: newStatus }) }) if (!response.ok) throw new Error('Bulk update failed') toast.success(`Successfully updated ${selectedOrders.length} orders`) setSelectedOrders([]) fetchOrders() } catch (error) { toast.error('Failed to update orders') } finally { setBulkActionLoading(false) } } const handleStatusUpdate = async (orderId: string, newStatus: string) => { try { const response = await fetch(`/api/admin/orders/${orderId}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ status: newStatus }) }) if (!response.ok) throw new Error('Status update failed') toast.success('Order status updated successfully') fetchOrders() } catch (error) { toast.error('Failed to update order status') } } return (
{/* Header */}

Orders Management

Manage customer orders and track shipments

{/* Stats Cards */} {Object.entries(statusConfig).map(([status, config], index) => { const StatusIcon = config.icon const count = orders.filter(order => order.status === status).length return (

{config.label}

{count}

{config.description}

) })}
{/* Main Orders Table */}
All Orders
{selectedOrders.length > 0 && ( {selectedOrders.length} selected )}
setSearch(e.target.value)} className="pl-10 w-64 bg-white shadow-sm" />
{loading ? (
) : (
0} onCheckedChange={handleSelectAll} /> Order Customer Items Total Status Date Actions {orders.map((order, index) => { const StatusIcon = statusConfig[order.status].icon return ( handleSelectOrder(order.id, !!checked)} />

#{order.id.slice(-8)}

{order.razorpayOrderId && (

Razorpay: {order.razorpayOrderId.slice(-8)}

)}
{order.user.name?.charAt(0) || 'U'}

{order.user.name}

{order.user.email}

{order.orderItems.slice(0, 2).map((item) => (
{item.quantity}x{' '} {item.product.name}
))} {order.orderItems.length > 2 && (

+{order.orderItems.length - 2} more items

)}
₹{order.total.toFixed(2)} {statusConfig[order.status].label}

{new Date(order.createdAt).toLocaleDateString('en-US', { month: 'short', day: 'numeric' })}

{new Date(order.createdAt).toLocaleDateString('en-US', { year: 'numeric' })}

View Details {order.status === 'PENDING' && ( handleStatusUpdate(order.id, 'PAID')} className="text-blue-600" > Mark as Paid )} {order.status === 'PAID' && ( handleStatusUpdate(order.id, 'SHIPPED')} className="text-purple-600" > Mark as Shipped )} {order.status === 'SHIPPED' && ( handleStatusUpdate(order.id, 'DELIVERED')} className="text-green-600" > Mark as Delivered )} {['PENDING', 'PAID'].includes(order.status) && ( handleStatusUpdate(order.id, 'CANCELLED')} className="text-red-600" > Cancel Order )}
) })}
)} {!loading && orders.length === 0 && (

No orders found

Try adjusting your search or filter criteria

)}
) }