Files
Fondex/lib/screen_ui/rental_service/rental_conformation_screen.dart

333 lines
19 KiB
Dart

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:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:get/get.dart';
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<ThemeController>();
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))),
],
),
);
}
}