INFRA: Set Up Project.
This commit is contained in:
332
lib/screen_ui/rental_service/rental_conformation_screen.dart
Normal file
332
lib/screen_ui/rental_service/rental_conformation_screen.dart
Normal file
@@ -0,0 +1,332 @@
|
||||
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))),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user