import 'dart:ui'; import 'package:flutter/material.dart'; import '../services/dio_client.dart'; import '../services/order_service.dart'; class OrderDetailScreen extends StatefulWidget { final String orderId; const OrderDetailScreen({super.key, required this.orderId}); @override State createState() => _OrderDetailScreenState(); } class _OrderDetailScreenState extends State { bool loading = true; Map order = {}; final Map _expanded = {}; bool confirming = false; bool get isOrderPlaced => order['status'] == 'order_placed'; bool get isConfirmed => order['status'] != 'order_placed'; @override void initState() { super.initState(); load(); } Future load() async { final service = OrderService(DioClient.getInstance(context)); final res = await service.getOrderDetails(widget.orderId); if (res['success'] == true) { order = res['order']; } loading = false; setState(() {}); } String _initials(String? s) { if (s == null || s.isEmpty) return "I"; final parts = s.split(" "); return parts.take(2).map((e) => e[0].toUpperCase()).join(); } @override Widget build(BuildContext context) { final items = order['items'] ?? []; final width = MediaQuery.of(context).size.width; final scale = (width / 430).clamp(0.85, 1.20); return Scaffold( backgroundColor: const Color(0xFFF0F6FF), appBar: AppBar( title: const Text("Order Details"), elevation: 0, ), body: loading ? const Center(child: CircularProgressIndicator()) : Padding( padding: EdgeInsets.all(16 * scale), child: SingleChildScrollView( child: Column( children: [ _summaryCard(scale), SizedBox(height: 18 * scale), _itemsSection(items, scale), SizedBox(height: 18 * scale), _totalsSection(scale), SizedBox(height: 24 * scale), _confirmOrderButton(scale), ], ), ), ), ); } Widget _confirmOrderButton(double scale) { final isPlaced = order['status'] == 'order_placed'; return SizedBox( width: double.infinity, height: 52 * scale, child: ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: isPlaced ? Colors.orange : Colors.green, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(14 * scale), ), ), onPressed: (!isPlaced || confirming) ? null : () async { setState(() => confirming = true); final service = OrderService(DioClient.getInstance(context)); final res = await service.confirmOrder(order['order_id']); confirming = false; if (res['success'] == true) { setState(() { order['status'] = 'order_confirmed'; }); ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Order confirmed successfully'), backgroundColor: Colors.green, ), ); } else { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(res['message'] ?? 'Failed to confirm order'), backgroundColor: Colors.red, ), ); } setState(() {}); }, child: confirming ? const CircularProgressIndicator(color: Colors.white) : Text( isPlaced ? 'Confirm Order' : 'Order Confirmed', style: TextStyle( fontSize: 16 * scale, fontWeight: FontWeight.bold, color: Colors.white, ), ), ), ); } // ----------------------------- // SUMMARY CARD // ----------------------------- Widget _summaryCard(double scale) { return Container( padding: EdgeInsets.all(18 * scale), decoration: _cardDecoration(scale), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text("Order Summary", style: TextStyle(fontSize: 20 * scale, fontWeight: FontWeight.bold)), SizedBox(height: 12 * scale), _infoRow("Order ID", order['order_id'], scale), _infoRow("Mark No", order['mark_no'], scale), _infoRow("Origin", order['origin'], scale), _infoRow("Destination", order['destination'], scale), ], ), ); } Widget _infoRow(String title, dynamic value, double scale) { return Padding( padding: EdgeInsets.symmetric(vertical: 6 * scale), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(title, style: TextStyle(color: Colors.grey, fontSize: 14 * scale)), Text(value?.toString() ?? "-", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15 * scale)), ], ), ); } // ----------------------------- // ORDER ITEMS SECTION // ----------------------------- Widget _itemsSection(List items, double scale) { return Container( padding: EdgeInsets.all(18 * scale), decoration: _cardDecoration(scale), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text("Order Items", style: TextStyle(fontSize: 18 * scale, fontWeight: FontWeight.bold)), SizedBox(height: 16 * scale), ...List.generate(items.length, (i) { return _expandableItem(items[i], i, scale); }) ], ), ); } // ----------------------------- // EXPANDABLE ITEM // ----------------------------- Widget _expandableItem(Map item, int index, double scale) { final id = "item_$index"; _expanded[id] = _expanded[id] ?? false; final description = item['description'] ?? "Item"; final initials = _initials(description); final imageUrl = item['image'] ?? ""; return AnimatedContainer( duration: const Duration(milliseconds: 300), margin: EdgeInsets.only(bottom: 16 * scale), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(14 * scale), border: Border.all(color: Colors.black12), ), child: Column( children: [ ListTile( minVerticalPadding: 10 * scale, leading: _avatar(imageUrl, initials, scale), title: Text(description, style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15 * scale)), trailing: Transform.rotate( angle: (_expanded[id]! ? 3.14 : 0), child: Icon(Icons.keyboard_arrow_down, size: 24 * scale), ), onTap: () { setState(() { _expanded[id] = !_expanded[id]!; }); }, ), if (_expanded[id]!) Padding( padding: EdgeInsets.all(12 * scale), child: Column( children: [ _pill("Qty", Icons.list_alt, "${item['qty']}", Colors.blue.shade100, scale), _pill("Unit", Icons.category, "${item['unit']}", Colors.orange.shade100, scale), _pill("KG", Icons.scale, "${item['kg']}", Colors.red.shade100, scale), _pill("CBM", Icons.straighten, "${item['cbm']}", Colors.purple.shade100, scale), _pill("Shop", Icons.storefront, "${item['shop_no']}", Colors.grey.shade300, scale), _pill("Amount", Icons.currency_rupee, "₹${item['ttl_amount']}", Colors.green.shade100, scale), ], ), ), ], ), ); } // ----------------------------- // AVATAR (RESPONSIVE) // ----------------------------- Widget _avatar(String url, String initials, double scale) { return Container( width: 48 * scale, height: 48 * scale, decoration: BoxDecoration( color: Colors.blue.shade200, borderRadius: BorderRadius.circular(10 * scale), ), child: url.isNotEmpty ? ClipRRect( borderRadius: BorderRadius.circular(10 * scale), child: Image.network(url, fit: BoxFit.cover, errorBuilder: (c, e, s) => Center( child: Text(initials, style: TextStyle( fontSize: 18 * scale, color: Colors.white, fontWeight: FontWeight.bold)), )), ) : Center( child: Text(initials, style: TextStyle( fontSize: 18 * scale, color: Colors.white, fontWeight: FontWeight.bold)), ), ); } // ----------------------------- // COLOR-CODED PILL (RESPONSIVE) // ----------------------------- Widget _pill( String title, IconData icon, String value, Color bgColor, double scale) { return Container( margin: EdgeInsets.only(bottom: 12 * scale), padding: EdgeInsets.symmetric(horizontal: 14 * scale, vertical: 12 * scale), decoration: BoxDecoration( color: bgColor, borderRadius: BorderRadius.circular(12 * scale), ), child: Row( children: [ Icon(icon, size: 20 * scale, color: Colors.black54), SizedBox(width: 10 * scale), Text("$title: ", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14 * scale)), Expanded( child: Text(value, style: TextStyle( fontWeight: FontWeight.w700, fontSize: 15 * scale)), ), ], ), ); } // ----------------------------- // TOTAL SECTION // ----------------------------- Widget _totalsSection(double scale) { return Container( padding: EdgeInsets.all(18 * scale), decoration: _cardDecoration(scale), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text("Totalss", style: TextStyle(fontSize: 18 * scale, fontWeight: FontWeight.bold)), SizedBox(height: 12 * scale), _totalRow("Total Qty", order['ttl_qty'], scale), _totalRow("Total KG", order['ttl_kg'], scale), SizedBox(height: 12 * scale), Container( width: double.infinity, padding: EdgeInsets.symmetric(vertical: 20 * scale), decoration: BoxDecoration( color: Colors.green.shade50, borderRadius: BorderRadius.circular(12 * scale), ), child: Column( children: [ Text("₹${order['ttl_amount'] ?? 0}", style: TextStyle( color: Colors.green, fontSize: 28 * scale, fontWeight: FontWeight.bold, )), SizedBox(height: 4 * scale), Text("Total Amount", style: TextStyle( color: Colors.black54, fontSize: 14 * scale)), ], ), ), ], ), ); } Widget _totalRow(String title, dynamic value, double scale) { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(title, style: TextStyle(color: Colors.grey, fontSize: 14 * scale)), Text(value?.toString() ?? "0", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15 * scale)), ], ); } // ----------------------------- // CARD DECORATION // ----------------------------- BoxDecoration _cardDecoration(double scale) { return BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16 * scale), boxShadow: [ BoxShadow( color: Colors.black12, blurRadius: 8 * scale, offset: Offset(0, 3 * scale)), ], ); } }