From 4962ea2d8bb657d7f7e4e809edca6244d4875cb3 Mon Sep 17 00:00:00 2001 From: "Mirza.Shafique@cloudsolutions.com.sa" <5093@Shf> Date: Sun, 31 Dec 2023 09:30:30 +0300 Subject: [PATCH 1/2] Appointment implementation in Provider --- lib/classes/consts.dart | 1 + lib/extensions/string_extensions.dart | 48 +++++- .../appointment_list_model.dart | 99 ++++++++----- lib/repositories/appointment_repo.dart | 136 +++++++++-------- lib/utils/enums.dart | 6 +- lib/view_models/appointments_view_model.dart | 68 +++++++-- .../customer_appointment_slider_widget.dart | 137 +++++++++++------- 7 files changed, 329 insertions(+), 166 deletions(-) diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index b178ed7..4932d5a 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -108,6 +108,7 @@ class ApiConsts { static String getAppointmentSlots = "${baseUrlServices}api/ServiceProviders/ScheduleSlotsInfo_Get"; static String updateAppointmentStatus = "${baseUrlServices}api/ServiceProviders/ServiceProvidersAppointmentStatus_Update"; static String updateAppointmentPaymentStatus = "${baseUrlServices}api/ServiceProviders/ServiceProviderAppointmentServiceItemPaymentStatus_Update"; + static String createMergeAppointment = "${baseUrlServices}api/ServiceProviders/ServiceProviderMergeAppointment_Create"; //Subscription static String getAllSubscriptions = "${baseUrlServices}api/Common/Subscription_Get"; diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index 3431a3f..cd553be 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -231,10 +231,10 @@ extension AppointmentStatusToInt on AppointmentStatusEnum { case AppointmentStatusEnum.upcoming: return 6; - case AppointmentStatusEnum.inProgress: + case AppointmentStatusEnum.workStarted: return 7; - case AppointmentStatusEnum.completed: + case AppointmentStatusEnum.visitCompleted: return 8; default: @@ -243,7 +243,41 @@ extension AppointmentStatusToInt on AppointmentStatusEnum { } } +extension AppointmentStatusToString on AppointmentStatusEnum { + String getAppointmentNameFromEnum() { + switch (this) { + case AppointmentStatusEnum.booked: + return "Booked"; + + case AppointmentStatusEnum.confirmed: + return "Confirmed"; + + case AppointmentStatusEnum.arrived: + return "Arrived"; + + case AppointmentStatusEnum.cancelled: + return "Canceled"; + + case AppointmentStatusEnum.rescheduled: + return "Rescheduled"; + + case AppointmentStatusEnum.upcoming: + return "Upcoming"; + + case AppointmentStatusEnum.workStarted: + return "Work Started"; + + case AppointmentStatusEnum.visitCompleted: + return "Visit Completed"; + + default: + return "Booked"; + } + } +} + //TODO: Need to verify Enum on upcoming and inprogress with the database +//TODO: 6 is service Deactivated extension AppointmentEnum on int { AppointmentStatusEnum toAppointmentStatusEnum() { if (this == 1) { @@ -259,9 +293,9 @@ extension AppointmentEnum on int { } else if (this == 6) { return AppointmentStatusEnum.upcoming; } else if (this == 7) { - return AppointmentStatusEnum.inProgress; + return AppointmentStatusEnum.workStarted; } else if (this == 8) { - return AppointmentStatusEnum.completed; + return AppointmentStatusEnum.visitCompleted; } else { return AppointmentStatusEnum.allAppointments; } @@ -271,7 +305,7 @@ extension AppointmentEnum on int { extension AppointmentPaymentStatusToInt on AppointmentPaymentStatusEnum { int getIdFromAppointmentPaymentStatusEnum() { switch (this) { - case AppointmentPaymentStatusEnum.notConfirmed: + case AppointmentPaymentStatusEnum.defaultStatus: return 1; case AppointmentPaymentStatusEnum.payNow: @@ -295,7 +329,7 @@ extension AppointmentPaymentStatusToInt on AppointmentPaymentStatusEnum { extension AppointmentPaymentEnum on int { AppointmentPaymentStatusEnum toAppointmentPaymentStatusEnum() { if (this == 1) { - return AppointmentPaymentStatusEnum.notConfirmed; + return AppointmentPaymentStatusEnum.defaultStatus; } else if (this == 2) { return AppointmentPaymentStatusEnum.payNow; } else if (this == 3) { @@ -305,7 +339,7 @@ extension AppointmentPaymentEnum on int { } else if (this == 5) { return AppointmentPaymentStatusEnum.payPartial; } else { - return AppointmentPaymentStatusEnum.notConfirmed; + return AppointmentPaymentStatusEnum.defaultStatus; } } } diff --git a/lib/models/appointments_models/appointment_list_model.dart b/lib/models/appointments_models/appointment_list_model.dart index b19f957..5f4f026 100644 --- a/lib/models/appointments_models/appointment_list_model.dart +++ b/lib/models/appointments_models/appointment_list_model.dart @@ -24,35 +24,38 @@ class AppointmentListModel { int? servicePaymentStatus; double? totalAmount; double? remainingAmount; + bool? isSelected; + bool? isMerged; AppointmentStatusEnum? appointmentStatusEnum; AppointmentPaymentStatusEnum? appointmentPaymentStatusEnum; List? appointmentServicesList; List? customerAppointmentList; + List? mergeAppointmentList; - AppointmentListModel( - {this.id, - this.serviceSlotID, - this.appointmentStatusID, - this.appointmentStatusText, - this.serviceProviderID, - this.customerID, - this.isActive, - this.isPaymentRequired, - this.paymentStatus, - this.paymentStatusText, - this.customerName, - this.customerMobileNum, - this.appointmentType, - this.providerName, - this.duration, - this.branchName, - this.branchId, - this.servicePaymentStatus, - this.totalAmount, - this.remainingAmount, - this.appointmentDate, - this.appointmentServicesList, - this.customerAppointmentList}); + AppointmentListModel({this.id, + this.serviceSlotID, + this.appointmentStatusID, + this.appointmentStatusText, + this.serviceProviderID, + this.customerID, + this.isActive, + this.isPaymentRequired, + this.paymentStatus, + this.paymentStatusText, + this.customerName, + this.customerMobileNum, + this.appointmentType, + this.providerName, + this.duration, + this.branchName, + this.branchId, + this.servicePaymentStatus, + this.totalAmount, + this.remainingAmount, + this.isSelected, + this.appointmentDate, + this.appointmentServicesList, + this.customerAppointmentList, this.mergeAppointmentList,}); @override String toString() { @@ -81,6 +84,7 @@ class AppointmentListModel { servicePaymentStatus = json['servicePaymentStatus']; totalAmount = json['amountTotal']; remainingAmount = json['amountRem']; + isSelected = false; appointmentStatusEnum = (json['appointmentStatusID'] as int).toAppointmentStatusEnum(); appointmentPaymentStatusEnum = @@ -93,6 +97,10 @@ class AppointmentListModel { .add(ServiceModel.fromJson(v, isForAppointment: true)); }); } + mergeAppointmentList = + json["mergeAppointmentList"] == null ? [] : List.from( + json["mergeAppointmentList"]!.map((x) => + MergeAppointmentList.fromJson(x))); } } @@ -102,11 +110,10 @@ class ServiceAppointmentItems { String? serviceItemName; String? serviceItemDescription; - ServiceAppointmentItems( - {this.id, - this.serviceItemID, - this.serviceItemName, - this.serviceItemDescription}); + ServiceAppointmentItems({this.id, + this.serviceItemID, + this.serviceItemName, + this.serviceItemDescription}); ServiceAppointmentItems.fromJson(Map json) { id = json['id']; @@ -131,8 +138,34 @@ class CustomerData { final String customerName; final List appointmentList; - CustomerData( - {required this.customerID, - required this.customerName, - required this.appointmentList}); + CustomerData({required this.customerID, + required this.customerName, + required this.appointmentList}); } + + +class MergeAppointmentList { + int? id; + int? mergeAppointmentId; + int? serviceAppointmentId; + + MergeAppointmentList({ + this.id, + this.mergeAppointmentId, + this.serviceAppointmentId, + }); + + factory MergeAppointmentList.fromJson(Map json) => + MergeAppointmentList( + id: json["id"], + mergeAppointmentId: json["mergeAppointmentID"], + serviceAppointmentId: json["serviceAppointmentID"], + ); + + Map toJson() => + { + "id": id, + "mergeAppointmentID": mergeAppointmentId, + "serviceAppointmentID": serviceAppointmentId, + }; +} \ No newline at end of file diff --git a/lib/repositories/appointment_repo.dart b/lib/repositories/appointment_repo.dart index 95d1a24..540d25a 100644 --- a/lib/repositories/appointment_repo.dart +++ b/lib/repositories/appointment_repo.dart @@ -17,14 +17,14 @@ abstract class AppointmentRepo { Future> getMyAppointments( Map map); - Future updateAppointmentStatus( - Map map); + Future updateAppointmentStatus(Map map); - Future updateAppointmentPaymentStatus( - Map map); + Future updateAppointmentPaymentStatus(Map map); Future getAppointmentSlots(Map map); + Future createMergeAppointment(Map map); + Future getAllServices(String branchId); Future createSchedule(Map map); @@ -38,19 +38,19 @@ abstract class AppointmentRepo { Future updateServicesInSchedule(Map map); Future> - mergeServiceIntoAvailableSchedules({ + mergeServiceIntoAvailableSchedules({ required List serviceItemIdsForHome, required List serviceItemIdsForWorkshop, }); Future createServiceAppointment( {required List schedules, - required int serviceProviderID}); + required int serviceProviderID}); Future cancelOrRescheduleServiceAppointment( {required int serviceAppointmentID, - required int serviceSlotID, - required int appointmentScheduleAction}); + required int serviceSlotID, + required int appointmentScheduleAction}); } class AppointmentRepoImp implements AppointmentRepo { @@ -59,7 +59,7 @@ class AppointmentRepoImp implements AppointmentRepo { Map map = {"ProviderBranchID": branchId}; String t = AppState().getUser.data!.accessToken ?? ""; return await injector.get().getJsonForObject( - (json) => Services.fromJson(json), ApiConsts.getServicesOfBranch, + (json) => Services.fromJson(json), ApiConsts.getServicesOfBranch, token: t, queryParameters: map); } @@ -67,7 +67,7 @@ class AppointmentRepoImp implements AppointmentRepo { Future createSchedule(Map map) async { String t = AppState().getUser.data!.accessToken ?? ""; return await injector.get().postJsonForObject( - (json) => MResponse.fromJson(json), ApiConsts.createSchedule, map, + (json) => MResponse.fromJson(json), ApiConsts.createSchedule, map, token: t); } @@ -75,7 +75,7 @@ class AppointmentRepoImp implements AppointmentRepo { Future addServicesInSchedule(Map map) async { String t = AppState().getUser.data!.accessToken ?? ""; return await injector.get().postJsonForObject( - (json) => MResponse.fromJson(json), ApiConsts.createGroup, map, + (json) => MResponse.fromJson(json), ApiConsts.createGroup, map, token: t); } @@ -85,22 +85,22 @@ class AppointmentRepoImp implements AppointmentRepo { String t = AppState().getUser.data!.accessToken ?? ""; GenericRespModel adsGenericModel = - await injector.get().getJsonForObject( - (json) => GenericRespModel.fromJson(json), - ApiConsts.getSchedule, - token: t, - queryParameters: map, - ); + await injector.get().getJsonForObject( + (json) => GenericRespModel.fromJson(json), + ApiConsts.getSchedule, + token: t, + queryParameters: map, + ); return List.generate(adsGenericModel.data.length, - (index) => ScheduleData.fromJson(adsGenericModel.data[index])); + (index) => ScheduleData.fromJson(adsGenericModel.data[index])); } @override Future updateSchedule(Map map) async { String t = AppState().getUser.data!.accessToken ?? ""; return await injector.get().postJsonForObject( - (json) => MResponse.fromJson(json), ApiConsts.updateSchedule, map, + (json) => MResponse.fromJson(json), ApiConsts.updateSchedule, map, token: t); } @@ -108,12 +108,12 @@ class AppointmentRepoImp implements AppointmentRepo { Future updateServicesInSchedule(Map map) async { String t = AppState().getUser.data!.accessToken ?? ""; return await injector.get().postJsonForObject( - (json) => MResponse.fromJson(json), ApiConsts.updateGroup, map, + (json) => MResponse.fromJson(json), ApiConsts.updateGroup, map, token: t); } Future> - mergeServiceIntoAvailableSchedules({ + mergeServiceIntoAvailableSchedules({ required List serviceItemIdsForHome, required List serviceItemIdsForWorkshop, }) async { @@ -129,19 +129,20 @@ class AppointmentRepoImp implements AppointmentRepo { } ]; GenericRespModel adsGenericModel = - await injector.get().postJsonForObject( - (json) => GenericRespModel.fromJson(json), - ApiConsts.GetServiceItemAppointmentScheduleSlots, - queryParameters, - token: t, - ); + await injector.get().postJsonForObject( + (json) => GenericRespModel.fromJson(json), + ApiConsts.GetServiceItemAppointmentScheduleSlots, + queryParameters, + token: t, + ); if (adsGenericModel.data == null) { return []; } List serviceAppointmentScheduleModel = - List.generate( - adsGenericModel.data.length, - (index) => ServiceAppointmentScheduleModel.fromJson( + List.generate( + adsGenericModel.data.length, + (index) => + ServiceAppointmentScheduleModel.fromJson( adsGenericModel.data[index], isForAppointment: true)); return serviceAppointmentScheduleModel; @@ -149,7 +150,7 @@ class AppointmentRepoImp implements AppointmentRepo { Future createServiceAppointment( {required List schedules, - required int serviceProviderID}) async { + required int serviceProviderID}) async { String t = AppState().getUser.data!.accessToken ?? ""; int customerId = AppState().getUser.data!.userInfo!.customerId ?? 0; @@ -170,12 +171,12 @@ class AppointmentRepoImp implements AppointmentRepo { }); GenericRespModel adsGenericModel = - await injector.get().postJsonForObject( - (json) => GenericRespModel.fromJson(json), - ApiConsts.ServiceProvidersAppointmentCreate, - mapList, - token: t, - ); + await injector.get().postJsonForObject( + (json) => GenericRespModel.fromJson(json), + ApiConsts.ServiceProvidersAppointmentCreate, + mapList, + token: t, + ); return adsGenericModel; } @@ -183,8 +184,8 @@ class AppointmentRepoImp implements AppointmentRepo { @override Future cancelOrRescheduleServiceAppointment( {required int serviceAppointmentID, - required int serviceSlotID, - required int appointmentScheduleAction}) async { + required int serviceSlotID, + required int appointmentScheduleAction}) async { String t = AppState().getUser.data!.accessToken ?? ""; final payload = { @@ -194,12 +195,12 @@ class AppointmentRepoImp implements AppointmentRepo { }; GenericRespModel adsGenericModel = - await injector.get().postJsonForObject( - (json) => GenericRespModel.fromJson(json), - ApiConsts.ServiceProviderAppointmentRescheduleCancelAppointment, - payload, - token: t, - ); + await injector.get().postJsonForObject( + (json) => GenericRespModel.fromJson(json), + ApiConsts.ServiceProviderAppointmentRescheduleCancelAppointment, + payload, + token: t, + ); return adsGenericModel; } @@ -210,15 +211,16 @@ class AppointmentRepoImp implements AppointmentRepo { String t = AppState().getUser.data!.accessToken ?? ""; GenericRespModel genericRespModel = - await injector.get().getJsonForObject( - token: t, - (json) => GenericRespModel.fromJson(json), - queryParameters: map, - ApiConsts.serviceProvidersAppointmentGet, - ); + await injector.get().getJsonForObject( + token: t, + (json) => GenericRespModel.fromJson(json), + queryParameters: map, + ApiConsts.serviceProvidersAppointmentGet, + ); List appointmentList = List.generate( genericRespModel.data.length, - (index) => AppointmentListModel.fromJson(genericRespModel.data[index])); + (index) => + AppointmentListModel.fromJson(genericRespModel.data[index])); return appointmentList; } @@ -227,21 +229,23 @@ class AppointmentRepoImp implements AppointmentRepo { String t = AppState().getUser.data!.accessToken ?? ""; MResponse adsGenericModel = - await injector.get().getJsonForObject( - (json) => MResponse.fromJson(json), - ApiConsts.getAppointmentSlots, - token: t, - queryParameters: map, - ); + await injector.get().getJsonForObject( + (json) => MResponse.fromJson(json), + ApiConsts.getAppointmentSlots, + token: t, + queryParameters: map, + ); return adsGenericModel; } @override - Future updateAppointmentPaymentStatus(Map map) async { + Future updateAppointmentPaymentStatus( + Map map) async { String t = AppState().getUser.data!.accessToken ?? ""; return await injector.get().postJsonForObject( - (json) => MResponse.fromJson(json), ApiConsts.updateAppointmentPaymentStatus, map, + (json) => MResponse.fromJson(json), + ApiConsts.updateAppointmentPaymentStatus, map, token: t); } @@ -249,7 +253,17 @@ class AppointmentRepoImp implements AppointmentRepo { Future updateAppointmentStatus(Map map) async { String t = AppState().getUser.data!.accessToken ?? ""; return await injector.get().postJsonForObject( - (json) => MResponse.fromJson(json), ApiConsts.updateAppointmentStatus, map, + (json) => MResponse.fromJson(json), + ApiConsts.updateAppointmentStatus, map, + token: t); + } + + @override + Future createMergeAppointment(Map map) async { + String t = AppState().getUser.data!.accessToken ?? ""; + return await injector.get().postJsonForObject( + (json) => MResponse.fromJson(json), + ApiConsts.createMergeAppointment, map, token: t); } } diff --git a/lib/utils/enums.dart b/lib/utils/enums.dart index 1bf4bd0..8fcfa8a 100644 --- a/lib/utils/enums.dart +++ b/lib/utils/enums.dart @@ -150,12 +150,12 @@ enum AppointmentStatusEnum { rescheduled, allAppointments, upcoming, - inProgress, - completed, + workStarted, + visitCompleted, } enum AppointmentPaymentStatusEnum { - notConfirmed, + defaultStatus, payNow, paid, payLater, diff --git a/lib/view_models/appointments_view_model.dart b/lib/view_models/appointments_view_model.dart index 2a9fb1b..a2ccd49 100644 --- a/lib/view_models/appointments_view_model.dart +++ b/lib/view_models/appointments_view_model.dart @@ -83,13 +83,16 @@ class AppointmentsVM extends BaseVM { appointmentsFilterOptions.add( FilterListModel(id: 0, title: "All Appointments", isSelected: true)); appointmentsFilterOptions - .add(FilterListModel(id: 6, title: "Upcoming", isSelected: false)); + .add(FilterListModel(id: 2, title: "Confirmed", isSelected: false)); appointmentsFilterOptions .add(FilterListModel(id: 3, title: "Arrived", isSelected: false)); appointmentsFilterOptions - .add(FilterListModel(id: 7, title: "In Progress", isSelected: false)); + .add( + FilterListModel(id: 7, title: "Work In Progress", isSelected: false)); appointmentsFilterOptions .add(FilterListModel(id: 8, title: "Completed", isSelected: false)); + appointmentsFilterOptions + .add(FilterListModel(id: 4, title: "Canceled", isSelected: false)); } Future onItemsSelectedInService() async { @@ -330,6 +333,7 @@ class AppointmentsVM extends BaseVM { notifyListeners(); } + findAppointmentsBasedOnCustomers() { // Use a Set to ensure uniqueness of customerIDs Set uniqueCustomerIDs = Set(); @@ -401,15 +405,15 @@ class AppointmentsVM extends BaseVM { myAppointments = await scheduleRepo.getMyAppointments(map); myFilteredAppointments = myAppointments; - // myUpComingAppointments = myAppointments - // .where((element) => - // element.appointmentStatusEnum == AppointmentStatusEnum.booked) - // .toList(); - setState(ViewState.idle); + myUpComingAppointments = myAppointments + .where((element) => + element.appointmentStatusEnum == AppointmentStatusEnum.booked) + .toList(); + applyFilterOnAppointmentsVM( appointmentStatusEnum: AppointmentStatusEnum.allAppointments, isNeedCustomerFilter: true); - notifyListeners(); + setState(ViewState.idle); } updateSelectedBranch(BranchDetailModel branchDetailModel) { @@ -418,10 +422,12 @@ class AppointmentsVM extends BaseVM { notifyListeners(); } - updateAppointmentStatus(Map map,{bool isNeedToRebuild = false}) async { + updateAppointmentStatus(Map map, + {bool isNeedToRebuild = false}) async { if (isNeedToRebuild) setState(ViewState.busy); try { - MResponse genericRespModel = await scheduleRepo.updateAppointmentStatus(map); + MResponse genericRespModel = + await scheduleRepo.updateAppointmentStatus(map); if (genericRespModel.messageStatus == 1) { Utils.showToast("appointment status updated"); @@ -433,10 +439,12 @@ class AppointmentsVM extends BaseVM { } } - updateAppointmentPaymentStatus(Map map,{bool isNeedToRebuild = false}) async { + updateAppointmentPaymentStatus(Map map, + {bool isNeedToRebuild = false}) async { if (isNeedToRebuild) setState(ViewState.busy); try { - MResponse genericRespModel = await scheduleRepo.updateAppointmentPaymentStatus(map); + MResponse genericRespModel = + await scheduleRepo.updateAppointmentPaymentStatus(map); if (genericRespModel.messageStatus == 1) { Utils.showToast("payment status updated"); @@ -448,6 +456,42 @@ class AppointmentsVM extends BaseVM { } } + Future createMergeAppointment(Map map, + {bool isNeedToRebuild = false}) async { + if (isNeedToRebuild) setState(ViewState.busy); + MResponse genericRespModel = + await scheduleRepo.createMergeAppointment(map); + + return genericRespModel; + } + + bool inNeedToEnableMergeButton = false; + + updateCheckBoxInMergeRequest(int currentIndex) { + myFilteredAppointments2[selectedAppointmentIndex] + .customerAppointmentList![currentIndex] + .isSelected = !(myFilteredAppointments2[selectedAppointmentIndex] + .customerAppointmentList?[currentIndex] + .isSelected ?? + false); + + int count = countSelected(myFilteredAppointments2[selectedAppointmentIndex] + .customerAppointmentList ?? + []); + if (count > 1) + inNeedToEnableMergeButton = true; + else + inNeedToEnableMergeButton = false; + notifyListeners(); + } + + int countSelected(List appointments) { + return appointments + .where((appointment) => appointment.isSelected == true) + .toList() + .length; + } + updateSelectedAppointmentDate( {required int dateIndex, required int scheduleIndex}) { for (var element in serviceAppointmentScheduleList[scheduleIndex] diff --git a/lib/views/appointments/widgets/customer_appointment_slider_widget.dart b/lib/views/appointments/widgets/customer_appointment_slider_widget.dart index d795747..a237e4e 100644 --- a/lib/views/appointments/widgets/customer_appointment_slider_widget.dart +++ b/lib/views/appointments/widgets/customer_appointment_slider_widget.dart @@ -13,14 +13,23 @@ import 'package:mc_common_app/views/advertisement/custom_add_button.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:provider/provider.dart'; +//TODO: Need to make onTapped dynamic class CustomerAppointmentSliderWidget extends StatelessWidget { final List myUpComingAppointments; + bool isNeedToShowEmptyMessage; + Function()? onAppointmentClick; - const CustomerAppointmentSliderWidget({Key? key, required this.myUpComingAppointments}) : super(key: key); + CustomerAppointmentSliderWidget({Key? key, + required this.myUpComingAppointments, + this.isNeedToShowEmptyMessage = false, + this.onAppointmentClick}) + : super(key: key); @override Widget build(BuildContext context) { if (myUpComingAppointments.isEmpty) { + if (isNeedToShowEmptyMessage) + return "No Upcoming Appointment Available".toText().paddingAll(21); return CustomAddButton( needsBorder: true, bgColor: MyColors.white, @@ -29,7 +38,8 @@ class CustomerAppointmentSliderWidget extends StatelessWidget { icon: Container( height: 24, width: 24, - decoration: const BoxDecoration(shape: BoxShape.circle, color: MyColors.darkTextColor), + decoration: const BoxDecoration( + shape: BoxShape.circle, color: MyColors.darkTextColor), child: const Icon(Icons.add, color: MyColors.white), ), ).padding(EdgeInsets.symmetric(vertical: 10, horizontal: 21)); @@ -41,7 +51,8 @@ class CustomerAppointmentSliderWidget extends StatelessWidget { Container( height: 24, width: 24, - decoration: BoxDecoration(shape: BoxShape.circle, color: MyColors.darkTextColor), + decoration: BoxDecoration( + shape: BoxShape.circle, color: MyColors.darkTextColor), child: Icon( Icons.add, color: MyColors.white, @@ -55,7 +66,9 @@ class CustomerAppointmentSliderWidget extends StatelessWidget { ), ], ), - ).onPress(() {}).toWhiteContainer(width: double.infinity, margin: EdgeInsets.symmetric(horizontal: 21, vertical: 10)); + ).onPress(() {}).toWhiteContainer( + width: double.infinity, + margin: EdgeInsets.symmetric(horizontal: 21, vertical: 10)); } return CarouselSlider.builder( options: CarouselOptions( @@ -65,11 +78,16 @@ class CustomerAppointmentSliderWidget extends StatelessWidget { enableInfiniteScroll: false, ), itemCount: myUpComingAppointments.length, - itemBuilder: (BuildContext context, int itemIndex, int pageViewIndex) => BuildAppointmentContainerForCustomer( - isForHome: true, - appointmentListModel: myUpComingAppointments[itemIndex], - onTapped: () => navigateWithName(context, AppRoutes.appointmentDetailView, arguments: myUpComingAppointments[itemIndex]), - ), + itemBuilder: (BuildContext context, int itemIndex, int pageViewIndex) => + BuildAppointmentContainerForCustomer( + isForHome: true, + appointmentListModel: myUpComingAppointments[itemIndex], + onTapped: isNeedToShowEmptyMessage + ? onAppointmentClick! + : () => + navigateWithName(context, AppRoutes.appointmentDetailView, + arguments: myUpComingAppointments[itemIndex]), + ), ); } } @@ -79,7 +97,11 @@ class BuildAppointmentContainerForCustomer extends StatelessWidget { final AppointmentListModel? appointmentListModel; final Function() onTapped; - const BuildAppointmentContainerForCustomer({Key? key, this.isForHome = false, required this.onTapped, required this.appointmentListModel}) : super(key: key); + const BuildAppointmentContainerForCustomer({Key? key, + this.isForHome = false, + required this.onTapped, + required this.appointmentListModel}) + : super(key: key); Widget showServices(String title, String icon, {bool isMoreText = false}) { return Row( @@ -99,15 +121,18 @@ class BuildAppointmentContainerForCustomer extends StatelessWidget { ); } - List buildServicesFromAppointment({required AppointmentListModel appointmentListModel}) { - if (appointmentListModel.appointmentServicesList == null || appointmentListModel.appointmentServicesList!.isEmpty) { + List buildServicesFromAppointment( + {required AppointmentListModel appointmentListModel}) { + if (appointmentListModel.appointmentServicesList == null || + appointmentListModel.appointmentServicesList!.isEmpty) { return [SizedBox()]; } if (appointmentListModel.appointmentServicesList!.length == 1) { return [ showServices( - appointmentListModel.appointmentServicesList![0].providerServiceDescription, + appointmentListModel + .appointmentServicesList![0].providerServiceDescription, MyAssets.modificationsIcon, ) ]; @@ -115,7 +140,11 @@ class BuildAppointmentContainerForCustomer extends StatelessWidget { List servicesList = List.generate( 2, - (index) => showServices(appointmentListModel.appointmentServicesList![index].providerServiceDescription, MyAssets.modificationsIcon), + (index) => + showServices( + appointmentListModel + .appointmentServicesList![index].providerServiceDescription, + MyAssets.modificationsIcon), ); if (appointmentListModel.appointmentServicesList!.length > 1) { @@ -141,29 +170,33 @@ class BuildAppointmentContainerForCustomer extends StatelessWidget { children: [ isForHome != null && isForHome! ? Image.asset( - MyAssets.bnCar, - width: 56, - height: 56, - fit: BoxFit.fill, - ).toCircle(borderRadius: 100) + MyAssets.bnCar, + width: 56, + height: 56, + fit: BoxFit.fill, + ).toCircle(borderRadius: 100) : Image.asset( - MyAssets.bnCar, - width: 80, - height: 85, - fit: BoxFit.cover, - ), + MyAssets.bnCar, + width: 80, + height: 85, + fit: BoxFit.cover, + ), 8.width, Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ - (appointmentListModel!.providerName ?? "").toText(color: MyColors.black, isBold: true, fontSize: 16), + (appointmentListModel!.providerName ?? "").toText( + color: MyColors.black, isBold: true, fontSize: 16), Row( children: [ MyAssets.miniClock.buildSvg(height: 12), 2.width, - "${appointmentListModel!.duration ?? ""} ${appointmentListModel!.appointmentDate!.toFormattedDateWithoutTime()}".toText( + "${appointmentListModel!.duration ?? + ""} ${appointmentListModel!.appointmentDate! + .toFormattedDateWithoutTime()}" + .toText( color: MyColors.lightTextColor, fontSize: 12, ), @@ -172,38 +205,42 @@ class BuildAppointmentContainerForCustomer extends StatelessWidget { 9.height, isForHome != null && isForHome! ? Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - "Appointment Details".toText( - color: MyColors.primaryColor, - isUnderLine: true, - isBold: true, - fontSize: 14, - ), - const Icon(Icons.arrow_forward), - ], - ) + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + "Appointment Details".toText( + color: MyColors.primaryColor, + isUnderLine: true, + isBold: true, + fontSize: 14, + ), + const Icon(Icons.arrow_forward), + ], + ) : Row( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Expanded( - child: Column( - children: buildServicesFromAppointment(appointmentListModel: appointmentListModel!), - ), - ), - const Icon( - Icons.arrow_forward, - ), - ], + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Expanded( + child: Column( + children: buildServicesFromAppointment( + appointmentListModel: + appointmentListModel!), ), + ), + const Icon( + Icons.arrow_forward, + ), + ], + ), ], ), ), ], ), ], - ).onPress(onTapped).toWhiteContainer(width: double.infinity, allPading: 12), + ) + .onPress(onTapped) + .toWhiteContainer(width: double.infinity, allPading: 12), ); } } From 511342adefb19975cf7c2afe91d1ed6f3ec3162b Mon Sep 17 00:00:00 2001 From: "Mirza.Shafique@cloudsolutions.com.sa" <5093@Shf> Date: Sun, 31 Dec 2023 11:06:02 +0300 Subject: [PATCH 2/2] Appointment implementation in Provider 1.0 --- lib/view_models/appointments_view_model.dart | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/view_models/appointments_view_model.dart b/lib/view_models/appointments_view_model.dart index a2ccd49..b0739bb 100644 --- a/lib/view_models/appointments_view_model.dart +++ b/lib/view_models/appointments_view_model.dart @@ -44,6 +44,7 @@ class AppointmentsVM extends BaseVM { required this.providerRepo, required this.commonRepo}); + bool isUpcommingEnabled = true; bool isFetchingLists = false; int selectedBranch = 0; int selectedAppointmentIndex = 0; @@ -374,7 +375,7 @@ class AppointmentsVM extends BaseVM { myFilteredAppointments = myAppointments; myUpComingAppointments = myAppointments .where((element) => - element.appointmentStatusEnum == AppointmentStatusEnum.booked) + element.appointmentStatusEnum == AppointmentStatusEnum.confirmed) .toList(); setState(ViewState.idle); // applyFilterOnAppointmentsVM(appointmentStatusEnum: AppointmentStatusEnum.allAppointments); @@ -407,7 +408,7 @@ class AppointmentsVM extends BaseVM { myFilteredAppointments = myAppointments; myUpComingAppointments = myAppointments .where((element) => - element.appointmentStatusEnum == AppointmentStatusEnum.booked) + element.appointmentStatusEnum == AppointmentStatusEnum.booked) .toList(); applyFilterOnAppointmentsVM( @@ -456,7 +457,7 @@ class AppointmentsVM extends BaseVM { } } - Future createMergeAppointment(Map map, + Future createMergeAppointment(Map map, {bool isNeedToRebuild = false}) async { if (isNeedToRebuild) setState(ViewState.busy); MResponse genericRespModel =