import 'package:dotted_border/dotted_border.dart'; import 'package:driver/themes/responsive.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:get/get.dart'; import '../../constant/constant.dart'; import '../../controllers/parcel_order_details_controller.dart'; import '../../themes/app_them_data.dart'; import '../../themes/theme_controller.dart'; import '../../utils/network_image_widget.dart'; class ParcelOrderDetails extends StatelessWidget { const ParcelOrderDetails({super.key}); @override Widget build(BuildContext context) { final themeController = Get.find(); final isDark = themeController.isDark.value; return GetX( init: ParcelOrderDetailsController(), builder: (controller) { return Scaffold( appBar: AppBar( title: Text( "Order Details".tr, style: TextStyle( color: isDark ? Colors.white : Colors.black, ), ), backgroundColor: isDark ? Colors.black : Colors.white, iconTheme: IconThemeData( color: isDark ? Colors.white : Colors.black, ), ), body: controller.isLoading.value ? Constant.loader() : SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(15), color: isDark ? AppThemeData.greyDark50 : AppThemeData.grey50, border: Border.all(color: isDark ? AppThemeData.greyDark200 : AppThemeData.grey200), ), width: double.infinity, padding: const EdgeInsets.all(16), child: Text( "${'Order Id:'.tr} ${Constant.orderId(orderId: controller.parcelOrder.value.id.toString())}".tr, textAlign: TextAlign.start, style: TextStyle( fontFamily: AppThemeData.semiBold, fontSize: 18, color: isDark ? AppThemeData.grey50 : AppThemeData.grey900, ), ), ), const SizedBox(height: 16), Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(15), color: isDark ? AppThemeData.greyDark50 : AppThemeData.grey50, border: Border.all(color: isDark ? AppThemeData.greyDark200 : AppThemeData.grey200), ), padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Timeline with icons and line Column( children: [ Image.asset("assets/images/image_parcel.png", height: 32, width: 32), DottedBorder( options: CustomPathDottedBorderOptions( color: Colors.grey.shade400, strokeWidth: 2, dashPattern: [4, 4], customPath: (size) => Path() ..moveTo(size.width / 2, 0) ..lineTo(size.width / 2, size.height), ), child: const SizedBox(width: 20, height: 95), ), Image.asset("assets/images/image_parcel.png", height: 32, width: 32), ], ), const SizedBox(width: 12), // Address Details Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _infoSection( "Pickup Address (Sender):".tr, controller.parcelOrder.value.sender?.name ?? '', controller.parcelOrder.value.sender?.address ?? '', controller.parcelOrder.value.sender?.phone ?? '', // controller.parcelOrder.value.senderPickupDateTime != null // ? "Pickup Time: ${controller.formatDate(controller.parcelOrder.value.senderPickupDateTime!)}" // : '', isDark, ), const SizedBox(height: 16), _infoSection( "Delivery Address (Receiver):".tr, controller.parcelOrder.value.receiver?.name ?? '', controller.parcelOrder.value.receiver?.address ?? '', controller.parcelOrder.value.receiver?.phone ?? '', // controller.parcelOrder.value.receiverPickupDateTime != null // ? "Delivery Time: ${controller.formatDate(controller.parcelOrder.value.receiverPickupDateTime!)}" // : '', isDark, ), ], ), ), ], ), const Divider(), if (controller.parcelOrder.value.isSchedule == true) Padding( padding: const EdgeInsets.only(bottom: 8.0), child: Text( "Schedule Pickup time: ${controller.formatDate(controller.parcelOrder.value.senderPickupDateTime!)}".tr, style: AppThemeData.mediumTextStyle(fontSize: 14, color: AppThemeData.info400), ), ), Padding( padding: const EdgeInsets.only(bottom: 8.0), child: Text( "Order Date:${controller.parcelOrder.value.isSchedule == true ? controller.formatDate(controller.parcelOrder.value.createdAt!) : controller.formatDate(controller.parcelOrder.value.senderPickupDateTime!)}".tr, style: AppThemeData.mediumTextStyle(fontSize: 14, color: AppThemeData.info400), ), ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "Parcel Type:".tr, style: AppThemeData.semiBoldTextStyle( fontSize: 16, color: isDark ? AppThemeData.greyDark800 : AppThemeData.grey800, ), ), Row( children: [ Text( controller.parcelOrder.value.parcelType ?? '', style: AppThemeData.semiBoldTextStyle( fontSize: 16, color: isDark ? AppThemeData.greyDark800 : AppThemeData.grey800, ), ), const SizedBox(width: 8), if (controller.getSelectedCategory()?.image != null && controller.getSelectedCategory()!.image!.isNotEmpty) NetworkImageWidget(imageUrl: controller.getSelectedCategory()?.image ?? '', height: 20, width: 20), ], ), ], ), controller.parcelOrder.value.parcelImages == null || controller.parcelOrder.value.parcelImages!.isEmpty ? SizedBox() : SizedBox( height: 120, child: ListView.builder( itemCount: controller.parcelOrder.value.parcelImages!.length, shrinkWrap: true, scrollDirection: Axis.horizontal, itemBuilder: (context, index) { return Padding( padding: const EdgeInsets.all(8.0), child: ClipRRect( borderRadius: BorderRadius.circular(10), child: NetworkImageWidget( imageUrl: controller.parcelOrder.value.parcelImages![index], width: 100, fit: BoxFit.cover, borderRadius: 10, ), ), ); }, ), ) ], ), ), const SizedBox(height: 16), // Distance, Weight, Rate Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(15), color: isDark ? AppThemeData.greyDark50 : AppThemeData.grey50, border: Border.all(color: isDark ? AppThemeData.greyDark200 : AppThemeData.grey200), ), padding: EdgeInsets.all(16), child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ _iconTile( "${controller.parcelOrder.value.distance ?? '--'} ${Constant.distanceType}", "Distance".tr, "assets/icons/ic_distance_parcel.svg", isDark, ), _iconTile( controller.parcelOrder.value.parcelWeight ?? '--', "Weight".tr, "assets/icons/ic_weight_parcel.svg", isDark, ), _iconTile( Constant.amountShow(amount: controller.parcelOrder.value.subTotal), "Rate".tr, "assets/icons/ic_rate_parcel.svg", isDark, ), ], ), ), const SizedBox(height: 16), Column( children: [ Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(15), color: isDark ? AppThemeData.greyDark50 : AppThemeData.grey50, border: Border.all(color: isDark ? AppThemeData.greyDark200 : AppThemeData.grey200), ), padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text("About Customer".tr, style: AppThemeData.boldTextStyle( fontSize: 14, color: isDark ? AppThemeData.greyDark500 : AppThemeData.grey500)), const SizedBox(height: 8), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ Row( children: [ SizedBox( width: 52, height: 52, child: ClipRRect( borderRadius: BorderRadiusGeometry.circular(10), child: NetworkImageWidget( imageUrl: controller.parcelOrder.value.author?.profilePictureURL ?? '', height: 70, width: 70, borderRadius: 35), ), ), SizedBox(width: 20), Text( controller.parcelOrder.value.author?.fullName() ?? '', style: AppThemeData.boldTextStyle( color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900, fontSize: 18), ), ], ), ], ), ], ), ), const SizedBox(height: 15), ], ), Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(15), color: isDark ? AppThemeData.greyDark50 : AppThemeData.grey50, border: Border.all(color: isDark ? AppThemeData.greyDark200 : AppThemeData.grey200), ), padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text("Order Summary".tr, style: AppThemeData.boldTextStyle(fontSize: 14, color: AppThemeData.grey500)), const SizedBox(height: 8), // Subtotal _summaryTile("Subtotal".tr, Constant.amountShow(amount: controller.subTotal.value.toString()), isDark, null), // Discount _summaryTile("Discount".tr, Constant.amountShow(amount: controller.discount.value.toString()), isDark, null), // Tax List ...List.generate(controller.parcelOrder.value.taxSetting!.length, (index) { return _summaryTile( "${controller.parcelOrder.value.taxSetting![index].title} ${controller.parcelOrder.value.taxSetting![index].type == 'fix' ? '' : '(${controller.parcelOrder.value.taxSetting![index].tax}%)'}", Constant.amountShow( amount: Constant.getTaxValue( amount: ((double.tryParse(controller.parcelOrder.value.subTotal.toString()) ?? 0.0) - (double.tryParse(controller.parcelOrder.value.discount.toString()) ?? 0.0)) .toString(), taxModel: controller.parcelOrder.value.taxSetting![index], ).toString(), ), isDark, null); }), const Divider(), // Total _summaryTile( "Order Total".tr, Constant.amountShow(amount: controller.totalAmount.value.toString()), isDark, null), _summaryTile( "Admin Commission (${controller.parcelOrder.value.adminCommission}${controller.parcelOrder.value.adminCommissionType == "Percentage" || controller.parcelOrder.value.adminCommissionType == "percentage" ? "%" : Constant.currencyModel!.symbol})" .tr, Constant.amountShow(amount: controller.adminCommission.value.toString()), isDark, AppThemeData.danger300, ), // controller.parcelOrder.value.driver?.ownerId != null && // controller.parcelOrder.value.driver?.ownerId.isNotEmpty || // controller.parcelOrder.value.status == Constant.orderPlaced ((controller.parcelOrder.value.driver?.ownerId != null && (controller.parcelOrder.value.driver?.ownerId?.isNotEmpty ?? false)) || controller.parcelOrder.value.status == Constant.orderPlaced) ? SizedBox() : Container( width: Responsive.width(100, context), decoration: BoxDecoration( border: Border.all(color: isDark ? AppThemeData.danger50 : AppThemeData.danger50), borderRadius: BorderRadius.circular(10), ), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "Note : Admin commission will be debited from your wallet balance. \n \nAdmin commission will apply on your booking Amount minus Discount(if applicable).", style: AppThemeData.boldTextStyle( fontSize: 16, color: isDark ? AppThemeData.danger300 : AppThemeData.danger300), ), ], ), ), ), ], ), ), const SizedBox(height: 24), ], ), ), ); }, ); } Widget _infoSection(String title, String name, String address, String phone, bool isDark) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(title, style: AppThemeData.semiBoldTextStyle(fontSize: 18, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900)), Text(name, style: AppThemeData.semiBoldTextStyle(fontSize: 16, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900)), Text(address, style: AppThemeData.mediumTextStyle(fontSize: 14, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900)), Text(phone, style: AppThemeData.mediumTextStyle(fontSize: 14, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900)), //Text(time, style: AppThemeData.semiBoldTextStyle(fontSize: 14, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900)), ], ); } Widget _iconTile(String value, title, icon, bool isDark) { return Column( children: [ // Icon(icon, color: AppThemeData.primary300), SvgPicture.asset(icon, height: 28, width: 28, color: isDark ? AppThemeData.greyDark800 : AppThemeData.grey800), const SizedBox(height: 6), Text(value, style: AppThemeData.semiBoldTextStyle(fontSize: 16, color: isDark ? AppThemeData.greyDark800 : AppThemeData.grey800)), const SizedBox(height: 6), Text(title, style: AppThemeData.semiBoldTextStyle(fontSize: 12, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900)), ], ); } Widget _summaryTile(String title, String value, bool isDark, Color? colors) { return Padding( padding: const EdgeInsets.symmetric(vertical: 4), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(title, style: AppThemeData.mediumTextStyle(fontSize: 16, color: isDark ? AppThemeData.greyDark800 : AppThemeData.grey800)), Text( value, style: AppThemeData.semiBoldTextStyle( fontSize: title == "Order Total" ? 18 : 16, color: colors ?? (isDark ? AppThemeData.greyDark900 : AppThemeData.grey900)), ), ], ), ); } }