import 'package:customer/constant/constant.dart'; import 'package:customer/models/coupon_model.dart'; import 'package:customer/screen_ui/rental_service/rental_coupon_screen.dart'; import 'package:customer/themes/show_toast_dialog.dart'; import 'package:customer/utils/network_image_widget.dart'; import 'package:dotted_border/dotted_border.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:get/get.dart' hide Trans; import '../../controllers/rental_conformation_controller.dart'; import '../../controllers/theme_controller.dart'; import '../../themes/app_them_data.dart'; import '../../themes/round_button_fill.dart'; class RentalConformationScreen extends StatelessWidget { const RentalConformationScreen({super.key}); @override Widget build(BuildContext context) { final themeController = Get.find(); final isDark = themeController.isDark.value; return GetX( init: RentalConformationController(), builder: (controller) { return Scaffold( appBar: AppBar( automaticallyImplyLeading: false, backgroundColor: AppThemeData.primary300, title: Padding( padding: const EdgeInsets.only(bottom: 10), child: Row( children: [ GestureDetector( onTap: () { Get.back(); }, child: Container( height: 42, width: 42, decoration: BoxDecoration( shape: BoxShape.circle, color: AppThemeData.grey50, ), child: Center( child: Padding( padding: const EdgeInsets.only(left: 5), child: Icon( Icons.arrow_back_ios, color: AppThemeData.grey900, size: 20, ), ), ), ), ), const SizedBox(width: 10), Text( "Confirm Rent a Car".tr(), style: AppThemeData.boldTextStyle( fontSize: 18, color: AppThemeData.grey900, ), ), ], ), ), ), body: controller.isLoading.value ? Center(child: Constant.loader()) : SingleChildScrollView( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox(height: 20), 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: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Image.asset( "assets/icons/pickup.png", height: 15, width: 15, ), SizedBox(width: 15), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "${controller.rentalOrderModel.value.sourceLocationName}", style: AppThemeData.semiBoldTextStyle( fontSize: 16, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900, ), ), Text( Constant.timestampToDate( controller .rentalOrderModel .value .bookingDateTime!, ), style: AppThemeData.semiBoldTextStyle( fontSize: 12, color: isDark ? AppThemeData.greyDark600 : AppThemeData.grey600, ), ), ], ), ), ], ), ), SizedBox(height: 20), 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( "Your Preference".tr(), style: AppThemeData.boldTextStyle( fontSize: 14, color: isDark ? AppThemeData.greyDark500 : AppThemeData.grey500, ), ), SizedBox(height: 10), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( controller .rentalOrderModel .value .rentalPackageModel! .name .toString(), style: AppThemeData.semiBoldTextStyle( fontSize: 18, color: isDark ? AppThemeData .greyDark900 : AppThemeData .grey900, ), ), const SizedBox(height: 4), Text( controller .rentalOrderModel .value .rentalPackageModel! .description .toString(), style: AppThemeData.mediumTextStyle( fontSize: 14, color: isDark ? AppThemeData.greyDark600 : AppThemeData.grey600, ), ), ], ), ), SizedBox(width: 10), Text( Constant.amountShow( amount: controller .rentalOrderModel .value .rentalPackageModel! .baseFare .toString(), ), style: AppThemeData.boldTextStyle( fontSize: 18, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900, ), ), ], ), ], ), ), SizedBox(height: 20), 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( "Vehicle Type".tr(), style: AppThemeData.boldTextStyle( fontSize: 14, color: isDark ? AppThemeData.greyDark500 : AppThemeData.grey500, ), ), SizedBox(height: 10), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ ClipRRect( borderRadius: BorderRadiusGeometry.circular(10), child: NetworkImageWidget( imageUrl: controller .rentalOrderModel .value .rentalVehicleType! .rentalVehicleIcon .toString(), height: 50, width: 50, borderRadius: 10, ), ), SizedBox(width: 10), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "${controller.rentalOrderModel.value.rentalVehicleType!.name}", style: AppThemeData.semiBoldTextStyle( fontSize: 18, color: isDark ? AppThemeData .greyDark900 : AppThemeData .grey900, ), ), Text( "${controller.rentalOrderModel.value.rentalVehicleType!.shortDescription}", style: AppThemeData.mediumTextStyle( fontSize: 16, color: isDark ? AppThemeData.greyDark600 : AppThemeData.grey600, ), ), ], ), ), ], ), ], ), ), SizedBox(height: 10), Row( children: [ Expanded( child: Text( "Coupons".tr(), style: AppThemeData.boldTextStyle( fontSize: 16, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900, ), ), ), InkWell( onTap: () { Get.to(RentalCouponScreen())!.then((value) { if (value != null) { double couponAmount = Constant.calculateDiscount( amount: controller.subTotal.value .toString(), offerModel: value, ); if (couponAmount < controller.subTotal.value) { controller.selectedCouponModel.value = value; controller.calculateAmount(); } else { ShowToastDialog.showToast( "This offer not eligible for this booking" .tr(), ); } } }); }, child: Text( "View All".tr(), style: AppThemeData.boldTextStyle( decoration: TextDecoration.underline, fontSize: 14, color: isDark ? AppThemeData.primary300 : AppThemeData.primary300, ), ), ), ], ), const SizedBox(height: 5), // Coupon input DottedBorder( options: RoundedRectDottedBorderOptions( strokeWidth: 1, radius: const Radius.circular(10), color: isDark ? AppThemeData.parcelServiceDark300 : AppThemeData.primary300, ), child: Container( decoration: BoxDecoration( color: AppThemeData.parcelService50, borderRadius: BorderRadius.circular(10), ), padding: const EdgeInsets.symmetric( horizontal: 12, vertical: 8, ), child: Row( children: [ SvgPicture.asset( "assets/icons/ic_coupon_parcel.svg", height: 28, width: 28, ), SizedBox(width: 15), Expanded( child: TextFormField( controller: controller.couponController.value, style: AppThemeData.semiBoldTextStyle( color: AppThemeData.grey900, ), decoration: InputDecoration( hintText: "Write coupon code".tr(), hintStyle: AppThemeData.mediumTextStyle( fontSize: 16, color: AppThemeData.parcelService500, ), border: InputBorder.none, ), ), ), RoundedButtonFill( title: "Redeem now".tr(), onPress: () { if (controller.couponList .where( (element) => element.code!.toLowerCase() == controller .couponController .value .text .toLowerCase(), ) .isNotEmpty) { CouponModel couponModel = controller .couponList .firstWhere( (p0) => p0.code!.toLowerCase() == controller .couponController .value .text .toLowerCase(), ); if (couponModel.expiresAt! .toDate() .isAfter(DateTime.now())) { double couponAmount = Constant.calculateDiscount( amount: controller.subTotal.value .toString(), offerModel: couponModel, ); if (couponAmount < controller.subTotal.value) { controller .selectedCouponModel .value = couponModel; controller.calculateAmount(); controller.update(); } else { ShowToastDialog.showToast( "This offer not eligible for this booking" .tr(), ); } } else { ShowToastDialog.showToast( "This coupon code has been expired" .tr(), ); } } else { ShowToastDialog.showToast( "Invalid coupon code".tr(), ); } }, borderRadius: 10, height: 4, width: 28, fontSizes: 14, color: AppThemeData.primary300, textColor: AppThemeData.grey900, ), ], ), ), ), const SizedBox(height: 10), 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, AppThemeData.dangerDark300, ), // Tax List ...List.generate( controller .rentalOrderModel .value .taxSetting! .length, (index) { final taxModel = controller .rentalOrderModel .value .taxSetting![index]; final taxTitle = "${taxModel.title} ${taxModel.type == 'fix' ? '(${Constant.amountShow(amount: taxModel.tax)})' : '(${taxModel.tax}%)'}"; return _summaryTile( taxTitle, Constant.amountShow( amount: Constant.getTaxValue( amount: (controller.subTotal.value - controller .discount .value) .toString(), taxModel: controller .rentalOrderModel .value .taxSetting![index], ).toString(), ), isDark, null, ); }, ), const Divider(), // Total _summaryTile( "Order Total".tr(), Constant.amountShow( amount: controller.totalAmount.value.toString(), ), isDark, null, ), ], ), ), SizedBox(height: 20), RoundedButtonFill( title: "Book now".tr(), onPress: () { controller.placeOrder(); }, color: AppThemeData.primary300, textColor: AppThemeData.grey900, ), SizedBox(height: 20), ], ), ), ), ); }, ); } 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), ), ), ], ), ); } }