import 'package:wanisdriver/models/Ride.dart'; import 'package:wanisdriver/widgets/custom_text.dart'; import 'package:flutter/material.dart'; import 'package:flutter_lucide/flutter_lucide.dart'; import 'package:intl/intl.dart'; import '../config/constants/app_constant.dart'; import '../utils/colors.dart'; class TripCard extends StatelessWidget { final Ride trip; final bool cancelled; const TripCard({super.key, required this.cancelled, required this.trip}); Color _getStatusColor(String status) { switch (status.toLowerCase()) { case 'cancelled': case 'canceled': return const Color(0xFFE92020); case 'finished': case 'completed': return Colors.green; case 'ongoing': case 'in_progress': return Colors.blue; case 'scheduled': return Colors.orange; default: return Colors.grey; } } Color _getStatusBackgroundColor(String status) { switch (status.toLowerCase()) { case 'cancelled': case 'canceled': return const Color(0x1EF03D3D); case 'finished': case 'completed': return Colors.green.withOpacity(0.12); case 'ongoing': case 'in_progress': return Colors.blue.withOpacity(0.12); case 'scheduled': return Colors.orange.withOpacity(0.12); default: return Colors.grey.withOpacity(0.12); } } String _getStatusText(String status) { switch (status.toLowerCase()) { case 'cancelled': case 'canceled': return 'Cancelled'; case 'finished': return 'Finished'; case 'completed': return 'Completed'; case 'ongoing': return 'Ongoing'; case 'in_progress': return 'In Progress'; case 'scheduled': return 'Scheduled'; default: return status; } } @override Widget build(BuildContext context) { final String statusText = _getStatusText(trip.rideStatus); final Color statusColor = _getStatusColor(trip.rideStatus); final Color statusBackgroundColor = _getStatusBackgroundColor(trip.rideStatus); final bool isDarkMode = Theme.of(context).brightness == Brightness.dark; return Container( margin: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 8.0), padding: const EdgeInsets.all(16), decoration: ShapeDecoration( color: isDarkMode ? AppColors.blackBackgroundColor : Colors.white, shape: RoundedRectangleBorder( side: BorderSide( width: 1, color: Colors.black.withOpacity(0.12), ), borderRadius: BorderRadius.circular(32), ), shadows: [ const BoxShadow( color: Color(0x0A000000), blurRadius: 16, offset: Offset(0, 4), spreadRadius: 0, ), ], ), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ // Pick up and Drop off section Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ // Pick up section Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Txt(text: 'PICK UP', style: TextStyle( color: Color(0xFF5B616D), fontSize: 12, fontFamily: 'Inter', fontWeight: FontWeight.w500, height: 1.33, ), ), const SizedBox(height: 4), Txt(text: trip.startLocationName ?? 'Pick up location', style: TextStyle( color: isDarkMode ? AppColors.whiteBackgroundColor : const Color(0xFF0A0C11), fontSize: 14, fontFamily: 'Inter', fontWeight: FontWeight.w600, height: 1.43, ), ), ], ), ), const SizedBox(width: 16), // Drop off section Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ const Txt( text: 'DROP OFF', style: TextStyle( color: Color(0xFF5B616D), fontSize: 12, fontFamily: 'Inter', fontWeight: FontWeight.w500, height: 1.33, ), ), const SizedBox(height: 4), Txt(text: trip.endLocationName ?? 'Drop off location', textAlign: TextAlign.right, style: TextStyle( color: isDarkMode ? AppColors.whiteBackgroundColor : const Color(0xFF0A0C11), fontSize: 14, fontFamily: 'Inter', fontWeight: FontWeight.w600, height: 1.43, ), ), ], ), ), ], ), const SizedBox(height: 16), // Divider Container( width: double.infinity, height: 1, color: Colors.black.withOpacity(0.08), ), const SizedBox(height: 16), // Date, Time, and Price section Row( children: [ // Date section Expanded( child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.calendar_today, size: 16, color: isDarkMode ? AppColors.whiteBackgroundColor : const Color(0xFF0A0C11), ), const SizedBox(width: 8), Txt(text: DateFormat('EEE dd MMM').format(trip.rideStartTime!), style: TextStyle( color: isDarkMode ? AppColors.whiteBackgroundColor : const Color(0xFF0A0C11), fontSize: 14, fontFamily: 'Inter', fontWeight: FontWeight.w600, height: 1.43, ), ), ], ), ), // Time section Expanded( child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.access_time, size: 16, color: isDarkMode ? AppColors.whiteBackgroundColor : const Color(0xFF0A0C11), ), const SizedBox(width: 8), Txt(text: DateFormat('hh:mm a').format(trip.rideStartTime!), style: TextStyle( color: isDarkMode ? AppColors.whiteBackgroundColor : const Color(0xFF0A0C11), fontSize: 14, fontFamily: 'Inter', fontWeight: FontWeight.w600, height: 1.43, ), ), ], ), ), // Price section if (!cancelled || statusText != 'Cancelled') Expanded( child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( LucideIcons.banknote, size: 16, color: isDarkMode ? AppColors.whiteBackgroundColor : const Color(0xFF0A0C11), ),SizedBox(width: 5,), Txt(text: "${trip.totalPrice?.toStringAsFixed(2) ?? '0'} TND", style: TextStyle( color: isDarkMode ? AppColors.whiteBackgroundColor : const Color(0xFF0A0C11), fontSize: 14, fontFamily: 'Inter', fontWeight: FontWeight.w600, height: 1.43, ), ), ], ), ), ], ), const SizedBox(height: 16), // Bottom divider Container( width: double.infinity, height: 1, color: Colors.black.withOpacity(0.08), ), const SizedBox(height: 12), // Status and additional info section Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ // Status badge Container( height: 24, padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: ShapeDecoration( color: statusBackgroundColor, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon( _getStatusIcon(trip.rideStatus), size: 14, color: statusColor, ), const SizedBox(width: 4), Txt(text: statusText, style: TextStyle( color: statusColor, fontSize: 12, fontFamily: 'Inter', fontWeight: FontWeight.w600, height: 1.33, ), ), ], ), ), // Additional info based on status and cancelled flag if (cancelled && statusText == 'Cancelled') ...[ Txt(text: trip.ridername, style: TextStyle( color: isDarkMode ? AppColors.whiteBackgroundColor : const Color(0xFF0A0C11), fontSize: 12, fontWeight: FontWeight.w500, ), ), ] else if (!cancelled && statusText != 'Cancelled') ...[ Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ if (trip.durationInMinutes != null) Txt(text: "${trip.durationInMinutes!.round()} min", style: TextStyle( color: isDarkMode ? AppColors.whiteBackgroundColor : const Color(0xFF0A0C11), fontSize: 12, fontWeight: FontWeight.w600, ), ), Txt(text: trip.paymenttype, style: const TextStyle( fontSize: 10, color: Color(0xFF5B616D), fontWeight: FontWeight.w500, ), ), ], ), ], ], ), ], ), ); } IconData _getStatusIcon(String status) { switch (status.toLowerCase()) { case 'cancelled': case 'canceled': return Icons.cancel_outlined; case 'finished': case 'completed': return Icons.check_circle_outline; case 'ongoing': case 'in_progress': return Icons.play_circle_outline; case 'scheduled': return Icons.schedule; default: return Icons.info_outline; } } }