import 'package:SEFER/constant/colors.dart'; import 'package:SEFER/constant/links.dart'; import 'package:SEFER/constant/style.dart'; import 'package:SEFER/controller/firebase/firbase_messge.dart'; import 'package:SEFER/controller/home/map_passenger_controller.dart'; import 'package:SEFER/main.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; import '../../../constant/box_name.dart'; import '../../../controller/functions/launch.dart'; import '../../widgets/my_textField.dart'; class ApplyOrderWidget extends StatelessWidget { const ApplyOrderWidget({super.key}); @override Widget build(BuildContext context) { Color _parseColor(String colorHex) { if (colorHex.isEmpty) return Colors.grey; String processedHex = colorHex.replaceFirst('#', '0xff').trim(); return Color(int.parse(processedHex.startsWith('0xff') ? processedHex : '0xff$processedHex')); } return GetBuilder(builder: (controller) { if (controller.statusRide == 'Apply' && !controller.isSearchingWindow) { return Positioned( bottom: 0, left: 0, right: 0, child: Container( decoration: BoxDecoration( // More modern BoxDecoration color: Theme.of(context).cardColor, borderRadius: const BorderRadius.vertical(top: Radius.circular(20)), boxShadow: [BoxShadow(blurRadius: 10, color: Colors.black12)], ), padding: const EdgeInsets.all(16), child: Column( mainAxisSize: MainAxisSize.min, children: [ _buildPriceInfo(context, controller), const SizedBox(height: 16), _buildDriverInfoCard(context, controller, _parseColor), ], ), ), ); } else { return const SizedBox(); } }); } Widget _buildPriceInfo( BuildContext context, MapPassengerController controller) { return InkWell( onTap: () { String message; if (box.read(BoxName.carType) == 'Speed' || box.read(BoxName.carType) == 'Awfar Car' || box.read(BoxName.carType) == 'Delivery') { message = 'This ride type does not allow changes to the destination or additional stops' .tr; } else { message = 'This ride type allows changes, but the price may increase'.tr; } Get.snackbar( 'This price is'.tr + ' ${controller.totalPassenger.toStringAsFixed(2)}'.tr, message, snackPosition: SnackPosition.BOTTOM, duration: const Duration(seconds: 2), backgroundColor: AppColor.yellowColor.withOpacity(0.8), // More subtle background ); }, child: Center( child: Text.rich( TextSpan( children: [ TextSpan( text: '${'The driver accepted your order for'.tr} ', style: AppStyle.title), TextSpan( text: controller.totalPassenger.toStringAsFixed(2), style: AppStyle.title.copyWith( fontWeight: FontWeight.bold, color: AppColor.redColor), ), TextSpan(text: ' ${'LE'.tr}', style: AppStyle.title), ], ), textAlign: TextAlign.center, ), ), ); } Widget _buildDriverInfoCard(BuildContext context, MapPassengerController controller, Color Function(String) parseColor) { return Container( decoration: BoxDecoration( color: Theme.of(context).canvasColor, borderRadius: BorderRadius.circular(10), border: Border.all(color: Colors.grey.shade200), ), child: Column( children: [ Padding( padding: const EdgeInsets.all(12.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(box.read(BoxName.carType.toString()), style: AppStyle.title.copyWith(fontWeight: FontWeight.w500)), Row( children: [ _buildCarDetails(context, controller), const SizedBox(width: 10), _buildCarImage(controller, parseColor), ], ), ], ), ), const Divider(height: 1, thickness: 1, color: Colors.grey), Padding( padding: const EdgeInsets.all(12.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ _buildDriverAvatarAndInfo(controller), _buildContactButtons(context, controller), ], ), ), Padding( padding: const EdgeInsets.only(left: 12.0, right: 12.0, bottom: 12.0), child: controller.isDriverArrivePassenger ? const DriverArrivePassengerAndWaitMinute() : const TimeDriverToPassenger(), ), ], ), ); } Widget _buildCarDetails( BuildContext context, MapPassengerController controller) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(controller.model.toString(), style: AppStyle.title), Text(controller.licensePlate.toString(), style: Theme.of(context).textTheme.bodyMedium), Text(controller.carColor.toString(), style: Theme.of(context).textTheme.bodyMedium), ], ); } Widget _buildCarImage( MapPassengerController controller, Color Function(String) parseColor) { return ColorFiltered( colorFilter: ColorFilter.mode(parseColor(controller.colorHex), BlendMode.srcIn), child: Image.asset( box.read(BoxName.carType) == 'Scooter' || box.read(BoxName.carType) == 'Pink Bike' ? 'assets/images/moto.png' : 'assets/images/car3.png', height: 60, ), ); } Widget _buildDriverAvatarAndInfo(MapPassengerController controller) { return Row( children: [ CircleAvatar( radius: 30, backgroundImage: NetworkImage( '${AppLink.server}/portrate_captain_image/${controller.driverId}.jpg'), onBackgroundImageError: (exception, stackTrace) => const Icon(Icons.person, size: 30, color: AppColor.blueColor), ), const SizedBox(width: 8), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(controller.driverName, style: AppStyle.title.copyWith(fontWeight: FontWeight.w500)), Text('⭐ ${controller.driverRate}', style: const TextStyle(fontSize: 16, color: Colors.grey)), ], ), ], ); } Widget _buildContactButtons( BuildContext context, MapPassengerController controller) { return Row( children: [ IconButton( onPressed: () => _showContactOptionsDialog(context, controller), icon: const Icon(Icons.message, color: AppColor.blueColor, size: 28), ), IconButton( onPressed: () { HapticFeedback.heavyImpact(); makePhoneCall(controller.driverPhone); }, icon: const Icon(Icons.call, color: AppColor.greenColor, size: 28), ), ], ); } void _showContactOptionsDialog( BuildContext context, MapPassengerController controller) { Get.defaultDialog( title: 'Contact Options'.tr, content: SizedBox( width: 300, height: Get.height * .4, child: ListView( // shrinkWrap: true, children: [ ..._buildPredefinedMessages(controller), const SizedBox(height: 8), _buildCustomMessageInput(controller, context), ], ), ), ); } List _buildPredefinedMessages(MapPassengerController controller) { const messages = [ 'Hello, I\'m at the agreed-upon location', 'My location is correct. You can search for me using the navigation app', 'I\'m waiting for you', "How much longer will you be?", ]; return messages .map((message) => Padding( padding: const EdgeInsets.only(bottom: 8.0), child: ElevatedButton( onPressed: () { FirebaseMessagesController().sendNotificationToDriverMAP( 'message From passenger', message.tr, controller.driverToken.toString(), [], 'ding.wav', ); Get.back(); }, child: Text(message.tr), ), )) .toList(); } Widget _buildCustomMessageInput( MapPassengerController controller, BuildContext context) { return Row( children: [ Expanded( child: Form( key: controller.messagesFormKey, child: MyTextForm( controller: controller.messageToDriver, label: 'Send a custom message'.tr, hint: 'Type your message'.tr, type: TextInputType.text, ), ), ), IconButton( onPressed: () { if (controller.messagesFormKey.currentState!.validate()) { FirebaseMessagesController().sendNotificationToDriverMAP( 'message From passenger', controller.messageToDriver.text, controller.driverToken, [], 'ding.wav', ); controller.messageToDriver.clear(); Get.back(); } }, icon: const Icon(Icons.send), ), ], ); } } class DriverArrivePassengerAndWaitMinute extends StatelessWidget { const DriverArrivePassengerAndWaitMinute({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return GetBuilder(builder: (controller) { return Column( children: [ ClipRRect( borderRadius: BorderRadius.circular(15), child: LinearProgressIndicator( backgroundColor: AppColor.accentColor.withOpacity(0.3), color: controller.remainingTimeDriverWaitPassenger5Minute < 60 ? AppColor.redColor : AppColor.greenColor, minHeight: 20, value: controller.progressTimerDriverWaitPassenger5Minute.toDouble(), ), ), const SizedBox(height: 4), Center( child: Text.rich( TextSpan( children: [ TextSpan( text: '${'Driver is waiting at pickup.'.tr} ', style: AppStyle.subtitle), TextSpan( text: controller .stringRemainingTimeDriverWaitPassenger5Minute, style: AppStyle.title), ], ), textAlign: TextAlign.center, ), ), ], ); }); } } class TimeDriverToPassenger extends StatelessWidget { const TimeDriverToPassenger({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return GetBuilder(builder: (controller) { return controller.isDriverInPassengerWay == false || controller.timeToPassengerFromDriverAfterApplied > 0 ? Column( children: [ ClipRRect( borderRadius: BorderRadius.circular(15), child: LinearProgressIndicator( backgroundColor: AppColor.accentColor.withOpacity(0.3), color: controller .remainingTimeToPassengerFromDriverAfterApplied < 60 ? AppColor.redColor : AppColor.greenColor, minHeight: 20, value: controller .progressTimerToPassengerFromDriverAfterApplied .toDouble() .clamp(0.0, 1.0), ), ), const SizedBox(height: 4), Center( child: Text.rich( TextSpan( children: [ TextSpan( text: '${'Driver is on the way'.tr} ', style: AppStyle.subtitle, ), TextSpan( text: controller.stringRemainingTimeToPassenger, style: AppStyle.title, ), ], ), textAlign: TextAlign.center, ), ), ], ) : const SizedBox(); }); } }