import 'package:cached_network_image/cached_network_image.dart'; import 'package:customer/models/rental_order_model.dart'; import 'package:customer/screen_ui/auth_screens/login_screen.dart'; import 'package:customer/screen_ui/multi_vendor_service/wallet_screen/wallet_screen.dart'; import 'package:customer/screen_ui/rental_service/rental_order_details_screen.dart'; import 'package:customer/themes/round_button_fill.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../../constant/constant.dart'; import '../../controllers/my_rental_booking_controller.dart'; import '../../controllers/theme_controller.dart'; import '../../themes/app_them_data.dart'; class MyRentalBookingScreen extends StatelessWidget { const MyRentalBookingScreen({super.key}); @override Widget build(BuildContext context) { final themeController = Get.find(); final isDark = themeController.isDark.value; return GetX( init: MyRentalBookingController(), builder: (controller) { return DefaultTabController( length: controller.tabTitles.length, initialIndex: controller.tabTitles.indexOf( controller.selectedTab.value, ), child: Scaffold( appBar: AppBar( automaticallyImplyLeading: false, backgroundColor: AppThemeData.primary300, title: Padding( padding: const EdgeInsets.only(bottom: 10), child: Row( children: [ const SizedBox(width: 10), Text( "Rental History".tr, style: AppThemeData.boldTextStyle( fontSize: 18, color: AppThemeData.grey900, ), ), ], ), ), bottom: TabBar( onTap: (index) { controller.selectTab(controller.tabTitles[index]); }, indicatorColor: AppThemeData.parcelService500, labelColor: AppThemeData.parcelService500, unselectedLabelColor: AppThemeData.parcelService500, labelStyle: AppThemeData.boldTextStyle(fontSize: 13), unselectedLabelStyle: AppThemeData.mediumTextStyle( fontSize: 13, ), tabs: controller.tabTitles .map((title) => Tab(child: Center(child: Text(title)))) .toList(), ), ), body: controller.isLoading.value ? Constant.loader() : Constant.userModel == null ? Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( "Please Log In to Continue".tr, style: TextStyle( color: isDark ? AppThemeData.grey100 : AppThemeData.grey800, fontSize: 22, fontFamily: AppThemeData.semiBold, ), ), const SizedBox(height: 5), Text( "You’re not logged in. Please sign in to access your account and explore all features." .tr, textAlign: TextAlign.center, style: TextStyle( color: isDark ? AppThemeData.grey50 : AppThemeData.grey500, fontSize: 16, fontFamily: AppThemeData.bold, ), ), const SizedBox(height: 20), RoundedButtonFill( title: "Log in".tr, width: 55, height: 5.5, color: AppThemeData.primary300, textColor: AppThemeData.grey50, onPress: () async { Get.offAll(const LoginScreen()); }, ), ], ), ) : TabBarView( children: controller.tabTitles.map((title) { List orders = controller .getOrdersForTab(title); if (orders.isEmpty) { return Center( child: Text( "No orders found".tr, style: AppThemeData.mediumTextStyle( color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900, ), ), ); } return ListView.builder( padding: const EdgeInsets.all(16), itemCount: orders.length, itemBuilder: (context, index) { RentalOrderModel order = orders[index]; //use this return InkWell( onTap: () { Get.to( () => RentalOrderDetailsScreen(), arguments: order, ); }, child: 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), margin: const EdgeInsets.only(bottom: 10), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.only( top: 5, ), child: Image.asset( "assets/icons/pickup.png", height: 18, width: 18, ), ), const SizedBox(width: 10), Expanded( //prevents overflow child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( crossAxisAlignment: CrossAxisAlignment .start, children: [ Expanded( //text wraps if too long child: Text( order.sourceLocationName ?? "-", style: AppThemeData.semiBoldTextStyle( fontSize: 16, color: isDark ? AppThemeData .greyDark900 : AppThemeData .grey900, ), overflow: TextOverflow .ellipsis, //safe cutoff maxLines: 2, ), ), if (order.status != null) ...[ const SizedBox( width: 8, ), Container( padding: const EdgeInsets.symmetric( vertical: 6, horizontal: 12, ), decoration: BoxDecoration( color: AppThemeData .info50, border: Border.all( color: AppThemeData .info300, ), borderRadius: BorderRadius.circular( 12, ), ), child: Text( order.status ?? '', style: AppThemeData.boldTextStyle( fontSize: 14, color: AppThemeData .info500, ), ), ), ], ], ), if (order.bookingDateTime != null) Text( Constant.timestampToDateTime( order.bookingDateTime!, ), style: AppThemeData.mediumTextStyle( fontSize: 12, color: isDark ? AppThemeData .greyDark600 : AppThemeData .grey600, ), ), ], ), ), ], ), const SizedBox(height: 12), Text( "Vehicle Type :".tr, style: AppThemeData.boldTextStyle( fontSize: 16, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900, ), ), Padding( padding: const EdgeInsets.symmetric( vertical: 10, horizontal: 10, ), child: Row( children: [ ClipRRect( //borderRadius: BorderRadius.circular(10), child: CachedNetworkImage( imageUrl: order .rentalVehicleType! .rentalVehicleIcon .toString(), height: 60, width: 60, imageBuilder: ( context, imageProvider, ) => Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular( 10, ), image: DecorationImage( image: imageProvider, fit: BoxFit.cover, ), ), ), placeholder: (context, url) => Center( child: CircularProgressIndicator.adaptive( valueColor: AlwaysStoppedAnimation( AppThemeData .primary300, ), ), ), errorWidget: ( context, url, error, ) => Image.network( Constant .placeHolderImage, fit: BoxFit.cover, ), fit: BoxFit.cover, ), ), Expanded( child: Padding( padding: const EdgeInsets.symmetric( horizontal: 10, ), child: Column( crossAxisAlignment: CrossAxisAlignment .start, children: [ Text( "${order.rentalVehicleType!.name}", style: AppThemeData.semiBoldTextStyle( fontSize: 18, color: isDark ? AppThemeData .greyDark900 : AppThemeData .grey900, ), ), Padding( padding: const EdgeInsets.only( top: 2.0, ), child: Text( "${order.rentalVehicleType!.shortDescription}", style: AppThemeData.mediumTextStyle( fontSize: 14, color: isDark ? AppThemeData .greyDark600 : AppThemeData .grey600, ), ), ), ], ), ), ), ], ), ), Text( "Package info :".tr, style: AppThemeData.boldTextStyle( fontSize: 16, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900, ), ), Padding( padding: const EdgeInsets.symmetric( vertical: 10, horizontal: 10, ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( order .rentalPackageModel! .name .toString(), style: AppThemeData.semiBoldTextStyle( fontSize: 18, color: isDark ? AppThemeData .greyDark900 : AppThemeData .grey900, ), ), const SizedBox(height: 4), Text( order .rentalPackageModel! .description .toString(), style: AppThemeData.mediumTextStyle( fontSize: 14, color: isDark ? AppThemeData .greyDark600 : AppThemeData .grey600, ), ), ], ), ), SizedBox(width: 10), Text( Constant.amountShow( amount: order .rentalPackageModel! .baseFare .toString(), ), style: AppThemeData.boldTextStyle( fontSize: 18, color: isDark ? AppThemeData .greyDark900 : AppThemeData .grey900, ), ), ], ), ), if (Constant .isEnableOTPTripStartForRental == true) Text( "${'OTP :'.tr} ${order.otpCode}", style: AppThemeData.boldTextStyle( fontSize: 16, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900, ), ), SizedBox(height: 10), Row( children: [ order.status == Constant .orderInTransit && order.paymentStatus == false ? Expanded( child: RoundedButtonFill( title: "Pay Now", onPress: () { Get.to( () => RentalOrderDetailsScreen(), arguments: order, ); }, color: AppThemeData.primary300, textColor: AppThemeData.grey900, ), ) : SizedBox(), order.status == Constant.orderPlaced || order.status == Constant.driverAccepted ? Expanded( child: RoundedButtonFill( title: "Cancel Booking", onPress: () => controller .cancelRentalRequest( order, taxList: order .taxSetting, ), color: AppThemeData.danger300, textColor: AppThemeData.surface, ), ) : SizedBox(), ], ), ], ), ), ); }, ); }).toList(), ), ), ); }, ); } Obx cardDecoration( MyRentalBookingController controller, PaymentGateway value, isDark, String image, ) { return Obx( () => Padding( padding: const EdgeInsets.symmetric(vertical: 5), child: Column( children: [ InkWell( onTap: () { controller.selectedPaymentMethod.value = value.name; }, child: Row( children: [ Container( width: 50, height: 50, decoration: ShapeDecoration( shape: RoundedRectangleBorder( side: const BorderSide( width: 1, color: Color(0xFFE5E7EB), ), borderRadius: BorderRadius.circular(8), ), ), child: Padding( padding: EdgeInsets.all( value.name == "payFast" ? 0 : 8.0, ), child: Image.asset(image), ), ), const SizedBox(width: 10), value.name == "wallet" ? Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( value.name.capitalizeString(), textAlign: TextAlign.start, style: AppThemeData.semiBoldTextStyle( fontSize: 16, color: isDark ? AppThemeData.grey50 : AppThemeData.grey900, ), ), Text( Constant.amountShow( amount: Constant.userModel!.walletAmount == null ? '0.0' : Constant.userModel!.walletAmount .toString(), ), textAlign: TextAlign.start, style: AppThemeData.semiBoldTextStyle( fontSize: 14, color: isDark ? AppThemeData.primary300 : AppThemeData.primary300, ), ), ], ), ) : Expanded( child: Text( value.name.capitalizeString(), textAlign: TextAlign.start, style: AppThemeData.semiBoldTextStyle( fontSize: 16, color: isDark ? AppThemeData.grey50 : AppThemeData.grey900, ), ), ), const Expanded(child: SizedBox()), Radio( value: value.name, groupValue: controller.selectedPaymentMethod.value, activeColor: isDark ? AppThemeData.primary300 : AppThemeData.primary300, onChanged: (value) { controller.selectedPaymentMethod.value = value.toString(); }, ), ], ), ), ], ), ), ); } }