Merge branch 'refs/heads/faiz_dev' into aamir_dev

# Conflicts:
#	lib/main.dart
#	pubspec.yaml
aamir_dev
Aamir 1 year ago
commit 3d657092aa

@ -23,6 +23,7 @@ import 'package:flutter/material.dart';
import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart'; import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart';
import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart'; import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart';
import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/views/setting_options/provider_accepted_requests_view.dart';
class ProviderAppRoutes { class ProviderAppRoutes {
static final Map<String, WidgetBuilder> routes = { static final Map<String, WidgetBuilder> routes = {
@ -37,8 +38,8 @@ class ProviderAppRoutes {
//Appointments //Appointments
AppRoutes.appointment: (context) => AppointmentPage(branch: ModalRoute.of(context)!.settings.arguments as BranchDetailModel), AppRoutes.appointment: (context) => AppointmentPage(branch: ModalRoute.of(context)!.settings.arguments as BranchDetailModel),
AppRoutes.appointmentDetailList: (context) => const AppointmentDetailListPage(), AppRoutes.appointmentDetailList: (context) => AppointmentDetailListPage(),
AppRoutes.updateAppointmentPage: (context) => UpdateAppointmentPage(), AppRoutes.updateAppointmentPage: (context) => const UpdateAppointmentPage(),
AppRoutes.addServiceInAppointment: (context) => AddNewServiceAppointmentPage(ModalRoute.of(context)!.settings.arguments as AppointmentListModel), AppRoutes.addServiceInAppointment: (context) => AddNewServiceAppointmentPage(ModalRoute.of(context)!.settings.arguments as AppointmentListModel),
AppRoutes.mergeAppointments: (context) => const MergeAppointmentListPage(), AppRoutes.mergeAppointments: (context) => const MergeAppointmentListPage(),
@ -61,5 +62,8 @@ class ProviderAppRoutes {
//Branch Duplication //Branch Duplication
AppRoutes.matchServices: (context) => MatchedServicesPage((ModalRoute.of(context)!.settings.arguments) == null ? null : (ModalRoute.of(context)!.settings.arguments as MatchServicesArguments)), AppRoutes.matchServices: (context) => MatchedServicesPage((ModalRoute.of(context)!.settings.arguments) == null ? null : (ModalRoute.of(context)!.settings.arguments as MatchServicesArguments)),
//Requests
AppRoutes.providerAcceptedRequestsView: (context) => const ProviderAcceptedRequestsView(),
}; };
} }

@ -1,5 +1,6 @@
import 'dart:io'; import 'dart:io';
import 'package:car_provider_app/config/provider_dependencies.dart'; import 'package:car_provider_app/config/provider_dependencies.dart';
import 'package:flutter/services.dart';
import 'package:mc_common_app/repositories/items_repo.dart'; import 'package:mc_common_app/repositories/items_repo.dart';
import 'package:mc_common_app/repositories/schedule_repo.dart'; import 'package:mc_common_app/repositories/schedule_repo.dart';
import 'package:car_provider_app/view_models/items_view_model.dart'; import 'package:car_provider_app/view_models/items_view_model.dart';
@ -159,14 +160,18 @@ Future<void> main() async {
// command to generate languages data from json // command to generate languages data from json
class MyApp extends StatelessWidget { class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key); const MyApp({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
return Sizer(
return ResponsiveSizer( return ResponsiveSizer(
builder: (context, orientation, deviceType) { builder: (context, orientation, deviceType) {
injector.get<AppState>().setAppType(AppType.provider); injector.get<AppState>().setAppType(AppType.provider);
AppState().setPostParamsModel( AppState().setPostParamsModel(
PostParamsModel( PostParamsModel(
languageID: EasyLocalization.of(context)?.locale.languageCode == "ar" ? 1 : 2, languageID: EasyLocalization.of(context)?.locale.languageCode == "ar" ? 1 : 2,

@ -105,6 +105,11 @@ class ScheduleVM extends BaseVM {
return response; return response;
} }
Future<GenericRespModel> checkServiceGroupInBranchSchedule(Map map) async {
GenericRespModel response = await scheduleRepo.checkServiceGroupInBranchSchedule(map);
return response;
}
Future<GenericRespModel> addServicesInSchedule(Map map) async { Future<GenericRespModel> addServicesInSchedule(Map map) async {
GenericRespModel response = await scheduleRepo.addServicesInSchedule(map); GenericRespModel response = await scheduleRepo.addServicesInSchedule(map);
return response; return response;

@ -1,4 +1,5 @@
import 'dart:async'; import 'dart:async';
import 'dart:developer';
import 'package:car_provider_app/views/dashboard/widget/general_appointment_widget.dart'; import 'package:car_provider_app/views/dashboard/widget/general_appointment_widget.dart';
import 'package:car_provider_app/views/branch_management/schedule/widgets/chips_picker_item.dart'; import 'package:car_provider_app/views/branch_management/schedule/widgets/chips_picker_item.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
@ -23,6 +24,7 @@ import 'package:mc_common_app/widgets/bottom_sheet.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart'; import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart'; import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart'; import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
import 'package:mc_common_app/widgets/empty_widget.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
@ -43,6 +45,8 @@ class _AddNewServiceAppointmentPageState extends State<AddNewServiceAppointmentP
List<ItemData> selectedList = []; List<ItemData> selectedList = [];
double totalPrice = 0.0;
List<PickerItem>? pickedItems; List<PickerItem>? pickedItems;
ServiceVM? serviceVM; ServiceVM? serviceVM;
@ -56,6 +60,29 @@ class _AddNewServiceAppointmentPageState extends State<AddNewServiceAppointmentP
}); });
} }
openItemsSelectionBottomSheet() async {
return showMyBottomSheet(
context,
child: SelectItemsSheet(
serviceId: service?.id ?? 0,
list: pickedItems,
onSelectItems: (List<ItemData> list) {
selectedList.clear();
selectedList.addAll(list);
pickedItems = [];
totalPrice = 0.0;
for (var element in list) {
totalPrice = totalPrice + double.parse(element.price ?? "0");
pickedItems!.add(
PickerItem(id: element.id ?? 0, title: element.name ?? ""),
);
}
setState(() {});
},
),
);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
@ -116,23 +143,7 @@ class _AddNewServiceAppointmentPageState extends State<AddNewServiceAppointmentP
service = value; service = value;
pickedItems = null; pickedItems = null;
serviceVm.setState(ViewState.idle); serviceVm.setState(ViewState.idle);
showMyBottomSheet( openItemsSelectionBottomSheet();
context,
child: SelectItemsSheet(
serviceId: service?.id ?? 0,
onSelectItems: (List<ItemData> selectedList) {
this.selectedList.clear();
this.selectedList = selectedList;
pickedItems = [];
for (var element in selectedList) {
pickedItems!.add(
PickerItem(id: element.id ?? 0, title: element.name ?? ""),
);
}
serviceVm.notifyListeners();
},
),
);
}, },
dropdownValue: service, dropdownValue: service,
list: serviceVm.servicesDropList, list: serviceVm.servicesDropList,
@ -141,7 +152,7 @@ class _AddNewServiceAppointmentPageState extends State<AddNewServiceAppointmentP
: category == null : category == null
? Container() ? Container()
: serviceVm.services != null && serviceVm.servicesDropList.isEmpty : serviceVm.services != null && serviceVm.servicesDropList.isEmpty
? Text(LocaleKeys.noServiceFound.tr()) ? EmptyWidget(text: LocaleKeys.noServicesAvailable.tr())
: const CircularProgressIndicator(), : const CircularProgressIndicator(),
12.height, 12.height,
(service != null && pickedItems != null && pickedItems!.isNotEmpty) (service != null && pickedItems != null && pickedItems!.isNotEmpty)
@ -149,26 +160,11 @@ class _AddNewServiceAppointmentPageState extends State<AddNewServiceAppointmentP
hint: LocaleKeys.selectItems.tr(), hint: LocaleKeys.selectItems.tr(),
itemsList: [...pickedItems ?? []], itemsList: [...pickedItems ?? []],
onClick: () { onClick: () {
showMyBottomSheet( openItemsSelectionBottomSheet();
context,
child: SelectItemsSheet(
serviceId: service?.id ?? 0,
list: pickedItems,
onSelectItems: (List<ItemData> selectedList) {
pickedItems = [];
for (var element in selectedList) {
pickedItems!.add(
PickerItem(id: element.id ?? 0, title: element.name ?? ""),
);
}
serviceVm.notifyListeners();
},
),
);
}, },
) )
: service != null : service != null
? Text(LocaleKeys.noItemSelectedYet.tr()) ? EmptyWidget(text: LocaleKeys.noItemSelectedYet.tr())
: const SizedBox(), : const SizedBox(),
if ((service != null && pickedItems != null && pickedItems!.isNotEmpty)) if ((service != null && pickedItems != null && pickedItems!.isNotEmpty))
Column( Column(
@ -183,7 +179,7 @@ class _AddNewServiceAppointmentPageState extends State<AddNewServiceAppointmentP
Row( Row(
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
calculatePrice().toString().toText( totalPrice.toString().toText(
fontSize: 29, fontSize: 29,
isBold: true, isBold: true,
), ),
@ -198,6 +194,7 @@ class _AddNewServiceAppointmentPageState extends State<AddNewServiceAppointmentP
.paddingOnly(bottom: 5), .paddingOnly(bottom: 5),
], ],
), ),
10.height,
], ],
), ),
], ],
@ -208,6 +205,7 @@ class _AddNewServiceAppointmentPageState extends State<AddNewServiceAppointmentP
); );
}, },
), ),
55.height,
], ],
), ),
), ),
@ -278,12 +276,4 @@ class _AddNewServiceAppointmentPageState extends State<AddNewServiceAppointmentP
}, },
); );
} }
double calculatePrice() {
double total = 0;
for (var element in selectedList) {
total = total + double.parse(element.price ?? "0");
}
return total;
}
} }

@ -3,23 +3,44 @@ import 'package:car_provider_app/views/dashboard/widget/general_appointment_widg
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/view_models/appointments_view_model.dart'; import 'package:mc_common_app/view_models/appointments_view_model.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart'; import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart'; import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/common_widgets/info_bottom_sheet.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:mc_common_app/widgets/txt_field.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
class AppointmentDetailListPage extends StatelessWidget { class AppointmentDetailListPage extends StatelessWidget {
const AppointmentDetailListPage({Key? key}) : super(key: key); AppointmentDetailListPage({super.key});
int customerID = 0;
int complainType = 1;
String customerName = "";
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: CustomAppBar( appBar: CustomAppBar(
title: LocaleKeys.appointment_details.tr(), title: LocaleKeys.appointment_details.tr(),
actions: [
IconButton(
onPressed: () {
context.read<AppointmentsVM>().buildComplaintBottomSheet(
customerID: customerID,
customerName: customerName,
complainType: complainType,
context: context,
);
},
icon: const Icon(Icons.report_problem_outlined).paddingOnly(right: 21),
),
],
), ),
body: SizedBox( body: SizedBox(
width: double.infinity, width: double.infinity,
@ -33,6 +54,12 @@ class AppointmentDetailListPage extends StatelessWidget {
} else { } else {
return ListView.separated( return ListView.separated(
itemBuilder: (context, index) { itemBuilder: (context, index) {
if (customerID == 0) {
customerID = appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index].customerID ?? 0;
}
if (customerName.isEmpty) {
customerName = appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index].customerName ?? "";
}
return GeneralAppointmentWidget( return GeneralAppointmentWidget(
appointmentListModel: appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index], appointmentListModel: appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index],
isNeedTotalPayment: true, isNeedTotalPayment: true,
@ -41,7 +68,8 @@ class AppointmentDetailListPage extends StatelessWidget {
onTap: () { onTap: () {
appointmentsVM.selectedAppointmentId = appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index].id ?? 0; appointmentsVM.selectedAppointmentId = appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index].id ?? 0;
appointmentsVM.selectedAppointmentSubIndex = index; appointmentsVM.selectedAppointmentSubIndex = index;
navigateWithName(context, AppRoutes.updateAppointmentPage, arguments: appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index]); navigateWithName(context, AppRoutes.updateAppointmentPage,
arguments: appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index]);
}, },
); );
}, },

@ -104,32 +104,35 @@ class _AppointmentPageState extends State<AppointmentPage> {
EmptyWidget( EmptyWidget(
spacerWidget: const SizedBox(height: 25), spacerWidget: const SizedBox(height: 25),
text: LocaleKeys.noAppointmentFound.tr(), text: LocaleKeys.noAppointmentFound.tr(),
)
else ...[
ListView.separated(
itemBuilder: (context, index) {
return GeneralAppointmentWidget(
isNeedToShowItems: true,
appointmentListModel: appointmentsVM.myFilteredAppointments2[index],
isNeedTotalPayment: false,
onTap: () {
context.read<AppointmentsVM>().selectedAppointmentIndex = index;
navigateWithName(
context,
AppRoutes.appointmentDetailList,
// arguments: appointmentsVM
// .myFilteredAppointments2[index]
// .customerAppointmentList,
);
},
);
},
separatorBuilder: (context, snapchat) {
return 21.height;
},
itemCount: appointmentsVM.myFilteredAppointments2.length,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: const EdgeInsets.all(21),
), ),
ListView.separated( ],
itemBuilder: (context, index) {
return GeneralAppointmentWidget(
appointmentListModel: appointmentsVM.myFilteredAppointments2[index],
isNeedTotalPayment: false,
onTap: () {
context.read<AppointmentsVM>().selectedAppointmentIndex = index;
navigateWithName(
context,
AppRoutes.appointmentDetailList,
// arguments: appointmentsVM
// .myFilteredAppointments2[index]
// .customerAppointmentList,
);
},
);
},
separatorBuilder: (context, snapchat) {
return 21.height;
},
itemCount: appointmentsVM.myFilteredAppointments2.length,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: const EdgeInsets.all(21),
),
], ],
), ),
), ),

