import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import '../../../../common/theme/theme.dart'; import '../../../../domain/order/order.dart'; class OrderTile extends StatelessWidget { final Order order; final VoidCallback? onTap; final VoidCallback? onPrint; final VoidCallback? onRefund; const OrderTile({ super.key, required this.order, this.onTap, this.onPrint, this.onRefund, }); @override Widget build(BuildContext context) { return Container( margin: const EdgeInsets.only(bottom: 16), child: Card( elevation: 4, shadowColor: AppColor.primaryWithOpacity(0.1), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), side: BorderSide(color: AppColor.border, width: 0.5), ), child: InkWell( onTap: onTap, borderRadius: BorderRadius.circular(16), child: Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( borderRadius: BorderRadius.circular(16), gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [AppColor.backgroundLight, AppColor.background], ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Header Row _buildHeaderRow(), const SizedBox(height: 12), // Order Info _buildOrderInfo(), const SizedBox(height: 16), // Amount Section _buildAmountSection(), const SizedBox(height: 16), // Footer with Actions _buildFooterActions(), ], ), ), ), ), ); } Widget _buildHeaderRow() { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( order.orderNumber.isNotEmpty ? order.orderNumber : 'ORD-${order.id}', style: const TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: AppColor.textPrimary, ), ), const SizedBox(height: 2), Text( _formatDate(order.createdAt), style: const TextStyle( fontSize: 12, color: AppColor.textSecondary, ), ), ], ), _buildStatusChip(), ], ); } Widget _buildStatusChip() { Color statusColor; String statusText; IconData statusIcon; // Check isVoid and isRefund first for display if (order.isVoid) { statusColor = AppColor.error; statusText = 'Void'; statusIcon = Icons.block; } else if (order.isRefund) { statusColor = AppColor.info; statusText = 'Refunded'; statusIcon = Icons.undo; } else { // Handle status values (only pending and completed) switch (order.status.toLowerCase()) { case 'completed': case 'paid': case 'finished': statusColor = AppColor.success; statusText = 'Completed'; statusIcon = Icons.check_circle; break; case 'pending': case 'waiting': case 'processing': statusColor = AppColor.warning; statusText = 'Pending'; statusIcon = Icons.schedule; break; default: statusColor = AppColor.textSecondary; statusText = order.status; statusIcon = Icons.info; break; } } return Container( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6), decoration: BoxDecoration( color: statusColor.withOpacity(0.1), borderRadius: BorderRadius.circular(20), border: Border.all(color: statusColor.withOpacity(0.3), width: 1), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon(statusIcon, size: 14, color: statusColor), const SizedBox(width: 4), Text( statusText, style: TextStyle( fontSize: 12, fontWeight: FontWeight.w600, color: statusColor, ), ), ], ), ); } Widget _buildOrderInfo() { return Row( children: [ Expanded( flex: 2, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon(_getOrderInfoIcon(), size: 16, color: AppColor.primary), const SizedBox(width: 6), Expanded( child: Text( _getOrderInfoText(), style: const TextStyle( fontSize: 14, fontWeight: FontWeight.w600, color: AppColor.textPrimary, ), overflow: TextOverflow.ellipsis, ), ), ], ), const SizedBox(height: 8), Row( children: [ Icon( Icons.shopping_bag_outlined, size: 16, color: AppColor.primary, ), const SizedBox(width: 6), Text( '${order.orderItems.length} items', style: const TextStyle( fontSize: 13, color: AppColor.textSecondary, ), ), ], ), ], ), ), Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), decoration: BoxDecoration( color: AppColor.primaryWithOpacity(0.1), borderRadius: BorderRadius.circular(12), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon( _getOrderTypeIcon(order.orderType), size: 16, color: AppColor.primary, ), const SizedBox(width: 6), Text( order.orderType.isNotEmpty ? order.orderType : 'Dine In', style: const TextStyle( fontSize: 12, fontWeight: FontWeight.w500, color: AppColor.primary, ), ), ], ), ), ], ); } Widget _buildAmountSection() { return Container( width: double.infinity, padding: const EdgeInsets.all(16), decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: AppColor.primaryGradient, ), borderRadius: BorderRadius.circular(12), boxShadow: [ BoxShadow( color: AppColor.primary.withOpacity(0.2), blurRadius: 8, offset: const Offset(0, 4), ), ], ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'Total Amount', style: TextStyle( fontSize: 14, color: AppColor.textWhite, fontWeight: FontWeight.w500, ), ), const SizedBox(height: 4), Text( 'Rp ${NumberFormat('#,###').format(order.totalAmount)}', style: const TextStyle( fontSize: 24, fontWeight: FontWeight.bold, color: AppColor.textWhite, ), ), if (order.remainingAmount > 0) ...[ const SizedBox(height: 4), Text( 'Remaining: Rp ${NumberFormat('#,###').format(order.remainingAmount)}', style: const TextStyle( fontSize: 12, color: AppColor.textWhite, fontWeight: FontWeight.w400, ), ), ], ], ), Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: AppColor.backgroundLight.withOpacity(0.2), shape: BoxShape.circle, ), child: Icon( _getPaymentStatusIcon(order.paymentStatus), color: AppColor.textWhite, size: 24, ), ), ], ), ); } Widget _buildFooterActions() { // Don't show anything if order is void or refunded if (order.isVoid || order.isRefund) { return const SizedBox.shrink(); } return Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ if (order.payments.isNotEmpty) ...[ const SizedBox(height: 2), Text( 'Payment: ${_getPaymentMethods()}', style: const TextStyle( fontSize: 11, color: AppColor.textLight, fontWeight: FontWeight.w400, ), ), ], ], ), ), if (order.status.toLowerCase() == 'completed') ...[ _buildActionButton( icon: Icons.print, label: 'Print', onPressed: onPrint, color: AppColor.info, ), const SizedBox(width: 8), _buildActionButton( icon: Icons.undo, label: 'Refund', onPressed: onRefund, color: AppColor.warning, ), ], ], ); } Widget _buildActionButton({ required IconData icon, required String label, required VoidCallback? onPressed, required Color color, }) { return Material( color: color.withOpacity(0.1), borderRadius: BorderRadius.circular(8), child: InkWell( onTap: onPressed, borderRadius: BorderRadius.circular(8), child: Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon(icon, size: 16, color: color), const SizedBox(width: 4), Text( label, style: TextStyle( fontSize: 12, fontWeight: FontWeight.w600, color: color, ), ), ], ), ), ), ); } IconData _getOrderInfoIcon() { switch (order.orderType.toLowerCase()) { case 'dine in': case 'dine_in': return Icons.table_restaurant_outlined; case 'takeaway': case 'take_away': case 'pickup': return Icons.person_outline; case 'delivery': return Icons.location_on_outlined; default: return Icons.receipt_outlined; } } String _getOrderInfoText() { switch (order.orderType.toLowerCase()) { case 'dine in': case 'dine_in': return 'Table ${order.tableNumber.isNotEmpty ? order.tableNumber : 'N/A'}'; case 'takeaway': case 'take_away': case 'pickup': return 'Pickup Order'; case 'delivery': return 'Delivery Order'; default: return order.tableNumber.isNotEmpty ? 'Table ${order.tableNumber}' : 'Order ${order.orderNumber}'; } } IconData _getOrderTypeIcon(String orderType) { switch (orderType.toLowerCase()) { case 'dine in': case 'dine_in': return Icons.restaurant; case 'takeaway': case 'take_away': case 'pickup': return Icons.shopping_bag; case 'delivery': return Icons.delivery_dining; default: return Icons.restaurant_menu; } } IconData _getPaymentStatusIcon(String paymentStatus) { switch (paymentStatus.toLowerCase()) { case 'paid': case 'completed': return Icons.check_circle; case 'pending': case 'partial': return Icons.schedule; case 'failed': case 'cancelled': return Icons.error; default: return Icons.attach_money; } } String _getPaymentMethods() { if (order.payments.isEmpty) return 'N/A'; // Get unique payment methods from payments final methods = order.payments .map((payment) => payment.paymentMethodName) .toSet() .join(', '); return methods.isEmpty ? 'N/A' : methods; } String _formatDate(String dateString) { try { final date = DateTime.parse(dateString); return DateFormat('dd MMM yyyy, HH:mm').format(date); } catch (e) { return dateString; } } }