Initial commit
This commit is contained in:
807
lib/app/owner_screen/driver_create_screen.dart
Normal file
807
lib/app/owner_screen/driver_create_screen.dart
Normal file
@@ -0,0 +1,807 @@
|
||||
import 'package:country_code_picker/country_code_picker.dart';
|
||||
import 'package:driver/constant/constant.dart';
|
||||
import 'package:driver/constant/show_toast_dialog.dart';
|
||||
import 'package:driver/controllers/driver_create_controller.dart';
|
||||
import 'package:driver/models/car_makes.dart';
|
||||
import 'package:driver/models/section_model.dart';
|
||||
import 'package:driver/models/vehicle_type.dart';
|
||||
import 'package:driver/models/zone_model.dart';
|
||||
import 'package:driver/themes/app_them_data.dart';
|
||||
import 'package:driver/themes/text_field_widget.dart';
|
||||
import 'package:driver/themes/theme_controller.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import '../../models/car_model.dart' show CarModel;
|
||||
import '../../themes/responsive.dart' show Responsive;
|
||||
|
||||
class DriverCreateScreen extends StatelessWidget {
|
||||
const DriverCreateScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final themeController = Get.find<ThemeController>();
|
||||
final isDark = themeController.isDark.value;
|
||||
return GetX(
|
||||
init: DriverCreateController(),
|
||||
builder: (controller) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(controller.driverModel.value.id != null && controller.driverModel.value.id!.isNotEmpty
|
||||
? 'Update Driver'.tr
|
||||
: 'Create Driver'.tr),
|
||||
),
|
||||
body: controller.isLoading.value
|
||||
? Constant.loader()
|
||||
: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Service".tr,
|
||||
style: TextStyle(
|
||||
fontFamily: AppThemeData.semiBold,
|
||||
fontSize: 14,
|
||||
color: isDark ? AppThemeData.grey100 : AppThemeData.grey800),
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
DropdownButtonFormField<String>(
|
||||
hint: Text(
|
||||
'Service Type'.tr,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: isDark ? AppThemeData.grey700 : AppThemeData.grey700,
|
||||
fontFamily: AppThemeData.regular),
|
||||
),
|
||||
icon: const Icon(Icons.keyboard_arrow_down),
|
||||
dropdownColor: isDark ? AppThemeData.grey900 : AppThemeData.grey50,
|
||||
decoration: InputDecoration(
|
||||
errorStyle: const TextStyle(color: Colors.red),
|
||||
isDense: true,
|
||||
filled: true,
|
||||
fillColor: isDark ? AppThemeData.grey900 : AppThemeData.grey50,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: BorderSide(color: isDark ? AppThemeData.primary300 : AppThemeData.primary300),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: BorderSide(color: isDark ? AppThemeData.greyDark400 : AppThemeData.grey400),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide:
|
||||
BorderSide(color: isDark ? AppThemeData.greyDark400 : AppThemeData.grey400, width: 1.2),
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: const BorderSide(color: Colors.red),
|
||||
),
|
||||
disabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: BorderSide(color: isDark ? AppThemeData.greyDark400 : AppThemeData.grey400),
|
||||
),
|
||||
),
|
||||
initialValue: controller.selectedService.value.isEmpty ? null : controller.selectedService.value,
|
||||
onChanged: (value) {
|
||||
controller.selectedService.value = value!;
|
||||
if (value != "Delivery Service") {
|
||||
controller.getSection();
|
||||
}
|
||||
controller.update();
|
||||
},
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: isDark ? AppThemeData.grey50 : AppThemeData.grey900,
|
||||
fontFamily: AppThemeData.medium),
|
||||
items: controller.service.map((item) {
|
||||
return DropdownMenuItem<String>(value: item, child: Text(item.toString()));
|
||||
}).toList(),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
],
|
||||
),
|
||||
controller.selectedService.value == "Cab Service" ||
|
||||
controller.selectedService.value == "Rental Service" ||
|
||||
controller.selectedService.value == "Parcel Service"
|
||||
? Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Select section".tr,
|
||||
style: TextStyle(
|
||||
fontFamily: AppThemeData.semiBold,
|
||||
fontSize: 14,
|
||||
color: isDark ? AppThemeData.grey100 : AppThemeData.grey800),
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
DropdownButtonFormField<SectionModel>(
|
||||
hint: Text(
|
||||
'Service Type'.tr,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: isDark ? AppThemeData.grey700 : AppThemeData.grey700,
|
||||
fontFamily: AppThemeData.regular),
|
||||
),
|
||||
icon: const Icon(Icons.keyboard_arrow_down),
|
||||
dropdownColor: isDark ? AppThemeData.grey900 : AppThemeData.grey50,
|
||||
decoration: InputDecoration(
|
||||
errorStyle: const TextStyle(color: Colors.red),
|
||||
isDense: true,
|
||||
filled: true,
|
||||
fillColor: isDark ? AppThemeData.grey900 : AppThemeData.grey50,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: BorderSide(color: isDark ? AppThemeData.primary300 : AppThemeData.primary300),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: BorderSide(color: isDark ? AppThemeData.greyDark400 : AppThemeData.grey400),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide:
|
||||
BorderSide(color: isDark ? AppThemeData.greyDark400 : AppThemeData.grey400, width: 1.2),
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: const BorderSide(color: Colors.red),
|
||||
),
|
||||
disabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: BorderSide(color: isDark ? AppThemeData.greyDark400 : AppThemeData.grey400),
|
||||
),
|
||||
),
|
||||
initialValue:
|
||||
controller.selectedSection.value.id == null ? null : controller.selectedSection.value,
|
||||
onChanged: (value) {
|
||||
controller.selectedSection.value = value!;
|
||||
controller.getVehicleType();
|
||||
controller.update();
|
||||
},
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: isDark ? AppThemeData.grey50 : AppThemeData.grey900,
|
||||
fontFamily: AppThemeData.medium),
|
||||
items: controller.sectionList.map((item) {
|
||||
return DropdownMenuItem<SectionModel>(value: item, child: Text(item.name.toString()));
|
||||
}).toList(),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
controller.selectedService.value == "Cab Service" ||
|
||||
controller.selectedService.value == "Rental Service"
|
||||
? Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Select Vehicle Type".tr,
|
||||
style: TextStyle(
|
||||
fontFamily: AppThemeData.semiBold,
|
||||
fontSize: 14,
|
||||
color: isDark ? AppThemeData.grey100 : AppThemeData.grey800),
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
DropdownButtonFormField<VehicleType>(
|
||||
hint: Text(
|
||||
'Vehicle Type'.tr,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: isDark ? AppThemeData.grey700 : AppThemeData.grey700,
|
||||
fontFamily: AppThemeData.regular),
|
||||
),
|
||||
icon: const Icon(Icons.keyboard_arrow_down),
|
||||
dropdownColor: isDark ? AppThemeData.grey900 : AppThemeData.grey50,
|
||||
decoration: InputDecoration(
|
||||
errorStyle: const TextStyle(color: Colors.red),
|
||||
isDense: true,
|
||||
filled: true,
|
||||
fillColor: isDark ? AppThemeData.grey900 : AppThemeData.grey50,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide:
|
||||
BorderSide(color: isDark ? AppThemeData.primary300 : AppThemeData.primary300),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide:
|
||||
BorderSide(color: isDark ? AppThemeData.greyDark400 : AppThemeData.grey400),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: BorderSide(
|
||||
color: isDark ? AppThemeData.greyDark400 : AppThemeData.grey400, width: 1.2),
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: const BorderSide(color: Colors.red),
|
||||
),
|
||||
disabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide:
|
||||
BorderSide(color: isDark ? AppThemeData.greyDark400 : AppThemeData.grey400),
|
||||
),
|
||||
),
|
||||
initialValue: controller.selectedVehicleType.value.id == null
|
||||
? null
|
||||
: controller.selectedVehicleType.value,
|
||||
onChanged: (value) {
|
||||
controller.selectedVehicleType.value = value!;
|
||||
controller.update();
|
||||
},
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: isDark ? AppThemeData.grey50 : AppThemeData.grey900,
|
||||
fontFamily: AppThemeData.medium),
|
||||
items: controller.cabVehicleType.map((item) {
|
||||
return DropdownMenuItem<VehicleType>(
|
||||
value: item, child: Text(item.name.toString()));
|
||||
}).toList(),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
"Select Car Brand".tr,
|
||||
style: TextStyle(
|
||||
fontFamily: AppThemeData.semiBold,
|
||||
fontSize: 14,
|
||||
color: isDark ? AppThemeData.grey100 : AppThemeData.grey800),
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
DropdownButtonFormField<CarMakes>(
|
||||
hint: Text(
|
||||
'Car Brand'.tr,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: isDark ? AppThemeData.grey700 : AppThemeData.grey700,
|
||||
fontFamily: AppThemeData.regular),
|
||||
),
|
||||
icon: const Icon(Icons.keyboard_arrow_down),
|
||||
dropdownColor: isDark ? AppThemeData.grey900 : AppThemeData.grey50,
|
||||
decoration: InputDecoration(
|
||||
errorStyle: const TextStyle(color: Colors.red),
|
||||
isDense: true,
|
||||
filled: true,
|
||||
fillColor: isDark ? AppThemeData.grey900 : AppThemeData.grey50,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide:
|
||||
BorderSide(color: isDark ? AppThemeData.primary300 : AppThemeData.primary300),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide:
|
||||
BorderSide(color: isDark ? AppThemeData.greyDark400 : AppThemeData.grey400),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: BorderSide(
|
||||
color: isDark ? AppThemeData.greyDark400 : AppThemeData.grey400, width: 1.2),
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: const BorderSide(color: Colors.red),
|
||||
),
|
||||
disabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide:
|
||||
BorderSide(color: isDark ? AppThemeData.greyDark400 : AppThemeData.grey400),
|
||||
),
|
||||
),
|
||||
initialValue: controller.selectedCarMakes.value.id == null
|
||||
? null
|
||||
: controller.selectedCarMakes.value,
|
||||
onChanged: (value) {
|
||||
controller.selectedCarMakes.value = value!;
|
||||
controller.getCarModel();
|
||||
controller.update();
|
||||
},
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: isDark ? AppThemeData.grey50 : AppThemeData.grey900,
|
||||
fontFamily: AppThemeData.medium),
|
||||
items: controller.carMakesList.map((item) {
|
||||
return DropdownMenuItem<CarMakes>(value: item, child: Text(item.name.toString()));
|
||||
}).toList(),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
"Select car model".tr,
|
||||
style: TextStyle(
|
||||
fontFamily: AppThemeData.semiBold,
|
||||
fontSize: 14,
|
||||
color: isDark ? AppThemeData.grey100 : AppThemeData.grey800),
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
DropdownButtonFormField<CarModel>(
|
||||
hint: Text(
|
||||
'Car model'.tr,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: isDark ? AppThemeData.grey700 : AppThemeData.grey700,
|
||||
fontFamily: AppThemeData.regular),
|
||||
),
|
||||
icon: const Icon(Icons.keyboard_arrow_down),
|
||||
dropdownColor: isDark ? AppThemeData.grey900 : AppThemeData.grey50,
|
||||
decoration: InputDecoration(
|
||||
errorStyle: const TextStyle(color: Colors.red),
|
||||
isDense: true,
|
||||
filled: true,
|
||||
fillColor: isDark ? AppThemeData.grey900 : AppThemeData.grey50,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide:
|
||||
BorderSide(color: isDark ? AppThemeData.primary300 : AppThemeData.primary300),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide:
|
||||
BorderSide(color: isDark ? AppThemeData.greyDark400 : AppThemeData.grey400),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: BorderSide(
|
||||
color: isDark ? AppThemeData.greyDark400 : AppThemeData.grey400, width: 1.2),
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: const BorderSide(color: Colors.red),
|
||||
),
|
||||
disabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide:
|
||||
BorderSide(color: isDark ? AppThemeData.greyDark400 : AppThemeData.grey400),
|
||||
),
|
||||
),
|
||||
initialValue: controller.selectedCarModel.value.id == null
|
||||
? null
|
||||
: controller.selectedCarModel.value,
|
||||
onChanged: (value) {
|
||||
controller.selectedCarModel.value = value!;
|
||||
controller.update();
|
||||
},
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: isDark ? AppThemeData.grey50 : AppThemeData.grey900,
|
||||
fontFamily: AppThemeData.medium),
|
||||
items: controller.carModelList.map((item) {
|
||||
return DropdownMenuItem<CarModel>(value: item, child: Text(item.name.toString()));
|
||||
}).toList(),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
TextFieldWidget(
|
||||
title: 'Car Plat Number'.tr,
|
||||
controller: controller.carPlatNumberEditingController.value,
|
||||
hintText: 'Enter Car Plat Number'.tr,
|
||||
textInputAction: TextInputAction.next,
|
||||
),
|
||||
],
|
||||
)
|
||||
: SizedBox()
|
||||
],
|
||||
)
|
||||
: SizedBox(),
|
||||
controller.selectedService.value == "Cab Service"
|
||||
? Padding(
|
||||
padding: const EdgeInsets.only(top: 10, bottom: 10),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Select Ride Type".tr,
|
||||
style: TextStyle(
|
||||
fontFamily: AppThemeData.semiBold,
|
||||
fontSize: 14,
|
||||
color: isDark ? AppThemeData.grey100 : AppThemeData.grey800,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
Obx(
|
||||
() => Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
Expanded(
|
||||
child: RadioListTile<String>(
|
||||
dense: true,
|
||||
visualDensity: VisualDensity(horizontal: -4, vertical: -4),
|
||||
contentPadding: EdgeInsets.zero,
|
||||
title: Text('Ride'.tr,
|
||||
style: TextStyle(
|
||||
fontSize: 14, color: isDark ? AppThemeData.grey100 : AppThemeData.grey800)),
|
||||
value: 'ride',
|
||||
activeColor: AppThemeData.primary300,
|
||||
groupValue: controller.selectedValue.value,
|
||||
onChanged: (value) {
|
||||
controller.selectedValue.value = value!;
|
||||
},
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: RadioListTile<String>(
|
||||
dense: true,
|
||||
visualDensity: VisualDensity(horizontal: -4, vertical: -4),
|
||||
contentPadding: EdgeInsets.zero,
|
||||
activeColor: AppThemeData.primary300,
|
||||
title: Text('Intercity'.tr,
|
||||
style: TextStyle(
|
||||
fontSize: 14, color: isDark ? AppThemeData.grey100 : AppThemeData.grey800)),
|
||||
value: 'intercity',
|
||||
groupValue: controller.selectedValue.value,
|
||||
onChanged: (value) {
|
||||
controller.selectedValue.value = value!;
|
||||
},
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: RadioListTile<String>(
|
||||
dense: true,
|
||||
visualDensity: VisualDensity(horizontal: -4, vertical: -4),
|
||||
contentPadding: EdgeInsets.zero,
|
||||
title: Text('Both'.tr,
|
||||
style: TextStyle(
|
||||
fontSize: 14, color: isDark ? AppThemeData.grey100 : AppThemeData.grey800)),
|
||||
value: 'both',
|
||||
activeColor: AppThemeData.primary300,
|
||||
groupValue: controller.selectedValue.value,
|
||||
onChanged: (value) {
|
||||
controller.selectedValue.value = value!;
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
: SizedBox(),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("Zone".tr,
|
||||
style: TextStyle(
|
||||
fontFamily: AppThemeData.semiBold,
|
||||
fontSize: 14,
|
||||
color: isDark ? AppThemeData.grey100 : AppThemeData.grey800)),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
DropdownButtonFormField<ZoneModel>(
|
||||
hint: Text(
|
||||
'Select zone'.tr,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: isDark ? AppThemeData.grey700 : AppThemeData.grey700,
|
||||
fontFamily: AppThemeData.regular,
|
||||
),
|
||||
),
|
||||
dropdownColor: isDark ? AppThemeData.grey900 : AppThemeData.grey50,
|
||||
decoration: InputDecoration(
|
||||
errorStyle: const TextStyle(color: Colors.red),
|
||||
isDense: true,
|
||||
filled: true,
|
||||
fillColor: isDark ? AppThemeData.grey900 : AppThemeData.grey50,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide:
|
||||
BorderSide(color: isDark ? AppThemeData.greyDark400 : AppThemeData.grey400, width: 1.2),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide:
|
||||
BorderSide(color: isDark ? AppThemeData.greyDark400 : AppThemeData.grey400, width: 1.2),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide:
|
||||
BorderSide(color: isDark ? AppThemeData.greyDark400 : AppThemeData.grey400, width: 1.2),
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: const BorderSide(color: Colors.red),
|
||||
),
|
||||
disabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide:
|
||||
BorderSide(color: isDark ? AppThemeData.greyDark400 : AppThemeData.grey400, width: 1.2),
|
||||
),
|
||||
),
|
||||
initialValue: controller.selectedZone.value.id == null ? null : controller.selectedZone.value,
|
||||
onChanged: (value) {
|
||||
controller.selectedZone.value = value!;
|
||||
controller.update();
|
||||
},
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: isDark ? AppThemeData.grey50 : AppThemeData.grey900,
|
||||
fontFamily: AppThemeData.medium),
|
||||
items: controller.zoneList.map((item) {
|
||||
return DropdownMenuItem<ZoneModel>(
|
||||
value: item,
|
||||
child: Text(item.name.toString()),
|
||||
);
|
||||
}).toList()),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: TextFieldWidget(
|
||||
title: 'First Name'.tr,
|
||||
controller: controller.firstNameEditingController.value,
|
||||
hintText: 'Enter First Name'.tr,
|
||||
prefix: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: SvgPicture.asset(
|
||||
"assets/icons/ic_user.svg",
|
||||
colorFilter: ColorFilter.mode(
|
||||
isDark ? AppThemeData.grey300 : AppThemeData.grey600,
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Expanded(
|
||||
child: TextFieldWidget(
|
||||
title: 'Last Name'.tr,
|
||||
controller: controller.lastNameEditingController.value,
|
||||
hintText: 'Enter Last Name'.tr,
|
||||
prefix: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: SvgPicture.asset(
|
||||
"assets/icons/ic_user.svg",
|
||||
colorFilter: ColorFilter.mode(
|
||||
isDark ? AppThemeData.grey300 : AppThemeData.grey600,
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
TextFieldWidget(
|
||||
title: 'Email Address'.tr,
|
||||
textInputType: TextInputType.emailAddress,
|
||||
controller: controller.emailEditingController.value,
|
||||
hintText: 'Enter Email Address'.tr,
|
||||
enable:
|
||||
controller.driverModel.value.id != null && controller.driverModel.value.id!.isNotEmpty ? false : true,
|
||||
prefix: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: SvgPicture.asset(
|
||||
"assets/icons/ic_mail.svg",
|
||||
colorFilter: ColorFilter.mode(
|
||||
isDark ? AppThemeData.grey300 : AppThemeData.grey600,
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
TextFieldWidget(
|
||||
title: 'Phone Number'.tr,
|
||||
controller: controller.phoneNUmberEditingController.value,
|
||||
hintText: 'Enter Phone Number'.tr,
|
||||
textInputType: const TextInputType.numberWithOptions(signed: true, decimal: true),
|
||||
textInputAction: TextInputAction.done,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp('[0-9]')),
|
||||
],
|
||||
prefix: CountryCodePicker(
|
||||
onChanged: (value) {
|
||||
controller.countryCodeEditingController.value.text = value.dialCode ?? Constant.defaultCountryCode;
|
||||
},
|
||||
dialogTextStyle: TextStyle(
|
||||
color: isDark ? AppThemeData.grey50 : AppThemeData.grey900,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontFamily: AppThemeData.medium),
|
||||
dialogBackgroundColor: isDark ? AppThemeData.grey800 : AppThemeData.grey100,
|
||||
initialSelection: controller.countryCodeEditingController.value.text,
|
||||
comparator: (a, b) => b.name!.compareTo(a.name.toString()),
|
||||
textStyle: TextStyle(
|
||||
fontSize: 14,
|
||||
color: isDark ? AppThemeData.grey50 : AppThemeData.grey900,
|
||||
fontFamily: AppThemeData.medium),
|
||||
searchDecoration: InputDecoration(iconColor: isDark ? AppThemeData.grey50 : AppThemeData.grey900),
|
||||
searchStyle: TextStyle(
|
||||
color: isDark ? AppThemeData.grey50 : AppThemeData.grey900,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontFamily: AppThemeData.medium),
|
||||
),
|
||||
),
|
||||
controller.driverModel.value.id != null && controller.driverModel.value.id!.isNotEmpty
|
||||
? SizedBox()
|
||||
: Column(
|
||||
children: [
|
||||
TextFieldWidget(
|
||||
title: 'Password'.tr,
|
||||
controller: controller.passwordEditingController.value,
|
||||
hintText: 'Enter Password'.tr,
|
||||
obscureText: controller.passwordVisible.value,
|
||||
prefix: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: SvgPicture.asset(
|
||||
"assets/icons/ic_lock.svg",
|
||||
colorFilter: ColorFilter.mode(
|
||||
isDark ? AppThemeData.grey300 : AppThemeData.grey600,
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
),
|
||||
),
|
||||
suffix: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
controller.passwordVisible.value = !controller.passwordVisible.value;
|
||||
},
|
||||
child: controller.passwordVisible.value
|
||||
? SvgPicture.asset(
|
||||
"assets/icons/ic_password_show.svg",
|
||||
colorFilter: ColorFilter.mode(
|
||||
isDark ? AppThemeData.grey300 : AppThemeData.grey600,
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
)
|
||||
: SvgPicture.asset(
|
||||
"assets/icons/ic_password_close.svg",
|
||||
colorFilter: ColorFilter.mode(
|
||||
isDark ? AppThemeData.grey300 : AppThemeData.grey600,
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
)),
|
||||
),
|
||||
),
|
||||
TextFieldWidget(
|
||||
title: 'Confirm Password'.tr,
|
||||
controller: controller.conformPasswordEditingController.value,
|
||||
hintText: 'Enter Confirm Password'.tr,
|
||||
obscureText: controller.conformPasswordVisible.value,
|
||||
prefix: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: SvgPicture.asset(
|
||||
"assets/icons/ic_lock.svg",
|
||||
colorFilter: ColorFilter.mode(
|
||||
isDark ? AppThemeData.grey300 : AppThemeData.grey600,
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
),
|
||||
),
|
||||
suffix: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
controller.conformPasswordVisible.value = !controller.conformPasswordVisible.value;
|
||||
},
|
||||
child: controller.conformPasswordVisible.value
|
||||
? SvgPicture.asset(
|
||||
"assets/icons/ic_password_show.svg",
|
||||
colorFilter: ColorFilter.mode(
|
||||
isDark ? AppThemeData.grey300 : AppThemeData.grey600,
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
)
|
||||
: SvgPicture.asset(
|
||||
"assets/icons/ic_password_close.svg",
|
||||
colorFilter: ColorFilter.mode(
|
||||
isDark ? AppThemeData.grey300 : AppThemeData.grey600,
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
)),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
if (controller.firstNameEditingController.value.text.isEmpty) {
|
||||
ShowToastDialog.showToast("Please enter first name".tr);
|
||||
return;
|
||||
} else if (controller.lastNameEditingController.value.text.isEmpty) {
|
||||
ShowToastDialog.showToast("Please enter last name".tr);
|
||||
return;
|
||||
} else if (controller.emailEditingController.value.text.isEmpty) {
|
||||
ShowToastDialog.showToast("Please enter email address".tr);
|
||||
return;
|
||||
} else if (!GetUtils.isEmail(controller.emailEditingController.value.text)) {
|
||||
ShowToastDialog.showToast("Please enter valid email address".tr);
|
||||
return;
|
||||
} else if (controller.phoneNUmberEditingController.value.text.isEmpty) {
|
||||
ShowToastDialog.showToast("Please enter phone number".tr);
|
||||
return;
|
||||
} else if (controller.selectedZone.value.id == null) {
|
||||
ShowToastDialog.showToast("Please select zone".tr);
|
||||
return;
|
||||
}
|
||||
|
||||
// Fix: use OR (||) instead of AND (&&)
|
||||
if ((controller.driverModel.value.id == null || controller.driverModel.value.id!.isEmpty) &&
|
||||
controller.passwordEditingController.value.text.isEmpty) {
|
||||
ShowToastDialog.showToast("Please enter password".tr);
|
||||
return;
|
||||
} else if ((controller.driverModel.value.id == null || controller.driverModel.value.id!.isEmpty) &&
|
||||
controller.passwordEditingController.value.text.length < 6) {
|
||||
ShowToastDialog.showToast("Password must be at least 6 characters".tr);
|
||||
return;
|
||||
} else if ((controller.driverModel.value.id == null || controller.driverModel.value.id!.isEmpty) &&
|
||||
controller.conformPasswordEditingController.value.text.isEmpty) {
|
||||
ShowToastDialog.showToast("Please enter confirm password".tr);
|
||||
return;
|
||||
} else if (controller.passwordEditingController.value.text !=
|
||||
controller.conformPasswordEditingController.value.text) {
|
||||
ShowToastDialog.showToast("Password and confirm password do not match".tr);
|
||||
return;
|
||||
}
|
||||
|
||||
//Vehicle validation if service is NOT Parcel Service
|
||||
if (controller.selectedService.value != "Parcel Service") {
|
||||
if (controller.selectedVehicleType.value.id == null) {
|
||||
ShowToastDialog.showToast("Please select vehicle type".tr);
|
||||
return;
|
||||
} else if (controller.selectedCarMakes.value.id == null) {
|
||||
ShowToastDialog.showToast("Please select car brand".tr);
|
||||
return;
|
||||
} else if (controller.selectedCarModel.value.id == null) {
|
||||
ShowToastDialog.showToast("Please select car model".tr);
|
||||
return;
|
||||
} else if (controller.carPlatNumberEditingController.value.text.isEmpty) {
|
||||
ShowToastDialog.showToast("Please enter car plat number".tr);
|
||||
return;
|
||||
} else {
|
||||
//Will work now
|
||||
print("plz come..............");
|
||||
controller.signUp();
|
||||
}
|
||||
} else {
|
||||
//Parcel Service signup
|
||||
print("plz come signUp ..............");
|
||||
controller.signUp();
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
color: AppThemeData.primary300,
|
||||
width: Responsive.width(100, context),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||
child: Text(
|
||||
'Save'.tr,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: isDark ? AppThemeData.grey50 : AppThemeData.grey50,
|
||||
fontSize: 16,
|
||||
fontFamily: AppThemeData.medium,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
86
lib/app/owner_screen/driver_location_screen.dart
Normal file
86
lib/app/owner_screen/driver_location_screen.dart
Normal file
@@ -0,0 +1,86 @@
|
||||
import 'package:driver/constant/constant.dart';
|
||||
import 'package:driver/controllers/driver_location_controller.dart';
|
||||
import 'package:driver/themes/theme_controller.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_map/flutter_map.dart' as flutterMap;
|
||||
import 'package:get/get.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
|
||||
class DriverLocationScreen extends StatelessWidget {
|
||||
const DriverLocationScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final themeController = Get.find<ThemeController>();
|
||||
final isDark = themeController.isDark.value;
|
||||
return GetX(
|
||||
init: DriverLocationController(),
|
||||
builder: (controller) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(
|
||||
"Driver Locations",
|
||||
style: TextStyle(
|
||||
color: isDark ? Colors.white : Colors.black,
|
||||
),
|
||||
),
|
||||
backgroundColor: isDark ? Colors.black : Colors.white,
|
||||
iconTheme: IconThemeData(
|
||||
color: isDark ? Colors.white : Colors.black,
|
||||
),
|
||||
),
|
||||
body: controller.isLoading.value
|
||||
? Constant.loader()
|
||||
: Constant.selectedMapType == "osm"
|
||||
? Obx(() {
|
||||
// Schedule a post-frame callback to ensure the FlutterMap has been built
|
||||
// before we attempt to move the map to the driver's location.
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
try {
|
||||
controller.animateToSource();
|
||||
} catch (_) {}
|
||||
});
|
||||
|
||||
return flutterMap.FlutterMap(
|
||||
mapController: controller.osmMapController,
|
||||
options: flutterMap.MapOptions(
|
||||
// center the OSM map on the controller's current position (updated by controller)
|
||||
initialCenter: controller.current.value,
|
||||
initialZoom: 12,
|
||||
),
|
||||
children: [
|
||||
flutterMap.TileLayer(
|
||||
urlTemplate: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||
subdomains: const ['a', 'b', 'c'],
|
||||
userAgentPackageName: 'com.emart.app',
|
||||
),
|
||||
flutterMap.MarkerLayer(markers: controller.osmMarkers),
|
||||
],
|
||||
);
|
||||
})
|
||||
: GoogleMap(
|
||||
initialCameraPosition: controller.driverList.isNotEmpty
|
||||
? CameraPosition(
|
||||
target: LatLng(controller.driverList.first.location == null ? 12.9716 : controller.driverList.first.location!.latitude!,
|
||||
controller.driverList.first.location == null ? 77.5946 : controller.driverList.first.location!.longitude!),
|
||||
zoom: 14,
|
||||
)
|
||||
: CameraPosition(
|
||||
target: LatLng(12.9716, 77.5946),
|
||||
zoom: 14,
|
||||
),
|
||||
myLocationEnabled: true,
|
||||
myLocationButtonEnabled: true,
|
||||
markers: controller.markers.toSet(),
|
||||
onMapCreated: (GoogleMapController mapController) {
|
||||
controller.mapController.complete(mapController);
|
||||
// Wait for markers to load
|
||||
Future.delayed(const Duration(milliseconds: 500), () async {
|
||||
await controller.moveCameraToFirstDriver(mapController);
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
51
lib/app/owner_screen/driver_order_list.dart
Normal file
51
lib/app/owner_screen/driver_order_list.dart
Normal file
@@ -0,0 +1,51 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import '../../controllers/driver_order_controller.dart';
|
||||
import '../../themes/theme_controller.dart';
|
||||
import '../cab_screen/cab_order_list_screen.dart';
|
||||
import '../parcel_screen/parcel_order_list_screen.dart';
|
||||
import '../rental_service/rental_order_list_screen.dart';
|
||||
|
||||
class DriverOrderList extends StatelessWidget {
|
||||
const DriverOrderList({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final themeController = Get.find<ThemeController>();
|
||||
final isDark = themeController.isDark.value;
|
||||
|
||||
return GetX<DriverOrderListController>(
|
||||
init: DriverOrderListController(),
|
||||
builder: (controller) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(
|
||||
"Driver Orders".tr,
|
||||
style: TextStyle(
|
||||
color: isDark ? Colors.white : Colors.black,
|
||||
),
|
||||
),
|
||||
backgroundColor: isDark ? Colors.black : Colors.white,
|
||||
iconTheme: IconThemeData(
|
||||
color: isDark ? Colors.white : Colors.black,
|
||||
),
|
||||
),
|
||||
body: _buildBody(controller.serviceType.value),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildBody(String? serviceType) {
|
||||
switch (serviceType) {
|
||||
case "cab-service":
|
||||
return const CabOrderListScreen();
|
||||
case "parcel_delivery":
|
||||
return const ParcelOrderListScreen();
|
||||
case "rental-service":
|
||||
return const RentalOrderListScreen();
|
||||
default:
|
||||
return const Center(child: Text("Service type not supported"));
|
||||
}
|
||||
}
|
||||
}
|
||||
653
lib/app/owner_screen/owner_dashboard_screen.dart
Normal file
653
lib/app/owner_screen/owner_dashboard_screen.dart
Normal file
@@ -0,0 +1,653 @@
|
||||
import 'package:driver/app/auth_screen/login_screen.dart';
|
||||
import 'package:driver/app/change%20langauge/change_language_screen.dart';
|
||||
import 'package:driver/app/chat_screens/driver_inbox_screen.dart';
|
||||
import 'package:driver/app/edit_profile_screen/edit_profile_screen.dart';
|
||||
import 'package:driver/app/owner_screen/driver_location_screen.dart';
|
||||
import 'package:driver/app/owner_screen/owner_home_screen.dart';
|
||||
import 'package:driver/app/terms_and_condition/terms_and_condition_screen.dart';
|
||||
import 'package:driver/app/verification_screen/verification_screen.dart';
|
||||
import 'package:driver/app/wallet_screen/wallet_screen.dart';
|
||||
import 'package:driver/app/withdraw_method_setup_screens/withdraw_method_setup_screen.dart';
|
||||
import 'package:driver/constant/constant.dart';
|
||||
import 'package:driver/constant/show_toast_dialog.dart';
|
||||
import 'package:driver/controllers/owner_dashboard_controller.dart';
|
||||
import 'package:driver/services/audio_player_service.dart';
|
||||
import 'package:driver/themes/app_them_data.dart';
|
||||
import 'package:driver/themes/custom_dialog_box.dart';
|
||||
import 'package:driver/themes/theme_controller.dart';
|
||||
import 'package:driver/utils/fire_store_utils.dart';
|
||||
import 'package:driver/utils/network_image_widget.dart';
|
||||
import 'package:firebase_auth/firebase_auth.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:in_app_review/in_app_review.dart';
|
||||
import 'package:share_plus/share_plus.dart';
|
||||
|
||||
import 'owner_order_list.dart';
|
||||
|
||||
class OwnerDashboardScreen extends StatelessWidget {
|
||||
const OwnerDashboardScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final themeController = Get.find<ThemeController>();
|
||||
return Obx(() {
|
||||
final isDark = themeController.isDark.value;
|
||||
return GetX(
|
||||
init: OwnerDashboardController(),
|
||||
builder: (controller) {
|
||||
return Scaffold(
|
||||
drawerEnableOpenDragGesture: false,
|
||||
appBar: AppBar(
|
||||
// backgroundColor: isDark ? AppThemeData.grey900 : AppThemeData.grey50,
|
||||
titleSpacing: 5,
|
||||
title: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Welcome Back 👋'.tr,
|
||||
style: TextStyle(
|
||||
color: isDark ? AppThemeData.grey50 : AppThemeData.grey900,
|
||||
fontSize: 12,
|
||||
fontFamily: AppThemeData.medium,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
Constant.userModel!.fullName().tr,
|
||||
style: TextStyle(
|
||||
color: isDark ? AppThemeData.grey50 : AppThemeData.grey900,
|
||||
fontSize: 14,
|
||||
fontFamily: AppThemeData.semiBold,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
InkWell(
|
||||
onTap: () {
|
||||
Get.to(() => const DriverLocationScreen());
|
||||
},
|
||||
child: SvgPicture.asset("assets/icons/ic_location_pin.svg")),
|
||||
const SizedBox(
|
||||
width: 14,
|
||||
),
|
||||
Visibility(
|
||||
visible: Constant.userModel?.vendorID?.isEmpty == true,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
Get.to(const WalletScreen(isAppBarShow: true));
|
||||
},
|
||||
child: SvgPicture.asset("assets/icons/ic_wallet_home.svg")),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
Get.to(const EditProfileScreen());
|
||||
},
|
||||
child: SvgPicture.asset("assets/icons/ic_user_business.svg")),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
],
|
||||
leading: Builder(builder: (context) {
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
Scaffold.of(context).openDrawer();
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: Container(
|
||||
decoration: ShapeDecoration(
|
||||
color: isDark ? AppThemeData.carRent600 : AppThemeData.carRent50,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(120),
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: SvgPicture.asset("assets/icons/ic_drawer_open.svg"),
|
||||
)),
|
||||
),
|
||||
);
|
||||
}),
|
||||
),
|
||||
drawer: const DrawerView(),
|
||||
body: controller.drawerIndex.value == 0
|
||||
? const OwnerHomeScreen()
|
||||
: controller.drawerIndex.value == 1
|
||||
? OwnerOrderListScreen()
|
||||
: controller.drawerIndex.value == 2
|
||||
? const WalletScreen(
|
||||
isAppBarShow: false,
|
||||
)
|
||||
: controller.drawerIndex.value == 3
|
||||
? const WithdrawMethodSetupScreen()
|
||||
: controller.drawerIndex.value == 4
|
||||
? const VerificationScreen()
|
||||
: controller.drawerIndex.value == 5
|
||||
? const DriverInboxScreen()
|
||||
: controller.drawerIndex.value == 6
|
||||
? const ChangeLanguageScreen()
|
||||
: controller.drawerIndex.value == 7
|
||||
? const TermsAndConditionScreen(type: "temsandcondition")
|
||||
: const TermsAndConditionScreen(type: "privacy"),
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class DrawerView extends StatelessWidget {
|
||||
const DrawerView({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final themeController = Get.find<ThemeController>();
|
||||
return Obx(() {
|
||||
var isDark = themeController.isDark.value;
|
||||
return GetX(
|
||||
init: OwnerDashboardController(),
|
||||
builder: (controller) {
|
||||
return Drawer(
|
||||
backgroundColor: isDark ? AppThemeData.grey900 : AppThemeData.grey50,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(top: MediaQuery.of(context).viewPadding.top + 20, left: 16, right: 16),
|
||||
child: ListView(
|
||||
padding: EdgeInsets.zero,
|
||||
children: <Widget>[
|
||||
Row(
|
||||
children: [
|
||||
ClipOval(
|
||||
child: NetworkImageWidget(
|
||||
imageUrl: Constant.userModel == null ? "" : Constant.userModel!.profilePictureURL.toString(),
|
||||
height: 55,
|
||||
width: 55,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
Constant.userModel!.fullName().tr,
|
||||
style: TextStyle(
|
||||
color: isDark ? AppThemeData.grey50 : AppThemeData.grey900,
|
||||
fontSize: 18,
|
||||
fontFamily: AppThemeData.semiBold,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'${Constant.userModel!.email}'.tr,
|
||||
style: TextStyle(
|
||||
color: isDark ? AppThemeData.grey50 : AppThemeData.grey900,
|
||||
fontSize: 14,
|
||||
fontFamily: AppThemeData.regular,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
child: Text(
|
||||
'About App'.tr,
|
||||
style: TextStyle(
|
||||
color: isDark ? AppThemeData.grey400 : AppThemeData.grey500,
|
||||
fontSize: 12,
|
||||
fontFamily: AppThemeData.medium,
|
||||
),
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
visualDensity: const VisualDensity(horizontal: 0, vertical: -2),
|
||||
contentPadding: const EdgeInsets.only(left: 0.0, right: 0.0),
|
||||
leading: SvgPicture.asset(
|
||||
"assets/icons/ic_home_add.svg",
|
||||
width: 20,
|
||||
),
|
||||
trailing: const Icon(Icons.keyboard_arrow_right_rounded, size: 24),
|
||||
dense: true,
|
||||
title: Text(
|
||||
'Home'.tr,
|
||||
style: TextStyle(
|
||||
color: isDark ? AppThemeData.grey100 : AppThemeData.grey800,
|
||||
fontFamily: AppThemeData.semiBold,
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
Get.back();
|
||||
controller.drawerIndex.value = 0;
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
visualDensity: const VisualDensity(horizontal: 0, vertical: -2),
|
||||
contentPadding: const EdgeInsets.only(left: 0.0, right: 0.0),
|
||||
leading: SvgPicture.asset(
|
||||
"assets/icons/ic_shoping_cart.svg",
|
||||
colorFilter: ColorFilter.mode(AppThemeData.primary300, BlendMode.srcIn),
|
||||
),
|
||||
trailing: const Icon(Icons.keyboard_arrow_right_rounded, size: 24),
|
||||
dense: true,
|
||||
title: Text(
|
||||
'Orders'.tr,
|
||||
style: TextStyle(
|
||||
color: isDark ? AppThemeData.grey100 : AppThemeData.grey800,
|
||||
fontFamily: AppThemeData.semiBold,
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
Get.back();
|
||||
controller.drawerIndex.value = 1;
|
||||
},
|
||||
),
|
||||
Visibility(
|
||||
visible: Constant.userModel?.vendorID?.isEmpty == true,
|
||||
child: ListTile(
|
||||
visualDensity: const VisualDensity(horizontal: 0, vertical: -2),
|
||||
contentPadding: const EdgeInsets.only(left: 0.0, right: 0.0),
|
||||
leading: SvgPicture.asset(
|
||||
"assets/icons/ic_wallet.svg",
|
||||
colorFilter: ColorFilter.mode(AppThemeData.primary300, BlendMode.srcIn),
|
||||
),
|
||||
trailing: const Icon(Icons.keyboard_arrow_right_rounded, size: 24),
|
||||
dense: true,
|
||||
title: Text(
|
||||
'Wallet'.tr,
|
||||
style: TextStyle(
|
||||
color: isDark ? AppThemeData.grey100 : AppThemeData.grey800,
|
||||
fontFamily: AppThemeData.semiBold,
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
Get.back();
|
||||
controller.drawerIndex.value = 2;
|
||||
},
|
||||
),
|
||||
),
|
||||
Visibility(
|
||||
visible: Constant.userModel?.vendorID?.isEmpty == true,
|
||||
child: ListTile(
|
||||
visualDensity: const VisualDensity(horizontal: 0, vertical: -2),
|
||||
contentPadding: const EdgeInsets.only(left: 0.0, right: 0.0),
|
||||
leading: SvgPicture.asset(
|
||||
"assets/icons/ic_settings.svg",
|
||||
),
|
||||
trailing: const Icon(Icons.keyboard_arrow_right_rounded, size: 24),
|
||||
dense: true,
|
||||
title: Text(
|
||||
'Withdrawal Method'.tr,
|
||||
style: TextStyle(
|
||||
color: isDark ? AppThemeData.grey100 : AppThemeData.grey800,
|
||||
fontFamily: AppThemeData.semiBold,
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
Get.back();
|
||||
controller.drawerIndex.value = 3;
|
||||
},
|
||||
),
|
||||
),
|
||||
Constant.isOwnerVerification == true
|
||||
? ListTile(
|
||||
visualDensity: const VisualDensity(horizontal: 0, vertical: -2),
|
||||
contentPadding: const EdgeInsets.only(left: 0.0, right: 0.0),
|
||||
leading: SvgPicture.asset(
|
||||
"assets/icons/ic_notes.svg",
|
||||
),
|
||||
trailing: const Icon(Icons.keyboard_arrow_right_rounded, size: 24),
|
||||
dense: true,
|
||||
title: Text(
|
||||
'Document Verification'.tr,
|
||||
style: TextStyle(
|
||||
color: isDark ? AppThemeData.grey100 : AppThemeData.grey800,
|
||||
fontFamily: AppThemeData.semiBold,
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
Get.back();
|
||||
controller.drawerIndex.value = 4;
|
||||
},
|
||||
)
|
||||
: SizedBox(),
|
||||
Visibility(
|
||||
visible: false,
|
||||
child: ListTile(
|
||||
visualDensity: const VisualDensity(horizontal: 0, vertical: -2),
|
||||
contentPadding: const EdgeInsets.only(left: 0.0, right: 0.0),
|
||||
leading: SvgPicture.asset(
|
||||
"assets/icons/ic_chat.svg",
|
||||
),
|
||||
trailing: const Icon(Icons.keyboard_arrow_right_rounded, size: 24),
|
||||
dense: true,
|
||||
title: Text(
|
||||
'Inbox'.tr,
|
||||
style: TextStyle(
|
||||
color: isDark ? AppThemeData.grey100 : AppThemeData.grey800,
|
||||
fontFamily: AppThemeData.semiBold,
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
Get.back();
|
||||
controller.drawerIndex.value = 5;
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
child: Text(
|
||||
'App Preferences'.tr,
|
||||
style: TextStyle(
|
||||
color: isDark ? AppThemeData.grey400 : AppThemeData.grey500,
|
||||
fontSize: 12,
|
||||
fontFamily: AppThemeData.medium,
|
||||
),
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
visualDensity: const VisualDensity(horizontal: 0, vertical: -2),
|
||||
contentPadding: const EdgeInsets.only(left: 0.0, right: 0.0),
|
||||
leading: SvgPicture.asset(
|
||||
"assets/icons/ic_change_language.svg",
|
||||
),
|
||||
trailing: const Icon(Icons.keyboard_arrow_right_rounded, size: 24),
|
||||
dense: true,
|
||||
title: Text(
|
||||
'Change Language'.tr,
|
||||
style: TextStyle(
|
||||
color: isDark ? AppThemeData.grey100 : AppThemeData.grey800,
|
||||
fontFamily: AppThemeData.semiBold,
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
Get.back();
|
||||
controller.drawerIndex.value = 6;
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
visualDensity: const VisualDensity(horizontal: 0, vertical: -2),
|
||||
contentPadding: const EdgeInsets.only(left: 0.0, right: 0.0),
|
||||
leading: SvgPicture.asset(
|
||||
"assets/icons/ic_light_dark.svg",
|
||||
),
|
||||
trailing: Transform.scale(
|
||||
scale: 0.8,
|
||||
child: CupertinoSwitch(
|
||||
value: controller.isDarkModeSwitch.value,
|
||||
activeTrackColor: AppThemeData.primary300,
|
||||
onChanged: (value) {
|
||||
controller.toggleDarkMode(value);
|
||||
},
|
||||
),
|
||||
),
|
||||
dense: true,
|
||||
title: Text(
|
||||
'Dark Mode'.tr,
|
||||
style: TextStyle(
|
||||
color: isDark ? AppThemeData.grey100 : AppThemeData.grey800,
|
||||
fontFamily: AppThemeData.semiBold,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
child: Text(
|
||||
'Social'.tr,
|
||||
style: TextStyle(
|
||||
color: isDark ? AppThemeData.grey400 : AppThemeData.grey500,
|
||||
fontSize: 12,
|
||||
fontFamily: AppThemeData.medium,
|
||||
),
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
visualDensity: const VisualDensity(horizontal: 0, vertical: -2),
|
||||
contentPadding: const EdgeInsets.only(left: 0.0, right: 0.0),
|
||||
leading: SvgPicture.asset(
|
||||
"assets/icons/ic_share.svg",
|
||||
),
|
||||
trailing: const Icon(Icons.keyboard_arrow_right_rounded, size: 24),
|
||||
dense: true,
|
||||
title: Text(
|
||||
'Share app'.tr,
|
||||
style: TextStyle(
|
||||
color: isDark ? AppThemeData.grey100 : AppThemeData.grey800,
|
||||
fontFamily: AppThemeData.semiBold,
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
Get.back();
|
||||
Share.share(
|
||||
'${'Check out eMart, your ultimate food delivery application!'.tr} \n\n${'Google Play:'.tr} ${Constant.googlePlayLink} \n\n${'App Store:'.tr} ${Constant.appStoreLink}',
|
||||
subject: 'Look what I made!'.tr);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
visualDensity: const VisualDensity(horizontal: 0, vertical: -2),
|
||||
contentPadding: const EdgeInsets.only(left: 0.0, right: 0.0),
|
||||
leading: SvgPicture.asset(
|
||||
"assets/icons/ic_rate.svg",
|
||||
),
|
||||
trailing: const Icon(Icons.keyboard_arrow_right_rounded, size: 24),
|
||||
dense: true,
|
||||
title: Text(
|
||||
'Rate the app'.tr,
|
||||
style: TextStyle(
|
||||
color: isDark ? AppThemeData.grey100 : AppThemeData.grey800,
|
||||
fontFamily: AppThemeData.semiBold,
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
Get.back();
|
||||
final InAppReview inAppReview = InAppReview.instance;
|
||||
inAppReview.requestReview();
|
||||
},
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
child: Text(
|
||||
'Legal'.tr,
|
||||
style: TextStyle(
|
||||
color: isDark ? AppThemeData.grey400 : AppThemeData.grey500,
|
||||
fontSize: 12,
|
||||
fontFamily: AppThemeData.medium,
|
||||
),
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
visualDensity: const VisualDensity(horizontal: 0, vertical: -2),
|
||||
contentPadding: const EdgeInsets.only(left: 0.0, right: 0.0),
|
||||
leading: SvgPicture.asset(
|
||||
"assets/icons/ic_terms_condition.svg",
|
||||
colorFilter: ColorFilter.mode(AppThemeData.primary300, BlendMode.srcIn),
|
||||
),
|
||||
trailing: const Icon(Icons.keyboard_arrow_right_rounded, size: 24),
|
||||
dense: true,
|
||||
title: Text(
|
||||
'Terms and Conditions'.tr,
|
||||
style: TextStyle(
|
||||
color: isDark ? AppThemeData.grey100 : AppThemeData.grey800,
|
||||
fontFamily: AppThemeData.semiBold,
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
Get.back();
|
||||
controller.drawerIndex.value = 7;
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
visualDensity: const VisualDensity(horizontal: 0, vertical: -2),
|
||||
contentPadding: const EdgeInsets.only(left: 0.0, right: 0.0),
|
||||
leading: SvgPicture.asset(
|
||||
"assets/icons/ic_privacyPolicy.svg",
|
||||
colorFilter: const ColorFilter.mode(AppThemeData.danger300, BlendMode.srcIn),
|
||||
),
|
||||
trailing: const Icon(Icons.keyboard_arrow_right_rounded, size: 24),
|
||||
dense: true,
|
||||
title: Text(
|
||||
'Privacy Policy'.tr,
|
||||
style: TextStyle(
|
||||
color: isDark ? AppThemeData.grey100 : AppThemeData.grey800,
|
||||
fontFamily: AppThemeData.semiBold,
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
Get.back();
|
||||
controller.drawerIndex.value = 8;
|
||||
},
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
ListTile(
|
||||
visualDensity: const VisualDensity(horizontal: 0, vertical: -2),
|
||||
contentPadding: const EdgeInsets.only(left: 0.0, right: 0.0),
|
||||
leading: SvgPicture.asset(
|
||||
"assets/icons/ic_logout.svg",
|
||||
colorFilter: const ColorFilter.mode(AppThemeData.danger300, BlendMode.srcIn),
|
||||
),
|
||||
trailing: const Icon(
|
||||
Icons.keyboard_arrow_right_rounded,
|
||||
size: 24,
|
||||
color: AppThemeData.danger300,
|
||||
),
|
||||
dense: true,
|
||||
title: Text(
|
||||
'Log out'.tr,
|
||||
style: TextStyle(
|
||||
color: isDark ? AppThemeData.danger300 : AppThemeData.danger300,
|
||||
fontFamily: AppThemeData.semiBold,
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
Get.back();
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return CustomDialogBox(
|
||||
title: "Log out".tr,
|
||||
descriptions: "Are you sure you want to log out? You will need to enter your credentials to log back in.".tr,
|
||||
positiveString: "Log out".tr,
|
||||
negativeString: "Cancel".tr,
|
||||
positiveClick: () async {
|
||||
await AudioPlayerService.playSound(false);
|
||||
Constant.userModel!.fcmToken = "";
|
||||
await FireStoreUtils.updateUser(Constant.userModel!);
|
||||
await FirebaseAuth.instance.signOut();
|
||||
Get.offAll(const LoginScreen());
|
||||
},
|
||||
negativeClick: () {
|
||||
Get.back();
|
||||
},
|
||||
img: Image.asset(
|
||||
'assets/images/ic_logout.gif',
|
||||
height: 50,
|
||||
width: 50,
|
||||
),
|
||||
);
|
||||
});
|
||||
},
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return CustomDialogBox(
|
||||
title: "Delete Account".tr,
|
||||
descriptions: "Are you sure you want to delete your account? This action is irreversible and will permanently remove all your data.".tr,
|
||||
positiveString: "Delete".tr,
|
||||
negativeString: "Cancel".tr,
|
||||
positiveClick: () async {
|
||||
ShowToastDialog.showLoader("Please wait".tr);
|
||||
await FireStoreUtils.deleteUser().then((value) {
|
||||
ShowToastDialog.closeLoader();
|
||||
if (value == true) {
|
||||
ShowToastDialog.showToast("Account deleted successfully".tr);
|
||||
Get.offAll(const LoginScreen());
|
||||
} else {
|
||||
ShowToastDialog.showToast("Contact Administrator".tr);
|
||||
}
|
||||
});
|
||||
},
|
||||
negativeClick: () {
|
||||
Get.back();
|
||||
},
|
||||
img: Image.asset(
|
||||
'assets/icons/delete_dialog.gif',
|
||||
height: 50,
|
||||
width: 50,
|
||||
),
|
||||
);
|
||||
});
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
"assets/icons/ic_delete.svg",
|
||||
colorFilter: const ColorFilter.mode(AppThemeData.danger300, BlendMode.srcIn),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Text(
|
||||
'Delete Account'.tr,
|
||||
style: TextStyle(
|
||||
color: isDark ? AppThemeData.danger300 : AppThemeData.danger300,
|
||||
fontFamily: AppThemeData.semiBold,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Center(
|
||||
child: Text(
|
||||
"V : ${Constant.appVersion}",
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontFamily: AppThemeData.medium,
|
||||
fontSize: 14,
|
||||
color: isDark ? AppThemeData.grey50 : AppThemeData.grey900,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
436
lib/app/owner_screen/owner_home_screen.dart
Normal file
436
lib/app/owner_screen/owner_home_screen.dart
Normal file
@@ -0,0 +1,436 @@
|
||||
import 'package:driver/app/owner_screen/driver_create_screen.dart';
|
||||
import 'package:driver/app/owner_screen/view_all_drivers.dart';
|
||||
import 'package:driver/constant/constant.dart';
|
||||
import 'package:driver/controllers/owner_dashboard_controller.dart';
|
||||
import 'package:driver/controllers/owner_home_controller.dart';
|
||||
import 'package:driver/models/user_model.dart';
|
||||
import 'package:driver/themes/app_them_data.dart';
|
||||
import 'package:driver/themes/responsive.dart';
|
||||
import 'package:driver/themes/round_button_fill.dart';
|
||||
import 'package:driver/themes/theme_controller.dart';
|
||||
import 'package:driver/utils/network_image_widget.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'driver_order_list.dart';
|
||||
|
||||
class OwnerHomeScreen extends StatelessWidget {
|
||||
const OwnerHomeScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final themeController = Get.find<ThemeController>();
|
||||
final dashController = Get.put(OwnerDashboardController());
|
||||
return Obx(() {
|
||||
final isDark = themeController.isDark.value;
|
||||
return GetX(
|
||||
init: OwnerHomeController(),
|
||||
builder: (controller) {
|
||||
return Scaffold(
|
||||
body: controller.isLoading.value
|
||||
? Constant.loader()
|
||||
: Constant.isOwnerVerification == true && Constant.userModel!.isDocumentVerify == false
|
||||
? Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
decoration: ShapeDecoration(
|
||||
color: isDark ? AppThemeData.grey700 : AppThemeData.grey200,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(120),
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(20),
|
||||
child: SvgPicture.asset("assets/icons/ic_document.svg"),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
Text(
|
||||
"Document Verification in Pending".tr,
|
||||
style: TextStyle(color: isDark ? AppThemeData.grey100 : AppThemeData.grey800, fontSize: 22, fontFamily: AppThemeData.semiBold),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Text(
|
||||
"Your documents are being reviewed. We will notify you once the verification is complete.".tr,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(color: isDark ? AppThemeData.grey50 : AppThemeData.grey500, fontSize: 16, fontFamily: AppThemeData.bold),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
RoundedButtonFill(
|
||||
title: "View Status".tr,
|
||||
width: 55,
|
||||
height: 5.5,
|
||||
color: AppThemeData.primary300,
|
||||
textColor: AppThemeData.grey50,
|
||||
onPress: () {
|
||||
OwnerDashboardController dashBoardController = Get.put(OwnerDashboardController());
|
||||
dashBoardController.drawerIndex.value = 4;
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
|
||||
child: Column(
|
||||
children: [
|
||||
Obx(() {
|
||||
num wallet = dashController.userModel.value.walletAmount ?? 0.0;
|
||||
return wallet < double.parse(Constant.ownerMinimumDepositToRideAccept)
|
||||
? Padding(
|
||||
padding: const EdgeInsets.only(bottom: 10),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(color: AppThemeData.danger50, borderRadius: BorderRadius.circular(10)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
"You must have a minimum of ${Constant.amountShow(amount: Constant.ownerMinimumDepositToRideAccept.toString())} in your wallet to receive orders to your driver"
|
||||
.tr,
|
||||
style: TextStyle(
|
||||
color: AppThemeData.danger300,
|
||||
fontSize: 14,
|
||||
fontFamily: AppThemeData.semiBold,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
: const SizedBox();
|
||||
}),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: AppThemeData.homePageGradiant[0],
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SvgPicture.asset("assets/icons/ic_ride.svg"),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Text(
|
||||
controller.totalRidesAllDrivers.toString(),
|
||||
textAlign: TextAlign.center,
|
||||
style: AppThemeData.boldTextStyle(
|
||||
fontSize: 16,
|
||||
color: AppThemeData.grey900,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Text(
|
||||
'Total Bookings'.tr,
|
||||
textAlign: TextAlign.center,
|
||||
style: AppThemeData.mediumTextStyle(
|
||||
fontSize: 12,
|
||||
color: AppThemeData.grey900,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Expanded(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: AppThemeData.homePageGradiant[1],
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SvgPicture.asset("assets/icons/ic_total_ride.svg"),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Text(
|
||||
'${controller.driverList.length} ',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppThemeData.boldTextStyle(
|
||||
fontSize: 16,
|
||||
color: AppThemeData.grey900,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Text(
|
||||
'Total Drivers'.tr,
|
||||
textAlign: TextAlign.center,
|
||||
style: AppThemeData.mediumTextStyle(
|
||||
fontSize: 12,
|
||||
color: AppThemeData.grey900,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Container(
|
||||
width: Responsive.width(100, context),
|
||||
decoration: BoxDecoration(
|
||||
color: AppThemeData.homePageGradiant[2],
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SvgPicture.asset("assets/icons/ic_earning.svg"),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Text(
|
||||
'${Constant.currencyModel!.symbol.toString()}${controller.totalEarningsAllDrivers.toStringAsFixed(2)}',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppThemeData.boldTextStyle(
|
||||
fontSize: 16,
|
||||
color: AppThemeData.grey900,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Text(
|
||||
'Earnings'.tr,
|
||||
textAlign: TextAlign.center,
|
||||
style: AppThemeData.mediumTextStyle(
|
||||
fontSize: 12,
|
||||
color: AppThemeData.grey900,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
controller.driverList.isEmpty
|
||||
? SizedBox()
|
||||
: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Your Available Drivers'.tr,
|
||||
textAlign: TextAlign.center,
|
||||
style: AppThemeData.boldTextStyle(
|
||||
fontSize: 16,
|
||||
color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'Real-time status and earnings summary'.tr,
|
||||
textAlign: TextAlign.center,
|
||||
style: AppThemeData.mediumTextStyle(
|
||||
fontSize: 12,
|
||||
color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
Get.to(ViewAllDriverScreen())!.then(
|
||||
(value) {
|
||||
controller.getDriverList();
|
||||
},
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
'View all'.tr,
|
||||
textAlign: TextAlign.center,
|
||||
style: AppThemeData.mediumTextStyle(
|
||||
fontSize: 16, color: isDark ? AppThemeData.primary300 : AppThemeData.primary300, decoration: TextDecoration.underline),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 16,
|
||||
),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
border: Border.all(
|
||||
color: isDark ? AppThemeData.greyDark300 : AppThemeData.grey300,
|
||||
),
|
||||
),
|
||||
child: ListView.builder(
|
||||
// itemCount: controller.driverList.length,
|
||||
// physics: NeverScrollableScrollPhysics(),
|
||||
// shrinkWrap: true,
|
||||
itemCount: controller.driverList.length > 5 ? 5 : controller.driverList.length,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
shrinkWrap: true,
|
||||
itemBuilder: (context, index) {
|
||||
UserModel driverModel = controller.driverList[index];
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
children: [
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
child: NetworkImageWidget(
|
||||
imageUrl: driverModel.profilePictureURL.toString(),
|
||||
height: 42,
|
||||
width: 42,
|
||||
fit: BoxFit.fill,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
driverModel.fullName(),
|
||||
textAlign: TextAlign.center,
|
||||
style: AppThemeData.semiBoldTextStyle(
|
||||
fontSize: 16,
|
||||
color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'${driverModel.countryCode} ${driverModel.phoneNumber}',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppThemeData.mediumTextStyle(
|
||||
fontSize: 12,
|
||||
color: isDark ? AppThemeData.greyDark700 : AppThemeData.grey700,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
RoundedButtonFill(
|
||||
title: driverModel.isActive == false ? "Offline" : "Online".tr,
|
||||
height: 3.5,
|
||||
width: 18,
|
||||
borderRadius: 10,
|
||||
color: driverModel.isActive == false ? AppThemeData.danger300 : AppThemeData.success300,
|
||||
textColor: AppThemeData.grey50,
|
||||
onPress: () async {},
|
||||
),
|
||||
PopupMenuButton<String>(
|
||||
padding: EdgeInsets.zero,
|
||||
onSelected: (value) {
|
||||
if (value == 'Edit Driver') {
|
||||
Get.to(DriverCreateScreen(), arguments: {"driverModel": driverModel})!.then(
|
||||
(value0) {
|
||||
if (value0 == true) {
|
||||
controller.getDriverList();
|
||||
}
|
||||
},
|
||||
);
|
||||
} else if (value == 'Delete Driver') {
|
||||
controller.deleteDriver(driverModel.id.toString());
|
||||
} else if (value == 'View All Order') {
|
||||
print("driver ::::::: ${driverModel.email}");
|
||||
Get.to(() => const DriverOrderList(), arguments: {
|
||||
"driverId": driverModel.id,
|
||||
"serviceType": driverModel.serviceType,
|
||||
});
|
||||
}
|
||||
},
|
||||
itemBuilder: (BuildContext context) => <PopupMenuEntry<String>>[
|
||||
PopupMenuItem<String>(
|
||||
value: 'Edit Driver',
|
||||
child: Text('Edit Driver'.tr, style: TextStyle(color: isDark ? AppThemeData.grey50 : AppThemeData.greyDark50)),
|
||||
),
|
||||
PopupMenuItem<String>(
|
||||
value: 'Delete Driver',
|
||||
child: Text('Delete Driver'.tr, style: TextStyle(color: isDark ? AppThemeData.grey50 : AppThemeData.greyDark50)),
|
||||
),
|
||||
PopupMenuItem<String>(
|
||||
value: 'View All Order',
|
||||
child: Text('View All Order'.tr, style: TextStyle(color: isDark ? AppThemeData.grey50 : AppThemeData.greyDark50)),
|
||||
),
|
||||
],
|
||||
color: isDark ? AppThemeData.greyDark50 : AppThemeData.grey50,
|
||||
icon: Icon(Icons.more_vert, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900), // Three dots icon
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
floatingActionButton: Constant.userModel!.isDocumentVerify == true
|
||||
? ClipOval(
|
||||
child: FloatingActionButton(
|
||||
onPressed: () {
|
||||
Get.to(DriverCreateScreen())!.then((value) {
|
||||
if (value == true) {
|
||||
controller.getDriverList();
|
||||
}
|
||||
});
|
||||
},
|
||||
backgroundColor: AppThemeData.primary300,
|
||||
child: Icon(
|
||||
Icons.add,
|
||||
color: AppThemeData.grey50,
|
||||
),
|
||||
),
|
||||
)
|
||||
: SizedBox.shrink(),
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
669
lib/app/owner_screen/owner_order_list.dart
Normal file
669
lib/app/owner_screen/owner_order_list.dart
Normal file
@@ -0,0 +1,669 @@
|
||||
import 'package:dotted_border/dotted_border.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import '../../constant/constant.dart';
|
||||
import '../../controllers/owner_order_list_controller.dart';
|
||||
import '../../models/cab_order_model.dart';
|
||||
import '../../models/rental_order_model.dart';
|
||||
import '../../models/user_model.dart';
|
||||
import '../../themes/app_them_data.dart';
|
||||
import '../../themes/round_button_fill.dart';
|
||||
import '../cab_screen/cab_order_details.dart';
|
||||
import '../parcel_screen/parcel_order_details.dart';
|
||||
import '../rental_service/rental_order_details_screen.dart';
|
||||
import '../../themes/theme_controller.dart';
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
|
||||
class OwnerOrderListScreen extends StatelessWidget {
|
||||
const OwnerOrderListScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final themeController = Get.find<ThemeController>();
|
||||
final isDark = themeController.isDark.value;
|
||||
|
||||
return GetX<OwnerOrderListController>(
|
||||
init: OwnerOrderListController(),
|
||||
builder: (controller) {
|
||||
return Scaffold(
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("Select Service Type", style: TextStyle(color: isDark ? AppThemeData.grey50 : AppThemeData.greyDark50)),
|
||||
const SizedBox(height: 5),
|
||||
DropdownButtonFormField<String>(
|
||||
initialValue: controller.selectedService.value,
|
||||
style: TextStyle(
|
||||
color: themeController.isDark.value ? AppThemeData.grey50 : AppThemeData.grey900,
|
||||
fontFamily: AppThemeData.semiBold,
|
||||
),
|
||||
dropdownColor: themeController.isDark.value ? AppThemeData.grey800 : AppThemeData.grey50,
|
||||
items: controller.serviceList.map((service) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: service,
|
||||
child: Text(
|
||||
service,
|
||||
style: TextStyle(
|
||||
color: themeController.isDark.value ? AppThemeData.grey50 : AppThemeData.grey900,
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
onChanged: (value) {
|
||||
controller.selectedService.value = value!;
|
||||
controller.selectedDriver.value = null;
|
||||
controller.isDriverSelected.value = false;
|
||||
},
|
||||
decoration: _dropdownDecoration(themeController.isDark.value),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text("Select Driver", style: TextStyle(color: isDark ? AppThemeData.grey50 : AppThemeData.greyDark50)),
|
||||
const SizedBox(height: 5),
|
||||
Obx(() => DropdownButtonFormField<UserModel?>(
|
||||
initialValue: controller.selectedDriver.value,
|
||||
hint: Text("Select Driver",
|
||||
style: TextStyle(
|
||||
color: themeController.isDark.value ? AppThemeData.grey50 : AppThemeData.grey900,
|
||||
fontFamily: AppThemeData.semiBold,
|
||||
)),
|
||||
items: [
|
||||
const DropdownMenuItem<UserModel?>(
|
||||
value: null,
|
||||
child: Text("All Drivers"),
|
||||
),
|
||||
...controller.filteredDrivers.map((driver) {
|
||||
return DropdownMenuItem<UserModel?>(
|
||||
value: driver,
|
||||
child: Text(
|
||||
"${driver.firstName ?? ''} ${driver.lastName ?? ''}",
|
||||
style: TextStyle(
|
||||
color: themeController.isDark.value ? AppThemeData.grey50 : AppThemeData.grey900,
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
],
|
||||
onChanged: (UserModel? value) {
|
||||
controller.selectedDriver.value = value;
|
||||
},
|
||||
dropdownColor: isDark ? AppThemeData.grey900 : AppThemeData.grey50,
|
||||
decoration: _dropdownDecoration(themeController.isDark.value),
|
||||
)),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// --- Search Button ---
|
||||
RoundedButtonFill(
|
||||
title: "Search",
|
||||
height: 5.5,
|
||||
color: AppThemeData.primary300,
|
||||
textColor: AppThemeData.grey50,
|
||||
onPress: controller.searchOrders,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
Expanded(
|
||||
child: Obx(() {
|
||||
switch (controller.serviceKey.value) {
|
||||
case 'cab-service':
|
||||
return cabListView(controller, isDark);
|
||||
case 'parcel_delivery':
|
||||
return parcleListView(controller, isDark);
|
||||
case 'rental-service':
|
||||
return rentalListView(controller, isDark);
|
||||
default:
|
||||
return const Center(child: Text("Service type not supported"));
|
||||
}
|
||||
}),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
InputDecoration _dropdownDecoration(bool isDark) {
|
||||
return InputDecoration(
|
||||
isDense: true,
|
||||
filled: true,
|
||||
fillColor: isDark ? AppThemeData.grey800 : AppThemeData.grey50,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: BorderSide(color: isDark ? AppThemeData.greyDark400 : AppThemeData.grey400),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: BorderSide(color: isDark ? AppThemeData.greyDark400 : AppThemeData.grey400),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: BorderSide(color: AppThemeData.primary300, width: 1.2),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
DefaultTabController cabListView(OwnerOrderListController controller, bool isDark) {
|
||||
return DefaultTabController(
|
||||
length: controller.cabTabTitles.length,
|
||||
initialIndex: controller.cabTabTitles.indexOf(controller.cabSelectedTab.value),
|
||||
child: Column(
|
||||
children: [
|
||||
// TabBar
|
||||
TabBar(
|
||||
onTap: (index) {
|
||||
controller.cabSelectedTab(controller.cabTabTitles[index]);
|
||||
},
|
||||
// isScrollable: true,
|
||||
indicatorColor: AppThemeData.primary300,
|
||||
labelColor: AppThemeData.primary300,
|
||||
dividerColor: Colors.transparent,
|
||||
unselectedLabelColor: AppThemeData.primary300.withOpacity(0.60),
|
||||
labelStyle: AppThemeData.boldTextStyle(fontSize: 14),
|
||||
unselectedLabelStyle: AppThemeData.mediumTextStyle(fontSize: 14),
|
||||
tabs: controller.cabTabTitles.map((title) => Tab(child: Center(child: Text(title)))).toList(),
|
||||
),
|
||||
|
||||
// Body: loader or TabBarView
|
||||
Expanded(
|
||||
child: controller.isLoadingCab.value
|
||||
? Constant.loader()
|
||||
: TabBarView(
|
||||
children: controller.cabTabTitles.map((title) {
|
||||
final orders = controller.getCabOrdersForTab(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.only(top: 10),
|
||||
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: 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),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
DefaultTabController parcleListView(OwnerOrderListController controller, bool isDark) {
|
||||
return DefaultTabController(
|
||||
length: controller.parcelTabTitles.length,
|
||||
initialIndex: controller.parcelTabTitles.indexOf(controller.parcelSelectedTab.value),
|
||||
child: Column(
|
||||
children: [
|
||||
// TabBar
|
||||
TabBar(
|
||||
onTap: (index) {
|
||||
controller.parcelSelectedTab(controller.parcelTabTitles[index]);
|
||||
},
|
||||
indicatorColor: AppThemeData.parcelService500,
|
||||
labelColor: AppThemeData.parcelService500,
|
||||
dividerColor: Colors.transparent,
|
||||
unselectedLabelColor: AppThemeData.grey500,
|
||||
labelStyle: AppThemeData.boldTextStyle(fontSize: 16),
|
||||
unselectedLabelStyle: AppThemeData.mediumTextStyle(fontSize: 16),
|
||||
tabs: controller.parcelTabTitles.map((title) => Tab(child: Text(title))).toList(),
|
||||
),
|
||||
|
||||
// Body: loader or TabBarView
|
||||
Expanded(
|
||||
child: controller.isLoadingParcel.value
|
||||
? Constant.loader()
|
||||
: TabBarView(
|
||||
children: controller.parcelTabTitles.map((title) {
|
||||
// filter by tab using controller helper
|
||||
final orders = controller.getParcelOrdersForTab(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.only(top: 10),
|
||||
itemCount: orders.length,
|
||||
itemBuilder: (context, index) {
|
||||
final order = orders[index];
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
Get.to(() => const ParcelOrderDetails(), arguments: 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: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 8.0),
|
||||
child: Text(
|
||||
"Order Date:${order.isSchedule == true ? controller.formatDate(order.createdAt!) : controller.formatDate(order.senderPickupDateTime!)}",
|
||||
style: AppThemeData.mediumTextStyle(fontSize: 14, color: AppThemeData.info400),
|
||||
),
|
||||
),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
Image.asset("assets/images/image_parcel.png", height: 32, width: 32),
|
||||
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: 95),
|
||||
),
|
||||
Image.asset("assets/images/image_parcel.png", height: 32, width: 32),
|
||||
],
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_infoSection(
|
||||
"Pickup Address (Sender):".tr,
|
||||
order.sender?.name ?? '',
|
||||
order.sender?.address ?? '',
|
||||
order.sender?.phone ?? '',
|
||||
// order.senderPickupDateTime != null
|
||||
// ? "Pickup Time: ${controller.formatDate(order.senderPickupDateTime!)}"
|
||||
// : '',
|
||||
order.status,
|
||||
isDark,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
_infoSection(
|
||||
"Delivery Address (Receiver):".tr,
|
||||
order.receiver?.name ?? '',
|
||||
order.receiver?.address ?? '',
|
||||
order.receiver?.phone ?? '',
|
||||
// order.receiverPickupDateTime != null
|
||||
// ? "Delivery Time: ${controller.formatDate(order.receiverPickupDateTime!)}"
|
||||
// : '',
|
||||
null,
|
||||
isDark,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _infoSection(String title, String name, String address, String phone, String? status, bool isDark) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
title,
|
||||
style: AppThemeData.semiBoldTextStyle(fontSize: 16, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
if (status != null) ...[
|
||||
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(status, style: AppThemeData.boldTextStyle(fontSize: 14, color: AppThemeData.info500)),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
Text(name, style: AppThemeData.semiBoldTextStyle(fontSize: 14, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900)),
|
||||
Text(address, style: AppThemeData.mediumTextStyle(fontSize: 14, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900)),
|
||||
Text(phone, style: AppThemeData.mediumTextStyle(fontSize: 14, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900)),
|
||||
//Text(time, style: AppThemeData.semiBoldTextStyle(fontSize: 14, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900)),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
DefaultTabController rentalListView(OwnerOrderListController controller, bool isDark) {
|
||||
return DefaultTabController(
|
||||
length: controller.rentalTabTitles.length,
|
||||
initialIndex: controller.rentalTabTitles.indexOf(controller.rentalSelectedTab.value),
|
||||
child: Column(
|
||||
children: [
|
||||
// TabBar
|
||||
TabBar(
|
||||
onTap: (index) {
|
||||
controller.rentalSelectedTab(controller.rentalTabTitles[index]);
|
||||
},
|
||||
indicatorColor: AppThemeData.parcelService500,
|
||||
labelColor: AppThemeData.parcelService500,
|
||||
dividerColor: Colors.transparent,
|
||||
unselectedLabelColor: AppThemeData.grey500,
|
||||
labelStyle: AppThemeData.boldTextStyle(fontSize: 16),
|
||||
unselectedLabelStyle: AppThemeData.mediumTextStyle(fontSize: 16),
|
||||
tabs: controller.rentalTabTitles.map((title) => Tab(child: Text(title))).toList(),
|
||||
),
|
||||
|
||||
// Body: loader or TabBarView
|
||||
Expanded(
|
||||
child: controller.isLoadingRental.value
|
||||
? Constant.loader()
|
||||
: TabBarView(
|
||||
children: controller.rentalTabTitles.map((title) {
|
||||
// filter by tab using controller helper
|
||||
final orders = controller.getRentalOrdersForTab(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.only(top: 10),
|
||||
itemCount: orders.length,
|
||||
itemBuilder: (context, index) {
|
||||
RentalOrderModel order = orders[index]; //use this
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
Get.to(() => RentalOrderDetailsScreen(), arguments: {"rentalOrder": order.id});
|
||||
},
|
||||
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 ?? Constant.placeHolderImage,
|
||||
height: 60,
|
||||
width: 60,
|
||||
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,
|
||||
),
|
||||
),
|
||||
),
|
||||
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 :",
|
||||
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),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
127
lib/app/owner_screen/view_all_drivers.dart
Normal file
127
lib/app/owner_screen/view_all_drivers.dart
Normal file
@@ -0,0 +1,127 @@
|
||||
import 'package:driver/app/owner_screen/driver_create_screen.dart';
|
||||
import 'package:driver/app/owner_screen/driver_order_list.dart';
|
||||
import 'package:driver/controllers/owner_home_controller.dart';
|
||||
import 'package:driver/themes/app_them_data.dart';
|
||||
import 'package:driver/themes/round_button_fill.dart';
|
||||
import 'package:driver/themes/theme_controller.dart';
|
||||
import 'package:driver/utils/network_image_widget.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class ViewAllDriverScreen extends StatelessWidget {
|
||||
const ViewAllDriverScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final themeController = Get.find<ThemeController>();
|
||||
final isDark = themeController.isDark.value;
|
||||
|
||||
return GetX<OwnerHomeController>(
|
||||
init: Get.find<OwnerHomeController>(),
|
||||
builder: (controller) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text("All Drivers".tr),
|
||||
),
|
||||
body: controller.driverList.isEmpty
|
||||
? Center(child: Text("No drivers found".tr))
|
||||
: ListView.builder(
|
||||
padding: const EdgeInsets.all(10),
|
||||
itemCount: controller.driverList.length,
|
||||
itemBuilder: (context, index) {
|
||||
final driver = controller.driverList[index];
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
border: Border.all(
|
||||
color: isDark ? AppThemeData.greyDark300 : AppThemeData.grey300,
|
||||
),
|
||||
),
|
||||
padding: EdgeInsets.all(10),
|
||||
child: Row(
|
||||
children: [
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
child: NetworkImageWidget(
|
||||
imageUrl: driver.profilePictureURL ?? '',
|
||||
height: 42,
|
||||
width: 42,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
driver.fullName(),
|
||||
style: AppThemeData.semiBoldTextStyle(
|
||||
fontSize: 16,
|
||||
color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'${driver.countryCode ?? ''} ${driver.phoneNumber ?? ''}',
|
||||
style: AppThemeData.mediumTextStyle(
|
||||
fontSize: 12,
|
||||
color: isDark ? AppThemeData.greyDark700 : AppThemeData.grey700,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
RoundedButtonFill(
|
||||
title: driver.isActive == false ? "Offline" : "Online".tr,
|
||||
height: 3.5,
|
||||
width: 18,
|
||||
borderRadius: 10,
|
||||
color: driver.isActive == false ? AppThemeData.danger300 : AppThemeData.success300,
|
||||
textColor: AppThemeData.grey50,
|
||||
onPress: () {},
|
||||
),
|
||||
PopupMenuButton<String>(
|
||||
onSelected: (value) {
|
||||
if (value == 'Edit Driver') {
|
||||
Get.to(() => const DriverCreateScreen(), arguments: {"driverModel": driver})?.then((value0) {
|
||||
if (value0 == true) controller.getDriverList();
|
||||
});
|
||||
} else if (value == 'Delete Driver') {
|
||||
controller.deleteDriver(driver.id.toString());
|
||||
} else if (value == 'View All Order') {
|
||||
Get.to(() => const DriverOrderList(), arguments: {
|
||||
"driverId": driver.id,
|
||||
"serviceType": driver.serviceType,
|
||||
});
|
||||
}
|
||||
},
|
||||
itemBuilder: (BuildContext context) => <PopupMenuEntry<String>>[
|
||||
PopupMenuItem<String>(
|
||||
value: 'Edit Driver',
|
||||
child: Text('Edit Driver'.tr, style: TextStyle(color: isDark ? AppThemeData.grey50 : AppThemeData.greyDark50)),
|
||||
),
|
||||
PopupMenuItem<String>(
|
||||
value: 'Delete Driver',
|
||||
child: Text('Delete Driver'.tr, style: TextStyle(color: isDark ? AppThemeData.grey50 : AppThemeData.greyDark50)),
|
||||
),
|
||||
PopupMenuItem<String>(
|
||||
value: 'View All Order',
|
||||
child: Text('View All Order'.tr, style: TextStyle(color: isDark ? AppThemeData.grey50 : AppThemeData.greyDark50)),
|
||||
),
|
||||
],
|
||||
color: isDark ? AppThemeData.greyDark50 : AppThemeData.grey50,
|
||||
icon: Icon(Icons.more_vert, color: isDark ? AppThemeData.greyDark900 : AppThemeData.grey900),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user