@ -1,13 +1,10 @@
import 'package:car_provider_app/config/provider_routes.dart';
import 'package:car_provider_app/views/appoinments/widget/sheets.dart'; import 'package:car_provider_app/views/appoinments/widget/sheets.dart';
import 'package:car_provider_app/views/dashboard/widget/general_appointment_widget.dart'; import 'package:car_provider_app/views/dashboard/widget/general_appointment_widget.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/config/dependency_injection.dart'; import 'package:mc_common_app/config/dependency_injection.dart';
import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart'; import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
@ -22,10 +19,15 @@ import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
class UpdateAppointmentPage extends StatelessWidget { class UpdateAppointmentPage extends StatefulWidget {
late AppointmentListModel appointmentListModel; const UpdateAppointmentPage({super.key});
UpdateAppointmentPage({Key? key}) : super(key: key); @override
State<UpdateAppointmentPage> createState() => _UpdateAppointmentPageState();
}
class _UpdateAppointmentPageState extends State<UpdateAppointmentPage> {
late AppointmentListModel appointmentListModel;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -39,144 +41,157 @@ class UpdateAppointmentPage extends StatelessWidget {
if (appointmentsVM.state == ViewState.busy) { if (appointmentsVM.state == ViewState.busy) {
return const Center(child: CircularProgressIndicator()); return const Center(child: CircularProgressIndicator());
} else { } else {
return Column( return RefreshIndicator(
children: [ onRefresh: () async => _updateAppointment(context, appointmentListModel.branchId ?? 0),
Expanded( child: Column(
child: ListView( children: [
padding: const EdgeInsets.all(21), Expanded(
children: [ child: ListView(
GeneralAppointmentWidget( padding: const EdgeInsets.all(21),
appointmentListModel: appointmentListModel, children: [
isNeedTotalPayment: true, GeneralAppointmentWidget(
isNeedToShowItems: true, appointmentListModel: appointmentListModel,
isNeedToShowToMoreText: false, isNeedTotalPayment: true,
onTap: () {}, isNeedToShowItems: true,
), isNeedToShowToMoreText: false,
21.height, isFromUpdateAppointmentPage: true,
if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.confirmed || onTap: () {},
appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.arrived ||
appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.workStarted) ...[
ShowFillButton(
title: ("+ ${LocaleKeys.addNewService.tr()}"),
txtColor: MyColors.darkPrimaryColor,
isFilled: false,
onPressed: () {
navigateWithName(
context,
AppRoutes.addServiceInAppointment,
arguments: appointmentListModel,
);
},
), ),
21.height,
if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.confirmed ||
appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.arrived ||
appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.workStarted) ...[
ShowFillButton(
title: ("+ ${LocaleKeys.addNewService.tr()}"),
txtColor: MyColors.darkPrimaryColor,
isFilled: false,
onPressed: () {
navigateWithName(
context,
AppRoutes.addServiceInAppointment,
arguments: appointmentListModel,
);
},
),
],
], ],
], ),
), ),
), if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.cancelled) ...[
if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.cancelled) ...[ Utils.buildStatusContainer(LocaleKeys.appointmentCancelled.tr()).paddingAll(10),
Utils.buildStatusContainer(LocaleKeys.appointmentCancelled.tr()).paddingAll(10), ],
], if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.booked)
if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.booked) Row(
Row( mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
children: [ Expanded(child: showPayNowButton(context, appointmentsVM, color: MyColors.greenColor)),
Expanded(child: showPayNowButton(context, appointmentsVM)), 12.width,
12.width, Expanded(child: showCancelButton(context, appointmentsVM)),
Expanded(child: showCancelButton(context, appointmentsVM)), ],
], ).paddingAll(21),
).paddingAll(21),
if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.confirmed &&
(appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.payPartial ||
appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.defaultStatus))
Column(
children: [
Row(
children: [
Expanded(child: showArrivedButton(context, appointmentsVM)),
12.width,
Expanded(child: showCancelButton(context, appointmentsVM)),
],
),
],
).paddingAll(21),
if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.confirmed && if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.arrived &&
(appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.payPartial || appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.defaultStatus)) (appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.payPartial ||
Column( appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.defaultStatus))
children: [ Row(
showArrivedButton(context, appointmentsVM), mainAxisAlignment: MainAxisAlignment.spaceBetween,
], children: [
).paddingAll(21), Expanded(child: showPayNowButton(context, appointmentsVM)),
12.width,
Expanded(child: showPayLaterButton(context, appointmentsVM)),
],
).paddingAll(21),
if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.arrived && if ((appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.arrived || appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.workStarted) &&
(appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.payPartial || appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.defaultStatus)) appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.payNow)
Row( Utils.buildStatusContainer(LocaleKeys.waitingPaymentfromtheCustomer.tr()).paddingAll(10),
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(child: showPayNowButton(context, appointmentsVM)),
12.width,
Expanded(child: showPayLaterButton(context, appointmentsVM)),
],
).paddingAll(21),
if ((appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.arrived || appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.workStarted) && if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.arrived &&
appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.payNow) (appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.paid ||
Utils.buildStatusContainer(LocaleKeys.waitingPaymentfromtheCustomer.tr()).paddingAll(10), appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.payLater))
Column(
children: [
showWorkStartButton(context, appointmentsVM),
],
).paddingAll(21),
if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.arrived && if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.workStarted && appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.payPartial)
(appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.paid || appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.payLater)) Row(
Column( mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
showWorkStartButton(context, appointmentsVM), Expanded(child: showPayNowButton(context, appointmentsVM)),
], 12.width,
).paddingAll(21), Expanded(child: showPayLaterButton(context, appointmentsVM)),
],
).paddingAll(21),
// "Show Pay Now".toText(),
if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.workStarted && appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.payPartial) if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.workStarted && appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.paid)
Row( Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
children: [ showCompleteButton(context, appointmentsVM),
Expanded(child: showPayNowButton(context, appointmentsVM)), ],
12.width, ).paddingAll(21),
Expanded(child: showPayLaterButton(context, appointmentsVM)), // "Show Complete Button".toText(),
], if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.workStarted && appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.payLater)
).paddingAll(21), showPayNowButton(context, appointmentsVM).paddingAll(21),
// "Show Pay Now".toText(),
if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.workStarted && appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.paid) if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.visitCompleted) ...[
Column( Utils.buildStatusContainer(LocaleKeys.appointmentisCompleted.tr()).paddingAll(10),
children: [ ],
showCompleteButton(context, appointmentsVM),
],
).paddingAll(21),
// "Show Complete Button".toText(),
if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.workStarted && appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.payLater)
showPayNowButton(context, appointmentsVM).paddingAll(21),
if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.visitCompleted) ...[ //TODO: THIS NEEDS TO BE CHECKED. IMPORTANT
Utils.buildStatusContainer(LocaleKeys.appointmentisCompleted.tr()).paddingAll(10), // Padding(
// padding: const EdgeInsets.all(21.0),
// child: Column(
// children: [
// ShowFillButton(
// title: "Confirm Arrive",
// maxWidth: double.infinity,
// onPressed: () {
// showMyBottomSheet(
// context,
// child: ShowCollectPaymentSheet(
// onClickYes: () {},
// onClickNo: () {},
// ),
// );
// },
// ),
// 12.height,
// ShowFillButton(
// title: "Cancel Appointment",
// maxWidth: double.infinity,
// isFilled: false,
// txtColor: MyColors.redColor,
// borderColor: MyColors.redColor,
// onPressed: () {
// showMyBottomSheet(context,
// child: CancelAppointmentReasonSheet(
// onCancelClick: (String reason) {},
// ));
// },
// ),
// ],
// ),
// ),
], ],
),
//TODO: THIS NEEDS TO BE CHECKED. IMPORTANT
// Padding(
// padding: const EdgeInsets.all(21.0),
// child: Column(
// children: [
// ShowFillButton(
// title: "Confirm Arrive",
// maxWidth: double.infinity,
// onPressed: () {
// showMyBottomSheet(
// context,
// child: ShowCollectPaymentSheet(
// onClickYes: () {},
// onClickNo: () {},
// ),
// );
// },
// ),
// 12.height,
// ShowFillButton(
// title: "Cancel Appointment",
// maxWidth: double.infinity,
// isFilled: false,
// txtColor: MyColors.redColor,
// borderColor: MyColors.redColor,
// onPressed: () {
// showMyBottomSheet(context,
// child: CancelAppointmentReasonSheet(
// onCancelClick: (String reason) {},
// ));
// },
// ),
// ],
// ),
// ),
],
); );
} }
})), })),
@ -189,9 +204,14 @@ class UpdateAppointmentPage extends StatelessWidget {
maxWidth: double.infinity, maxWidth: double.infinity,
onPressed: () async { onPressed: () async {
Utils.showLoading(context); Utils.showLoading(context);
await appointmentsVM.updateAppointmentStatus(appointmentId: appointmentListModel.id!, appointmentStatusEnum: AppointmentStatusEnum.workStarted); bool status = await appointmentsVM.updateAppointmentStatus(appointmentId: appointmentListModel.id!, appointmentStatusEnum: AppointmentStatusEnum.workStarted);
if (status) {
_updateAppointment(context, appointmentListModel.branchId ?? 0);
}
Utils.hideLoading(context); Utils.hideLoading(context);
pop(context); // pop(context);
// showMyBottomSheet( // showMyBottomSheet(
// context, // context,
@ -204,14 +224,17 @@ class UpdateAppointmentPage extends StatelessWidget {
); );
} }
Widget showPayNowButton(BuildContext context, AppointmentsVM appointmentsVM) { Widget showPayNowButton(BuildContext context, AppointmentsVM appointmentsVM, {Color? color}) {
return ShowFillButton( return ShowFillButton(
title: LocaleKeys.payNow.tr(), title: LocaleKeys.payNow.tr(),
maxWidth: double.infinity, maxWidth: double.infinity,
backgroundColor: color ?? MyColors.darkPrimaryColor,
onPressed: () async { onPressed: () async {
Utils.showLoading(context); Utils.showLoading(context);
await appointmentsVM.updateAppointmentPaymentStatus({"appointmentID": appointmentListModel.id.toString(), "appointmentServicePaymentStatusID": 2}); bool status = await appointmentsVM.updateAppointmentPaymentStatus({"appointmentID": appointmentListModel.id.toString(), "appointmentServicePaymentStatusID": 2});
_updateAppointment(context, appointmentListModel.branchId ?? 0); if (status) {
_updateAppointment(context, appointmentListModel.branchId ?? 0);
}
Utils.hideLoading(context); Utils.hideLoading(context);
pop(context); pop(context);
}, },
@ -222,10 +245,14 @@ class UpdateAppointmentPage extends StatelessWidget {
return ShowFillButton( return ShowFillButton(
title: LocaleKeys.arrived.tr(), title: LocaleKeys.arrived.tr(),
maxWidth: double.infinity, maxWidth: double.infinity,
txtColor: MyColors.white,
backgroundColor: MyColors.greenColor,
onPressed: () async { onPressed: () async {
Utils.showLoading(context); Utils.showLoading(context);
await appointmentsVM.updateAppointmentStatus(appointmentId: appointmentListModel.id!, appointmentStatusEnum: AppointmentStatusEnum.arrived); bool status = await appointmentsVM.updateAppointmentStatus(appointmentId: appointmentListModel.id!, appointmentStatusEnum: AppointmentStatusEnum.arrived);
_updateAppointment(context, appointmentListModel.branchId ?? 0); if (status) {
_updateAppointment(context, appointmentListModel.branchId ?? 0);
}
Utils.hideLoading(context); Utils.hideLoading(context);
pop(context); pop(context);
}, },
@ -260,19 +287,25 @@ class UpdateAppointmentPage extends StatelessWidget {
); );
} }
Widget showCancelButton(BuildContext context, AppointmentsVM appointmentsVM) { Widget showCancelButton(BuildContext pContext, AppointmentsVM appointmentsVM) {
return ShowFillButton( return ShowFillButton(
title: LocaleKeys.cancel.tr(), title: LocaleKeys.cancel.tr(),
maxWidth: double.infinity, maxWidth: double.infinity,
isFilled: false, txtColor: MyColors.white,
txtColor: MyColors.redColor, backgroundColor: MyColors.redColor,
borderColor: MyColors.redColor,
onPressed: () { onPressed: () {
showMyBottomSheet( showModalBottomSheet(
context, context: pContext,
child: ShowCollectPaymentSheet( isScrollControlled: true,
onClickYes: () {}, builder: (context) => CancelAppointmentReasonSheet(
onClickNo: () {}, onCancelClick: (String reason) async {
pop(context);
await appointmentsVM.onCancelAppointmentPressed(context: pContext, appointmentListModel: appointmentListModel).whenComplete(() async {
await _updateAppointment(pContext, appointmentListModel.branchId ?? 0);
pop(pContext);
pop(pContext);
});
},
), ),
); );
}, },

@ -1,3 +1,5 @@
import 'dart:developer';
import 'package:car_provider_app/view_models/items_view_model.dart'; import 'package:car_provider_app/view_models/items_view_model.dart';
import 'package:car_provider_app/views/branch_management/schedule/widgets/chips_picker_item.dart'; import 'package:car_provider_app/views/branch_management/schedule/widgets/chips_picker_item.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -13,11 +15,11 @@ import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
class SelectItemsSheet extends StatelessWidget { class SelectItemsSheet extends StatelessWidget {
int serviceId; final int serviceId;
Function(List<ItemData>) onSelectItems; final Function(List<ItemData>) onSelectItems;
List<PickerItem>? list; final List<PickerItem>? list;
SelectItemsSheet({Key? key, required this.serviceId, required this.onSelectItems, this.list}) : super(key: key); const SelectItemsSheet({super.key, required this.serviceId, required this.onSelectItems, this.list});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -72,10 +74,11 @@ class SelectItemsSheet extends StatelessWidget {
controlAffinity: ListTileControlAffinity.leading, controlAffinity: ListTileControlAffinity.leading,
title: itemsVM.serviceItems!.data![index].name!.toText(fontSize: 16), title: itemsVM.serviceItems!.data![index].name!.toText(fontSize: 16),
subtitle: itemsVM.serviceItems!.data![index].price.toString().toText(fontSize: 14, color: MyColors.lightTextColor), subtitle: itemsVM.serviceItems!.data![index].price.toString().toText(fontSize: 14, color: MyColors.lightTextColor),
value: itemsVM.serviceItems!.data![index].isUpdateOrSelected, value: itemsVM.serviceItems!.data![index].isUpdateOrSelected,
onChanged: (bool? v) { onChanged: (bool? v) {
itemsVM.serviceItems!.data![index].isUpdateOrSelected = v; itemsVM.serviceItems!.data![index].isUpdateOrSelected = v;
log("itemsVM.serviceItems!.data![index].isUpdateOrSelected: ${itemsVM.serviceItems!.data![index].isUpdateOrSelected}");
itemsVM.notifyListeners(); itemsVM.notifyListeners();
}, },
); );
@ -97,9 +100,10 @@ class SelectItemsSheet extends StatelessWidget {
maxWidth: double.infinity, maxWidth: double.infinity,
margin: const EdgeInsets.all(20), margin: const EdgeInsets.all(20),
onPressed: () { onPressed: () {
if (context.read<ItemsVM>().serviceItems != null) { final itemsVM = context.read<ItemsVM>();
if (itemsVM.serviceItems != null) {
List<ItemData> list = []; List<ItemData> list = [];
for (var element in context.read<ItemsVM>().serviceItems!.data!) { for (var element in itemsVM.serviceItems!.data!) {
if (element.isUpdateOrSelected ?? false) { if (element.isUpdateOrSelected ?? false) {
list.add(element); list.add(element);
} }

@ -1,23 +1,22 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/models/chat_models/chat_message_model.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/utils/utils.dart'; import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart'; import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/checkbox_with_title_desc.dart';
import 'package:mc_common_app/widgets/common_widgets/info_bottom_sheet.dart';
import 'package:mc_common_app/widgets/txt_field.dart'; import 'package:mc_common_app/widgets/txt_field.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
class ShowCollectPaymentSheet extends StatelessWidget { class ShowCollectPaymentSheet extends StatelessWidget {
Function() onClickYes; final Function() onClickYes;
Function() onClickNo; final Function() onClickNo;
ShowCollectPaymentSheet( const ShowCollectPaymentSheet({required this.onClickYes, required this.onClickNo, super.key});
{required this.onClickYes, required this.onClickNo, Key? key})
: super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -26,9 +25,9 @@ class ShowCollectPaymentSheet extends StatelessWidget {
child: Column( child: Column(
children: [ children: [
LocaleKeys.collectMoneyBefore.tr().toText( LocaleKeys.collectMoneyBefore.tr().toText(
fontSize: 24, fontSize: 24,
isBold: true, isBold: true,
), ),
21.height, 21.height,
Row( Row(
children: [ children: [
@ -55,134 +54,91 @@ class ShowCollectPaymentSheet extends StatelessWidget {
} }
} }
class Reason {
String title;
bool isSelected;
Reason(this.title, this.isSelected);
}
class CancelAppointmentReasonSheet extends StatefulWidget { class CancelAppointmentReasonSheet extends StatefulWidget {
Function(String) onCancelClick; final Function(String) onCancelClick;
CancelAppointmentReasonSheet({required this.onCancelClick, Key? key}) const CancelAppointmentReasonSheet({required this.onCancelClick, super.key});
: super(key: key);
@override @override
State<CancelAppointmentReasonSheet> createState() => State<CancelAppointmentReasonSheet> createState() => _CancelAppointmentReasonSheetState();
_CancelAppointmentReasonSheetState();
} }
class _CancelAppointmentReasonSheetState class _CancelAppointmentReasonSheetState extends State<CancelAppointmentReasonSheet> {
extends State<CancelAppointmentReasonSheet> {
String reason = ""; String reason = "";
List<Reason> reasonList = [ List<OfferRequestCommentModel> reasonList = [
Reason("Operational Issue", true), OfferRequestCommentModel(title: LocaleKeys.operationalIssue.tr(), isSelected: true, index: 0),
Reason("Material Issue", false), OfferRequestCommentModel(title: LocaleKeys.materialIssue.tr(), isSelected: false, index: 1),
Reason("The customer no longer responding", false), OfferRequestCommentModel(title: LocaleKeys.customerNotResponding.tr(), isSelected: false, index: 2),
Reason("Other", false), OfferRequestCommentModel(title: LocaleKeys.otherVar.tr(), isSelected: false, index: 3),
]; ];
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return InfoBottomSheet(
padding: const EdgeInsets.only(left: 21, right: 21, top: 12, bottom: 21), title: LocaleKeys.pleaseSpecify.tr().toText(fontSize: 28, isBold: true, letterSpacing: -1.44, height: 1),
width: double.infinity, description: Padding(
child: Column( padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
crossAxisAlignment: CrossAxisAlignment.start, child: Column(
children: [ crossAxisAlignment: CrossAxisAlignment.start,
LocaleKeys.reason.tr().toText(fontSize: 24, isBold: true), children: [
ListView.separated( LocaleKeys.selectReasonBeforeCancel.tr().toText(fontSize: 13, color: MyColors.lightTextColor, fontWeight: MyFonts.Medium),
itemBuilder: (context, index) { Column(
return Padding( crossAxisAlignment: CrossAxisAlignment.start,
padding: const EdgeInsets.only(top: 12, bottom: 12), children: [
child: Row( 12.height,
children: [ ListView.separated(
Container( shrinkWrap: true,
width: 14, itemCount: reasonList.length,
height: 14, separatorBuilder: (BuildContext context, int index) {
decoration: BoxDecoration( return const Divider(thickness: 0.5);
color: reasonList[index].isSelected },
? MyColors.darkPrimaryColor itemBuilder: (BuildContext context, int index) {
: Colors.transparent, OfferRequestCommentModel offerRequestCommentModel = reasonList[index];
borderRadius: BorderRadius.circular(122), return CircleCheckBoxWithTitle(
border: Border.all( isChecked: offerRequestCommentModel.isSelected ?? false,
color: reasonList[index].isSelected title: '${offerRequestCommentModel.title}',
? MyColors.darkPrimaryColor onSelected: () {
: borderColor, for (var element in reasonList) {
width: 1), element.isSelected = false;
), }
child: const Icon(
Icons.done, setState(() {
size: 12, reason = reasonList[index].title ?? "";
color: Colors.white, reasonList[index].isSelected = true;
), });
},
selectedColor: MyColors.darkPrimaryColor,
);
},
),
if (reason == LocaleKeys.otherVar.tr()) ...[
12.height,
TxtField(
maxLines: 5,
keyboardType: TextInputType.text,
hint: LocaleKeys.description.tr(),
onChanged: (v) {
reason = v;
},
), ),
12.width,
reasonList[index].title.toText(isBold: true)
], ],
), ],
).onPress(() {
for (var element in reasonList) {
element.isSelected = false;
}
setState(() {
reason = reasonList[index].title;
reasonList[index].isSelected = true;
});
});
},
separatorBuilder: (context, index) {
return Container(
width: double.infinity,
height: 1,
color: MyColors.borderColor,
);
},
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: reasonList.length,
),
if (reason == "Other")
TxtField(
hint: LocaleKeys.typeHere.tr(),
maxLines: 5,
onChanged: (v) {
reason = v;
},
),
12.height,
Row(
children: [
Expanded(
child: ShowFillButton(
title: LocaleKeys.no.tr(),
isFilled: false,
txtColor: MyColors.darkPrimaryColor,
onPressed: () {
pop(context);
},
),
), ),
12.width, 25.height,
Expanded( ShowFillButton(
child: ShowFillButton( title: LocaleKeys.cancel.tr(),
title: LocaleKeys.yes.tr(), onPressed: () {
onPressed: () { if (reason.isEmpty && reason == LocaleKeys.otherVar.tr()) {
if (reason.isEmpty || reason == "Other") { Utils.showToast(LocaleKeys.pleaseSelectReason.tr());
Utils.showToast(LocaleKeys.pleaseSelectReason.tr()); } else {
} else { widget.onCancelClick(reason);
widget.onCancelClick(reason); }
pop(context); },
} maxWidth: double.infinity,
},
),
), ),
19.height,
], ],
) ),
], ));
),
);
} }
} }

@ -1,4 +1,5 @@
import 'dart:async'; import 'dart:async';
import 'dart:developer';
import 'package:car_provider_app/view_models/schedule_view_model.dart'; import 'package:car_provider_app/view_models/schedule_view_model.dart';
import 'package:car_provider_app/views/branch_management/branch/dealer/widget/assign_dealer_user_sheet.dart'; import 'package:car_provider_app/views/branch_management/branch/dealer/widget/assign_dealer_user_sheet.dart';
@ -13,6 +14,7 @@ import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart'; import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/categroy.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/utils/navigator.dart';
@ -296,7 +298,7 @@ class _BranchDetailPageState extends State<BranchDetailPage> {
.margin(right: 5), .margin(right: 5),
).onPress(() { ).onPress(() {
if (widget.branchData.branchStatus == BranchStatusEnum.pending || widget.branchData.branchStatus == BranchStatusEnum.rejected) { if (widget.branchData.branchStatus == BranchStatusEnum.pending || widget.branchData.branchStatus == BranchStatusEnum.rejected) {
Utils.showToast("Please wait for the branch verification."); Utils.showToast(LocaleKeys.waitForBranchVerification.tr());
return; return;
} }
context.read<ScheduleVM>().currentSelectedBranchName = widget.branchData.branchName.toString(); context.read<ScheduleVM>().currentSelectedBranchName = widget.branchData.branchName.toString();
@ -308,7 +310,7 @@ class _BranchDetailPageState extends State<BranchDetailPage> {
bgColor: MyColors.white, bgColor: MyColors.white,
onTap: () { onTap: () {
if (widget.branchData.branchStatus == BranchStatusEnum.pending || widget.branchData.branchStatus == BranchStatusEnum.rejected) { if (widget.branchData.branchStatus == BranchStatusEnum.pending || widget.branchData.branchStatus == BranchStatusEnum.rejected) {
Utils.showToast("Please wait for the branch verification."); Utils.showToast(LocaleKeys.waitForBranchVerification.tr());
return; return;
} }
navigateWithName( navigateWithName(
@ -367,7 +369,21 @@ class _BranchDetailPageState extends State<BranchDetailPage> {
return buildServiceTileWidget(pIndex, serviceVM).onPress(() { return buildServiceTileWidget(pIndex, serviceVM).onPress(() {
serviceVM.categories[pIndex].branchId = widget.branchData.id.toString(); serviceVM.categories[pIndex].branchId = widget.branchData.id.toString();
serviceVM.categories[pIndex].branchName = widget.branchData.branchName.toString(); serviceVM.categories[pIndex].branchName = widget.branchData.branchName.toString();
navigateWithName(context, AppRoutes.servicesList, arguments: serviceVM.categories[pIndex]); // CategoryData categoryData = serviceVM.categories[pIndex];
serviceVM.applyFilterOnBranchServices(serviceStatusEnum: ServiceStatusEnum.approvedOrActive);
CategoryData categoryData = CategoryData(
id: serviceVM.categories[pIndex].id,
branchId: serviceVM.categories[pIndex].branchId,
branchName: serviceVM.categories[pIndex].branchName,
categoryName: serviceVM.categories[pIndex].categoryName,
categoryNameN: serviceVM.categories[pIndex].categoryNameN,
serviceCategoryIconUrl: serviceVM.categories[pIndex].serviceCategoryIconUrl,
serviceCategoryImageUrl: serviceVM.categories[pIndex].serviceCategoryImageUrl,
services: [],
);
navigateWithName(context, AppRoutes.servicesList, arguments: categoryData);
}); });
}, },
itemCount: serviceVM.categories.length, itemCount: serviceVM.categories.length,

@ -1,26 +1,25 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/utils/dialogs_and_bottomsheets.dart';
import 'package:mc_common_app/view_models/dashboard_view_model_provider.dart';
import 'package:mc_common_app/view_models/service_view_model.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart'; import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/dialogs_and_bottomsheets.dart';
import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/utils/utils.dart'; import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/dashboard_view_model_provider.dart';
import 'package:mc_common_app/view_models/service_view_model.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart'; import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart'; import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart'; import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:mc_common_app/widgets/tab/role_type_tab.dart';
import 'package:mc_common_app/widgets/row_with_arrow.dart'; import 'package:mc_common_app/widgets/row_with_arrow.dart';
import 'package:mc_common_app/widgets/tab/role_type_tab.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class BranchListPage extends StatelessWidget { class BranchListPage extends StatelessWidget {
@ -139,12 +138,12 @@ class BranchListPage extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Utils.statusContainerChip( Utils.statusContainerChip(
text: branchModel.branchStatusLabel ?? "", text: (branchModel.branchStatusLabel ?? "").replaceFirst("ApprovedOrActive", "Active"),
chipColor: Utils.getChipColorByBranchStatus(branchModel.branchStatus!), chipColor: Utils.getChipColorByBranchStatus(branchModel.branchStatus!),
), ),
], ],
), ),
2.height, 5.height,
// branchModel.distanceKm == null // branchModel.distanceKm == null
// ? const SizedBox() // ? const SizedBox()
// : Row( // : Row(
@ -168,7 +167,7 @@ class BranchListPage extends StatelessWidget {
children: [ children: [
(branchModel.branchName ?? "").toText(fontSize: 16, height: 18 / 16), (branchModel.branchName ?? "").toText(fontSize: 16, height: 18 / 16),
], ],
).withArrow(isArrowEnabled: true).margin(right: 10), ).withArrow(isArrowEnabled: branchModel.branchStatus != BranchStatusEnum.blocked).margin(right: 10),
(branchModel.branchDescription ?? "").toText( (branchModel.branchDescription ?? "").toText(
fontSize: 10, fontSize: 10,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
@ -180,6 +179,9 @@ class BranchListPage extends StatelessWidget {
), ),
], ],
).toWhiteContainer(width: double.infinity, pading: const EdgeInsets.all(12)).onPress(() async { ).toWhiteContainer(width: double.infinity, pading: const EdgeInsets.all(12)).onPress(() async {
if (branchModel.branchStatus == BranchStatusEnum.blocked) {
return;
}
branchModel.countryID = serviceVM.branches!.data!.countryID; branchModel.countryID = serviceVM.branches!.data!.countryID;
branchModel.countryName = serviceVM.branches!.data!.countryName; branchModel.countryName = serviceVM.branches!.data!.countryName;
serviceVM.updateSelectedBranchId(branchModel.id); serviceVM.updateSelectedBranchId(branchModel.id);

@ -180,7 +180,7 @@ class _DefineBranchViewState extends State<DefineBranchView> {
text: LocaleKeys.attachImage.tr(), text: LocaleKeys.attachImage.tr(),
icon: MyAssets.attachmentIcon.buildSvg(), icon: MyAssets.attachmentIcon.buildSvg(),
), ),
], ],
if (serviceVM.branchImageError != "") ...[ if (serviceVM.branchImageError != "") ...[
10.height, 10.height,
Row( Row(
@ -249,8 +249,8 @@ class _DefineBranchViewState extends State<DefineBranchView> {
closedTime: serviceVM.closedTime, closedTime: serviceVM.closedTime,
cityID: serviceVM.cityId, cityID: serviceVM.cityId,
address: serviceVM.address, address: serviceVM.address,
latitude: widget.branchData!.latitude ?? "0", latitude: (serviceVM.latitude).toString(),
longitude: widget.branchData!.longitude ?? "0", longitude: (serviceVM.longitude).toString(),
); );
}, },
).horPaddingMain(), ).horPaddingMain(),

@ -1,4 +1,5 @@
import 'dart:async'; import 'dart:async';
import 'dart:developer';
import 'package:car_provider_app/view_models/schedule_view_model.dart'; import 'package:car_provider_app/view_models/schedule_view_model.dart';
import 'package:car_provider_app/views/branch_management/schedule/widgets/chips_picker_item.dart'; import 'package:car_provider_app/views/branch_management/schedule/widgets/chips_picker_item.dart';
import 'package:car_provider_app/views/branch_management/schedule/widgets/select_days_sheet.dart'; import 'package:car_provider_app/views/branch_management/schedule/widgets/select_days_sheet.dart';
@ -35,6 +36,8 @@ class _AddSchedulesPageState extends State<AddSchedulesPage> {
late ScheduleData scheduleData; late ScheduleData scheduleData;
int? scheduleID;
setEditData() { setEditData() {
name = scheduleData.scheduleName ?? ""; name = scheduleData.scheduleName ?? "";
startDate = DateHelper.formatAsYearMonthDay(scheduleData.fromDate ?? DateTime.now()); startDate = DateHelper.formatAsYearMonthDay(scheduleData.fromDate ?? DateTime.now());
@ -97,6 +100,10 @@ class _AddSchedulesPageState extends State<AddSchedulesPage> {
DropValue(2, 'Customer Location', ''), DropValue(2, 'Customer Location', ''),
]; ];
DateTime tomorrowDate = DateTime.now().add(const Duration(days: 1)).subtract(
Duration(hours: DateTime.now().hour, minutes: DateTime.now().minute, seconds: DateTime.now().second, microseconds: DateTime.now().microsecond),
);
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -107,7 +114,9 @@ class _AddSchedulesPageState extends State<AddSchedulesPage> {
schedulevm.selectedServicesItems = []; schedulevm.selectedServicesItems = [];
schedulevm.selectedDaysItems = []; schedulevm.selectedDaysItems = [];
if (scheduleData.id != null) { if (scheduleData.id != null) {
scheduleID = scheduleData.id;
setEditData(); setEditData();
setState(() {});
} }
}); });
} }
@ -115,7 +124,7 @@ class _AddSchedulesPageState extends State<AddSchedulesPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: CustomAppBar(title: LocaleKeys.createGroupServices.tr()), appBar: CustomAppBar(title: scheduleID == null ? LocaleKeys.createGroupServices.tr() : LocaleKeys.updateGroupServices.tr()),
body: SizedBox( body: SizedBox(
width: double.infinity, width: double.infinity,
child: Consumer<ScheduleVM>( child: Consumer<ScheduleVM>(
@ -172,8 +181,20 @@ class _AddSchedulesPageState extends State<AddSchedulesPage> {
onTap: () async { onTap: () async {
startDate = await Utils.pickDateFromDatePicker( startDate = await Utils.pickDateFromDatePicker(
context, context,
initial: tomorrowDate,
firstDate: DateTime.now(), firstDate: DateTime.now(),
); );
if (endDate.isNotEmpty) {
DateTime sDate = DateTime.parse(startDate);
DateTime eDate = DateTime.parse(endDate);
if (sDate.isAfter(eDate)) {
startDate = "";
Utils.showToast(LocaleKeys.endDateAfterStartDate.tr());
}
}
FocusManager.instance.primaryFocus?.unfocus(); FocusManager.instance.primaryFocus?.unfocus();
scheduleVM.refresh(); scheduleVM.refresh();
}, },
@ -188,10 +209,30 @@ class _AddSchedulesPageState extends State<AddSchedulesPage> {
value: endDate, value: endDate,
isNeedClickAll: true, isNeedClickAll: true,
onTap: () async { onTap: () async {
DateTime? firstDate;
DateTime? sDate;
if (startDate.isEmpty) {
Utils.showToast(LocaleKeys.pleaseEnterStartDateFirst.tr());
return;
} else {
sDate = DateTime.parse(startDate);
firstDate = sDate.add(const Duration(days: 1)).subtract(
Duration(hours: DateTime.now().hour, minutes: DateTime.now().minute, seconds: DateTime.now().second, microseconds: DateTime.now().microsecond),
);
}
endDate = await Utils.pickDateFromDatePicker( endDate = await Utils.pickDateFromDatePicker(
context, context,
firstDate: DateTime.now(), initial: tomorrowDate,
firstDate: firstDate ?? tomorrowDate,
); );
DateTime eDate = DateTime.parse(endDate);
if (!eDate.isAfter(sDate)) {
endDate = "";
Utils.showToast(LocaleKeys.endDateAfterStartDate.tr());
}
FocusManager.instance.primaryFocus?.unfocus(); FocusManager.instance.primaryFocus?.unfocus();
scheduleVM.refresh(); scheduleVM.refresh();
}, },
@ -226,6 +267,16 @@ class _AddSchedulesPageState extends State<AddSchedulesPage> {
isNeedClickAll: true, isNeedClickAll: true,
onTap: () async { onTap: () async {
startTime = await Utils.pickTime(context); startTime = await Utils.pickTime(context);
if (endTime.isNotEmpty) {
TimeOfDay sTime = TimeOfDayUtils.convertStringToTimeOfDay(startTime);
TimeOfDay eTime = TimeOfDayUtils.convertStringToTimeOfDay(endTime);
if (!eTime.isAfter(sTime)) {
startTime = "";
Utils.showToast(LocaleKeys.endTimeAfterStartTime.tr());
}
}
FocusManager.instance.primaryFocus?.unfocus(); FocusManager.instance.primaryFocus?.unfocus();
scheduleVM.refresh(); scheduleVM.refresh();
}, },
@ -243,11 +294,23 @@ class _AddSchedulesPageState extends State<AddSchedulesPage> {
isNeedClickAll: true, isNeedClickAll: true,
onTap: () async { onTap: () async {
TimeOfDay _startTime = TimeOfDay.now(); TimeOfDay _startTime = TimeOfDay.now();
if (startTime.isNotEmpty) _startTime = TimeOfDay(hour: int.parse(startTime.split(":")[0]), minute: int.parse(startTime.split(":")[1])); if (startTime.isNotEmpty) {
_startTime = TimeOfDay(hour: int.parse(startTime.split(":")[0]), minute: int.parse(startTime.split(":")[1]));
}
endTime = await Utils.pickTime( endTime = await Utils.pickTime(
context, context,
initialTime: _startTime, initialTime: _startTime,
); );
if (startTime.isNotEmpty) {
TimeOfDay sTime = TimeOfDayUtils.convertStringToTimeOfDay(startTime);
TimeOfDay eTime = TimeOfDayUtils.convertStringToTimeOfDay(endTime);
if (!eTime.isAfter(sTime)) {
endTime = "";
Utils.showToast(LocaleKeys.endTimeAfterStartTime.tr());
}
}
FocusManager.instance.primaryFocus?.unfocus(); FocusManager.instance.primaryFocus?.unfocus();
scheduleVM.refresh(); scheduleVM.refresh();
}, },
@ -298,7 +361,7 @@ class _AddSchedulesPageState extends State<AddSchedulesPage> {
), ),
), ),
ShowFillButton( ShowFillButton(
title: LocaleKeys.create.tr(), title: scheduleID == null ? LocaleKeys.create.tr() : LocaleKeys.update.tr(),
maxWidth: double.infinity, maxWidth: double.infinity,
margin: const EdgeInsets.all(20), margin: const EdgeInsets.all(20),
onPressed: () { onPressed: () {
@ -353,102 +416,129 @@ class _AddSchedulesPageState extends State<AddSchedulesPage> {
} }
createSchedule(BuildContext context, ScheduleVM scheduleVM) async { createSchedule(BuildContext context, ScheduleVM scheduleVM) async {
List<int> days = [];
for (var element in scheduleVM.selectedDaysItems) {
days.add(element.id);
}
//TODO: needs to verify with Zahoor about appointment type while creating Schedule
var map = {
"scheduleName": name,
"serviceProviderBranchID": scheduleData.branchId,
"fromDate": startDate,
"toDate": endDate,
"startTime": startTime,
"endTime": endTime,
"slotDurationMinute": slotsTime.replaceFirst(' Minutes', ''),
"perSlotAppointment": appointmentPerSlot,
"deliveryServiceType": 1,
"appointmentType": selectedScheduleLocationDrop.id,
"weeklyOffDays": days
};
Utils.showLoading(context); Utils.showLoading(context);
GenericRespModel scheduleResponse = await scheduleVM.createSchedule(map);
if (scheduleResponse.messageStatus == 1) { try {
List<int> services = []; List<int> services = [];
for (var element in scheduleVM.selectedServicesItems) { for (var element in scheduleVM.selectedServicesItems) {
services.add(element.id); services.add(element.id);
} }
var map1 = { var map1 = {
"branchAppointmentScheduleID": scheduleResponse.data,
"serviceProviderServiceID": services, "serviceProviderServiceID": services,
"serviceGroupDescription": "string", "appointmentType": selectedScheduleLocationDrop.id,
}; };
GenericRespModel servicesResponse = await scheduleVM.addServicesInSchedule(map1); GenericRespModel respModel = await scheduleVM.checkServiceGroupInBranchSchedule(map1);
Utils.hideLoading(context); Utils.hideLoading(context);
if (servicesResponse.messageStatus == 1) {
Utils.showToast("Successfully schedule created"); log("respModel: ${respModel.data}");
context.read<ScheduleVM>().getSchedules(scheduleData.branchId ?? ""); if (respModel.messageStatus == 2) {
pop(context); Utils.showToast(respModel.message ?? "");
return;
}
List<int> days = [];
for (var element in scheduleVM.selectedDaysItems) {
days.add(element.id);
}
var map = {
"scheduleName": name,
"serviceProviderBranchID": scheduleData.branchId,
"fromDate": startDate,
"toDate": endDate,
"startTime": startTime,
"endTime": endTime,
"slotDurationMinute": slotsTime.replaceFirst(' Minutes', ''),
"perSlotAppointment": appointmentPerSlot,
"deliveryServiceType": 1,
"appointmentType": selectedScheduleLocationDrop.id,
"weeklyOffDays": days
};
Utils.showLoading(context);
GenericRespModel scheduleResponse = await scheduleVM.createSchedule(map);
if (scheduleResponse.messageStatus == 1) {
var map1 = {
"branchAppointmentScheduleID": scheduleResponse.data,
"serviceProviderServiceID": services,
"serviceGroupDescription": "string",
};
GenericRespModel servicesResponse = await scheduleVM.addServicesInSchedule(map1);
Utils.hideLoading(context);
if (servicesResponse.messageStatus == 1) {
Utils.showToast("Successfully schedule created");
context.read<ScheduleVM>().getSchedules(scheduleData.branchId ?? "");
pop(context);
} else {
Utils.showToast(servicesResponse.message ?? "");
// context.read<ScheduleVM>().getSchedules(scheduleData.branchId ?? "");
// pop(context);
}
} else { } else {
Utils.showToast(servicesResponse.message ?? ""); Utils.hideLoading(context);
// context.read<ScheduleVM>().getSchedules(scheduleData.branchId ?? ""); Utils.showToast(scheduleResponse.message ?? "");
// pop(context);
} }
} else { } catch (e) {
Utils.showToast(e.toString());
Utils.hideLoading(context); Utils.hideLoading(context);
Utils.showToast(scheduleResponse.message ?? "");
} }
} }
updateSchedule(BuildContext context, ScheduleVM model) async { updateSchedule(BuildContext context, ScheduleVM scheduleVM) async {
List<int> days = []; try {
for (var element in model.selectedDaysItems) { List<int> days = [];
days.add(element.id); for (var element in scheduleVM.selectedDaysItems) {
} days.add(element.id);
var map = {
"id": scheduleData.id,
"scheduleName": name,
"serviceProviderBranchID": scheduleData.branchId,
"fromDate": startDate,
"toDate": endDate,
"startTime": startTime,
"endTime": endTime,
"slotDurationMinute": slotsTime.replaceFirst(' Minutes', ''),
"perSlotAppointment": appointmentPerSlot,
"deliveryServiceType": 1,
"weeklyOffDays": days,
"appointmentType": selectedScheduleLocationDrop.id,
};
Utils.showLoading(context);
GenericRespModel scheduleResponse = await model.updateSchedule(map);
if (scheduleResponse.messageStatus == 1) {
List<int> services = [];
for (var element in model.selectedServicesItems) {
services.add(element.id);
} }
var map1 = { var map = {
"branchAppointmentScheduleID": scheduleData.id, "id": scheduleData.id,
"serviceProviderServiceID": services, "scheduleName": name,
"serviceGroupDescription": "string", "serviceProviderBranchID": scheduleData.branchId,
"fromDate": startDate,
"toDate": endDate,
"startTime": startTime,
"endTime": endTime,
"slotDurationMinute": slotsTime.replaceFirst(' Minutes', ''),
"perSlotAppointment": appointmentPerSlot,
"deliveryServiceType": 1,
"weeklyOffDays": days,
"appointmentType": selectedScheduleLocationDrop.id,
}; };
GenericRespModel servicesResponse = await model.updateServicesInSchedule(map1); Utils.showLoading(context);
Utils.hideLoading(context); GenericRespModel scheduleResponse = await scheduleVM.updateSchedule(map);
if (servicesResponse.messageStatus == 1) { if (scheduleResponse.messageStatus == 1) {
Utils.showToast(servicesResponse.message ?? "Schedule Successfully Updated"); List<int> services = [];
context.read<ScheduleVM>().getSchedules(scheduleData.branchId ?? ""); for (var element in scheduleVM.selectedServicesItems) {
pop(context); services.add(element.id);
}
var map1 = {
"branchAppointmentScheduleID": scheduleData.id,
"serviceProviderServiceID": services,
"serviceGroupDescription": "string",
};
GenericRespModel servicesResponse = await scheduleVM.updateServicesInSchedule(map1);
Utils.hideLoading(context);
if (servicesResponse.messageStatus == 1) {
Utils.showToast(servicesResponse.message ?? "Schedule Successfully Updated");
context.read<ScheduleVM>().getSchedules(scheduleData.branchId ?? "");
pop(context);
} else {
Utils.showToast(servicesResponse.message ?? LocaleKeys.somethingWrong.tr());
}
} else { } else {
Utils.showToast(servicesResponse.message ?? LocaleKeys.somethingWrong.tr()); Utils.hideLoading(context);
Utils.showToast(scheduleResponse.message ?? LocaleKeys.somethingWrong.tr());
} }
} else { } catch (e) {
Utils.showToast(e.toString());
Utils.hideLoading(context); Utils.hideLoading(context);
Utils.showToast(scheduleResponse.message ?? LocaleKeys.somethingWrong.tr());
} }
} }
} }

@ -103,24 +103,21 @@ class _SchedulesListPageState extends State<SchedulesListPage> {
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Expanded(child: scheduleVM.schedule!.data![index].scheduleName.toString().toText(fontSize: 16)), Expanded(child: scheduleVM.schedule!.data![index].scheduleName.toString().toText(fontSize: 16)),
IconButton(
onPressed: () async {
return deleteScheduleConfirmationSheet(index, scheduleVM, context);
},
icon: const Icon(Icons.delete_outline),
color: Colors.red,
),
Padding( Padding(
padding: const EdgeInsets.all(4.0), padding: const EdgeInsets.all(4.0),
child: SvgPicture.asset( child: SvgPicture.asset(
MyAssets.icEdit, MyAssets.icEdit,
width: 16, width: 18,
height: 16, height: 18,
), ),
).onPress(() { ).onPress(() {
scheduleVM.schedule!.data![index].branchId = widget.branchId ?? ""; scheduleVM.schedule!.data![index].branchId = widget.branchId ?? "";
navigateWithName(context, AppRoutes.addSchedule, arguments: scheduleVM.schedule!.data![index]); navigateWithName(context, AppRoutes.addSchedule, arguments: scheduleVM.schedule!.data![index]);
}), }),
MyAssets.closeWithOrangeBg
.buildSvg(height: 28, width: 28)
.onPress(() => deleteScheduleConfirmationSheet(index, scheduleVM, context))
.paddingOnly(top: 3, left: 4),
], ],
), ),
8.height, 8.height,
@ -130,7 +127,8 @@ class _SchedulesListPageState extends State<SchedulesListPage> {
showItem("${LocaleKeys.shiftEndTime.tr()}:", scheduleVM.schedule!.data![index].endTime ?? ""), showItem("${LocaleKeys.shiftEndTime.tr()}:", scheduleVM.schedule!.data![index].endTime ?? ""),
showItem("${LocaleKeys.slotsTime.tr()}:", "${scheduleVM.schedule!.data![index].slotDurationMinute} Mins"), showItem("${LocaleKeys.slotsTime.tr()}:", "${scheduleVM.schedule!.data![index].slotDurationMinute} Mins"),
showItem("${LocaleKeys.appointmentPerSlot.tr()}:", scheduleVM.schedule!.data![index].perSlotAppointment.toString()), showItem("${LocaleKeys.appointmentPerSlot.tr()}:", scheduleVM.schedule!.data![index].perSlotAppointment.toString()),
showItem(LocaleKeys.serviceLocation.tr(), scheduleVM.schedule!.data![index].appointmentType == 1 ? LocaleKeys.companyLocation.tr() : LocaleKeys.customerLocation.tr()), showItem(
LocaleKeys.serviceLocation.tr(), scheduleVM.schedule!.data![index].appointmentType == 1 ? LocaleKeys.companyLocation.tr() : LocaleKeys.customerLocation.tr()),
showItem("${LocaleKeys.offDays.tr()}:", offDays(scheduleVM.schedule!.data![index])), showItem("${LocaleKeys.offDays.tr()}:", offDays(scheduleVM.schedule!.data![index])),
12.height, 12.height,
"${LocaleKeys.services.tr()}:".toText(fontSize: 12, color: MyColors.lightTextColor), "${LocaleKeys.services.tr()}:".toText(fontSize: 12, color: MyColors.lightTextColor),

@ -19,7 +19,7 @@ class ChipsPickerItem extends StatelessWidget {
final List<PickerItem> itemsList; final List<PickerItem> itemsList;
final Function onClick; final Function onClick;
const ChipsPickerItem({Key? key, required this.hint, required this.itemsList, required this.onClick}) : super(key: key); const ChipsPickerItem({super.key, required this.hint, required this.itemsList, required this.onClick});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

@ -5,6 +5,7 @@ import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart'; import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -72,9 +73,7 @@ class _SelectDaysSheetState extends State<SelectDaysSheet> {
); );
}, },
separatorBuilder: (BuildContext context, int index) { separatorBuilder: (BuildContext context, int index) {
return const Divider( return const Divider(height: 1);
height: 1,
);
}, },
itemCount: list.length, itemCount: list.length,
), ),
@ -83,8 +82,19 @@ class _SelectDaysSheetState extends State<SelectDaysSheet> {
title: LocaleKeys.addSelectedDays.tr(), title: LocaleKeys.addSelectedDays.tr(),
maxWidth: double.infinity, maxWidth: double.infinity,
onPressed: () { onPressed: () {
widget.onSelected(list); bool isOneUnSelected = false;
Navigator.pop(context); for (var day in list) {
if (!(day.isSelected ?? false)) {
isOneUnSelected = true;
break;
}
}
if (isOneUnSelected) {
widget.onSelected(list);
Navigator.pop(context);
} else {
Utils.showToast(LocaleKeys.cannotSelectAllDaysAsOff.tr());
}
}, },
) )
], ],

@ -1,4 +1,5 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:developer';
import 'dart:io'; import 'dart:io';
import 'package:car_provider_app/view_models/items_view_model.dart'; import 'package:car_provider_app/view_models/items_view_model.dart';
@ -103,7 +104,7 @@ class _CreateItemPageState extends State<CreateItemPage> {
), ),
12.height, 12.height,
TxtField( TxtField(
hint: LocaleKeys.manufacturedOn.tr(), hint: LocaleKeys.manufacturedOn.tr(),
value: year, value: year,
keyboardType: TextInputType.number, keyboardType: TextInputType.number,
isNeedClickAll: true, isNeedClickAll: true,
@ -196,7 +197,12 @@ class _CreateItemPageState extends State<CreateItemPage> {
maxWidth: double.infinity, maxWidth: double.infinity,
onPressed: () async { onPressed: () async {
if (validation()) { if (validation()) {
var attachedFile = Utils.convertFileToBase64(file!); var attachedFile = "";
if (file != null) {
attachedFile = Utils.convertFileToBase64(file!);
} else {
attachedFile = pickedImage.first.filePath ?? "";
}
if (!(itemData?.isUpdateOrSelected ?? false)) { if (!(itemData?.isUpdateOrSelected ?? false)) {
Map map = { Map map = {
"name": name, "name": name,
@ -215,7 +221,7 @@ class _CreateItemPageState extends State<CreateItemPage> {
GenericRespModel mResponse = await itemsVM!.createServiceItem(map); GenericRespModel mResponse = await itemsVM!.createServiceItem(map);
Utils.hideLoading(context); Utils.hideLoading(context);
if (mResponse.messageStatus == 1) { if (mResponse.messageStatus == 1) {
itemsVM!.getServiceItems(itemData!.serviceProviderServiceId ?? 0); // itemsVM!.getServiceItems(itemData!.serviceProviderServiceId ?? 0);
pop(context); pop(context);
} }
Utils.showToast(mResponse.message ?? ""); Utils.showToast(mResponse.message ?? "");
@ -225,7 +231,7 @@ class _CreateItemPageState extends State<CreateItemPage> {
"name": name, "name": name,
"price": price, "price": price,
"description": description, "description": description,
"itemImage": attachedFile ?? "", "itemImage": file == null ? "" : attachedFile,
"companyID": 1, "companyID": 1,
"manufactureDate": year, "manufactureDate": year,
"serviceProviderServiceID": itemData!.serviceProviderServiceId, "serviceProviderServiceID": itemData!.serviceProviderServiceId,
@ -238,11 +244,10 @@ class _CreateItemPageState extends State<CreateItemPage> {
GenericRespModel mResponse = await itemsVM!.updateServiceItem(map); GenericRespModel mResponse = await itemsVM!.updateServiceItem(map);
Utils.hideLoading(context); Utils.hideLoading(context);
if (mResponse.messageStatus == 1) { if (mResponse.messageStatus == 1) {
itemsVM!.getServiceItems(itemData!.serviceProviderServiceId ?? 0); // itemsVM!.getServiceItems(itemData!.serviceProviderServiceId ?? 0);
pop(context); pop(context);
} }
Utils.showToast(mResponse.message ?? ""); Utils.showToast(mResponse.message ?? "");
pop(context);
} }
} }
}, },
@ -255,7 +260,7 @@ class _CreateItemPageState extends State<CreateItemPage> {
bool validation() { bool validation() {
bool valid = true; bool valid = true;
if (file == null) { if (pickedImage.isEmpty && file == null) {
Utils.showToast("Please add al least one item image."); Utils.showToast("Please add al least one item image.");
valid = false; valid = false;
} }
@ -268,9 +273,6 @@ class _CreateItemPageState extends State<CreateItemPage> {
} else if (price == null) { } else if (price == null) {
Utils.showToast("Please add valid item price"); Utils.showToast("Please add valid item price");
valid = false; valid = false;
} else if (year == null) {
Utils.showToast("Please add valid year");
valid = false;
} }
return valid; return valid;
} }

@ -1,6 +1,8 @@
import 'dart:async'; import 'dart:async';
import 'dart:developer'; import 'dart:developer';
import 'package:flutter/cupertino.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/models/appointments_models/appointment_basic_detail_model.dart';
import 'package:mc_common_app/models/general_models/generic_resp_model.dart'; import 'package:mc_common_app/models/general_models/generic_resp_model.dart';
import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/view_models/service_view_model.dart'; import 'package:mc_common_app/view_models/service_view_model.dart';
@ -29,7 +31,7 @@ import 'package:provider/provider.dart';
class CreateServicesPage3 extends StatefulWidget { class CreateServicesPage3 extends StatefulWidget {
final CreateBranchModel? branchModel; final CreateBranchModel? branchModel;
const CreateServicesPage3(this.branchModel, {Key? key}) : super(key: key); const CreateServicesPage3(this.branchModel, {super.key});
@override @override
State<CreateServicesPage3> createState() => _CreateServicesPage3State(); State<CreateServicesPage3> createState() => _CreateServicesPage3State();
@ -38,6 +40,7 @@ class CreateServicesPage3 extends StatefulWidget {
class _CreateServicesPage3State extends State<CreateServicesPage3> { class _CreateServicesPage3State extends State<CreateServicesPage3> {
bool isAppointmentAvailable = false; bool isAppointmentAvailable = false;
bool isHomeAppointmentAvailable = false; bool isHomeAppointmentAvailable = false;
ServiceStatusEnum serviceStatusEnum = ServiceStatusEnum.pending;
int serviceRage = 0; int serviceRage = 0;
String chargersPerKm = ""; String chargersPerKm = "";
int? categoryId = -1; int? categoryId = -1;
@ -45,18 +48,23 @@ class _CreateServicesPage3State extends State<CreateServicesPage3> {
DropValue? category; DropValue? category;
DropValue? service; DropValue? service;
bool isEditDisabled = false;
bool isServiceActive = false;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
scheduleMicrotask(() async { scheduleMicrotask(() async {
ServiceVM serviceVM = context.read<ServiceVM>(); ServiceVM serviceVM = context.read<ServiceVM>();
log("widget.branchModel!.categoryId: ${widget.branchModel!.categoryId}");
if (widget.branchModel!.categoryId != null) { if (widget.branchModel!.categoryId != null) {
await serviceVM.fetchServicesByCategoryId(int.parse(widget.branchModel!.categoryId ?? "0")); await serviceVM.fetchServicesByCategoryId(int.parse(widget.branchModel!.categoryId ?? "0"));
category = DropValue(int.parse(widget.branchModel!.categoryId ?? "0"), widget.branchModel!.categoryName ?? "", ""); category = DropValue(int.parse(widget.branchModel!.categoryId ?? "0"), widget.branchModel!.categoryName ?? "", "");
service = serviceVM.servicesDropList.firstWhere((element) => element.id == widget.branchModel!.serviceProviderService!.serviceId); service = serviceVM.servicesDropList.firstWhere((element) => element.id == widget.branchModel!.serviceProviderService!.serviceId);
isAppointmentAvailable = widget.branchModel?.serviceProviderService?.isAllowAppointment ?? false; isAppointmentAvailable = widget.branchModel?.serviceProviderService?.isAllowAppointment ?? false;
serviceRage = widget.branchModel?.serviceProviderService?.customerLocationRange ?? 0; serviceRage = widget.branchModel?.serviceProviderService?.customerLocationRange ?? 0;
serviceStatusEnum = widget.branchModel?.serviceProviderService?.serviceStatusEnum ?? ServiceStatusEnum.pending;
isServiceActive = widget.branchModel?.serviceProviderService?.serviceStatusEnum != ServiceStatusEnum.deactivated;
isEditDisabled = serviceStatusEnum == ServiceStatusEnum.blocked;
if (serviceRage > 0) { if (serviceRage > 0) {
isHomeAppointmentAvailable = true; isHomeAppointmentAvailable = true;
} }
@ -71,14 +79,13 @@ class _CreateServicesPage3State extends State<CreateServicesPage3> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
log("categoryId: ${categoryId}");
return Scaffold( return Scaffold(
appBar: CustomAppBar(title: LocaleKeys.editServices.tr()), appBar: CustomAppBar(title: LocaleKeys.editServices.tr()),
body: SizedBox( body: SizedBox(
width: double.infinity, width: double.infinity,
height: double.infinity, height: double.infinity,
child: Consumer<ServiceVM>( child: Consumer<ServiceVM>(
builder: (context, model, _) { builder: (context, serviceVM, _) {
return Column( return Column(
children: [ children: [
Expanded( Expanded(
@ -96,30 +103,67 @@ class _CreateServicesPage3State extends State<CreateServicesPage3> {
serviceId = -1; serviceId = -1;
isAppointmentAvailable = false; isAppointmentAvailable = false;
isHomeAppointmentAvailable = false; isHomeAppointmentAvailable = false;
model.fetchServicesByCategoryId(value.id); serviceVM.fetchServicesByCategoryId(value.id);
}, },
dropdownValue: category, dropdownValue: category,
list: model.categoryDropList, list: serviceVM.categoryDropList,
hint: category != null ? category!.value : LocaleKeys.selectServiceCategory.tr(), hint: category != null ? category!.value : LocaleKeys.selectServiceCategory.tr(),
), ),
12.height, if (widget.branchModel!.isForEdit) ...[
(model.state == ViewState.idle) 22.height,
? categoryId != -1 && model.servicesDropList.isNotEmpty Padding(
padding: const EdgeInsets.symmetric(horizontal: 18),
child: Row(
children: [
LocaleKeys.active.tr().toText(fontSize: 16),
8.width,
Container(
width: 50,
height: 30,
decoration: BoxDecoration(
color: isServiceActive ? MyColors.darkPrimaryColor : MyColors.white,
borderRadius: BorderRadius.circular(25.0),
border: Border.all(color: MyColors.lightTextColor, width: 1),
),
child: Transform.scale(
scale: 0.8,
child: CupertinoSwitch(
activeColor: MyColors.darkPrimaryColor,
trackColor: MyColors.white,
thumbColor: MyColors.greyACColor,
value: isServiceActive,
onChanged: (value) async {
if (isEditDisabled) return;
isServiceActive = await updateServiceStatus(context, value);
setState(() {});
},
),
),
),
],
),
),
] else ...[
12.height,
],
(serviceVM.state == ViewState.idle)
? categoryId != -1 && serviceVM.servicesDropList.isNotEmpty
? DropdownField( ? DropdownField(
(DropValue value) { (DropValue value) {
service = value; service = value;
serviceId = value.id; serviceId = value.id;
isAppointmentAvailable = false; isAppointmentAvailable = false;
isHomeAppointmentAvailable = false; isHomeAppointmentAvailable = false;
model.setState(ViewState.idle); serviceVM.setState(ViewState.idle);
}, },
dropdownValue: service, dropdownValue: service,
list: model.servicesDropList, list: serviceVM.servicesDropList,
hint: LocaleKeys.defineServices.tr(), hint: LocaleKeys.defineServices.tr(),
) )
: categoryId == -1 : categoryId == -1
? const SizedBox() ? const SizedBox()
: model.state == ViewState.idle : serviceVM.state == ViewState.idle
? EmptyWidget(text: LocaleKeys.noServicesAvailable.tr()) ? EmptyWidget(text: LocaleKeys.noServicesAvailable.tr())
: const SizedBox() : const SizedBox()
: const CircularProgressIndicator(), : const CircularProgressIndicator(),
@ -129,24 +173,33 @@ class _CreateServicesPage3State extends State<CreateServicesPage3> {
children: [ children: [
20.height, 20.height,
CheckBoxWithTitleDescription( CheckBoxWithTitleDescription(
isDisabled: isEditDisabled,
isSelected: isAppointmentAvailable, isSelected: isAppointmentAvailable,
title: LocaleKeys.availableforAppointment.tr(), title: LocaleKeys.availableforAppointment.tr(),
description: LocaleKeys.bookAppointmentForServices.tr(), description: LocaleKeys.bookAppointmentForServices.tr(),
onSelection: (bool v) { onSelection: (bool v) {
isAppointmentAvailable = v; isAppointmentAvailable = v;
model.setState(ViewState.idle); if (!isAppointmentAvailable) {
isHomeAppointmentAvailable = false;
}
serviceVM.setState(ViewState.idle);
}, },
), ),
20.height, 20.height,
CheckBoxWithTitleDescription( if (isAppointmentAvailable)
isSelected: isHomeAppointmentAvailable, CheckBoxWithTitleDescription(
title: LocaleKeys.allowingHomeService.tr(), isDisabled: isEditDisabled,
description: LocaleKeys.bookAppointmentAtLocation.tr(), isSelected: isHomeAppointmentAvailable,
onSelection: (bool v) { title: LocaleKeys.allowingHomeService.tr(),
isHomeAppointmentAvailable = v; description: LocaleKeys.bookAppointmentAtLocation.tr(),
model.setState(ViewState.idle); onSelection: (bool v) {
}, isHomeAppointmentAvailable = v;
), if (isHomeAppointmentAvailable && !isAppointmentAvailable) {
isAppointmentAvailable = true;
}
serviceVM.setState(ViewState.idle);
},
),
20.height, 20.height,
if (isHomeAppointmentAvailable) if (isHomeAppointmentAvailable)
Column( Column(
@ -203,20 +256,24 @@ class _CreateServicesPage3State extends State<CreateServicesPage3> {
), ),
), ),
if (serviceId != -1) if (serviceId != -1)
ShowFillButton( if (isEditDisabled) ...[
title: LocaleKeys.save.tr(), Utils.buildStatusContainer(LocaleKeys.blockedByAdmin.tr()),
maxWidth: double.infinity, ] else ...[
margin: const EdgeInsets.all(20), ShowFillButton(
onPressed: () { title: LocaleKeys.save.tr(),
if (widget.branchModel!.serviceProviderService != null) { maxWidth: double.infinity,
updateService(context, model); margin: const EdgeInsets.all(20),
} else { onPressed: () {
if (model.services != null) { if (widget.branchModel!.serviceProviderService != null) {
createService(context, model); updateService(context, serviceVM);
} else {
if (serviceVM.services != null) {
createService(context, serviceVM);
}
} }
} },
}, ),
), ],
], ],
); );
}, },
@ -225,9 +282,15 @@ class _CreateServicesPage3State extends State<CreateServicesPage3> {
); );
} }
createService(BuildContext context, ServiceVM model) async { createService(BuildContext context, ServiceVM serviceVM) async {
if (isHomeAppointmentAvailable) {
if (serviceRage == 0 || chargersPerKm.isEmpty || double.parse(chargersPerKm) < 1) {
Utils.showToast(LocaleKeys.chargesAndServiceRangeGreaterThanZero.tr());
return;
}
}
List<Map<String, dynamic>> map = []; List<Map<String, dynamic>> map = [];
model.services!.data?.forEach((element) { serviceVM.services!.data?.forEach((element) {
if (serviceId == element.id) { if (serviceId == element.id) {
element.isSelected = true; element.isSelected = true;
} else { } else {
@ -235,12 +298,12 @@ class _CreateServicesPage3State extends State<CreateServicesPage3> {
} }
}); });
for (int i = 0; i < model.services!.data!.length; i++) { for (int i = 0; i < serviceVM.services!.data!.length; i++) {
if (model.services!.data![i].isSelected ?? false) { if (serviceVM.services!.data![i].isSelected ?? false) {
var postParams = { var postParams = {
// "id": services!.data![i].id, // "id": services!.data![i].id,
"providerBranchID": widget.branchModel!.branchId, "providerBranchID": widget.branchModel!.branchId,
"serviceID": model.services!.data![i].id, "serviceID": serviceVM.services!.data![i].id,
"isAllowAppointment": isAppointmentAvailable, "isAllowAppointment": isAppointmentAvailable,
"isActive": true, "isActive": true,
"customerLocationRange": serviceRage, "customerLocationRange": serviceRage,
@ -251,8 +314,8 @@ class _CreateServicesPage3State extends State<CreateServicesPage3> {
} }
// print(map); // print(map);
Utils.showLoading(context); Utils.showLoading(context);
GenericRespModel mResponse = await model.createService(map); GenericRespModel mResponse = await serviceVM.createService(map);
await model.getBranchAndServices(); await serviceVM.getBranchAndServices();
Utils.hideLoading(context); Utils.hideLoading(context);
Utils.showToast(mResponse.message ?? ""); Utils.showToast(mResponse.message ?? "");
if (mResponse.messageStatus == 1) { if (mResponse.messageStatus == 1) {
@ -263,6 +326,13 @@ class _CreateServicesPage3State extends State<CreateServicesPage3> {
updateService(BuildContext context, ServiceVM model) async { updateService(BuildContext context, ServiceVM model) async {
List<Map<String, dynamic>> map = []; List<Map<String, dynamic>> map = [];
if (isHomeAppointmentAvailable) {
if (serviceRage == 0 || chargersPerKm.isEmpty || double.parse(chargersPerKm) < 1) {
Utils.showToast(LocaleKeys.chargesAndServiceRangeGreaterThanZero.tr());
return;
}
}
if (isHomeAppointmentAvailable) { if (isHomeAppointmentAvailable) {
map = [ map = [
{ {
@ -282,16 +352,58 @@ class _CreateServicesPage3State extends State<CreateServicesPage3> {
} }
]; ];
} }
try {
// print(map);
Utils.showLoading(context);
GenericRespModel mResponse = await model.updateServices(map);
model.getBranchAndServices();
Utils.hideLoading(context);
Utils.showToast(mResponse.message ?? "");
if (mResponse.messageStatus == 1) {
context.read<ServiceVM>().filterUserBranchCategories();
context.read<ServiceVM>().isNeedRefreshServicesList = true;
pop(context);
}
} catch (e) {
Utils.hideLoading(context);
log(e.toString());
Utils.showToast(e.toString() ?? "");
}
}
// print(map); Future<bool> updateServiceStatus(BuildContext context, bool value) async {
Utils.showLoading(context); try {
GenericRespModel mResponse = await model.updateServices(map); final serviceVM = context.read<ServiceVM>();
model.getBranchAndServices(); List<AppointmentBasicDetailsModel> list = await serviceVM.getAppointmentsByServiceID(
Utils.hideLoading(context); context: context,
Utils.showToast(mResponse.message ?? ""); branchId: int.parse(widget.branchModel!.branchId),
if (mResponse.messageStatus == 1) { serviceId: widget.branchModel!.serviceProviderService!.serviceProviderServiceId!,
context.read<ServiceVM>().filterUserBranchCategories(); );
pop(context);
List<int> providerServiceIds = [];
providerServiceIds.add(widget.branchModel!.serviceProviderService!.serviceProviderServiceId!);
if (list.isEmpty) {
bool status = await serviceVM.updateServiceStatus(
context: context,
serviceStatusEnum: ServiceStatusEnum.deactivated,
branchId: int.parse(widget.branchModel!.branchId),
providerServiceIds: providerServiceIds,
);
return !status;
} else {
serviceVM.buildDealNotCompletedBottomSheetOptions(
mainContext: context,
appointments: list,
branchName: widget.branchModel!.branchName,
);
}
return value;
} catch (e) {
Utils.hideLoading(context);
log(e.toString());
Utils.showToast(e.toString() ?? "");
return value;
} }
} }
} }

@ -1,15 +1,18 @@
import 'package:mc_common_app/generated/locale_keys.g.dart'; import 'dart:developer';
import 'package:mc_common_app/view_models/service_view_model.dart';
import 'package:car_provider_app/views/branch_management/services/duplication/sheet/approved_branches_list_sheet.dart'; import 'package:car_provider_app/views/branch_management/services/duplication/sheet/approved_branches_list_sheet.dart';
import 'package:car_provider_app/views/branch_management/services/duplication/sheet/items_selection_sheet.dart'; import 'package:car_provider_app/views/branch_management/services/duplication/sheet/items_selection_sheet.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/models/services_models/item_model.dart'; import 'package:mc_common_app/models/services_models/item_model.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/utils.dart'; import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/service_view_model.dart';
import 'package:mc_common_app/widgets/bottom_sheet.dart'; import 'package:mc_common_app/widgets/bottom_sheet.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart'; import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart'; import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
@ -17,12 +20,11 @@ import 'package:mc_common_app/widgets/dropdown/dropdown_text.dart';
import 'package:mc_common_app/widgets/empty_widget.dart'; import 'package:mc_common_app/widgets/empty_widget.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart';
class MatchedServicesPage extends StatefulWidget { class MatchedServicesPage extends StatefulWidget {
final MatchServicesArguments? matchServicesArguments; final MatchServicesArguments? matchServicesArguments;
const MatchedServicesPage(this.matchServicesArguments, {Key? key}) : super(key: key); const MatchedServicesPage(this.matchServicesArguments, {super.key});
@override @override
State<MatchedServicesPage> createState() => _MatchedServicesPageState(); State<MatchedServicesPage> createState() => _MatchedServicesPageState();
@ -39,7 +41,11 @@ class _MatchedServicesPageState extends State<MatchedServicesPage> {
} }
getMatchedServices() { getMatchedServices() {
serviceVM.getAllMatchedServices(widget.matchServicesArguments!.oldBranch, widget.matchServicesArguments!.newBranch, widget.matchServicesArguments!.categoryId); serviceVM.getAllMatchedServices(
oldBranchId: widget.matchServicesArguments!.oldBranch,
newBranchId: widget.matchServicesArguments!.newBranch,
categoryId: widget.matchServicesArguments!.categoryId,
);
} }
@override @override
@ -53,47 +59,40 @@ class _MatchedServicesPageState extends State<MatchedServicesPage> {
height: double.infinity, height: double.infinity,
child: Column( child: Column(
children: [ children: [
DropDownText(widget.matchServicesArguments!.oldBranchName).toContainer( 12.height,
padding: const EdgeInsets.only( DropDownText(
left: 14, title: widget.matchServicesArguments!.oldBranchName,
right: 14, showDropDownIcon: false,
top: 21,
),
), ),
12.height, 12.height,
Row( GestureDetector(
mainAxisAlignment: MainAxisAlignment.spaceBetween, onTap: () {
children: [ bool newValue = !context.read<ServiceVM>().isAllSelected;
Row( serviceVM.selectAllServices(newValue);
children: [ },
Checkbox( child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
SizedBox(
height: 30,
width: 30,
child: Checkbox(
value: context.watch<ServiceVM>().isAllSelected, value: context.watch<ServiceVM>().isAllSelected,
onChanged: (v) { onChanged: (v) {
serviceVM.selectAllServices(v ?? false); serviceVM.selectAllServices(v ?? false);
}, },
), ),
LocaleKeys.selectAll.tr().toText(isBold: true) ),
], LocaleKeys.selectAll.tr().toText(fontSize: 14),
), ],
Container( ),
alignment: Alignment.centerRight,
margin: const EdgeInsets.symmetric(horizontal: 14, vertical: 7),
child: LocaleKeys.unselectAll.tr().toText(
color: MyColors.primaryColor,
isUnderLine: true,
isBold: true,
),
).onPress(() {
serviceVM.selectAllServices(false);
}),
],
), ),
12.height, 12.height,
Expanded( Expanded(
child: Consumer<ServiceVM>(builder: (context, model, _) { child: Consumer<ServiceVM>(builder: (context, ServiceVM serviceVM, _) {
if (model.matchedServices == null) { if (serviceVM.matchedServices == null) {
return const Center(child: CircularProgressIndicator()); return const Center(child: CircularProgressIndicator());
} else if (model.matchedServices!.isEmpty) { } else if (serviceVM.matchedServices!.isEmpty) {
return EmptyWidget(text: LocaleKeys.noServicesAvailable.tr(), isWrappedColumn: false); return EmptyWidget(text: LocaleKeys.noServicesAvailable.tr(), isWrappedColumn: false);
} }
return ListView.separated( return ListView.separated(
@ -103,13 +102,13 @@ class _MatchedServicesPageState extends State<MatchedServicesPage> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Checkbox( Checkbox(
value: model.matchedServices![index].isExpandedOrSelected, value: serviceVM.matchedServices![index].isExpandedOrSelected,
onChanged: (v) { onChanged: (v) {
if (model.matchedServices![index].serviceItems!.isEmpty) { if (serviceVM.matchedServices![index].serviceItems!.isEmpty) {
Utils.showToast(LocaleKeys.noItemsToShow.tr()); Utils.showToast(LocaleKeys.noAvailableItems.tr());
} else { } else {
model.matchedServices![index].isExpandedOrSelected = v ?? false; serviceVM.matchedServices![index].isExpandedOrSelected = v ?? false;
model.updateServiceItem(index, model.matchedServices![index].isExpandedOrSelected); serviceVM.updateServiceItem(index, serviceVM.matchedServices![index].isExpandedOrSelected);
} }
}, },
), ),
@ -118,25 +117,22 @@ class _MatchedServicesPageState extends State<MatchedServicesPage> {
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
model.matchedServices![index].serviceDescription.toString().toText(fontSize: 16, isBold: true), serviceVM.matchedServices![index].serviceDescription.toString().toText(fontSize: 16, isBold: true),
"${model.matchedServices![index].serviceItems!.where((c) => c.isUpdateOrSelected == true).length} items selected out of ${model.matchedServices![index].serviceItems!.length}".toText(color: MyColors.lightTextColor) "${serviceVM.matchedServices![index].serviceItems!.where((c) => c.isUpdateOrSelected == true).length} items selected out of ${serviceVM.matchedServices![index].serviceItems!.length}"
.toText(color: MyColors.lightTextColor),
LocaleKeys.tapToSeeItems.toText(color: MyColors.lightTextColor),
], ],
), ),
), ),
SvgPicture.asset(
MyAssets.icEdit,
width: 16,
height: 16,
),
], ],
).toWhiteContainer(width: double.infinity, allPading: 8).onPress( ).toWhiteContainer(width: double.infinity, allPading: 8).onPress(
() { () {
showMyBottomSheet( showMyBottomSheet(
context, context,
child: ItemsSelectionSheet( child: ItemsSelectionSheet(
model.matchedServices![index].serviceItems ?? [], serviceVM.matchedServices![index].serviceItems ?? [],
onItemCopied: (List<ItemData> selected) { onItemCopied: (List<ItemData> selected) {
model.copyItems(index, selected); serviceVM.copyItems(index, selected);
}, },
), ),
); );
@ -146,8 +142,8 @@ class _MatchedServicesPageState extends State<MatchedServicesPage> {
separatorBuilder: (context, index) { separatorBuilder: (context, index) {
return 8.height; return 8.height;
}, },
padding: const EdgeInsets.symmetric(horizontal: 14), // padding: const EdgeInsets.symmetric(horizontal: 14),
itemCount: model.matchedServices!.length, itemCount: serviceVM.matchedServices!.length,
); );
}), }),
), ),
@ -164,7 +160,7 @@ class _MatchedServicesPageState extends State<MatchedServicesPage> {
}, },
), ),
], ],
), ).padding(const EdgeInsets.symmetric(horizontal: 14)),
), ),
); );
} }

@ -1,8 +1,6 @@
import 'package:mc_common_app/config/routes.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:mc_common_app/view_models/service_view_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart';
@ -10,11 +8,9 @@ import 'package:mc_common_app/models/provider_branches_models/branch_detail_mode
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/view_models/service_view_model.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter_svg/svg.dart';
import 'package:geolocator/geolocator.dart';
class MatchServicesArguments { class MatchServicesArguments {
int oldBranch, newBranch, categoryId; int oldBranch, newBranch, categoryId;
@ -24,9 +20,9 @@ class MatchServicesArguments {
} }
class ApprovedBranchesListSheet extends StatelessWidget { class ApprovedBranchesListSheet extends StatelessWidget {
int newBranch, categoryId; final int branchId, categoryId;
ApprovedBranchesListSheet({required this.newBranch, required this.categoryId, Key? key}) : super(key: key); const ApprovedBranchesListSheet({required this.branchId, required this.categoryId, super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -37,10 +33,8 @@ class ApprovedBranchesListSheet extends StatelessWidget {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
"Select Branch".toText(fontSize: 20, isBold: true), LocaleKeys.selectBranch.tr().toText(fontSize: 20, isBold: true),
"Select the branch to copy their items to this branch. You can modify the selection at any time.".toText( LocaleKeys.noteCopyItemsExplanation.tr().toText(fontSize: 12),
fontSize: 12,
),
12.height, 12.height,
Expanded( Expanded(
child: Consumer<ServiceVM>( child: Consumer<ServiceVM>(
@ -50,25 +44,20 @@ class ApprovedBranchesListSheet extends StatelessWidget {
} else { } else {
List<BranchDetailModel> branches = []; List<BranchDetailModel> branches = [];
if (model.branches!.data != null) { if (model.branches!.data != null) {
branches = model.branches!.data!.serviceProviderBranch!.where((element) => model.selectedBranchStatus == element.statusId).toList(); branches = model.branches!.data!.serviceProviderBranch!.where((element) => element.branchStatus == BranchStatusEnum.approvedOrActive && element.id != branchId).toList();
} }
return branches.isEmpty return branches.isEmpty
? Center(child: Text(LocaleKeys.no_branch.tr())) ? Center(child: Text(LocaleKeys.noBranchFound.tr()))
: ListView.separated( : ListView.separated(
itemBuilder: (context, index) { itemBuilder: (context, index) {
return Row( return Row(
children: [ children: [
Container( SizedBox(
width: 74, width: 70,
height: 50, height: 55,
decoration: const BoxDecoration( child: ClipRRect(
color: MyColors.darkPrimaryColor, borderRadius: const BorderRadius.all(Radius.circular(8)),
borderRadius: BorderRadius.all(Radius.circular(8)), child: branches[index].branchProfileImage.buildNetworkImage(fit: BoxFit.cover),
),
padding: const EdgeInsets.all(6),
child: SvgPicture.asset(
MyAssets.icBranches,
color: Colors.white,
), ),
), ),
12.width, 12.width,
@ -77,22 +66,6 @@ class ApprovedBranchesListSheet extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
Row(
children: [
const Icon(
Icons.place,
size: 12,
color: MyColors.darkPrimaryColor,
),
Geolocator.distanceBetween(AppState().currentLocation.latitude, AppState().currentLocation.latitude, double.parse(branches[index].latitude ?? "0"),
double.parse(branches[index].longitude ?? "0"))
.toStringAsFixed(2)
.toText(
fontSize: 12,
color: MyColors.darkPrimaryColor,
)
],
),
Text( Text(
branches[index].branchName ?? "", branches[index].branchName ?? "",
style: const TextStyle( style: const TextStyle(
@ -100,15 +73,12 @@ class ApprovedBranchesListSheet extends StatelessWidget {
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
), ),
"Tap to select".toText(fontSize: 10, color: MyColors.grey70Color), "${LocaleKeys.totalNumberOfServices.tr()} ${branches[index].branchServices!.length}".toText(fontSize: 10, color: MyColors.grey70Color),
], ],
), ),
), ),
12.width, 12.width,
const Icon( const Icon(Icons.arrow_forward_rounded, size: 16),
Icons.arrow_forward_rounded,
size: 16,
),
], ],
).toContainer(isShadowEnabled: true).onPress(() async { ).toContainer(isShadowEnabled: true).onPress(() async {
// branches[index].countryID = model.branchs!.data!.countryID; // branches[index].countryID = model.branchs!.data!.countryID;
@ -117,9 +87,9 @@ class ApprovedBranchesListSheet extends StatelessWidget {
context, context,
AppRoutes.matchServices, AppRoutes.matchServices,
arguments: MatchServicesArguments( arguments: MatchServicesArguments(
oldBranch: branches[index].id ?? 0,
oldBranchName: branches[index].branchName ?? "", oldBranchName: branches[index].branchName ?? "",
newBranch: newBranch, newBranch: branchId,
oldBranch: branches[index].id ?? 0,
categoryId: categoryId, categoryId: categoryId,
), ),
); );

@ -1,18 +1,21 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/models/services_models/item_model.dart'; import 'package:mc_common_app/models/services_models/item_model.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart'; import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/checkbox_with_title_desc.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:mc_common_app/widgets/txt_field.dart'; import 'package:mc_common_app/widgets/txt_field.dart';
import 'package:easy_localization/easy_localization.dart';
class ItemsSelectionSheet extends StatefulWidget { class ItemsSelectionSheet extends StatefulWidget {
final List<ItemData> serviceItems; final List<ItemData> serviceItems;
final Function(List<ItemData>) onItemCopied; final Function(List<ItemData>) onItemCopied;
const ItemsSelectionSheet(this.serviceItems, {required this.onItemCopied, Key? key}) : super(key: key); const ItemsSelectionSheet(this.serviceItems, {required this.onItemCopied, super.key});
@override @override
State<ItemsSelectionSheet> createState() => _ItemsSelectionSheetState(); State<ItemsSelectionSheet> createState() => _ItemsSelectionSheetState();
@ -21,34 +24,39 @@ class ItemsSelectionSheet extends StatefulWidget {
class _ItemsSelectionSheetState extends State<ItemsSelectionSheet> { class _ItemsSelectionSheetState extends State<ItemsSelectionSheet> {
bool isAllItemsSelected = false; bool isAllItemsSelected = false;
List<ItemData>? tempItems; List<ItemData>? tempItems;
List<ItemData>? filteredItems; // To store filtered items based on search query
String searchQuery = ""; // To store the search query
@override @override
void initState() { void initState() {
super.initState(); super.initState();
//tempItems=List.from(widget.serviceItems); tempItems = widget.serviceItems.map((item) => ItemData.fromJson(item.toJson())).toList();
// tempItems=[...widget.serviceItems]; filteredItems = List.from(tempItems!); // Initially show all items
//tempItems.addAll(widget.serviceItems); }
tempItems = widget.serviceItems
.map( // Method to filter items based on search query
(item) => ItemData.fromJson(item.toJson()) void filterItems(String query) {
setState(() {
searchQuery = query;
filteredItems = tempItems!.where((item) {
return item.name!.toLowerCase().contains(query.toLowerCase()) ||
item.description!.toLowerCase().contains(
query.toLowerCase(),
);
}).toList();
});
}
selectAllTempItems(bool value) {
for (var element in filteredItems ?? []) {
element.isUpdateOrSelected = value;
}
setState(() {});
}
// ItemData( updateTempItem(int index, bool value) {
// id: item.id, filteredItems![index].isUpdateOrSelected = value;
// name: item.name, setState(() {});
// price: item.price,
// manufactureDate: item.manufactureDate,
// description: item.description,
// pictureUrl: item.pictureUrl,
// companyId: item.companyId,
// serviceProviderServiceId: item.serviceProviderServiceId,
// isActive: item.isActive,
// isAllowAppointment: item.isAllowAppointment,
// isAppointmentCompanyLoc: item.isAppointmentCompanyLoc,
// isAppointmentCustomerLoc: item.isAppointmentCompanyLoc,
// isUpdateOrSelected: item.isUpdateOrSelected,
// ),
)
.toList();
} }
@override @override
@ -60,69 +68,58 @@ class _ItemsSelectionSheetState extends State<ItemsSelectionSheet> {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
"Select Items To Copy".toText(fontSize: 16, isBold: true), LocaleKeys.pleaseSelectItems.tr().toText(fontSize: 18, isBold: true),
12.height, 12.height,
TxtField( TxtField(
hint: "Search Items", value: searchQuery,
onChanged: (v) {}, hint: LocaleKeys.searchItems.tr(),
onChanged: (v) {
filterItems(v); // Filter items when the user types in the text field
},
), ),
6.height, 6.height,
Row( GestureDetector(
mainAxisAlignment: MainAxisAlignment.spaceBetween, onTap: () {
children: [ isAllItemsSelected = false;
Row( selectAllTempItems(false);
children: [ },
Checkbox( child: Row(
// value: context.watch<ServiceVM>().isAllSelected, mainAxisAlignment: MainAxisAlignment.end,
children: [
SizedBox(
height: 30,
width: 30,
child: Checkbox(
value: isAllItemsSelected, value: isAllItemsSelected,
onChanged: (v) { onChanged: (v) {
isAllItemsSelected = v ?? false; if (v == null) return;
selectAllTempItems(v ?? false); isAllItemsSelected = v;
selectAllTempItems(v);
}, },
), ),
"Select All".toText(
isBold: true,
)
],
),
Container(
alignment: Alignment.centerRight,
child: "Unselect All".toText(
color: MyColors.primaryColor,
isUnderLine: true,
isBold: true,
), ),
margin: const EdgeInsets.symmetric(horizontal: 14, vertical: 7), LocaleKeys.selectAll.tr().toText(fontSize: 14),
).onPress(() { ],
isAllItemsSelected = false; ),
selectAllTempItems(false);
}),
],
), ),
Flexible( Flexible(
child: ListView.separated( child: ListView.separated(
itemBuilder: (context, index) { itemBuilder: (context, index) {
return Row( return CheckBoxWithTitleDescription(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ isSelected: filteredItems![index].isUpdateOrSelected ?? false,
Checkbox( title: filteredItems![index].name.toString(),
value: tempItems![index].isUpdateOrSelected, description: filteredItems![index].description.toString(),
onChanged: (v) { onSelection: (bool v) {
isAllItemsSelected = false; isAllItemsSelected = false;
updateTempItem(index, v ?? false); updateTempItem(index, v);
}, },
),
Expanded(
child: tempItems![index].name.toString().toText(fontSize: 16, isBold: true),
),
],
); );
}, },
separatorBuilder: (context, index) { separatorBuilder: (context, index) {
return const Divider(); return const Divider();
}, },
itemCount: tempItems!.length, itemCount: filteredItems!.length, // Use filtered items list
).toWhiteContainer(width: double.infinity), ).toWhiteContainer(width: double.infinity),
), ),
12.height, 12.height,
@ -130,7 +127,7 @@ class _ItemsSelectionSheetState extends State<ItemsSelectionSheet> {
title: "Copy Selected Item", title: "Copy Selected Item",
maxWidth: double.infinity, maxWidth: double.infinity,
onPressed: () { onPressed: () {
widget.onItemCopied(tempItems ?? []); widget.onItemCopied(filteredItems ?? []);
pop(context); pop(context);
}, },
), ),
@ -138,16 +135,4 @@ class _ItemsSelectionSheetState extends State<ItemsSelectionSheet> {
), ),
); );
} }
selectAllTempItems(bool value) {
for (var element in tempItems ?? []) {
element.isUpdateOrSelected = value;
}
setState(() {});
}
updateTempItem(int index, bool value) {
tempItems![index].isUpdateOrSelected = value;
setState(() {});
}
} }

@ -21,7 +21,7 @@ import 'package:easy_localization/easy_localization.dart';
class ItemsListPage extends StatelessWidget { class ItemsListPage extends StatelessWidget {
ServiceModel? serviceProviderService; ServiceModel? serviceProviderService;
ItemsListPage({Key? key}) : super(key: key); ItemsListPage({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -58,9 +58,12 @@ class ItemsListPage extends StatelessWidget {
children: [ children: [
model.serviceItems!.data![index].name.toString().toText(fontSize: 16, isBold: true), model.serviceItems!.data![index].name.toString().toText(fontSize: 16, isBold: true),
4.height, 4.height,
showItem("${LocaleKeys.availableforAppointment.tr()}:", (model.serviceItems!.data![index].isAllowAppointment ?? false) ? "Yes" : "No", valueColor: Colors.green), showItem("${LocaleKeys.availableforAppointment.tr()}:", (model.serviceItems!.data![index].isAllowAppointment ?? false) ? "Yes" : "No",
showItem("${LocaleKeys.allowingWorkshopService.tr()}:", (model.serviceItems!.data![index].isAppointmentCompanyLoc ?? false) ? "Yes" : "No", valueColor: Colors.green), valueColor: Colors.green),
showItem("${LocaleKeys.allowingHomeService.tr()}:", (model.serviceItems!.data![index].isAppointmentCustomerLoc ?? false) ? "Yes" : "No", valueColor: Colors.green), showItem("${LocaleKeys.allowingWorkshopService.tr()}:", (model.serviceItems!.data![index].isAppointmentCompanyLoc ?? false) ? "Yes" : "No",
valueColor: Colors.green),
showItem("${LocaleKeys.allowingHomeService.tr()}:", (model.serviceItems!.data![index].isAppointmentCustomerLoc ?? false) ? "Yes" : "No",
valueColor: Colors.green),
12.height, 12.height,
LocaleKeys.serviceAmount.tr().toText(fontSize: 13, color: MyColors.lightTextColor), LocaleKeys.serviceAmount.tr().toText(fontSize: 13, color: MyColors.lightTextColor),
Row( Row(

@ -1,7 +1,9 @@
import 'dart:async'; import 'dart:async';
import 'dart:developer';
import 'package:car_provider_app/views/branch_management/services/duplication/sheet/approved_branches_list_sheet.dart'; import 'package:car_provider_app/views/branch_management/services/duplication/sheet/approved_branches_list_sheet.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/classes/consts.dart';
@ -18,6 +20,7 @@ import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/service_view_model.dart'; import 'package:mc_common_app/view_models/service_view_model.dart';
import 'package:mc_common_app/widgets/bottom_sheet.dart'; import 'package:mc_common_app/widgets/bottom_sheet.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart'; import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/common_widgets/categories_list.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart'; import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:mc_common_app/widgets/tab/role_type_tab.dart'; import 'package:mc_common_app/widgets/tab/role_type_tab.dart';
@ -42,16 +45,14 @@ class CreateBranchModel {
} }
class ServicesListPage extends StatefulWidget { class ServicesListPage extends StatefulWidget {
const ServicesListPage({Key? key}) : super(key: key); const ServicesListPage({super.key});
@override @override
State<ServicesListPage> createState() => _ServicesListPageState(); State<ServicesListPage> createState() => _ServicesListPageState();
} }
class _ServicesListPageState extends State<ServicesListPage> { class _ServicesListPageState extends State<ServicesListPage> {
int selectedTab = 0;
ServiceStatusEnum selectedService = ServiceStatusEnum.approvedOrActive; ServiceStatusEnum selectedService = ServiceStatusEnum.approvedOrActive;
List<ServiceModel> filteredServices = []; List<ServiceModel> filteredServices = [];
late CategoryData categoryData; late CategoryData categoryData;
@ -60,26 +61,130 @@ class _ServicesListPageState extends State<ServicesListPage> {
@override @override
void initState() { void initState() {
scheduleMicrotask(() async { scheduleMicrotask(() async {
await _fetchServices(); await _onRefresh(ServiceStatusEnum.approvedOrActive);
}); });
super.initState(); super.initState();
} }
Future<void> _fetchServices() async { Future<void> _onRefresh(ServiceStatusEnum status) async {
log("status: $status");
screenState = ViewState.busy;
setState(() {});
categoryData.services = await context.read<ServiceVM>().fetchProviderServicesModelByCategoryIdAndBranchID( categoryData.services = await context.read<ServiceVM>().fetchProviderServicesModelByCategoryIdAndBranchID(
branchID: categoryData.branchId.toString(), branchID: categoryData.branchId.toString(),
categoryId: categoryData.id.toString(), categoryId: categoryData.id.toString(),
); );
filteredServices = categoryData.services!.where((i) => i.serviceStatus == ServiceStatusEnum.approvedOrActive.index + 1).toList(); context.read<ServiceVM>().applyFilterOnBranchServices(serviceStatusEnum: status);
filteredServices = categoryData.services!.where((i) => i.serviceStatusEnum == status).toList();
screenState = ViewState.idle; screenState = ViewState.idle;
setState(() {}); setState(() {});
} }
bool isCategoryActive = true;
bool isEditDisabled = false;
Widget buildCategoryTileWidget() {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
flex: 1,
child: Padding(
padding: const EdgeInsets.only(top: 5),
child: SvgPicture.asset(
MyAssets.maintenanceIcon,
width: 14,
height: 14,
),
),
),
8.width,
Expanded(
flex: 20,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(child: categoryData.categoryName.toString().toText(fontSize: 16)),
],
),
// 5.height,
Container(
child: ("${LocaleKeys.branchName.tr()}: ${categoryData.branchName}").toText(
fontSize: 12,
color: MyColors.lightTextColor,
),
),
if (categoryData.services != null) ...[
Container(
child: ("${LocaleKeys.totalNumberOfServices.tr()} ${categoryData.services!.length}").toText(
fontSize: 12,
color: MyColors.lightTextColor,
),
),
],
],
),
),
// TODO: NEED TO CONFIRM CATEGORY DEACTIVATION FROM ZAHOOR
const Expanded(
flex: 4,
child: Column(
children: [
// LocaleKeys.active.tr().toText(fontSize: 16),
// 8.width,
// Container(
// width: 50,
// height: 30,
// decoration: BoxDecoration(
// color: isCategoryActive ? MyColors.darkPrimaryColor : MyColors.white,
// borderRadius: BorderRadius.circular(25.0),
// border: Border.all(color: MyColors.lightTextColor, width: 1),
// ),
// child: Transform.scale(
// scale: 0.8,
// child: CupertinoSwitch(
// activeColor: MyColors.darkPrimaryColor,
// trackColor: MyColors.white,
// thumbColor: MyColors.greyACColor,
// value: isCategoryActive,
// onChanged: (value) async {
// if (isEditDisabled) return;
// isCategoryActive = value;
// // isCategoryActive = await updateServiceStatus(context, value);
// setState(() {});
// },
// ),
// ),
// ),
],
),
),
],
).toWhiteContainer(width: double.infinity, allPading: 12);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
categoryData = ModalRoute.of(context)!.settings.arguments as CategoryData; categoryData = ModalRoute.of(context)!.settings.arguments as CategoryData;
final serviceVM = context.read<ServiceVM>();
if (serviceVM.isNeedRefreshServicesList) {
WidgetsBinding.instance.addPostFrameCallback((_) {
if (mounted) {
selectedService = ServiceStatusEnum.pending;
_onRefresh(ServiceStatusEnum.pending);
serviceVM.isNeedRefreshServicesList = false;
}
});
}
return Scaffold( return Scaffold(
appBar: CustomAppBar( appBar: CustomAppBar(
title: LocaleKeys.services.tr(), title: LocaleKeys.services.tr(),
@ -90,7 +195,7 @@ class _ServicesListPageState extends State<ServicesListPage> {
showMyBottomSheet( showMyBottomSheet(
context, context,
child: ApprovedBranchesListSheet( child: ApprovedBranchesListSheet(
newBranch: int.parse(categoryData.branchId ?? ''), branchId: int.parse(categoryData.branchId ?? ''),
categoryId: categoryData.id ?? 0, categoryId: categoryData.id ?? 0,
), ),
); );
@ -102,47 +207,26 @@ class _ServicesListPageState extends State<ServicesListPage> {
width: double.infinity, width: double.infinity,
child: Column( child: Column(
children: [ children: [
Padding( buildCategoryTileWidget().paddingOnly(left: 20, right: 20, top: 10),
padding: const EdgeInsets.only(left: 20, right: 20, top: 20), 20.height,
child: RoleTypeTab( Consumer(
selectedTab, builder: (BuildContext context, ServiceVM serviceVM, Widget? child) {
[ return FiltersList(
DropValue(0, 'Active', ''), filterList: serviceVM.branchServicesFilterOptions,
DropValue(1, 'Requested', ''), onFilterTapped: (index, selectedFilterId) {
], selectedService = selectedFilterId.toServiceStatusEnum();
width: (MediaQuery.of(context).size.width / 2) - 26, serviceVM.applyFilterOnBranchServices(serviceStatusEnum: selectedFilterId.toServiceStatusEnum());
onSelect: (DropValue value) { filteredServices = categoryData.services!.where((i) => i.serviceStatusEnum == selectedFilterId.toServiceStatusEnum()).toList();
setState(() { setState(() {});
selectedTab = value.id; },
if (selectedTab == 0) { );
selectedService = ServiceStatusEnum.approvedOrActive; },
filteredServices = categoryData.services!.where((i) => i.serviceStatus == ServiceStatusEnum.approvedOrActive.index + 1).toList();
} else {
selectedService = value.id.toServiceStatusEnum();
filteredServices = categoryData.services!.where((i) => i.serviceStatus != ServiceStatusEnum.approvedOrActive.index + 1).toList();
}
});
},
),
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
Expanded( Expanded(
child: RefreshIndicator( child: RefreshIndicator(
onRefresh: () async { onRefresh: () async {
screenState = ViewState.busy; _onRefresh(selectedService);
setState(() {});
categoryData.services = await context.read<ServiceVM>().fetchProviderServicesModelByCategoryIdAndBranchID(
branchID: categoryData.branchId.toString(),
categoryId: categoryData.id.toString(),
);
if (selectedService == ServiceStatusEnum.approvedOrActive) {
filteredServices = categoryData.services!.where((i) => i.serviceStatus == ServiceStatusEnum.approvedOrActive.index + 1).toList();
} else {
filteredServices = categoryData.services!.where((i) => i.serviceStatus != ServiceStatusEnum.approvedOrActive.index + 1).toList();
}
screenState = ViewState.idle;
setState(() {});
}, },
child: screenState == ViewState.busy child: screenState == ViewState.busy
? const Center( ? const Center(
@ -159,16 +243,14 @@ class _ServicesListPageState extends State<ServicesListPage> {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
if (filteredServices[index].serviceStatus == 1) ...[ // if (filteredServices[index].serviceStatusEnum == ServiceStatusEnum.pending) ...[
Utils.statusContainerChip(text: "Pending", chipColor: MyColors.adPendingStatusColor), // Utils.statusContainerChip(text: "Pending", chipColor: MyColors.adPendingStatusColor),
5.height, // 5.height,
], // ],
Row( Row(
children: [ children: [
Expanded( Expanded(child: (filteredServices[index].serviceDescription ?? "").toText(fontSize: 16)),
child: (filteredServices[index].serviceDescription ?? "").toText(fontSize: 16), if (filteredServices[index].serviceStatusEnum != ServiceStatusEnum.pending) ...[
),
if (filteredServices[index].serviceStatus != 1) ...[
Padding( Padding(
padding: const EdgeInsets.all(4.0), padding: const EdgeInsets.all(4.0),
child: SvgPicture.asset( child: SvgPicture.asset(
@ -176,7 +258,7 @@ class _ServicesListPageState extends State<ServicesListPage> {
width: 16, width: 16,
height: 16, height: 16,
), ),
).onPress(() { ).onPress(() async {
navigateWithName(context, AppRoutes.createServices3, navigateWithName(context, AppRoutes.createServices3,
arguments: CreateBranchModel( arguments: CreateBranchModel(
branchId: categoryData.branchId ?? '', branchId: categoryData.branchId ?? '',
@ -211,14 +293,25 @@ class _ServicesListPageState extends State<ServicesListPage> {
], ],
), ),
), ),
const Icon(Icons.arrow_forward_rounded, size: 20), if (filteredServices[index].serviceStatusEnum != ServiceStatusEnum.blocked && filteredServices[index].serviceStatusEnum != ServiceStatusEnum.deactivated) ...[
const Icon(Icons.arrow_forward_rounded, size: 20),
],
], ],
), ),
], ],
), ),
).toWhiteContainer(width: double.infinity, allPading: 12).onPress( ).toWhiteContainer(width: double.infinity, allPading: 12).onPress(() {
() => navigateWithName(context, AppRoutes.itemsList, arguments: filteredServices[index]), if (filteredServices[index].serviceStatusEnum == ServiceStatusEnum.blocked) {
); Utils.showToast(LocaleKeys.blockedByAdmin.tr());
return;
}
if (filteredServices[index].serviceStatusEnum == ServiceStatusEnum.deactivated) {
Utils.showToast(LocaleKeys.serviceDeactivated.tr());
return;
}
navigateWithName(context, AppRoutes.itemsList, arguments: filteredServices[index]);
});
}, },
separatorBuilder: (context, index) { separatorBuilder: (context, index) {
return const SizedBox(height: 12); return const SizedBox(height: 12);

@ -1,4 +1,3 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/config/routes.dart';
@ -16,9 +15,7 @@ import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
class BranchAppointmentFragment extends StatelessWidget { class BranchAppointmentFragment extends StatelessWidget {
const BranchAppointmentFragment({ const BranchAppointmentFragment({super.key});
Key? key,
}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -45,7 +42,9 @@ class BranchAppointmentFragment extends StatelessWidget {
return RefreshIndicator( return RefreshIndicator(
onRefresh: () async => serviceVM.getBranchAndServices(), onRefresh: () async => serviceVM.getBranchAndServices(),
child: branches.isEmpty child: branches.isEmpty
? Center(child: LocaleKeys.noBranchFound.tr().toText(fontSize: 16, color: MyColors.lightTextColor, fontWeight: MyFonts.Medium),) ? Center(
child: LocaleKeys.noBranchFound.tr().toText(fontSize: 16, color: MyColors.lightTextColor, fontWeight: MyFonts.Medium),
)
: ListView.separated( : ListView.separated(
itemBuilder: (context, index) { itemBuilder: (context, index) {
return Row( return Row(
@ -71,7 +70,6 @@ class BranchAppointmentFragment extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
// Row( // Row(
// children: [ // children: [
// const Icon( // const Icon(

@ -1,17 +1,13 @@
import 'package:car_provider_app/views/dashboard/widget/my_service_provider.dart'; import 'package:car_provider_app/views/dashboard/widget/my_service_provider.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart'; import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart'; import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/view_models/appointments_view_model.dart';
import 'package:mc_common_app/view_models/dashboard_view_model_provider.dart'; import 'package:mc_common_app/view_models/dashboard_view_model_provider.dart';
import 'package:mc_common_app/views/advertisement/components/ads_list_widget.dart'; import 'package:mc_common_app/views/advertisement/components/ads_list_widget.dart';
import 'package:mc_common_app/views/appointments/widgets/common_appointment_slider_widget.dart'; import 'package:mc_common_app/views/appointments/widgets/common_appointment_slider_widget.dart';
@ -19,10 +15,9 @@ import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/common_widgets/view_all_widget.dart'; import 'package:mc_common_app/widgets/common_widgets/view_all_widget.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart';
class HomeFragment extends StatelessWidget { class HomeFragment extends StatelessWidget {
const HomeFragment({Key? key}) : super(key: key); const HomeFragment({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -64,23 +59,15 @@ class HomeFragment extends StatelessWidget {
context.read<DashboardVMProvider>().onNavbarTapped(1); context.read<DashboardVMProvider>().onNavbarTapped(1);
}, },
).horPaddingMain(), ).horPaddingMain(),
// const AppointmentSliderWidget().horPaddingMain(), CommonAppointmentSliderWidget(
onAppointmentClick: (AppointmentListModel value) => navigateWithName(
//TODO TESTING PENDING context,
if (AppState().currentAppType == AppType.provider && context.read<AppointmentsVM>().myUpComingAppointments.isEmpty) ...[ AppRoutes.appointmentDetailList,
LocaleKeys.noUpcomingAppointments.tr().toText(fontSize: 16, color: MyColors.lightTextColor, fontWeight: MyFonts.Medium).paddingAll(21), arguments: value,
] else ...[ )).toWhiteContainer(width: double.infinity, backgroundColor: Colors.transparent).margin(
CommonAppointmentSliderWidget( left: 21,
onAppointmentClick: (AppointmentListModel value) { right: 21,
navigateWithName(context, AppRoutes.appointmentDetailList, arguments: value); ),
},
)
.toWhiteContainer(
width: double.infinity,
backgroundColor: Colors.transparent,
)
.margin(left: 21, right: 21),
],
24.height, 24.height,
ViewAllWidget( ViewAllWidget(
title: LocaleKeys.myBranches.tr(), title: LocaleKeys.myBranches.tr(),

@ -6,6 +6,7 @@ import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart'; import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
@ -16,6 +17,7 @@ class GeneralAppointmentWidget extends StatelessWidget {
final bool isNeedToShowItems; final bool isNeedToShowItems;
final bool isNeedToShowToMoreText; final bool isNeedToShowToMoreText;
final bool isSelectable; final bool isSelectable;
final bool isFromUpdateAppointmentPage;
final bool isNeedToShowAppointmentStatus; final bool isNeedToShowAppointmentStatus;
final bool isNeedToShowMergeStatus; final bool isNeedToShowMergeStatus;
final Function()? onTap; final Function()? onTap;
@ -28,9 +30,10 @@ class GeneralAppointmentWidget extends StatelessWidget {
this.isNeedToShowToMoreText = true, this.isNeedToShowToMoreText = true,
this.isSelectable = false, this.isSelectable = false,
this.isNeedToShowAppointmentStatus = false, this.isNeedToShowAppointmentStatus = false,
this.isFromUpdateAppointmentPage = false,
this.isNeedToShowMergeStatus = false, this.isNeedToShowMergeStatus = false,
Key? key, super.key,
}) : super(key: key); });
List<Widget> buildServicesFromAppointment({required AppointmentListModel appointmentListModel}) { List<Widget> buildServicesFromAppointment({required AppointmentListModel appointmentListModel}) {
if (appointmentListModel.appointmentServicesList == null || appointmentListModel.appointmentServicesList!.isEmpty) { if (appointmentListModel.appointmentServicesList == null || appointmentListModel.appointmentServicesList!.isEmpty) {
@ -51,7 +54,7 @@ class GeneralAppointmentWidget extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
showServices( showServices(
appointmentListModel.appointmentServicesList!.first.providerServiceDescription, "${appointmentListModel.appointmentServicesList!.first.providerServiceDescription} - ${appointmentListModel.appointmentServicesList!.first.serviceId}",
MyAssets.modificationsIcon, MyAssets.modificationsIcon,
), ),
if (isNeedToShowItems) ...itemsList, if (isNeedToShowItems) ...itemsList,
@ -67,28 +70,24 @@ class GeneralAppointmentWidget extends StatelessWidget {
if (isNeedToShowItems) { if (isNeedToShowItems) {
itemsList = List.generate( itemsList = List.generate(
appointmentListModel.appointmentServicesList?[index].serviceItems?.length ?? 0, appointmentListModel.appointmentServicesList?[index].serviceItems?.length ?? 0,
// (mIndex) => (" - ${appointmentListModel.appointmentServicesList?[index].serviceItems?[mIndex].name ?? ""}").toString().toText(
// color: MyColors.lightTextColor,
// ),
(mIndex) => showItems((appointmentListModel.appointmentServicesList?[index].serviceItems?[mIndex].name ?? "").toString(), MyAssets.modificationsIcon), (mIndex) => showItems((appointmentListModel.appointmentServicesList?[index].serviceItems?[mIndex].name ?? "").toString(), MyAssets.modificationsIcon),
); );
} }
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
showServices(appointmentListModel.appointmentServicesList![index].providerServiceDescription, MyAssets.modificationsIcon), showServices(
"${appointmentListModel.appointmentServicesList![index].providerServiceDescription} - ${appointmentListModel.appointmentServicesList![index].serviceId}", MyAssets.modificationsIcon),
if (isNeedToShowItems) ...itemsList, if (isNeedToShowItems) ...itemsList,
], ],
).paddingOnly(bottom: 6); ).paddingOnly(bottom: 6);
}, },
); );
if (isNeedToShowToMoreText && appointmentListModel.appointmentServicesList!.length > 1) { if (isNeedToShowToMoreText && appointmentListModel.appointmentServicesList!.length > 2) {
servicesList.add( servicesList.add(
showServices( showServices(
"+ ${appointmentListModel.appointmentServicesList!.length - 1} More", "+ ${appointmentListModel.appointmentServicesList!.length - 2} More",
"", "",
isMoreText: true, isMoreText: true,
), ),
@ -128,7 +127,7 @@ class GeneralAppointmentWidget extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
if (isNeedToShowMergeStatus) if (isNeedToShowMergeStatus)
"${LocaleKeys.merged.tr()}".toText(color: MyColors.white).toContainer( LocaleKeys.merged.tr().toText(color: MyColors.white).toContainer(
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 3), padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 3),
borderRadius: 12, borderRadius: 12,
backgroundColor: MyColors.greenColor, backgroundColor: MyColors.greenColor,
@ -183,13 +182,51 @@ class GeneralAppointmentWidget extends StatelessWidget {
), ),
Row( Row(
children: [ children: [
"${LocaleKeys.location.tr()}: ".toText(color: MyColors.lightTextColor), "${LocaleKeys.serviceDeliveryType.tr()}: ".toText(color: MyColors.lightTextColor),
2.width, 2.width,
(appointmentListModel.appointmentTypeEnum == AppointmentTypeEnum.home ? LocaleKeys.home.tr() : LocaleKeys.workshop.tr()).toText( (appointmentListModel.appointmentTypeEnum == AppointmentTypeEnum.home ? LocaleKeys.home.tr() : LocaleKeys.workshop.tr()).toText(
fontSize: 12, fontSize: 12,
), ),
], ],
), ),
Row(
children: [
"${LocaleKeys.createdOn.tr()}: ".toText(color: MyColors.lightTextColor),
2.width,
Flexible(child: appointmentListModel.appointmentDate!.toFormattedDateWithoutTime().toText(fontSize: 8))
],
),
if (isFromUpdateAppointmentPage) ...[
if (appointmentListModel.appointmentAddress != null && appointmentListModel.appointmentAddress!.isNotEmpty) ...[
Row(
children: [
"${LocaleKeys.address.tr()}: ".toText(color: MyColors.lightTextColor),
2.width,
Flexible(child: (appointmentListModel.appointmentAddress ?? "").toText(fontSize: 8))
],
),
],
Row(
children: [
"${LocaleKeys.paymentType.tr()}: ".toText(color: MyColors.lightTextColor),
2.width,
(appointmentListModel.paymentType ?? "").toText(fontSize: 8),
],
),
LocaleKeys.openMapLocation
.tr()
.toText(
isUnderLine: true,
color: MyColors.darkPrimaryColor,
fontSize: 10,
)
.onPress(() async {
double latitude, longitude = 0.0;
latitude = double.parse(appointmentListModel.appointmentLatitude!);
longitude = double.parse(appointmentListModel.appointmentLongitude!);
await Utils.openLocationInMaps(latitude: latitude, longitude: longitude);
}),
]
], ],
), ),
), ),

@ -9,7 +9,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# followed by an optional build number separated by a +. # followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter # Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively. # build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode. # In Android, build-name is used as versionName while build-number used as versionCode.e
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning # Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at # Read more about iOS versioning at
@ -41,7 +41,7 @@ dependencies:
mc_common_app: mc_common_app:
path: /Users/amir/StudioProjects/car_common_app path: /Users/amir/StudioProjects/car_common_app
# path: /Users/amir/StudioProjects/car_common_app # path: /Volumes/Data/Projects/Flutter/car_common_app

Loading…
Cancel
Save