| import React, { useState, useEffect, useCallback } from 'react'; |
| import { motion, AnimatePresence } from 'framer-motion'; |
| import { |
| ShoppingCart, Search, RefreshCw, Plus, Eye, Edit, Trash2, ChevronLeft, ChevronRight, X, User |
| } from 'lucide-react'; |
| import styles from './OrderManagement.module.css'; |
|
|
| const OrderManagement = ({ |
| orders, |
| ordersLoading, |
| orderPagination, |
| setOrderPagination, |
| orderStatus, |
| setOrderStatus, |
| selectedPeriod, |
| setSelectedPeriod, |
| searchQuery, |
| setSearchQuery, |
| lastUpdate, |
| formatLastUpdate, |
| formatCurrency, |
| formatDate, |
| getStatusColor, |
| handleManualRefresh, |
| setSelectedOrder, |
| setShowOrderModal, |
| setEditingOrder, |
| deleteOrder, |
| setIsFormActive |
| }) => { |
| return ( |
| <div className={styles['management-content']}> |
| <div className={`${styles['content-header']} ${styles['order-management-header']}`}> |
| {} |
| <div className={styles['order-header-column-1']}> |
| <div className={styles['order-header-title-section']}> |
| <h2 className={styles['order-header-title']}>Order Management</h2> |
| <span className={styles['order-header-badge']}> |
| Last updated: {formatLastUpdate(lastUpdate)} |
| </span> |
| </div> |
| <div className={styles['order-header-search-section']}> |
| <div className={styles['search-bar']} style={{position:'relative'}}> |
| <Search size={20} /> |
| <input |
| type="text" |
| placeholder="Search orders..." |
| value={searchQuery} |
| onChange={(e) => setSearchQuery(e.target.value)} |
| /> |
| {searchQuery && ( |
| <button |
| type="button" |
| style={{position:'absolute',right:8,top:'50%',transform:'translateY(-50%)',background:'none',border:'none',padding:0,cursor:'pointer'}} |
| onClick={() => { setSearchQuery(''); handleManualRefresh(); }} |
| aria-label="Clear search" |
| > |
| <X size={16} /> |
| </button> |
| )} |
| </div> |
| <button |
| className={`${styles['add-btn']} ${styles['adv-btn']} ${styles['order-refresh-btn']}`} |
| onClick={() => { |
| handleManualRefresh(); |
| }} |
| disabled={ordersLoading} |
| > |
| <RefreshCw size={20} className={ordersLoading ? styles['animate-spin'] : ''} /> |
| {ordersLoading ? 'Loading...' : 'Refresh'} |
| </button> |
| </div> |
| </div> |
| |
| {} |
| <div className={styles['order-header-column-2']}> |
| <select |
| value={orderStatus} |
| onChange={(e) => setOrderStatus(e.target.value)} |
| className={`${styles['filter-select']} ${styles['glass']} ${styles['order-filter-select']}`} |
| > |
| <option value="all">All Orders</option> |
| <option value="placed">Placed</option> |
| <option value="processing">Processing</option> |
| <option value="shipped">Shipped</option> |
| <option value="delivered">Delivered</option> |
| </select> |
| <select |
| value={selectedPeriod} |
| onChange={(e) => setSelectedPeriod(e.target.value)} |
| className={`${styles['filter-select']} ${styles['glass']} ${styles['order-period-select']}`} |
| > |
| <option value="7d">Last 7 days</option> |
| <option value="30d">Last 30 days</option> |
| <option value="90d">Last 90 days</option> |
| </select> |
| </div> |
| </div> |
| |
| <div className={`${styles['data-table']} ${styles['glass']} ${styles['order-data-table']}`}> |
| <div className={`${styles['table-header']} ${styles['order-table-header']}`}> |
| <div className={`${styles['table-cell']} ${styles['order-table-cell']} ${styles['table-cell-center']}`}>Order ID</div> |
| <div className={`${styles['table-cell']} ${styles['order-table-cell']} ${styles['table-cell-left']}`}>Customer</div> |
| <div className={`${styles['table-cell']} ${styles['order-table-cell']} ${styles['table-cell-center']}`}>City</div> |
| <div className={`${styles['table-cell']} ${styles['order-table-cell']} ${styles['table-cell-center']}`}>Phone</div> |
| <div className={`${styles['table-cell']} ${styles['order-table-cell']} ${styles['table-cell-center']}`}>Payment Method</div> |
| <div className={`${styles['table-cell']} ${styles['order-table-cell']} ${styles['table-cell-center']}`}>Est. Delivery</div> |
| <div className={`${styles['table-cell']} ${styles['order-table-cell']} ${styles['table-cell-center']}`}>Amount</div> |
| <div className={`${styles['table-cell']} ${styles['order-table-cell']} ${styles['table-cell-center']}`}>Status</div> |
| <div className={`${styles['table-cell']} ${styles['order-table-cell']} ${styles['table-cell-center']}`}>Date</div> |
| <div className={`${styles['table-cell']} ${styles['order-table-cell']} ${styles['table-cell-center']}`}>Actions</div> |
| </div> |
| {} |
| {ordersLoading ? ( |
| Array.from({length: orderPagination.limit}).map((_,i) => ( |
| <div key={i} className={`${styles['table-row']} ${styles['order-table-row']} ${styles['order-table-row-skeleton']}`}> |
| {[...Array(11)].map((_,j) => ( |
| <div key={j} className={`${styles['table-cell']} ${styles['order-table-cell-skeleton']}`}> |
| <div className={styles['skeleton-shimmer']}></div> |
| </div> |
| ))} |
| </div> |
| )) |
| ) : orders.length > 0 ? ( |
| orders.map((order, index) => ( |
| <motion.div |
| key={order._id} |
| className={`${styles['table-row']} ${styles['order-table-row']} ${styles['order-table-row-hover']} ${index % 2 === 0 ? styles['order-table-row-alternate'] : ''}`} |
| whileHover={{ |
| scale:1.01, |
| boxShadow:'0 4px 24px var(--color-shadow)', |
| background: 'rgba(255,255,255,0.02)' |
| }} |
| > |
| <div className={`${styles['table-cell']} ${styles['order-table-cell']} ${styles['table-cell-center']}`}> |
| <span className={styles['order-id-badge']}> |
| #{order._id.slice(-8)} |
| </span> |
| </div> |
| <div className={`${styles['table-cell']} ${styles['order-table-cell']} ${styles['table-cell-left']}`}> |
| <div className={styles['order-info']}> |
| <div className={`${styles['user-avatar']} ${styles['glass']} ${styles['order-user-avatar']}`}> |
| <User size={20} className={styles['order-user-avatar-icon']} /> |
| </div> |
| <span className={styles['order-customer-name']}>{order.userName}</span> |
| </div> |
| </div> |
| |
| <div className={`${styles['table-cell']} ${styles['order-table-cell']} ${styles['table-cell-center']}`}><span className={styles['order-customer-dname']}>{order.city}</span></div> |
| <div className={`${styles['table-cell']} ${styles['order-table-cell']} ${styles['table-cell-center']}`}><span className={styles['order-customer-dname']}>{order.phone}</span></div> |
| <div className={`${styles['table-cell']} ${styles['order-table-cell']} ${styles['table-cell-center']}`}><span className={styles['order-customer-dname']}>{order.paymentMethod}</span></div> |
| <div className={`${styles['table-cell']} ${styles['order-table-cell']} ${styles['table-cell-center']}`}><span className={styles['order-customer-dname']}>{order.estimatedDelivery ? new Date(order.estimatedDelivery).toLocaleDateString() : ''}</span></div> |
| <div className={`${styles['table-cell']} ${styles['order-table-cell']} ${styles['table-cell-center']}`}> |
| <span className={styles['order-amount-text']}> |
| {formatCurrency(order.amount)} |
| </span> |
| </div> |
| <div className={`${styles['table-cell']} ${styles['order-table-cell']} ${styles['table-cell-center']}`}> |
| <span |
| className={`${styles['order-status-badge']} ${styles[`status-${order.status}`]}`} |
| > |
| {order.status} |
| </span> |
| </div> |
| <div className={`${styles['table-cell']} ${styles['order-table-cell']} ${styles['table-cell-center']}`}> |
| <span className={styles['order-date-text']}> |
| {formatDate(order.createdAt)} |
| </span> |
| </div> |
| <div className={`${styles['table-cell']} ${styles['order-table-cell']} ${styles['table-cell-center']}`}> |
| <div className={styles['action-buttons-container']}> |
| <motion.button |
| className={`${styles['action-button']} ${styles['view']}`} |
| whileTap={{scale:0.95}} |
| onClick={() => { setSelectedOrder(order); setShowOrderModal(true); }} |
| > |
| <Eye size={20} /> |
| </motion.button> |
| <motion.button |
| className={`${styles['action-button']} ${styles['edit']}`} |
| whileTap={{scale:0.95}} |
| onClick={() => { setEditingOrder(order); setShowOrderModal(true); }} |
| > |
| <Edit size={20} /> |
| </motion.button> |
| <motion.button |
| className={`${styles['action-button']} ${styles['delete']}`} |
| whileTap={{scale:0.95}} |
| onClick={() => { |
| if (window.confirm('Are you sure you want to delete this order?')) { |
| deleteOrder(order._id); |
| } |
| }} |
| > |
| <Trash2 size={20} /> |
| </motion.button> |
| </div> |
| </div> |
| </motion.div> |
| )) |
| ) : ( |
| <div className={`${styles['table-row']} ${styles['order-table-row']}`}> |
| <div className={`${styles['table-cell']} ${styles['order-table-cell']} ${styles['empty-state-container']}`} colSpan="6" style={{textAlign: 'center', padding: '40px 20px'}}> |
| <div className={styles['empty-state-content']}> |
| <ShoppingCart size={64} className={styles['empty-state-icon']} /> |
| <div className={styles['empty-state-text']}> |
| <p className={styles['empty-state-title']}> |
| {orderStatus !== 'all' ? `No ${orderStatus} orders found` : 'No orders found'} |
| </p> |
| <p className={styles['empty-state-subtitle']}> |
| {orderStatus !== 'all' ? 'Try adjusting your filter settings' : 'Orders will appear here once customers start placing them'} |
| </p> |
| </div> |
| {orderStatus !== 'all' ? ( |
| <button |
| className={`${styles['adv-btn']} ${styles['empty-state-button']} ${styles['clear']}`} |
| onClick={() => setOrderStatus('all')} |
| > |
| Show All Orders |
| </button> |
| ) : ( |
| <button |
| className={`${styles['adv-btn']} ${styles['empty-state-button']} ${styles['add']}`} |
| onClick={() => { |
| |
| alert('Orders will be created when customers make purchases'); |
| }} |
| > |
| <ShoppingCart size={16} className={styles['empty-state-button-icon']} /> |
| View Dashboard |
| </button> |
| )} |
| </div> |
| </div> |
| </div> |
| )} |
| </div> |
| |
| <div className={`${styles['pagination']} ${styles['order-pagination']}`}> |
| <button |
| className={`${styles['pagination-btn']} ${styles['adv-btn']}`} |
| disabled={orderPagination.page === 1} |
| onClick={() => setOrderPagination(prev => ({ ...prev, page: prev.page - 1 }))} |
| > |
| <ChevronLeft size={20} /> |
| </button> |
| <span className={`${styles['pagination-info']} ${styles['order-pagination-info']}`}> |
| Page {orderPagination.page} of {orderPagination.pages} |
| </span> |
| <button |
| className={`${styles['pagination-btn']} ${styles['adv-btn']}`} |
| disabled={orderPagination.page === orderPagination.pages} |
| onClick={() => setOrderPagination(prev => ({ ...prev, page: prev.page + 1 }))} |
| > |
| <ChevronRight size={20} /> |
| </button> |
| </div> |
| </div> |
| ); |
| }; |
|
|
| export default OrderManagement; |