part of 'deliveries.dart'; // ------------------------------------------------------------------------- // DELIVERY CARD // ------------------------------------------------------------------------- class DeliveryCard extends StatelessWidget { final Map item; final int displayStep; final String distanceStr; final bool enabled; final bool isSkipped; const DeliveryCard({ super.key, required this.item, required this.displayStep, required this.distanceStr, this.enabled = true, this.isSkipped = false, }); @override Widget build(BuildContext context) { final String customerName = (item['deliverycustomer'] ?? 'Customer') .toString(); final String address = (item['deliveryaddress'] ?? 'Address not available') .toString(); final String tenantName = (item['tenantname'] ?? 'Store').toString(); final String orderId = (item['orderid'] ?? '').toString(); return Container( margin: const EdgeInsets.symmetric(horizontal: 14, vertical: 8), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), border: isSkipped ? Border.all(color: Colors.orange, width: 2) : null, boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.1), blurRadius: 6, offset: const Offset(0, 3), ), ], ), child: Padding( padding: const EdgeInsets.all(12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ if (isSkipped) Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( color: Colors.orange.shade100, borderRadius: BorderRadius.circular(8), ), child: Text( 'SKIPPED', style: TextStyle( fontSize: 13, fontWeight: FontWeight.bold, color: Colors.orange.shade900, fontFamily: FontConstants.fontFamily, ), ), ), if (isSkipped) const SizedBox(height: 8), Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Column( children: [ Container( width: 12, height: 12, decoration: const BoxDecoration( color: Colors.orange, shape: BoxShape.circle, ), ), Container( width: 2, height: 30, color: Colors.grey.shade300, ), Container( width: 12, height: 12, decoration: const BoxDecoration( color: Colors.green, shape: BoxShape.circle, ), ), ], ), const SizedBox(width: 10), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Transform.translate( offset: const Offset(0, -3), child: Text( customerName, style: TextStyle( fontWeight: FontWeight.bold, fontSize: 17.5, color: Colors.black, fontFamily: FontConstants.fontFamily, ), ), ), const SizedBox(height: 8), Transform.translate( offset: const Offset(0, 8), child: Text( address, style: TextStyle( fontSize: 18, color: Colors.black87, fontFamily: FontConstants.fontFamily, ), ), ), const SizedBox(height: 8), Text( 'Distance: $distanceStr km', style: TextStyle( fontSize: 17, color: Colors.blueGrey, fontFamily: FontConstants.fontFamily, ), ), ], ), ), InkWell( onTap: () async { // Just launch dialer; PiP is handled only from navigation screen final phone = (item['deliverycontactno'] ?? '').toString(); final bool success = await launchPhoneDialer( phone.isNotEmpty ? phone : '9876543210', ); if (!success && context.mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Could not launch dialer'), ), ); } }, child: Image.asset( 'assets/images/phone-call .png', height: 27, width: 27, errorBuilder: (c, e, s) => const Icon(Icons.phone, size: 27, color: Colors.green), ), ), ], ), const SizedBox(height: 8), const Divider(), const SizedBox(height: 8), Row( children: [ Image.asset( 'assets/images/shoppingbag.png', height: 32, width: 32, errorBuilder: (c, e, s) => const Icon( Icons.shopping_bag, size: 32, color: Colors.orange, ), ), const SizedBox(width: 8), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( tenantName, style: TextStyle( fontWeight: FontWeight.w600, fontSize: 18, color: Colors.black, fontFamily: FontConstants.fontFamily, ), ), if (!isSkipped) InkWell( onTap: () { final parentState = context .findAncestorStateOfType< _MyDeliveriesState >(); if (parentState != null) { _showMyOptionsSheet( context, item, parentState, ); } }, child: Transform.translate( offset: const Offset(0, -5), child: Text( 'Skip>>', style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, fontFamily: FontConstants.fontFamily, color: ColorConstants.primaryColor, ), ), ), ), ], ), Text( 'Order ID: #$orderId', style: TextStyle( fontSize: 18, color: Colors.black54, fontFamily: FontConstants.fontFamily, ), ), ], ), ), ], ), const SizedBox(height: 15), SliderButton( properties: SliderButtonProperties( height: 50, buttonSize: 45, width: MediaQuery.of(context).size.width - 56, backgroundColor: enabled ? ColorConstants.primaryColor : Colors.grey.shade400, dismissThresholds: 0.90, action: enabled ? () async { // Reduce delay to make it feel snappier await Future.delayed(const Duration(milliseconds: 50)); if (!context.mounted) return false; final parentState = context .findAncestorStateOfType<_MyDeliveriesState>(); // ✅ BLOCK: Check if there's already an active delivery (and this isn't it) if (parentState != null) { final currentOrderId = (item['orderid'] ?? '') .toString(); final activeOrderIds = parentState._activeDeliveries .map((d) => (d['orderid'] ?? '').toString()) .where((id) => id.isNotEmpty) .toSet(); // Block if there's a different active delivery: just ignore the swipe if (parentState._activeDeliveries.isNotEmpty && !activeOrderIds.contains(currentOrderId)) { return false; } } // Navigate to delivery map screen if (context.mounted) { Navigator.push( context, MaterialPageRoute( builder: (context) => _DeliveryMapScreen( delivery: item, parentState: parentState, ), ), ); } return false; } : () async => null, label: Transform.translate( offset: const Offset(-0.5, 0), child: Text( isSkipped ? 'Slide to resume Delivery' : (enabled ? 'Slide to start Delivery' : 'Complete previous delivery'), style: const TextStyle( fontSize: 18.5, fontWeight: FontWeight.w500, color: Colors.white, ), ), ), icon: ClipOval( child: Material( color: Colors.white, child: SizedBox( width: 45, height: 45, child: Center( child: Text( '$displayStep', style: TextStyle( fontSize: 24, fontWeight: FontWeight.bold, color: enabled ? const ui.Color.fromARGB(255, 0, 0, 0) : Colors.grey, ), ), ), ), ), ), ), ), ], ), ), ); } }