import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import '../models/order_history.dart'; import '../services/api.dart'; import 'order_detail_screen.dart'; class OrderHistoryScreen extends StatefulWidget { const OrderHistoryScreen({super.key}); @override State createState() => _OrderHistoryScreenState(); } class _OrderHistoryScreenState extends State { List _orders = []; bool _isLoading = true; String? _error; int _totalCount = 0; @override void initState() { super.initState(); _loadOrders(); } Future _loadOrders() async { setState(() { _isLoading = true; _error = null; }); try { final response = await Api.getOrderHistory(limit: 50); if (mounted) { setState(() { _orders = response.orders; _totalCount = response.totalCount; _isLoading = false; }); } } catch (e) { debugPrint('Error loading order history: $e'); if (mounted) { setState(() { _error = e.toString(); _isLoading = false; }); } } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Order History'), ), body: _buildBody(), ); } Widget _buildBody() { if (_isLoading) { return const Center(child: CircularProgressIndicator()); } if (_error != null) { return Center( child: Padding( padding: const EdgeInsets.all(24), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.error_outline, size: 48, color: Theme.of(context).colorScheme.error, ), const SizedBox(height: 16), Text( 'Failed to load orders', style: Theme.of(context).textTheme.titleMedium, ), const SizedBox(height: 8), Text( _error!, textAlign: TextAlign.center, style: Theme.of(context).textTheme.bodySmall, ), const SizedBox(height: 24), FilledButton.icon( onPressed: _loadOrders, icon: const Icon(Icons.refresh), label: const Text('Retry'), ), ], ), ), ); } if (_orders.isEmpty) { return Center( child: Padding( padding: const EdgeInsets.all(24), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.receipt_long_outlined, size: 64, color: Theme.of(context).colorScheme.onSurfaceVariant, ), const SizedBox(height: 16), Text( 'No orders yet', style: Theme.of(context).textTheme.titleMedium, ), const SizedBox(height: 8), Text( 'Your completed orders will appear here', style: Theme.of(context).textTheme.bodySmall?.copyWith( color: Theme.of(context).colorScheme.onSurfaceVariant, ), ), ], ), ), ); } return RefreshIndicator( onRefresh: _loadOrders, child: ListView.builder( padding: const EdgeInsets.symmetric(vertical: 8), itemCount: _orders.length, itemBuilder: (context, index) { return _OrderCard(order: _orders[index]); }, ), ); } } class _OrderCard extends StatelessWidget { final OrderHistoryItem order; const _OrderCard({required this.order}); @override Widget build(BuildContext context) { final dateFormat = DateFormat('MMM d, yyyy'); final timeFormat = DateFormat('h:mm a'); return Card( margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 6), child: InkWell( onTap: () { Navigator.push( context, MaterialPageRoute( builder: (_) => OrderDetailScreen(orderId: order.orderId), ), ); }, borderRadius: BorderRadius.circular(12), child: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Header row: Business name + total Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( child: Text( order.businessName, style: Theme.of(context).textTheme.titleMedium?.copyWith( fontWeight: FontWeight.w600, ), overflow: TextOverflow.ellipsis, ), ), Text( '\$${order.total.toStringAsFixed(2)}', style: Theme.of(context).textTheme.titleMedium?.copyWith( fontWeight: FontWeight.bold, color: Theme.of(context).colorScheme.primary, ), ), ], ), const SizedBox(height: 8), // Details row: Date, type, item count Row( children: [ Icon( Icons.calendar_today, size: 14, color: Theme.of(context).colorScheme.onSurfaceVariant, ), const SizedBox(width: 4), Text( dateFormat.format(order.createdAt), style: Theme.of(context).textTheme.bodySmall?.copyWith( color: Theme.of(context).colorScheme.onSurfaceVariant, ), ), const SizedBox(width: 12), Icon( _getOrderTypeIcon(order.orderTypeId), size: 14, color: Theme.of(context).colorScheme.onSurfaceVariant, ), const SizedBox(width: 4), Text( order.typeName, style: Theme.of(context).textTheme.bodySmall?.copyWith( color: Theme.of(context).colorScheme.onSurfaceVariant, ), ), const SizedBox(width: 12), Text( '${order.itemCount} item${order.itemCount == 1 ? '' : 's'}', style: Theme.of(context).textTheme.bodySmall?.copyWith( color: Theme.of(context).colorScheme.onSurfaceVariant, ), ), ], ), const SizedBox(height: 8), // Status chip Row( children: [ _StatusChip(statusId: order.statusId, statusName: order.statusName), const Spacer(), Icon( Icons.chevron_right, color: Theme.of(context).colorScheme.onSurfaceVariant, ), ], ), ], ), ), ), ); } IconData _getOrderTypeIcon(int typeId) { switch (typeId) { case 1: return Icons.restaurant; // Dine-in case 2: return Icons.shopping_bag; // Takeaway case 3: return Icons.delivery_dining; // Delivery default: return Icons.receipt; } } } class _StatusChip extends StatelessWidget { final int statusId; final String statusName; const _StatusChip({required this.statusId, required this.statusName}); @override Widget build(BuildContext context) { Color backgroundColor; Color textColor; IconData icon; switch (statusId) { case 1: // Submitted backgroundColor = Colors.blue.shade100; textColor = Colors.blue.shade800; icon = Icons.send; break; case 2: // In Progress backgroundColor = Colors.orange.shade100; textColor = Colors.orange.shade800; icon = Icons.pending; break; case 3: // Ready backgroundColor = Colors.green.shade100; textColor = Colors.green.shade800; icon = Icons.check_circle_outline; break; case 4: // Completed backgroundColor = Colors.green.shade100; textColor = Colors.green.shade800; icon = Icons.check_circle; break; case 5: // Cancelled backgroundColor = Colors.red.shade100; textColor = Colors.red.shade800; icon = Icons.cancel; break; default: backgroundColor = Colors.grey.shade200; textColor = Colors.grey.shade800; icon = Icons.help_outline; } return Container( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), decoration: BoxDecoration( color: backgroundColor, borderRadius: BorderRadius.circular(12), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon(icon, size: 14, color: textColor), const SizedBox(width: 4), Text( statusName, style: TextStyle( color: textColor, fontSize: 12, fontWeight: FontWeight.w500, ), ), ], ), ); } }