INFRA: Set Up Project.
This commit is contained in:
1586
lib/screen_ui/cab_service_screens/Intercity_home_screen.dart
Normal file
1586
lib/screen_ui/cab_service_screens/Intercity_home_screen.dart
Normal file
File diff suppressed because it is too large
Load Diff
1590
lib/screen_ui/cab_service_screens/cab_booking_screen.dart
Normal file
1590
lib/screen_ui/cab_service_screens/cab_booking_screen.dart
Normal file
File diff suppressed because it is too large
Load Diff
138
lib/screen_ui/cab_service_screens/cab_coupon_code_screen.dart
Normal file
138
lib/screen_ui/cab_service_screens/cab_coupon_code_screen.dart
Normal file
@@ -0,0 +1,138 @@
|
||||
import 'package:customer/constant/constant.dart';
|
||||
import 'package:customer/controllers/cab_coupon_code_controller.dart';
|
||||
import 'package:customer/controllers/theme_controller.dart';
|
||||
import 'package:customer/models/coupon_model.dart';
|
||||
import 'package:customer/themes/app_them_data.dart';
|
||||
import 'package:customer/themes/responsive.dart';
|
||||
import 'package:customer/widget/my_separator.dart';
|
||||
import 'package:dotted_border/dotted_border.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class CabCouponCodeScreen extends StatelessWidget {
|
||||
const CabCouponCodeScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final themeController = Get.find<ThemeController>();
|
||||
final isDark = themeController.isDark.value;
|
||||
return GetX(
|
||||
init: CabCouponCodeController(),
|
||||
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("Coupon".tr, style: AppThemeData.boldTextStyle(fontSize: 18, color: AppThemeData.grey900)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
body:
|
||||
controller.isLoading.value
|
||||
? Constant.loader()
|
||||
: controller.cabCouponList.isEmpty
|
||||
? Constant.showEmptyView(message: "Coupon not found".tr)
|
||||
: ListView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: controller.cabCouponList.length,
|
||||
itemBuilder: (context, index) {
|
||||
CouponModel couponModel = controller.cabCouponList[index];
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
|
||||
child: Container(
|
||||
height: Responsive.height(16, context),
|
||||
decoration: ShapeDecoration(color: isDark ? AppThemeData.grey900 : AppThemeData.grey50, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10))),
|
||||
child: Row(
|
||||
children: [
|
||||
ClipRRect(
|
||||
borderRadius: const BorderRadius.only(topLeft: Radius.circular(10), bottomLeft: Radius.circular(10)),
|
||||
child: Stack(
|
||||
children: [
|
||||
Image.asset("assets/images/ic_coupon_image.png", height: Responsive.height(16, context), fit: BoxFit.fill),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 10),
|
||||
child: Align(
|
||||
alignment: Alignment.center,
|
||||
child: RotatedBox(
|
||||
quarterTurns: -1,
|
||||
child: Text(
|
||||
"${couponModel.discountType == "Fix Price" ? Constant.amountShow(amount: couponModel.discount) : "${couponModel.discount}%"} ${'Off'.tr}",
|
||||
textAlign: TextAlign.start,
|
||||
style: TextStyle(fontFamily: AppThemeData.semiBold, fontSize: 16, color: isDark ? AppThemeData.grey50 : AppThemeData.grey50),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 18),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
DottedBorder(
|
||||
options: RoundedRectDottedBorderOptions(strokeWidth: 1, radius: const Radius.circular(6), color: isDark ? AppThemeData.grey400 : AppThemeData.grey500),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Text(
|
||||
"${couponModel.code}",
|
||||
textAlign: TextAlign.start,
|
||||
style: TextStyle(fontFamily: AppThemeData.semiBold, fontSize: 16, color: isDark ? AppThemeData.grey400 : AppThemeData.grey500),
|
||||
),
|
||||
),
|
||||
),
|
||||
const Expanded(child: SizedBox(height: 10)),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
Get.back(result: couponModel);
|
||||
},
|
||||
child: Text(
|
||||
"Tap To Apply".tr,
|
||||
textAlign: TextAlign.start,
|
||||
style: TextStyle(fontFamily: AppThemeData.medium, color: isDark ? AppThemeData.primary300 : AppThemeData.primary300),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
MySeparator(color: isDark ? AppThemeData.grey700 : AppThemeData.grey200),
|
||||
const SizedBox(height: 20),
|
||||
Text(
|
||||
"${couponModel.description}",
|
||||
textAlign: TextAlign.start,
|
||||
style: TextStyle(fontFamily: AppThemeData.medium, fontSize: 16, color: isDark ? AppThemeData.grey50 : AppThemeData.grey900),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
80
lib/screen_ui/cab_service_screens/cab_dashboard_screen.dart
Normal file
80
lib/screen_ui/cab_service_screens/cab_dashboard_screen.dart
Normal file
@@ -0,0 +1,80 @@
|
||||
import 'package:customer/constant/constant.dart';
|
||||
import 'package:customer/controllers/cab_dashboard_controller.dart';
|
||||
import 'package:customer/controllers/theme_controller.dart';
|
||||
import 'package:customer/themes/app_them_data.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class CabDashboardScreen extends StatelessWidget {
|
||||
const CabDashboardScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final themeController = Get.find<ThemeController>();
|
||||
return Obx(() {
|
||||
final isDark = themeController.isDark.value;
|
||||
return GetX(
|
||||
init: CabDashboardController(),
|
||||
builder: (controller) {
|
||||
return Scaffold(
|
||||
body: controller.pageList[controller.selectedIndex.value],
|
||||
bottomNavigationBar: BottomNavigationBar(
|
||||
type: BottomNavigationBarType.fixed,
|
||||
showUnselectedLabels: true,
|
||||
showSelectedLabels: true,
|
||||
selectedFontSize: 12,
|
||||
selectedLabelStyle: const TextStyle(fontFamily: AppThemeData.bold),
|
||||
unselectedLabelStyle: const TextStyle(fontFamily: AppThemeData.bold),
|
||||
currentIndex: controller.selectedIndex.value,
|
||||
backgroundColor: isDark ? AppThemeData.grey900 : AppThemeData.grey50,
|
||||
selectedItemColor: isDark ? AppThemeData.primary300 : AppThemeData.primary300,
|
||||
unselectedItemColor: isDark ? AppThemeData.grey300 : AppThemeData.grey600,
|
||||
onTap: (int index) {
|
||||
if (index == 0) {
|
||||
Get.put(CabDashboardController());
|
||||
}
|
||||
controller.selectedIndex.value = index;
|
||||
},
|
||||
items:
|
||||
Constant.walletSetting == false
|
||||
? [
|
||||
navigationBarItem(isDark, index: 0, assetIcon: "assets/icons/ic_home_cab.svg", label: 'Home'.tr, controller: controller),
|
||||
navigationBarItem(isDark, index: 1, assetIcon: "assets/icons/ic_booking_cab.svg", label: 'My Bookings'.tr, controller: controller),
|
||||
navigationBarItem(isDark, index: 2, assetIcon: "assets/icons/ic_profile.svg", label: 'Profile'.tr, controller: controller),
|
||||
]
|
||||
: [
|
||||
navigationBarItem(isDark, index: 0, assetIcon: "assets/icons/ic_home_cab.svg", label: 'Home'.tr, controller: controller),
|
||||
navigationBarItem(isDark, index: 1, assetIcon: "assets/icons/ic_booking_cab.svg", label: 'My Bookings'.tr, controller: controller),
|
||||
navigationBarItem(isDark, index: 2, assetIcon: "assets/icons/ic_wallet_cab.svg", label: 'Wallet'.tr, controller: controller),
|
||||
navigationBarItem(isDark, index: 3, assetIcon: "assets/icons/ic_profile.svg", label: 'Profile'.tr, controller: controller),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
BottomNavigationBarItem navigationBarItem(isDark, {required int index, required String label, required String assetIcon, required CabDashboardController controller}) {
|
||||
return BottomNavigationBarItem(
|
||||
icon: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 5),
|
||||
child: SvgPicture.asset(
|
||||
assetIcon,
|
||||
height: 22,
|
||||
width: 22,
|
||||
color:
|
||||
controller.selectedIndex.value == index
|
||||
? isDark
|
||||
? AppThemeData.primary300
|
||||
: AppThemeData.primary300
|
||||
: isDark
|
||||
? AppThemeData.grey300
|
||||
: AppThemeData.grey600,
|
||||
),
|
||||
),
|
||||
label: label,
|
||||
);
|
||||
}
|
||||
}
|
||||
285
lib/screen_ui/cab_service_screens/cab_home_screen.dart
Normal file
285
lib/screen_ui/cab_service_screens/cab_home_screen.dart
Normal file
@@ -0,0 +1,285 @@
|
||||
import 'package:customer/constant/constant.dart';
|
||||
import 'package:customer/controllers/cab_home_controller.dart';
|
||||
import 'package:customer/controllers/theme_controller.dart';
|
||||
import 'package:customer/models/banner_model.dart';
|
||||
import 'package:customer/screen_ui/auth_screens/login_screen.dart';
|
||||
import 'package:customer/themes/app_them_data.dart';
|
||||
import 'package:customer/themes/responsive.dart';
|
||||
import 'package:customer/utils/network_image_widget.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import 'Intercity_home_screen.dart';
|
||||
import 'cab_booking_screen.dart';
|
||||
|
||||
class CabHomeScreen extends StatelessWidget {
|
||||
const CabHomeScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final themeController = Get.find<ThemeController>();
|
||||
final isDark = themeController.isDark.value;
|
||||
return GetX(
|
||||
init: CabHomeController(),
|
||||
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),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Constant.userModel == null
|
||||
? InkWell(
|
||||
onTap: () {
|
||||
Get.offAll(const LoginScreen());
|
||||
},
|
||||
child: Text(
|
||||
"Login".tr,
|
||||
textAlign: TextAlign.center,
|
||||
style: AppThemeData.boldTextStyle(color: AppThemeData.grey900, fontSize: 12),
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
Constant.userModel!.fullName(),
|
||||
textAlign: TextAlign.center,
|
||||
style: AppThemeData.boldTextStyle(color: AppThemeData.grey900, fontSize: 12),
|
||||
),
|
||||
Text(
|
||||
Constant.selectedLocation.getFullAddress(),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: AppThemeData.boldTextStyle(fontSize: 18, color: AppThemeData.grey900),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
body:
|
||||
controller.isLoading.value
|
||||
? Constant.loader()
|
||||
: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 15),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
BannerView(bannerList: controller.bannerTopHome),
|
||||
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(height: 20),
|
||||
Text(
|
||||
"Where are you going for?".tr,
|
||||
style: AppThemeData.mediumTextStyle(
|
||||
color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900,
|
||||
fontSize: 18,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Constant.sectionConstantModel!.rideType == "both" || Constant.sectionConstantModel!.rideType == "ride"
|
||||
? GestureDetector(
|
||||
onTap: () {
|
||||
Get.to(() => CabBookingScreen());
|
||||
},
|
||||
child: Container(
|
||||
width: Responsive.width(40, context),
|
||||
decoration: BoxDecoration(
|
||||
color: AppThemeData.warning50,
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
border: Border.all(color: AppThemeData.warning200),
|
||||
),
|
||||
padding: EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SvgPicture.asset("assets/icons/ic_ride.svg", height: 38, width: 38),
|
||||
SizedBox(height: 20),
|
||||
Text(
|
||||
"Ride".tr,
|
||||
style: AppThemeData.semiBoldTextStyle(color: AppThemeData.taxiBooking500, fontSize: 16),
|
||||
),
|
||||
Text(
|
||||
"City rides, 24x7 availability".tr,
|
||||
style: AppThemeData.mediumTextStyle(color: AppThemeData.taxiBooking600, fontSize: 14),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
: SizedBox(),
|
||||
SizedBox(width: 20),
|
||||
Constant.sectionConstantModel!.rideType == "both" || Constant.sectionConstantModel!.rideType == "intercity"
|
||||
? GestureDetector(
|
||||
onTap: () {
|
||||
Get.to(() => IntercityHomeScreen());
|
||||
},
|
||||
child: Container(
|
||||
width: Responsive.width(44, context),
|
||||
decoration: BoxDecoration(
|
||||
color: AppThemeData.carRent50,
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
border: Border.all(color: AppThemeData.carRent200),
|
||||
),
|
||||
padding: EdgeInsets.all(15),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SvgPicture.asset("assets/icons/ic_intercity.svg", height: 38, width: 38),
|
||||
SizedBox(height: 20),
|
||||
Text(
|
||||
"Intercity/Outstation".tr,
|
||||
style: AppThemeData.semiBoldTextStyle(color: AppThemeData.carRent500, fontSize: 16),
|
||||
),
|
||||
Text(
|
||||
"Long trips, prepaid options".tr,
|
||||
style: AppThemeData.mediumTextStyle(color: AppThemeData.parcelService600, fontSize: 14),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
: SizedBox(),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 30),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Every Ride. Every Driver. Verified.".tr,
|
||||
style: AppThemeData.boldTextStyle(
|
||||
color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900,
|
||||
fontSize: 22,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
"All drivers go through ID checks and background verification for your safety.".tr,
|
||||
style: AppThemeData.mediumTextStyle(
|
||||
color: isDark ? AppThemeData.greyDark700 : AppThemeData.grey700,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(child: Image.asset("assets/images/img_ride_driver.png", height: 118, width: 68)),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class BannerView extends StatelessWidget {
|
||||
final List<BannerModel> bannerList;
|
||||
final RxInt currentPage = 0.obs;
|
||||
final ScrollController scrollController = ScrollController();
|
||||
|
||||
BannerView({super.key, required this.bannerList});
|
||||
|
||||
/// Computes the visible item index from scroll offset
|
||||
void onScroll(BuildContext context) {
|
||||
if (scrollController.hasClients && bannerList.isNotEmpty) {
|
||||
final screenWidth = MediaQuery.of(context).size.width;
|
||||
final itemWidth = screenWidth * 0.8 + 10; // banner width + spacing
|
||||
final offset = scrollController.offset;
|
||||
final index = (offset / itemWidth).round();
|
||||
|
||||
if (index != currentPage.value && index < bannerList.length) {
|
||||
currentPage.value = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
scrollController.addListener(() {
|
||||
onScroll(context);
|
||||
});
|
||||
|
||||
return bannerList.isEmpty
|
||||
? SizedBox()
|
||||
: Column(
|
||||
children: [
|
||||
SizedBox(height: 20),
|
||||
SizedBox(
|
||||
height: 150,
|
||||
child: ListView.separated(
|
||||
controller: scrollController,
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: bannerList.length,
|
||||
separatorBuilder: (context, index) => const SizedBox(width: 15),
|
||||
itemBuilder: (context, index) {
|
||||
final banner = bannerList[index];
|
||||
return ClipRRect(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
child: SizedBox(
|
||||
width: MediaQuery.of(context).size.width * 0.8,
|
||||
child: NetworkImageWidget(imageUrl: banner.photo ?? '', fit: BoxFit.cover),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Obx(() {
|
||||
return Row(
|
||||
children: List.generate(bannerList.length, (index) {
|
||||
bool isSelected = currentPage.value == index;
|
||||
return Expanded(
|
||||
child: Container(
|
||||
height: 4,
|
||||
decoration: BoxDecoration(
|
||||
color: isSelected ? AppThemeData.grey300 : AppThemeData.grey100,
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
);
|
||||
}),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
497
lib/screen_ui/cab_service_screens/cab_order_details.dart
Normal file
497
lib/screen_ui/cab_service_screens/cab_order_details.dart
Normal file
@@ -0,0 +1,497 @@
|
||||
import 'package:dotted_border/dotted_border.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:get/get.dart';
|
||||
import '../../constant/constant.dart';
|
||||
import '../../controllers/cab_order_details_controller.dart';
|
||||
import '../../controllers/theme_controller.dart';
|
||||
import '../../models/user_model.dart';
|
||||
import '../../service/fire_store_utils.dart';
|
||||
import '../../themes/app_them_data.dart';
|
||||
import 'package:flutter_map/flutter_map.dart' as fm;
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart' as gmap;
|
||||
import 'package:latlong2/latlong.dart' as osm;
|
||||
|
||||
import '../../themes/round_button_border.dart';
|
||||
import '../../themes/round_button_fill.dart';
|
||||
import '../../themes/show_toast_dialog.dart';
|
||||
import '../../utils/network_image_widget.dart';
|
||||
import '../multi_vendor_service/chat_screens/chat_screen.dart';
|
||||
import 'cab_review_screen.dart';
|
||||
import 'complain_screen.dart';
|
||||
|
||||
class CabOrderDetails extends StatelessWidget {
|
||||
const CabOrderDetails({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final themeController = Get.find<ThemeController>();
|
||||
final isDark = themeController.isDark.value;
|
||||
return GetX(
|
||||
init: CabOrderDetailsController(),
|
||||
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("Ride Details".tr, style: AppThemeData.boldTextStyle(fontSize: 18, color: AppThemeData.grey900)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
body:
|
||||
controller.isLoading.value
|
||||
? Constant.loader()
|
||||
: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
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.cabOrder.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(
|
||||
margin: const EdgeInsets.only(bottom: 16),
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: isDark ? AppThemeData.greyDark50 : AppThemeData.grey50,
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
border: Border.all(color: isDark ? AppThemeData.greyDark200 : AppThemeData.grey200),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"${'Booking Date:'.tr} ${controller.formatDate(controller.cabOrder.value.scheduleDateTime!)}".tr,
|
||||
textAlign: TextAlign.start,
|
||||
style: TextStyle(fontFamily: AppThemeData.semiBold, fontSize: 18, color: isDark ? AppThemeData.grey50 : AppThemeData.grey900),
|
||||
),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
Icon(Icons.stop_circle_outlined, color: Colors.green),
|
||||
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: 55),
|
||||
),
|
||||
Icon(Icons.radio_button_checked, color: Colors.red),
|
||||
],
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
// Source Location Name
|
||||
Expanded(
|
||||
child: Text(
|
||||
controller.cabOrder.value.sourceLocationName.toString(),
|
||||
style: AppThemeData.semiBoldTextStyle(fontSize: 16, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
border: Border.all(color: AppThemeData.warning300, width: 1),
|
||||
color: AppThemeData.warning50,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12),
|
||||
child: Text(
|
||||
controller.cabOrder.value.status.toString(),
|
||||
style: AppThemeData.boldTextStyle(fontSize: 14, color: AppThemeData.warning500),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 15),
|
||||
DottedBorder(
|
||||
options: CustomPathDottedBorderOptions(
|
||||
color: Colors.grey.shade400,
|
||||
strokeWidth: 2,
|
||||
dashPattern: [4, 4],
|
||||
customPath:
|
||||
(size) =>
|
||||
Path()
|
||||
..moveTo(0, size.height / 2) // start from left center
|
||||
..lineTo(size.width, size.height / 2), // draw to right center
|
||||
),
|
||||
child: const SizedBox(width: 295, height: 3),
|
||||
),
|
||||
SizedBox(height: 15),
|
||||
Text(
|
||||
controller.cabOrder.value.destinationLocationName.toString(),
|
||||
style: AppThemeData.semiBoldTextStyle(fontSize: 16, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// map view show
|
||||
Container(
|
||||
height: 180,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
color: isDark ? AppThemeData.greyDark50 : AppThemeData.grey50,
|
||||
border: Border.all(color: isDark ? AppThemeData.greyDark200 : AppThemeData.grey200),
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
child:
|
||||
Constant.selectedMapType == "osm"
|
||||
? fm.FlutterMap(
|
||||
options: fm.MapOptions(
|
||||
initialCenter: osm.LatLng(controller.cabOrder.value.sourceLocation!.latitude!, controller.cabOrder.value.sourceLocation!.longitude!),
|
||||
initialZoom: 13,
|
||||
),
|
||||
children: [
|
||||
fm.TileLayer(urlTemplate: "https://tile.openstreetmap.org/{z}/{x}/{y}.png"),
|
||||
|
||||
// Only show polyline if points exist
|
||||
if (controller.osmPolyline.isNotEmpty) fm.PolylineLayer(polylines: [fm.Polyline(points: controller.osmPolyline.toList(), color: Colors.blue, strokeWidth: 4)]),
|
||||
|
||||
fm.MarkerLayer(
|
||||
markers: [
|
||||
fm.Marker(
|
||||
point: osm.LatLng(controller.cabOrder.value.sourceLocation!.latitude!, controller.cabOrder.value.sourceLocation!.longitude!),
|
||||
width: 20,
|
||||
height: 20,
|
||||
child: Image.asset('assets/icons/ic_cab_pickup.png', width: 10, height: 10),
|
||||
),
|
||||
fm.Marker(
|
||||
point: osm.LatLng(controller.cabOrder.value.destinationLocation!.latitude!, controller.cabOrder.value.destinationLocation!.longitude!),
|
||||
width: 20,
|
||||
height: 20,
|
||||
child: Image.asset('assets/icons/ic_cab_destination.png', width: 10, height: 10),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
: gmap.GoogleMap(
|
||||
initialCameraPosition: gmap.CameraPosition(
|
||||
target: gmap.LatLng(controller.cabOrder.value.sourceLocation!.latitude!, controller.cabOrder.value.sourceLocation!.longitude!),
|
||||
zoom: 13,
|
||||
),
|
||||
polylines: controller.googlePolylines.toSet(),
|
||||
markers: controller.googleMarkers.toSet(),
|
||||
),
|
||||
),
|
||||
),
|
||||
controller.cabOrder.value.driver != null
|
||||
? Column(
|
||||
children: [
|
||||
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: [
|
||||
Text("Ride & Fare Summary".tr, style: AppThemeData.boldTextStyle(fontSize: 14, color: isDark ? AppThemeData.greyDark500 : AppThemeData.grey500)),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 52,
|
||||
height: 52,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadiusGeometry.circular(10),
|
||||
child: NetworkImageWidget(imageUrl: controller.cabOrder.value.driver?.profilePictureURL ?? '', height: 70, width: 70, borderRadius: 35),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 20),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
controller.cabOrder.value.driver?.fullName() ?? '',
|
||||
style: AppThemeData.boldTextStyle(color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900, fontSize: 18),
|
||||
),
|
||||
Text(
|
||||
"${controller.cabOrder.value.driver?.vehicleType ?? ''} | ${controller.cabOrder.value.driver?.carMakes.toString()}",
|
||||
style: TextStyle(fontFamily: AppThemeData.medium, color: isDark ? AppThemeData.greyDark700 : AppThemeData.grey700, fontSize: 14),
|
||||
),
|
||||
Text(
|
||||
controller.cabOrder.value.driver?.carNumber ?? '',
|
||||
style: AppThemeData.boldTextStyle(color: isDark ? AppThemeData.greyDark700 : AppThemeData.grey700, fontSize: 16),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
RoundedButtonBorder(
|
||||
title: controller.driverUser.value.averageRating.toStringAsFixed(1) ?? '',
|
||||
width: 20,
|
||||
height: 3.5,
|
||||
radius: 10,
|
||||
isRight: false,
|
||||
isCenter: true,
|
||||
textColor: AppThemeData.warning400,
|
||||
borderColor: AppThemeData.warning400,
|
||||
color: AppThemeData.warning50,
|
||||
icon: SvgPicture.asset("assets/icons/ic_start.svg"),
|
||||
onPress: () {},
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Visibility(
|
||||
visible: controller.cabOrder.value.status == Constant.orderCompleted ? true : false,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
child: RoundedButtonFill(
|
||||
title: controller.ratingModel.value.id != null && controller.ratingModel.value.id!.isNotEmpty ? 'Update Review'.tr : 'Add Review'.tr,
|
||||
onPress: () async {
|
||||
final result = await Get.to(() => CabReviewScreen(), arguments: {'order': controller.cabOrder.value});
|
||||
|
||||
// If review was submitted successfully
|
||||
if (result == true) {
|
||||
await controller.fetchDriverDetails();
|
||||
}
|
||||
},
|
||||
height: 5,
|
||||
borderRadius: 15,
|
||||
color: Colors.orange,
|
||||
textColor: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 5),
|
||||
Expanded(
|
||||
child: Visibility(
|
||||
visible: controller.cabOrder.value.status == Constant.orderCompleted ? true : false,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
child: RoundedButtonFill(
|
||||
title: 'Complain'.tr,
|
||||
onPress: () async {
|
||||
Get.to(() => ComplainScreen(), arguments: {'order': controller.cabOrder.value});
|
||||
},
|
||||
height: 5,
|
||||
borderRadius: 15,
|
||||
color: Colors.orange,
|
||||
textColor: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (controller.cabOrder.value.status != Constant.orderCompleted)
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
InkWell(
|
||||
onTap: () {
|
||||
Constant.makePhoneCall(controller.cabOrder.value.driver!.phoneNumber.toString());
|
||||
},
|
||||
child: Container(
|
||||
width: 150,
|
||||
height: 42,
|
||||
decoration: ShapeDecoration(
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide(width: 1, color: isDark ? AppThemeData.grey700 : AppThemeData.grey200),
|
||||
borderRadius: BorderRadius.circular(120),
|
||||
),
|
||||
),
|
||||
child: Padding(padding: const EdgeInsets.all(8.0), child: SvgPicture.asset("assets/icons/ic_phone_call.svg")),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
InkWell(
|
||||
onTap: () async {
|
||||
ShowToastDialog.showLoader("Please wait...".tr);
|
||||
|
||||
UserModel? customer = await FireStoreUtils.getUserProfile(controller.cabOrder.value.authorID ?? '');
|
||||
UserModel? driverUser = await FireStoreUtils.getUserProfile(controller.cabOrder.value.driverId ?? '');
|
||||
|
||||
ShowToastDialog.closeLoader();
|
||||
|
||||
Get.to(
|
||||
const ChatScreen(),
|
||||
arguments: {
|
||||
"customerName": customer?.fullName(),
|
||||
"restaurantName": driverUser?.fullName(),
|
||||
"orderId": controller.cabOrder.value.id,
|
||||
"restaurantId": driverUser?.id,
|
||||
"customerId": customer?.id,
|
||||
"customerProfileImage": customer?.profilePictureURL,
|
||||
"restaurantProfileImage": driverUser?.profilePictureURL,
|
||||
"token": driverUser?.fcmToken,
|
||||
"chatType": "Driver",
|
||||
},
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
width: 150,
|
||||
height: 42,
|
||||
decoration: ShapeDecoration(
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide(width: 1, color: isDark ? AppThemeData.grey700 : AppThemeData.grey200),
|
||||
borderRadius: BorderRadius.circular(120),
|
||||
),
|
||||
),
|
||||
child: Padding(padding: const EdgeInsets.all(8.0), child: SvgPicture.asset("assets/icons/ic_wechat.svg")),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: SizedBox(),
|
||||
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: EdgeInsets.all(16),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
_iconTile("${double.parse(controller.cabOrder.value.distance.toString()).toStringAsFixed(2)} ${'KM'.tr}", "Distance".tr, "assets/icons/ic_distance_parcel.svg", isDark),
|
||||
_iconTile(controller.cabOrder.value.duration ?? '--', "Duration".tr, "assets/icons/ic_duration.svg", isDark),
|
||||
_iconTile(Constant.amountShow(amount: controller.cabOrder.value.subTotal), "${controller.cabOrder.value.paymentMethod}".tr, "assets/icons/ic_rate_parcel.svg", isDark),
|
||||
],
|
||||
),
|
||||
),
|
||||
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: [
|
||||
Text("Order Summary".tr, style: AppThemeData.boldTextStyle(fontSize: 14, color: AppThemeData.grey500)),
|
||||
const SizedBox(height: 8),
|
||||
|
||||
// Subtotal
|
||||
_summaryTile("Subtotal", Constant.amountShow(amount: controller.subTotal.value.toString()), isDark),
|
||||
|
||||
// Discount
|
||||
_summaryTile("Discount", Constant.amountShow(amount: controller.discount.value.toString()), isDark),
|
||||
|
||||
// Tax List
|
||||
...List.generate(controller.cabOrder.value.taxSetting!.length, (index) {
|
||||
return _summaryTile(
|
||||
"${controller.cabOrder.value.taxSetting![index].title} ${controller.cabOrder.value.taxSetting![index].type == 'fix' ? '' : '(${controller.cabOrder.value.taxSetting![index].tax}%)'}",
|
||||
Constant.amountShow(
|
||||
amount:
|
||||
Constant.getTaxValue(
|
||||
amount:
|
||||
((double.tryParse(controller.cabOrder.value.subTotal.toString()) ?? 0.0) - (double.tryParse(controller.cabOrder.value.discount.toString()) ?? 0.0))
|
||||
.toString(),
|
||||
taxModel: controller.cabOrder.value.taxSetting![index],
|
||||
).toString(),
|
||||
),
|
||||
isDark,
|
||||
);
|
||||
}),
|
||||
|
||||
const Divider(),
|
||||
|
||||
// Total
|
||||
_summaryTile("Order Total", Constant.amountShow(amount: controller.totalAmount.value.toString()), isDark),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
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) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 4),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(title.tr, style: AppThemeData.mediumTextStyle(fontSize: 16, color: isDark ? AppThemeData.greyDark800 : AppThemeData.grey800)),
|
||||
Text(value, style: AppThemeData.semiBoldTextStyle(fontSize: title == "Order Total" ? 18 : 16, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
157
lib/screen_ui/cab_service_screens/cab_review_screen.dart
Normal file
157
lib/screen_ui/cab_service_screens/cab_review_screen.dart
Normal file
@@ -0,0 +1,157 @@
|
||||
import 'package:customer/controllers/cab_review_controller.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
|
||||
import 'package:get/get.dart';
|
||||
import '../../constant/constant.dart';
|
||||
import '../../controllers/theme_controller.dart';
|
||||
import '../../themes/app_them_data.dart';
|
||||
import '../../themes/round_button_fill.dart';
|
||||
import '../../themes/text_field_widget.dart';
|
||||
import '../../utils/network_image_widget.dart';
|
||||
|
||||
class CabReviewScreen extends StatelessWidget {
|
||||
const CabReviewScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final themeController = Get.find<ThemeController>();
|
||||
final isDark = themeController.isDark.value;
|
||||
|
||||
return GetX<CabReviewController>(
|
||||
init: CabReviewController(),
|
||||
builder: (controller) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
centerTitle: true,
|
||||
elevation: 0,
|
||||
backgroundColor: AppThemeData.primary300,
|
||||
leading: GestureDetector(onTap: () => Get.back(), child: Icon(Icons.arrow_back_ios, color: isDark ? Colors.white : Colors.black)),
|
||||
title: Text(controller.ratingModel.value != null ? "Update Review".tr : "Add Review".tr, style: TextStyle(color: isDark ? Colors.white : Colors.black, fontSize: 16)),
|
||||
),
|
||||
body: Obx(
|
||||
() =>
|
||||
controller.isLoading.value
|
||||
? Constant.loader()
|
||||
: Padding(
|
||||
padding: const EdgeInsets.only(top: 20),
|
||||
child: Stack(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 20, right: 20, top: 50, bottom: 20),
|
||||
child: Card(
|
||||
elevation: 2,
|
||||
color: isDark ? AppThemeData.greyDark50 : AppThemeData.grey50,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
|
||||
child: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(top: 65),
|
||||
child: Column(
|
||||
children: [
|
||||
// Driver Name
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: Text(
|
||||
controller.order.value!.driver?.fullName() ?? "",
|
||||
style: TextStyle(color: isDark ? Colors.white : Colors.black87, fontFamily: AppThemeData.medium, fontSize: 18),
|
||||
),
|
||||
),
|
||||
// Car info
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
controller.driverUser.value?.carNumber?.toUpperCase() ?? '',
|
||||
style: TextStyle(color: isDark ? Colors.white : Colors.black87, fontFamily: AppThemeData.medium),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
"${controller.driverUser.value?.carName} ${controller.driverUser.value?.carMakes}",
|
||||
style: TextStyle(color: isDark ? Colors.white : Colors.black38, fontFamily: AppThemeData.medium),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
const Padding(padding: EdgeInsets.symmetric(vertical: 12), child: Divider(color: Colors.grey)),
|
||||
|
||||
// Title
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 16),
|
||||
child: Text('How is your trip?'.tr, style: TextStyle(fontSize: 18, color: isDark ? Colors.white : Colors.black, fontWeight: FontWeight.bold, letterSpacing: 2)),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 8),
|
||||
child: Text(
|
||||
'Your feedback will help us improve \n driving experience better'.tr,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(color: isDark ? Colors.white : Colors.black.withOpacity(0.60), letterSpacing: 0.8),
|
||||
),
|
||||
),
|
||||
|
||||
// Rating
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 20),
|
||||
child: Text('Rate for'.tr, style: TextStyle(fontSize: 16, color: isDark ? Colors.white : Colors.black.withOpacity(0.60), letterSpacing: 0.8)),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 8),
|
||||
child: Text(
|
||||
controller.order.value!.driver?.fullName() ?? "",
|
||||
style: TextStyle(fontSize: 18, color: isDark ? Colors.white : Colors.black, fontWeight: FontWeight.bold, letterSpacing: 2),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
child: RatingBar.builder(
|
||||
initialRating: controller.ratings.value,
|
||||
minRating: 1,
|
||||
direction: Axis.horizontal,
|
||||
allowHalfRating: true,
|
||||
itemCount: 5,
|
||||
itemBuilder: (context, _) => const Icon(Icons.star, color: Colors.amber),
|
||||
unratedColor: isDark ? AppThemeData.greyDark400 : AppThemeData.grey400,
|
||||
onRatingUpdate: (rating) => controller.ratings.value = rating,
|
||||
),
|
||||
),
|
||||
|
||||
// Comment
|
||||
Padding(padding: const EdgeInsets.all(20.0), child: TextFieldWidget(hintText: "Type comment....".tr, controller: controller.comment.value, maxLine: 5)),
|
||||
|
||||
// Submit Button
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(20.0),
|
||||
child: RoundedButtonFill(
|
||||
title: controller.ratingModel.value != null ? "Update Review".tr : "Add Review".tr,
|
||||
color: AppThemeData.primary300,
|
||||
textColor: isDark ? Colors.white : Colors.black,
|
||||
onPress: controller.submitReview,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(60),
|
||||
color: Colors.white,
|
||||
boxShadow: [BoxShadow(color: Colors.grey.withOpacity(0.15), blurRadius: 8, spreadRadius: 6)],
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(60),
|
||||
child: NetworkImageWidget(imageUrl: controller.order.value?.driver?.profilePictureURL ?? '', fit: BoxFit.cover, height: 110, width: 110),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
65
lib/screen_ui/cab_service_screens/complain_screen.dart
Normal file
65
lib/screen_ui/cab_service_screens/complain_screen.dart
Normal file
@@ -0,0 +1,65 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import '../../controllers/complain_controller.dart';
|
||||
import '../../controllers/theme_controller.dart';
|
||||
import '../../themes/app_them_data.dart';
|
||||
import '../../themes/round_button_fill.dart';
|
||||
import '../../constant/constant.dart';
|
||||
import '../../themes/text_field_widget.dart';
|
||||
|
||||
class ComplainScreen extends StatelessWidget {
|
||||
const ComplainScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final themeController = Get.find<ThemeController>();
|
||||
final isDark = themeController.isDark.value;
|
||||
|
||||
return GetBuilder<ComplainController>(
|
||||
init: ComplainController(),
|
||||
builder: (controller) {
|
||||
return Obx(
|
||||
() => Scaffold(
|
||||
appBar: AppBar(
|
||||
automaticallyImplyLeading: false,
|
||||
backgroundColor: AppThemeData.taxiBooking300,
|
||||
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: const Center(child: Icon(Icons.arrow_back_ios, color: AppThemeData.grey900, size: 20)),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Text("Complain".tr, style: AppThemeData.boldTextStyle(fontSize: 18, color: AppThemeData.grey900)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
body:
|
||||
controller.isLoading.value
|
||||
? Constant.loader()
|
||||
: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
children: [
|
||||
Obx(() => TextFieldWidget(title: "Title".tr, hintText: "Title".tr, controller: controller.title.value)),
|
||||
const SizedBox(height: 10),
|
||||
Obx(() => TextFieldWidget(title: "Complain".tr, hintText: 'Type Description....'.tr, controller: controller.comment.value, maxLine: 8)),
|
||||
const SizedBox(height: 20),
|
||||
RoundedButtonFill(title: "Save".tr, color: AppThemeData.primary300, textColor: AppThemeData.grey50, onPress: () => controller.submitComplain()),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
481
lib/screen_ui/cab_service_screens/my_cab_booking_screen.dart
Normal file
481
lib/screen_ui/cab_service_screens/my_cab_booking_screen.dart
Normal file
@@ -0,0 +1,481 @@
|
||||
import 'package:customer/models/cab_order_model.dart';
|
||||
import 'package:customer/payment/createRazorPayOrderModel.dart';
|
||||
import 'package:customer/payment/rozorpayConroller.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/themes/round_button_fill.dart';
|
||||
import 'package:customer/themes/show_toast_dialog.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import '../../constant/constant.dart';
|
||||
import '../../controllers/my_cab_booking_controller.dart';
|
||||
import '../../controllers/theme_controller.dart';
|
||||
import '../../themes/app_them_data.dart';
|
||||
import 'package:dotted_border/dotted_border.dart';
|
||||
|
||||
import 'cab_order_details.dart';
|
||||
|
||||
class MyCabBookingScreen extends StatelessWidget {
|
||||
const MyCabBookingScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final themeController = Get.find<ThemeController>();
|
||||
final isDark = themeController.isDark.value;
|
||||
|
||||
return GetX(
|
||||
init: MyCabBookingController(),
|
||||
builder: (controller) {
|
||||
return DefaultTabController(
|
||||
// length: controller.tabTitles.length,
|
||||
// initialIndex: controller.tabTitles.indexOf(controller.selectedTab.value),
|
||||
length: controller.tabKeys.length,
|
||||
initialIndex: controller.tabKeys.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("Ride History".tr, style: AppThemeData.boldTextStyle(fontSize: 18, color: AppThemeData.grey900))]),
|
||||
),
|
||||
bottom: PreferredSize(
|
||||
preferredSize: const Size.fromHeight(48),
|
||||
child: TabBar(
|
||||
isScrollable: false,
|
||||
onTap: (index) {
|
||||
controller.selectTab(controller.tabKeys[index]);
|
||||
},
|
||||
indicatorColor: AppThemeData.taxiBooking500,
|
||||
labelColor: AppThemeData.taxiBooking500,
|
||||
unselectedLabelColor: AppThemeData.taxiBooking500,
|
||||
labelStyle: AppThemeData.boldTextStyle(fontSize: 14),
|
||||
unselectedLabelStyle: AppThemeData.mediumTextStyle(fontSize: 14),
|
||||
tabs:
|
||||
controller.tabKeys
|
||||
.map(
|
||||
(key) => Tab(
|
||||
child: SizedBox.expand(
|
||||
child: Center(
|
||||
child: Text(
|
||||
controller.getLocalizedTabTitle(key),
|
||||
textAlign: TextAlign.center,
|
||||
overflow: TextOverflow.visible, // 👈 show full text
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
.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.tabKeys.map((title) {
|
||||
final orders = controller.getOrdersForTab(title);
|
||||
|
||||
if (orders.isEmpty) {
|
||||
return Center(child: Text("No order 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) {
|
||||
CabOrderModel order = orders[index];
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
Get.to(() => CabOrderDetails(), arguments: {"cabOrderModel": order});
|
||||
},
|
||||
child: Container(
|
||||
margin: const EdgeInsets.only(bottom: 16),
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: isDark ? AppThemeData.greyDark50 : AppThemeData.grey50,
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
border: Border.all(color: isDark ? AppThemeData.greyDark200 : AppThemeData.grey200),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"${'Booking Date:'.tr} ${controller.formatDate(order.scheduleDateTime!)}".tr,
|
||||
textAlign: TextAlign.start,
|
||||
style: TextStyle(fontFamily: AppThemeData.semiBold, fontSize: 18, color: isDark ? AppThemeData.grey50 : AppThemeData.grey900),
|
||||
),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
Icon(Icons.stop_circle_outlined, color: Colors.green),
|
||||
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: 55),
|
||||
),
|
||||
Icon(Icons.radio_button_checked, color: Colors.red),
|
||||
],
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
// Source Location Name
|
||||
Expanded(
|
||||
child: Text(
|
||||
order.sourceLocationName.toString(),
|
||||
style: AppThemeData.semiBoldTextStyle(fontSize: 16, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
border: Border.all(color: AppThemeData.warning300, width: 1),
|
||||
color: AppThemeData.warning50,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12),
|
||||
child: Text(
|
||||
order.status.toString(),
|
||||
style: AppThemeData.boldTextStyle(fontSize: 14, color: AppThemeData.warning500),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 15),
|
||||
DottedBorder(
|
||||
options: CustomPathDottedBorderOptions(
|
||||
color: Colors.grey.shade400,
|
||||
strokeWidth: 2,
|
||||
dashPattern: [4, 4],
|
||||
customPath:
|
||||
(size) =>
|
||||
Path()
|
||||
..moveTo(0, size.height / 2) // start from left center
|
||||
..lineTo(size.width, size.height / 2), // draw to right center
|
||||
),
|
||||
child: const SizedBox(width: 295, height: 3),
|
||||
),
|
||||
SizedBox(height: 15),
|
||||
Text(
|
||||
order.destinationLocationName.toString(),
|
||||
style: AppThemeData.semiBoldTextStyle(fontSize: 16, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (Constant.isEnableOTPTripStart == true)
|
||||
Row(
|
||||
//mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text("Otp :".tr, style: AppThemeData.mediumTextStyle(fontSize: 16, color: isDark ? AppThemeData.greyDark800 : AppThemeData.grey800)),
|
||||
SizedBox(width: 5),
|
||||
Text(order.otpCode ?? '', style: AppThemeData.semiBoldTextStyle(fontSize: 16, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900)),
|
||||
],
|
||||
),
|
||||
if (order.status == Constant.orderInTransit && order.paymentStatus == false) SizedBox(height: 14),
|
||||
order.status == Constant.orderInTransit && order.paymentStatus == false
|
||||
? RoundedButtonFill(
|
||||
title: "Pay Now".tr,
|
||||
onPress: () async {
|
||||
controller.selectedPaymentMethod.value = order.paymentMethod.toString();
|
||||
controller.calculateTotalAmount(order);
|
||||
Get.bottomSheet(paymentBottomSheet(context, controller, isDark), isScrollControlled: true, backgroundColor: Colors.transparent);
|
||||
},
|
||||
color: AppThemeData.primary300,
|
||||
textColor: AppThemeData.grey900,
|
||||
)
|
||||
: SizedBox(),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget paymentBottomSheet(BuildContext context, MyCabBookingController controller, bool isDark) {
|
||||
return DraggableScrollableSheet(
|
||||
initialChildSize: 0.70,
|
||||
// Start height
|
||||
minChildSize: 0.30,
|
||||
// Minimum height
|
||||
maxChildSize: 0.8,
|
||||
// Maximum height
|
||||
expand: false,
|
||||
//Prevents full-screen takeover
|
||||
builder: (context, scrollController) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 20),
|
||||
decoration: BoxDecoration(color: isDark ? AppThemeData.grey500 : Colors.white, borderRadius: BorderRadius.vertical(top: Radius.circular(24))),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text("Select Payment Method".tr, style: AppThemeData.mediumTextStyle(fontSize: 18, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900)),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Get.back();
|
||||
},
|
||||
child: Icon(Icons.close),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Expanded(
|
||||
child: ListView(
|
||||
padding: EdgeInsets.zero,
|
||||
controller: scrollController,
|
||||
children: [
|
||||
Text("Preferred Payment".tr, textAlign: TextAlign.start, style: AppThemeData.boldTextStyle(fontSize: 15, color: isDark ? AppThemeData.greyDark500 : AppThemeData.grey500)),
|
||||
const SizedBox(height: 10),
|
||||
if (controller.walletSettingModel.value.isEnabled == true || controller.cashOnDeliverySettingModel.value.isEnabled == true)
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
color: isDark ? AppThemeData.greyDark50 : AppThemeData.grey50,
|
||||
border: Border.all(color: isDark ? AppThemeData.greyDark200 : AppThemeData.grey200),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Visibility(
|
||||
visible: controller.walletSettingModel.value.isEnabled == true,
|
||||
child: cardDecoration(controller, PaymentGateway.wallet, isDark, "assets/images/ic_wallet.png"),
|
||||
),
|
||||
Visibility(
|
||||
visible: controller.cashOnDeliverySettingModel.value.isEnabled == true,
|
||||
child: cardDecoration(controller, PaymentGateway.cod, isDark, "assets/images/ic_cash.png"),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
if (controller.walletSettingModel.value.isEnabled == true || controller.cashOnDeliverySettingModel.value.isEnabled == true)
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
"Other Payment Options".tr,
|
||||
textAlign: TextAlign.start,
|
||||
style: AppThemeData.boldTextStyle(fontSize: 15, color: isDark ? AppThemeData.greyDark500 : AppThemeData.grey500),
|
||||
),
|
||||
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),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Visibility(visible: controller.stripeModel.value.isEnabled == true, child: cardDecoration(controller, PaymentGateway.stripe, isDark, "assets/images/stripe.png")),
|
||||
Visibility(visible: controller.payPalModel.value.isEnabled == true, child: cardDecoration(controller, PaymentGateway.paypal, isDark, "assets/images/paypal.png")),
|
||||
Visibility(visible: controller.payStackModel.value.isEnable == true, child: cardDecoration(controller, PaymentGateway.payStack, isDark, "assets/images/paystack.png")),
|
||||
Visibility(
|
||||
visible: controller.mercadoPagoModel.value.isEnabled == true,
|
||||
child: cardDecoration(controller, PaymentGateway.mercadoPago, isDark, "assets/images/mercado-pago.png"),
|
||||
),
|
||||
Visibility(
|
||||
visible: controller.flutterWaveModel.value.isEnable == true,
|
||||
child: cardDecoration(controller, PaymentGateway.flutterWave, isDark, "assets/images/flutterwave_logo.png"),
|
||||
),
|
||||
Visibility(visible: controller.payFastModel.value.isEnable == true, child: cardDecoration(controller, PaymentGateway.payFast, isDark, "assets/images/payfast.png")),
|
||||
Visibility(visible: controller.razorPayModel.value.isEnabled == true, child: cardDecoration(controller, PaymentGateway.razorpay, isDark, "assets/images/razorpay.png")),
|
||||
Visibility(visible: controller.midTransModel.value.enable == true, child: cardDecoration(controller, PaymentGateway.midTrans, isDark, "assets/images/midtrans.png")),
|
||||
Visibility(
|
||||
visible: controller.orangeMoneyModel.value.enable == true,
|
||||
child: cardDecoration(controller, PaymentGateway.orangeMoney, isDark, "assets/images/orange_money.png"),
|
||||
),
|
||||
Visibility(visible: controller.xenditModel.value.enable == true, child: cardDecoration(controller, PaymentGateway.xendit, isDark, "assets/images/xendit.png")),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
],
|
||||
),
|
||||
),
|
||||
RoundedButtonFill(
|
||||
title: "Continue".tr,
|
||||
color: AppThemeData.primary300,
|
||||
textColor: AppThemeData.grey900,
|
||||
onPress: () async {
|
||||
if (controller.selectedPaymentMethod.value.isEmpty) {
|
||||
ShowToastDialog.showToast("Please select a payment method".tr);
|
||||
} else {
|
||||
if (controller.selectedPaymentMethod.value == PaymentGateway.stripe.name) {
|
||||
controller.stripeMakePayment(amount: controller.totalAmount.value.toString());
|
||||
} else if (controller.selectedPaymentMethod.value == PaymentGateway.paypal.name) {
|
||||
controller.paypalPaymentSheet(controller.totalAmount.value.toString(), context);
|
||||
} else if (controller.selectedPaymentMethod.value == PaymentGateway.payStack.name) {
|
||||
controller.payStackPayment(controller.totalAmount.value.toString());
|
||||
} else if (controller.selectedPaymentMethod.value == PaymentGateway.mercadoPago.name) {
|
||||
controller.mercadoPagoMakePayment(context: context, amount: controller.totalAmount.value.toString());
|
||||
} else if (controller.selectedPaymentMethod.value == PaymentGateway.flutterWave.name) {
|
||||
controller.flutterWaveInitiatePayment(context: context, amount: controller.totalAmount.value.toString());
|
||||
} else if (controller.selectedPaymentMethod.value == PaymentGateway.payFast.name) {
|
||||
controller.payFastPayment(context: context, amount: controller.totalAmount.value.toString());
|
||||
} else if (controller.selectedPaymentMethod.value == PaymentGateway.cod.name) {
|
||||
controller.completeOrder();
|
||||
} else if (controller.selectedPaymentMethod.value == PaymentGateway.wallet.name) {
|
||||
if (Constant.userModel!.walletAmount == null || Constant.userModel!.walletAmount! < controller.totalAmount.value) {
|
||||
ShowToastDialog.showToast("You do not have sufficient wallet balance".tr);
|
||||
} else {
|
||||
controller.completeOrder();
|
||||
}
|
||||
} else if (controller.selectedPaymentMethod.value == PaymentGateway.midTrans.name) {
|
||||
controller.midtransMakePayment(context: context, amount: controller.totalAmount.value.toString());
|
||||
} else if (controller.selectedPaymentMethod.value == PaymentGateway.orangeMoney.name) {
|
||||
controller.orangeMakePayment(context: context, amount: controller.totalAmount.value.toString());
|
||||
} else if (controller.selectedPaymentMethod.value == PaymentGateway.xendit.name) {
|
||||
controller.xenditPayment(context, controller.totalAmount.value.toString());
|
||||
} else if (controller.selectedPaymentMethod.value == PaymentGateway.razorpay.name) {
|
||||
RazorPayController().createOrderRazorPay(amount: double.parse(controller.totalAmount.value.toString()), razorpayModel: controller.razorPayModel.value).then((value) {
|
||||
if (value == null) {
|
||||
Get.back();
|
||||
ShowToastDialog.showToast("Something went wrong, please contact admin.".tr);
|
||||
} else {
|
||||
CreateRazorPayOrderModel result = value;
|
||||
controller.openCheckout(amount: controller.totalAmount.value.toString(), orderId: result.id);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
ShowToastDialog.showToast("Please select payment method".tr);
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Obx cardDecoration(MyCabBookingController 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();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user