From 36351fc9203d78a21e0f1be631b276bbba3e4b58 Mon Sep 17 00:00:00 2001 From: Faiz Hashmi Date: Wed, 20 Nov 2024 10:43:55 +0300 Subject: [PATCH 01/10] Fixing JIRA Issues --- lib/config/provider_routes.dart | 4 + lib/main.dart | 10 +- lib/view_models/schedule_view_model.dart | 5 + .../appoinment_detail_list_page.dart | 5 +- lib/views/appoinments/appointment_page.dart | 53 ++-- .../appoinments/update_appointment_page.dart | 292 ++++++++++-------- .../schedule/add_schedules_page.dart | 182 ++++++----- .../schedule/schedules_list_page.dart | 18 +- .../services/create_item_page.dart | 16 +- .../widget/general_appointment_widget.dart | 29 +- 10 files changed, 344 insertions(+), 270 deletions(-) diff --git a/lib/config/provider_routes.dart b/lib/config/provider_routes.dart index 97d233d..453303d 100644 --- a/lib/config/provider_routes.dart +++ b/lib/config/provider_routes.dart @@ -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/provider_branches_models/branch_detail_model.dart'; import 'package:mc_common_app/utils/enums.dart'; +import 'package:mc_common_app/views/setting_options/provider_accepted_requests_view.dart'; class ProviderAppRoutes { static final Map routes = { @@ -61,5 +62,8 @@ class ProviderAppRoutes { //Branch Duplication AppRoutes.matchServices: (context) => MatchedServicesPage((ModalRoute.of(context)!.settings.arguments) == null ? null : (ModalRoute.of(context)!.settings.arguments as MatchServicesArguments)), + + //Requests + AppRoutes.providerAcceptedRequestsView: (context) => const ProviderAcceptedRequestsView(), }; } diff --git a/lib/main.dart b/lib/main.dart index 13339a4..b686918 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,5 +1,6 @@ import 'dart:io'; 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/schedule_repo.dart'; import 'package:car_provider_app/view_models/items_view_model.dart'; @@ -159,14 +160,17 @@ Future main() async { // command to generate languages data from json class MyApp extends StatelessWidget { - const MyApp({Key? key}) : super(key: key); + const MyApp({super.key}); - @override + @override Widget build(BuildContext context) { + SystemChrome.setPreferredOrientations([ + DeviceOrientation.portraitUp, + DeviceOrientation.portraitDown, + ]); return Sizer( builder: (context, orientation, deviceType) { injector.get().setAppType(AppType.provider); - AppState().setPostParamsModel( PostParamsModel( languageID: EasyLocalization.of(context)?.locale.languageCode == "ar" ? 1 : 2, diff --git a/lib/view_models/schedule_view_model.dart b/lib/view_models/schedule_view_model.dart index 2a2996e..3bb42d9 100644 --- a/lib/view_models/schedule_view_model.dart +++ b/lib/view_models/schedule_view_model.dart @@ -105,6 +105,11 @@ class ScheduleVM extends BaseVM { return response; } + Future checkServiceGroupInBranchSchedule(Map map) async { + GenericRespModel response = await scheduleRepo.checkServiceGroupInBranchSchedule(map); + return response; + } + Future addServicesInSchedule(Map map) async { GenericRespModel response = await scheduleRepo.addServicesInSchedule(map); return response; diff --git a/lib/views/appoinments/appoinment_detail_list_page.dart b/lib/views/appoinments/appoinment_detail_list_page.dart index a278f17..782ac00 100644 --- a/lib/views/appoinments/appoinment_detail_list_page.dart +++ b/lib/views/appoinments/appoinment_detail_list_page.dart @@ -13,7 +13,7 @@ import 'package:provider/provider.dart'; import 'package:easy_localization/easy_localization.dart'; class AppointmentDetailListPage extends StatelessWidget { - const AppointmentDetailListPage({Key? key}) : super(key: key); + const AppointmentDetailListPage({super.key}); @override Widget build(BuildContext context) { @@ -41,7 +41,8 @@ class AppointmentDetailListPage extends StatelessWidget { onTap: () { appointmentsVM.selectedAppointmentId = appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index].id ?? 0; 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]); }, ); }, diff --git a/lib/views/appoinments/appointment_page.dart b/lib/views/appoinments/appointment_page.dart index 6173eed..6e120f9 100644 --- a/lib/views/appoinments/appointment_page.dart +++ b/lib/views/appoinments/appointment_page.dart @@ -104,32 +104,35 @@ class _AppointmentPageState extends State { EmptyWidget( spacerWidget: const SizedBox(height: 25), text: LocaleKeys.noAppointmentFound.tr(), + ) + else ...[ + ListView.separated( + itemBuilder: (context, index) { + return GeneralAppointmentWidget( + isNeedToShowItems: true, + appointmentListModel: appointmentsVM.myFilteredAppointments2[index], + isNeedTotalPayment: false, + onTap: () { + context.read().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().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), - ), + ], ], ), ), diff --git a/lib/views/appoinments/update_appointment_page.dart b/lib/views/appoinments/update_appointment_page.dart index 73efa06..189861b 100644 --- a/lib/views/appoinments/update_appointment_page.dart +++ b/lib/views/appoinments/update_appointment_page.dart @@ -22,10 +22,15 @@ import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:provider/provider.dart'; import 'package:easy_localization/easy_localization.dart'; -class UpdateAppointmentPage extends StatelessWidget { - late AppointmentListModel appointmentListModel; +class UpdateAppointmentPage extends StatefulWidget { + const UpdateAppointmentPage({super.key}); - UpdateAppointmentPage({Key? key}) : super(key: key); + @override + State createState() => _UpdateAppointmentPageState(); +} + +class _UpdateAppointmentPageState extends State { + late AppointmentListModel appointmentListModel; @override Widget build(BuildContext context) { @@ -39,144 +44,150 @@ class UpdateAppointmentPage extends StatelessWidget { if (appointmentsVM.state == ViewState.busy) { return const Center(child: CircularProgressIndicator()); } else { - return Column( - children: [ - Expanded( - child: ListView( - padding: const EdgeInsets.all(21), - children: [ - GeneralAppointmentWidget( - appointmentListModel: appointmentListModel, - isNeedTotalPayment: true, - isNeedToShowItems: true, - isNeedToShowToMoreText: false, - onTap: () {}, - ), - 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, - ); - }, + return RefreshIndicator( + onRefresh: () async => _updateAppointment(context, appointmentListModel.branchId ?? 0), + child: Column( + children: [ + Expanded( + child: ListView( + padding: const EdgeInsets.all(21), + children: [ + GeneralAppointmentWidget( + appointmentListModel: appointmentListModel, + isNeedTotalPayment: true, + isNeedToShowItems: true, + isNeedToShowToMoreText: false, + onTap: () {}, ), + 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) ...[ - Utils.buildStatusContainer(LocaleKeys.appointmentCancelled.tr()).paddingAll(10), - ], - if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.booked) - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded(child: showPayNowButton(context, appointmentsVM)), - 12.width, - Expanded(child: showCancelButton(context, appointmentsVM)), - ], - ).paddingAll(21), + if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.cancelled) ...[ + Utils.buildStatusContainer(LocaleKeys.appointmentCancelled.tr()).paddingAll(10), + ], + if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.booked) + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded(child: showPayNowButton(context, appointmentsVM)), + 12.width, + Expanded(child: showCancelButton(context, appointmentsVM)), + ], + ).paddingAll(21), - if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.confirmed && - (appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.payPartial || appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.defaultStatus)) - Column( - children: [ - showArrivedButton(context, appointmentsVM), - ], - ).paddingAll(21), + if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.confirmed && + (appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.payPartial || + appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.defaultStatus)) + Column( + children: [ + showArrivedButton(context, appointmentsVM), + ], + ).paddingAll(21), - if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.arrived && - (appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.payPartial || appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.defaultStatus)) - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded(child: showPayNowButton(context, appointmentsVM)), - 12.width, - Expanded(child: showPayLaterButton(context, appointmentsVM)), - ], - ).paddingAll(21), + if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.arrived && + (appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.payPartial || + appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.defaultStatus)) + Row( + 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) && - appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.payNow) - Utils.buildStatusContainer(LocaleKeys.waitingPaymentfromtheCustomer.tr()).paddingAll(10), + if ((appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.arrived || appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.workStarted) && + appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.payNow) + Utils.buildStatusContainer(LocaleKeys.waitingPaymentfromtheCustomer.tr()).paddingAll(10), - if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.arrived && - (appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.paid || appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.payLater)) - Column( - children: [ - showWorkStartButton(context, appointmentsVM), - ], - ).paddingAll(21), + if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.arrived && + (appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.paid || + appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.payLater)) + Column( + children: [ + showWorkStartButton(context, appointmentsVM), + ], + ).paddingAll(21), - if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.workStarted && appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.payPartial) - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded(child: showPayNowButton(context, appointmentsVM)), - 12.width, - Expanded(child: showPayLaterButton(context, appointmentsVM)), - ], - ).paddingAll(21), - // "Show Pay Now".toText(), + if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.workStarted && appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.payPartial) + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded(child: showPayNowButton(context, appointmentsVM)), + 12.width, + Expanded(child: showPayLaterButton(context, appointmentsVM)), + ], + ).paddingAll(21), + // "Show Pay Now".toText(), - if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.workStarted && appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.paid) - Column( - 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.workStarted && appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.paid) + Column( + 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) ...[ - Utils.buildStatusContainer(LocaleKeys.appointmentisCompleted.tr()).paddingAll(10), - ], + if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.visitCompleted) ...[ + Utils.buildStatusContainer(LocaleKeys.appointmentisCompleted.tr()).paddingAll(10), + ], - //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) {}, - // )); - // }, - // ), - // ], - // ), - // ), - ], + //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 +200,14 @@ class UpdateAppointmentPage extends StatelessWidget { maxWidth: double.infinity, onPressed: () async { 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); - pop(context); + // pop(context); // showMyBottomSheet( // context, @@ -210,8 +226,10 @@ class UpdateAppointmentPage extends StatelessWidget { maxWidth: double.infinity, onPressed: () async { Utils.showLoading(context); - await appointmentsVM.updateAppointmentPaymentStatus({"appointmentID": appointmentListModel.id.toString(), "appointmentServicePaymentStatusID": 2}); - _updateAppointment(context, appointmentListModel.branchId ?? 0); + bool status = await appointmentsVM.updateAppointmentPaymentStatus({"appointmentID": appointmentListModel.id.toString(), "appointmentServicePaymentStatusID": 2}); + if (status) { + _updateAppointment(context, appointmentListModel.branchId ?? 0); + } Utils.hideLoading(context); pop(context); }, @@ -224,8 +242,10 @@ class UpdateAppointmentPage extends StatelessWidget { maxWidth: double.infinity, onPressed: () async { Utils.showLoading(context); - await appointmentsVM.updateAppointmentStatus(appointmentId: appointmentListModel.id!, appointmentStatusEnum: AppointmentStatusEnum.arrived); - _updateAppointment(context, appointmentListModel.branchId ?? 0); + bool status = await appointmentsVM.updateAppointmentStatus(appointmentId: appointmentListModel.id!, appointmentStatusEnum: AppointmentStatusEnum.arrived); + if (status) { + _updateAppointment(context, appointmentListModel.branchId ?? 0); + } Utils.hideLoading(context); pop(context); }, diff --git a/lib/views/branch_management/schedule/add_schedules_page.dart b/lib/views/branch_management/schedule/add_schedules_page.dart index 33012e8..b323f12 100644 --- a/lib/views/branch_management/schedule/add_schedules_page.dart +++ b/lib/views/branch_management/schedule/add_schedules_page.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:developer'; 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/select_days_sheet.dart'; @@ -35,6 +36,8 @@ class _AddSchedulesPageState extends State { late ScheduleData scheduleData; + int? scheduleID; + setEditData() { name = scheduleData.scheduleName ?? ""; startDate = DateHelper.formatAsYearMonthDay(scheduleData.fromDate ?? DateTime.now()); @@ -107,7 +110,9 @@ class _AddSchedulesPageState extends State { schedulevm.selectedServicesItems = []; schedulevm.selectedDaysItems = []; if (scheduleData.id != null) { + scheduleID = scheduleData.id; setEditData(); + setState(() {}); } }); } @@ -115,7 +120,7 @@ class _AddSchedulesPageState extends State { @override Widget build(BuildContext context) { return Scaffold( - appBar: CustomAppBar(title: LocaleKeys.createGroupServices.tr()), + appBar: CustomAppBar(title: scheduleID == null ? LocaleKeys.createGroupServices.tr() : LocaleKeys.updateGroupServices.tr()), body: SizedBox( width: double.infinity, child: Consumer( @@ -298,7 +303,7 @@ class _AddSchedulesPageState extends State { ), ), ShowFillButton( - title: LocaleKeys.create.tr(), + title: scheduleID == null ? LocaleKeys.create.tr() : LocaleKeys.update.tr(), maxWidth: double.infinity, margin: const EdgeInsets.all(20), onPressed: () { @@ -353,102 +358,129 @@ class _AddSchedulesPageState extends State { } createSchedule(BuildContext context, ScheduleVM scheduleVM) async { - List 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); - GenericRespModel scheduleResponse = await scheduleVM.createSchedule(map); - if (scheduleResponse.messageStatus == 1) { + try { List services = []; for (var element in scheduleVM.selectedServicesItems) { services.add(element.id); } var map1 = { - "branchAppointmentScheduleID": scheduleResponse.data, "serviceProviderServiceID": services, - "serviceGroupDescription": "string", + "appointmentType": selectedScheduleLocationDrop.id, }; - GenericRespModel servicesResponse = await scheduleVM.addServicesInSchedule(map1); + GenericRespModel respModel = await scheduleVM.checkServiceGroupInBranchSchedule(map1); Utils.hideLoading(context); - if (servicesResponse.messageStatus == 1) { - Utils.showToast("Successfully schedule created"); - context.read().getSchedules(scheduleData.branchId ?? ""); - pop(context); + + log("respModel: ${respModel.data}"); + if (respModel.messageStatus == 2) { + Utils.showToast(respModel.message ?? ""); + + return; + } + + List 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().getSchedules(scheduleData.branchId ?? ""); + pop(context); + } else { + Utils.showToast(servicesResponse.message ?? ""); + // context.read().getSchedules(scheduleData.branchId ?? ""); + // pop(context); + } } else { - Utils.showToast(servicesResponse.message ?? ""); - // context.read().getSchedules(scheduleData.branchId ?? ""); - // pop(context); + Utils.hideLoading(context); + Utils.showToast(scheduleResponse.message ?? ""); } - } else { + } catch (e) { + Utils.showToast(e.toString()); Utils.hideLoading(context); - Utils.showToast(scheduleResponse.message ?? ""); } } - updateSchedule(BuildContext context, ScheduleVM model) async { - List days = []; - for (var element in model.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 services = []; - for (var element in model.selectedServicesItems) { - services.add(element.id); + updateSchedule(BuildContext context, ScheduleVM scheduleVM) async { + try { + List days = []; + for (var element in scheduleVM.selectedDaysItems) { + days.add(element.id); } - var map1 = { - "branchAppointmentScheduleID": scheduleData.id, - "serviceProviderServiceID": services, - "serviceGroupDescription": "string", + 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, }; - GenericRespModel servicesResponse = await model.updateServicesInSchedule(map1); - Utils.hideLoading(context); - if (servicesResponse.messageStatus == 1) { - Utils.showToast(servicesResponse.message ?? "Schedule Successfully Updated"); - context.read().getSchedules(scheduleData.branchId ?? ""); - pop(context); + Utils.showLoading(context); + GenericRespModel scheduleResponse = await scheduleVM.updateSchedule(map); + if (scheduleResponse.messageStatus == 1) { + List services = []; + for (var element in scheduleVM.selectedServicesItems) { + 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().getSchedules(scheduleData.branchId ?? ""); + pop(context); + } else { + Utils.showToast(servicesResponse.message ?? LocaleKeys.somethingWrong.tr()); + } } 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.showToast(scheduleResponse.message ?? LocaleKeys.somethingWrong.tr()); } } } diff --git a/lib/views/branch_management/schedule/schedules_list_page.dart b/lib/views/branch_management/schedule/schedules_list_page.dart index 503dc43..53dd43e 100644 --- a/lib/views/branch_management/schedule/schedules_list_page.dart +++ b/lib/views/branch_management/schedule/schedules_list_page.dart @@ -103,24 +103,21 @@ class _SchedulesListPageState extends State { crossAxisAlignment: CrossAxisAlignment.center, children: [ 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: const EdgeInsets.all(4.0), child: SvgPicture.asset( MyAssets.icEdit, - width: 16, - height: 16, + width: 18, + height: 18, ), ).onPress(() { scheduleVM.schedule!.data![index].branchId = widget.branchId ?? ""; 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, @@ -130,7 +127,8 @@ class _SchedulesListPageState extends State { showItem("${LocaleKeys.shiftEndTime.tr()}:", scheduleVM.schedule!.data![index].endTime ?? ""), showItem("${LocaleKeys.slotsTime.tr()}:", "${scheduleVM.schedule!.data![index].slotDurationMinute} Mins"), 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])), 12.height, "${LocaleKeys.services.tr()}:".toText(fontSize: 12, color: MyColors.lightTextColor), diff --git a/lib/views/branch_management/services/create_item_page.dart b/lib/views/branch_management/services/create_item_page.dart index 00ad966..6ebed41 100644 --- a/lib/views/branch_management/services/create_item_page.dart +++ b/lib/views/branch_management/services/create_item_page.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'dart:developer'; import 'dart:io'; import 'package:car_provider_app/view_models/items_view_model.dart'; @@ -103,7 +104,7 @@ class _CreateItemPageState extends State { ), 12.height, TxtField( - hint: LocaleKeys.manufacturedOn.tr(), + hint: LocaleKeys.manufacturedOn.tr(), value: year, keyboardType: TextInputType.number, isNeedClickAll: true, @@ -196,7 +197,12 @@ class _CreateItemPageState extends State { maxWidth: double.infinity, onPressed: () async { 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)) { Map map = { "name": name, @@ -220,6 +226,7 @@ class _CreateItemPageState extends State { } Utils.showToast(mResponse.message ?? ""); } else { + log("attachedIMag: $attachedFile"); Map map = { "id": itemData!.id, "name": name, @@ -255,7 +262,7 @@ class _CreateItemPageState extends State { bool validation() { bool valid = true; - if (file == null) { + if (pickedImage.isEmpty && file == null) { Utils.showToast("Please add al least one item image."); valid = false; } @@ -268,9 +275,6 @@ class _CreateItemPageState extends State { } else if (price == null) { Utils.showToast("Please add valid item price"); valid = false; - } else if (year == null) { - Utils.showToast("Please add valid year"); - valid = false; } return valid; } diff --git a/lib/views/dashboard/widget/general_appointment_widget.dart b/lib/views/dashboard/widget/general_appointment_widget.dart index c6daab6..331a684 100644 --- a/lib/views/dashboard/widget/general_appointment_widget.dart +++ b/lib/views/dashboard/widget/general_appointment_widget.dart @@ -29,8 +29,8 @@ class GeneralAppointmentWidget extends StatelessWidget { this.isSelectable = false, this.isNeedToShowAppointmentStatus = false, this.isNeedToShowMergeStatus = false, - Key? key, - }) : super(key: key); + super.key, + }); List buildServicesFromAppointment({required AppointmentListModel appointmentListModel}) { if (appointmentListModel.appointmentServicesList == null || appointmentListModel.appointmentServicesList!.isEmpty) { @@ -51,7 +51,7 @@ class GeneralAppointmentWidget extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.start, children: [ showServices( - appointmentListModel.appointmentServicesList!.first.providerServiceDescription, + "${appointmentListModel.appointmentServicesList!.first.providerServiceDescription} - ${appointmentListModel.appointmentServicesList!.first.serviceId}", MyAssets.modificationsIcon, ), if (isNeedToShowItems) ...itemsList, @@ -67,28 +67,24 @@ class GeneralAppointmentWidget extends StatelessWidget { if (isNeedToShowItems) { itemsList = List.generate( 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), ); } - return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - showServices(appointmentListModel.appointmentServicesList![index].providerServiceDescription, MyAssets.modificationsIcon), + showServices( + "${appointmentListModel.appointmentServicesList![index].providerServiceDescription} - ${appointmentListModel.appointmentServicesList![index].serviceId}", MyAssets.modificationsIcon), if (isNeedToShowItems) ...itemsList, ], ).paddingOnly(bottom: 6); }, ); - if (isNeedToShowToMoreText && appointmentListModel.appointmentServicesList!.length > 1) { + if (isNeedToShowToMoreText && appointmentListModel.appointmentServicesList!.length > 2) { servicesList.add( showServices( - "+ ${appointmentListModel.appointmentServicesList!.length - 1} More", + "+ ${appointmentListModel.appointmentServicesList!.length - 2} More", "", isMoreText: true, ), @@ -128,7 +124,7 @@ class GeneralAppointmentWidget extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ 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), borderRadius: 12, backgroundColor: MyColors.greenColor, @@ -183,13 +179,20 @@ class GeneralAppointmentWidget extends StatelessWidget { ), Row( children: [ - "${LocaleKeys.location.tr()}: ".toText(color: MyColors.lightTextColor), + "${LocaleKeys.serviceDeliveryType.tr()}: ".toText(color: MyColors.lightTextColor), 2.width, (appointmentListModel.appointmentTypeEnum == AppointmentTypeEnum.home ? LocaleKeys.home.tr() : LocaleKeys.workshop.tr()).toText( fontSize: 12, ), ], ), + Row( + children: [ + "${LocaleKeys.createdOn.tr()}: ".toText(color: MyColors.lightTextColor), + 2.width, + Flexible(child: appointmentListModel.appointmentDate!.toFormattedDateWithoutTime().toText(fontSize: 8)) + ], + ), ], ), ), From 31d0368e2a613e025f742bb7e9a5b7a95cd47af3 Mon Sep 17 00:00:00 2001 From: Faiz Hashmi Date: Thu, 21 Nov 2024 17:03:51 +0300 Subject: [PATCH 02/10] Fixing JIRA Issues --- lib/main.dart | 2 + .../branch/branch_detail_page.dart | 20 ++++++- .../services/create_item_page.dart | 8 +-- .../services/create_services_page3.dart | 2 +- .../services/items_list_page.dart | 11 ++-- .../services/services_list_page.dart | 57 +++++++++++-------- pubspec.yaml | 8 +-- 7 files changed, 68 insertions(+), 40 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index b686918..d017a79 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -190,3 +190,5 @@ class MyApp extends StatelessWidget { ); } } + + diff --git a/lib/views/branch_management/branch/branch_detail_page.dart b/lib/views/branch_management/branch/branch_detail_page.dart index 315fea3..45479bf 100644 --- a/lib/views/branch_management/branch/branch_detail_page.dart +++ b/lib/views/branch_management/branch/branch_detail_page.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:developer'; 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'; @@ -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/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/profile/categroy.dart'; import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/navigator.dart'; @@ -296,7 +298,7 @@ class _BranchDetailPageState extends State { .margin(right: 5), ).onPress(() { 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; } context.read().currentSelectedBranchName = widget.branchData.branchName.toString(); @@ -308,7 +310,7 @@ class _BranchDetailPageState extends State { bgColor: MyColors.white, onTap: () { 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; } navigateWithName( @@ -367,7 +369,19 @@ class _BranchDetailPageState extends State { return buildServiceTileWidget(pIndex, serviceVM).onPress(() { serviceVM.categories[pIndex].branchId = widget.branchData.id.toString(); serviceVM.categories[pIndex].branchName = widget.branchData.branchName.toString(); - navigateWithName(context, AppRoutes.servicesList, arguments: serviceVM.categories[pIndex]); + // CategoryData categoryData = serviceVM.categories[pIndex]; + 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, diff --git a/lib/views/branch_management/services/create_item_page.dart b/lib/views/branch_management/services/create_item_page.dart index 6ebed41..71398ae 100644 --- a/lib/views/branch_management/services/create_item_page.dart +++ b/lib/views/branch_management/services/create_item_page.dart @@ -221,18 +221,17 @@ class _CreateItemPageState extends State { GenericRespModel mResponse = await itemsVM!.createServiceItem(map); Utils.hideLoading(context); if (mResponse.messageStatus == 1) { - itemsVM!.getServiceItems(itemData!.serviceProviderServiceId ?? 0); + // itemsVM!.getServiceItems(itemData!.serviceProviderServiceId ?? 0); pop(context); } Utils.showToast(mResponse.message ?? ""); } else { - log("attachedIMag: $attachedFile"); Map map = { "id": itemData!.id, "name": name, "price": price, "description": description, - "itemImage": attachedFile ?? "", + "itemImage": file == null ? "" : attachedFile, "companyID": 1, "manufactureDate": year, "serviceProviderServiceID": itemData!.serviceProviderServiceId, @@ -245,11 +244,10 @@ class _CreateItemPageState extends State { GenericRespModel mResponse = await itemsVM!.updateServiceItem(map); Utils.hideLoading(context); if (mResponse.messageStatus == 1) { - itemsVM!.getServiceItems(itemData!.serviceProviderServiceId ?? 0); + // itemsVM!.getServiceItems(itemData!.serviceProviderServiceId ?? 0); pop(context); } Utils.showToast(mResponse.message ?? ""); - pop(context); } } }, diff --git a/lib/views/branch_management/services/create_services_page3.dart b/lib/views/branch_management/services/create_services_page3.dart index 470f492..a3466d4 100644 --- a/lib/views/branch_management/services/create_services_page3.dart +++ b/lib/views/branch_management/services/create_services_page3.dart @@ -71,7 +71,6 @@ class _CreateServicesPage3State extends State { @override Widget build(BuildContext context) { - log("categoryId: ${categoryId}"); return Scaffold( appBar: CustomAppBar(title: LocaleKeys.editServices.tr()), body: SizedBox( @@ -291,6 +290,7 @@ class _CreateServicesPage3State extends State { Utils.showToast(mResponse.message ?? ""); if (mResponse.messageStatus == 1) { context.read().filterUserBranchCategories(); + context.read().isNeedRefreshServicesList = true; pop(context); } } diff --git a/lib/views/branch_management/services/items_list_page.dart b/lib/views/branch_management/services/items_list_page.dart index 8abfa70..cac989e 100644 --- a/lib/views/branch_management/services/items_list_page.dart +++ b/lib/views/branch_management/services/items_list_page.dart @@ -21,7 +21,7 @@ import 'package:easy_localization/easy_localization.dart'; class ItemsListPage extends StatelessWidget { ServiceModel? serviceProviderService; - ItemsListPage({Key? key}) : super(key: key); + ItemsListPage({super.key}); @override Widget build(BuildContext context) { @@ -58,9 +58,12 @@ class ItemsListPage extends StatelessWidget { children: [ model.serviceItems!.data![index].name.toString().toText(fontSize: 16, isBold: true), 4.height, - showItem("${LocaleKeys.availableforAppointment.tr()}:", (model.serviceItems!.data![index].isAllowAppointment ?? 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), + showItem("${LocaleKeys.availableforAppointment.tr()}:", (model.serviceItems!.data![index].isAllowAppointment ?? 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, LocaleKeys.serviceAmount.tr().toText(fontSize: 13, color: MyColors.lightTextColor), Row( diff --git a/lib/views/branch_management/services/services_list_page.dart b/lib/views/branch_management/services/services_list_page.dart index 8931441..da02e70 100644 --- a/lib/views/branch_management/services/services_list_page.dart +++ b/lib/views/branch_management/services/services_list_page.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:developer'; import 'package:car_provider_app/views/branch_management/services/duplication/sheet/approved_branches_list_sheet.dart'; import 'package:easy_localization/easy_localization.dart'; @@ -60,26 +61,53 @@ class _ServicesListPageState extends State { @override void initState() { scheduleMicrotask(() async { - await _fetchServices(); + await _fetchServices(ServiceStatusEnum.approvedOrActive); }); super.initState(); } - Future _fetchServices() async { + Future _fetchServices(ServiceStatusEnum status) async { categoryData.services = await context.read().fetchProviderServicesModelByCategoryIdAndBranchID( branchID: categoryData.branchId.toString(), categoryId: categoryData.id.toString(), ); - filteredServices = categoryData.services!.where((i) => i.serviceStatus == ServiceStatusEnum.approvedOrActive.index + 1).toList(); + filteredServices = categoryData.services!.where((i) => i.serviceStatus == status.index + 1).toList(); screenState = ViewState.idle; setState(() {}); } + Future _onRefresh(ServiceStatusEnum status, int tab) async { + screenState = ViewState.busy; + selectedService = status; + selectedTab = tab; + setState(() {}); + categoryData.services = await context.read().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(() {}); + } + @override Widget build(BuildContext context) { categoryData = ModalRoute.of(context)!.settings.arguments as CategoryData; + if (context.read().isNeedRefreshServicesList) { + WidgetsBinding.instance.addPostFrameCallback((_) { + if (mounted) { + _onRefresh(ServiceStatusEnum.pending, 1); + context.read().isNeedRefreshServicesList = false; + } + }); + } return Scaffold( appBar: CustomAppBar( title: LocaleKeys.services.tr(), @@ -128,22 +156,7 @@ class _ServicesListPageState extends State { const SizedBox(height: 10), Expanded( child: RefreshIndicator( - onRefresh: () async { - screenState = ViewState.busy; - setState(() {}); - categoryData.services = await context.read().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(() {}); - }, + onRefresh: () async => _onRefresh(selectedService, selectedTab), child: screenState == ViewState.busy ? const Center( child: CircularProgressIndicator(), @@ -165,9 +178,7 @@ class _ServicesListPageState extends State { ], Row( children: [ - Expanded( - child: (filteredServices[index].serviceDescription ?? "").toText(fontSize: 16), - ), + Expanded(child: (filteredServices[index].serviceDescription ?? "").toText(fontSize: 16)), if (filteredServices[index].serviceStatus != 1) ...[ Padding( padding: const EdgeInsets.all(4.0), @@ -176,7 +187,7 @@ class _ServicesListPageState extends State { width: 16, height: 16, ), - ).onPress(() { + ).onPress(() async { navigateWithName(context, AppRoutes.createServices3, arguments: CreateBranchModel( branchId: categoryData.branchId ?? '', diff --git a/pubspec.yaml b/pubspec.yaml index ac8b00e..9bf8d2d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -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 +. # Both the version and the builder number may be overridden in flutter # 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 # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at @@ -40,9 +40,9 @@ dependencies: # path: C:/Users/mirza.shafique/AndroidStudioProjects/mc_common_app mc_common_app: -# path: D:\Development\car_common_app -# path: /Users/amir/StudioProjects/car_common_app - path: /Volumes/Data/Projects/Flutter/car_common_app + # path: D:\Development\car_common_app + # path: /Users/amir/StudioProjects/car_common_app + path: /Volumes/Data/Projects/Flutter/car_common_app From 48ce588021c698f1727d77501a542cb8e362488f Mon Sep 17 00:00:00 2001 From: Faiz Hashmi Date: Mon, 25 Nov 2024 17:40:32 +0300 Subject: [PATCH 03/10] Fixing JIRA Issues --- lib/config/provider_routes.dart | 4 +- .../appoinment_detail_list_page.dart | 29 ++++++++- .../schedule/add_schedules_page.dart | 64 ++++++++++++++++++- .../schedule/widgets/chips_picker_item.dart | 2 +- .../schedule/widgets/select_days_sheet.dart | 20 ++++-- .../services/create_services_page3.dart | 8 ++- 6 files changed, 114 insertions(+), 13 deletions(-) diff --git a/lib/config/provider_routes.dart b/lib/config/provider_routes.dart index 453303d..c9e0dd2 100644 --- a/lib/config/provider_routes.dart +++ b/lib/config/provider_routes.dart @@ -38,8 +38,8 @@ class ProviderAppRoutes { //Appointments AppRoutes.appointment: (context) => AppointmentPage(branch: ModalRoute.of(context)!.settings.arguments as BranchDetailModel), - AppRoutes.appointmentDetailList: (context) => const AppointmentDetailListPage(), - AppRoutes.updateAppointmentPage: (context) => UpdateAppointmentPage(), + AppRoutes.appointmentDetailList: (context) => AppointmentDetailListPage(), + AppRoutes.updateAppointmentPage: (context) => const UpdateAppointmentPage(), AppRoutes.addServiceInAppointment: (context) => AddNewServiceAppointmentPage(ModalRoute.of(context)!.settings.arguments as AppointmentListModel), AppRoutes.mergeAppointments: (context) => const MergeAppointmentListPage(), diff --git a/lib/views/appoinments/appoinment_detail_list_page.dart b/lib/views/appoinments/appoinment_detail_list_page.dart index 782ac00..deebb03 100644 --- a/lib/views/appoinments/appoinment_detail_list_page.dart +++ b/lib/views/appoinments/appoinment_detail_list_page.dart @@ -3,23 +3,44 @@ import 'package:car_provider_app/views/dashboard/widget/general_appointment_widg import 'package:flutter/material.dart'; import 'package:mc_common_app/config/routes.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/utils/enums.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/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/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:easy_localization/easy_localization.dart'; class AppointmentDetailListPage extends StatelessWidget { - const AppointmentDetailListPage({super.key}); + AppointmentDetailListPage({super.key}); + + int customerID = 0; + int complainType = 1; + String customerName = ""; @override Widget build(BuildContext context) { return Scaffold( appBar: CustomAppBar( title: LocaleKeys.appointment_details.tr(), + actions: [ + IconButton( + onPressed: () { + context.read().buildComplaintBottomSheet( + customerID: customerID, + customerName: customerName, + complainType: complainType, + context: context, + ); + }, + icon: const Icon(Icons.report_problem_outlined).paddingOnly(right: 21), + ), + ], ), body: SizedBox( width: double.infinity, @@ -33,6 +54,12 @@ class AppointmentDetailListPage extends StatelessWidget { } else { return ListView.separated( 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( appointmentListModel: appointmentsVM.myFilteredAppointments2[appointmentsVM.selectedAppointmentIndex].customerAppointmentList![index], isNeedTotalPayment: true, diff --git a/lib/views/branch_management/schedule/add_schedules_page.dart b/lib/views/branch_management/schedule/add_schedules_page.dart index b323f12..810417c 100644 --- a/lib/views/branch_management/schedule/add_schedules_page.dart +++ b/lib/views/branch_management/schedule/add_schedules_page.dart @@ -100,6 +100,10 @@ class _AddSchedulesPageState extends State { 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 void initState() { super.initState(); @@ -177,8 +181,20 @@ class _AddSchedulesPageState extends State { onTap: () async { startDate = await Utils.pickDateFromDatePicker( context, + initial: tomorrowDate, 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(); scheduleVM.refresh(); }, @@ -191,12 +207,32 @@ class _AddSchedulesPageState extends State { size: 16, ), value: endDate, - isNeedClickAll: true, + isNeedClickAll: true, 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( 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(); scheduleVM.refresh(); }, @@ -231,6 +267,16 @@ class _AddSchedulesPageState extends State { isNeedClickAll: true, onTap: () async { 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(); scheduleVM.refresh(); }, @@ -248,11 +294,23 @@ class _AddSchedulesPageState extends State { isNeedClickAll: true, onTap: () async { 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( context, 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(); scheduleVM.refresh(); }, diff --git a/lib/views/branch_management/schedule/widgets/chips_picker_item.dart b/lib/views/branch_management/schedule/widgets/chips_picker_item.dart index e9b68c0..216584c 100644 --- a/lib/views/branch_management/schedule/widgets/chips_picker_item.dart +++ b/lib/views/branch_management/schedule/widgets/chips_picker_item.dart @@ -19,7 +19,7 @@ class ChipsPickerItem extends StatelessWidget { final List itemsList; 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 Widget build(BuildContext context) { diff --git a/lib/views/branch_management/schedule/widgets/select_days_sheet.dart b/lib/views/branch_management/schedule/widgets/select_days_sheet.dart index 9ae331b..ed99ad0 100644 --- a/lib/views/branch_management/schedule/widgets/select_days_sheet.dart +++ b/lib/views/branch_management/schedule/widgets/select_days_sheet.dart @@ -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/generated/locale_keys.g.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/extensions/extensions_widget.dart'; import 'package:provider/provider.dart'; @@ -72,9 +73,7 @@ class _SelectDaysSheetState extends State { ); }, separatorBuilder: (BuildContext context, int index) { - return const Divider( - height: 1, - ); + return const Divider(height: 1); }, itemCount: list.length, ), @@ -83,8 +82,19 @@ class _SelectDaysSheetState extends State { title: LocaleKeys.addSelectedDays.tr(), maxWidth: double.infinity, onPressed: () { - widget.onSelected(list); - Navigator.pop(context); + bool isOneUnSelected = false; + 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()); + } }, ) ], diff --git a/lib/views/branch_management/services/create_services_page3.dart b/lib/views/branch_management/services/create_services_page3.dart index a3466d4..8c1a8e4 100644 --- a/lib/views/branch_management/services/create_services_page3.dart +++ b/lib/views/branch_management/services/create_services_page3.dart @@ -29,7 +29,7 @@ import 'package:provider/provider.dart'; class CreateServicesPage3 extends StatefulWidget { final CreateBranchModel? branchModel; - const CreateServicesPage3(this.branchModel, {Key? key}) : super(key: key); + const CreateServicesPage3(this.branchModel, {super.key}); @override State createState() => _CreateServicesPage3State(); @@ -225,6 +225,12 @@ class _CreateServicesPage3State extends State { } createService(BuildContext context, ServiceVM model) async { + if (isHomeAppointmentAvailable) { + if (serviceRage == 0 || chargersPerKm.isEmpty || double.parse(chargersPerKm) < 1) { + Utils.showToast(LocaleKeys.chargesAndServiceRangeGreaterThanZero.tr()); + return; + } + } List> map = []; model.services!.data?.forEach((element) { if (serviceId == element.id) { From 5cdcb46183cdaed72637f36f28179f692dde495d Mon Sep 17 00:00:00 2001 From: Faiz Hashmi Date: Wed, 27 Nov 2024 17:57:33 +0300 Subject: [PATCH 04/10] Dropped the JIRA Count to 23 --- .../appoinments/update_appointment_page.dart | 47 ++-- lib/views/appoinments/widget/sheets.dart | 204 +++++++----------- .../branch/define_branch_view.dart | 6 +- .../schedule/add_schedules_page.dart | 2 +- .../services/create_services_page3.dart | 32 ++- 5 files changed, 136 insertions(+), 155 deletions(-) diff --git a/lib/views/appoinments/update_appointment_page.dart b/lib/views/appoinments/update_appointment_page.dart index 189861b..1b00327 100644 --- a/lib/views/appoinments/update_appointment_page.dart +++ b/lib/views/appoinments/update_appointment_page.dart @@ -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/dashboard/widget/general_appointment_widget.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.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/routes.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/models/appointments_models/appointment_list_model.dart'; import 'package:mc_common_app/theme/colors.dart'; @@ -47,7 +44,7 @@ class _UpdateAppointmentPageState extends State { return RefreshIndicator( onRefresh: () async => _updateAppointment(context, appointmentListModel.branchId ?? 0), child: Column( - children: [ + children: [ Expanded( child: ListView( padding: const EdgeInsets.all(21), @@ -86,7 +83,7 @@ class _UpdateAppointmentPageState extends State { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Expanded(child: showPayNowButton(context, appointmentsVM)), + Expanded(child: showPayNowButton(context, appointmentsVM, color: MyColors.greenColor)), 12.width, Expanded(child: showCancelButton(context, appointmentsVM)), ], @@ -97,7 +94,13 @@ class _UpdateAppointmentPageState extends State { appointmentListModel.appointmentPaymentStatusEnum == AppointmentPaymentStatusEnum.defaultStatus)) Column( children: [ - showArrivedButton(context, appointmentsVM), + Row( + children: [ + Expanded(child: showArrivedButton(context, appointmentsVM)), + 12.width, + Expanded(child: showCancelButton(context, appointmentsVM)), + ], + ), ], ).paddingAll(21), @@ -220,10 +223,11 @@ class _UpdateAppointmentPageState extends State { ); } - Widget showPayNowButton(BuildContext context, AppointmentsVM appointmentsVM) { + Widget showPayNowButton(BuildContext context, AppointmentsVM appointmentsVM, {Color? color}) { return ShowFillButton( title: LocaleKeys.payNow.tr(), maxWidth: double.infinity, + backgroundColor: color ?? MyColors.darkPrimaryColor, onPressed: () async { Utils.showLoading(context); bool status = await appointmentsVM.updateAppointmentPaymentStatus({"appointmentID": appointmentListModel.id.toString(), "appointmentServicePaymentStatusID": 2}); @@ -240,6 +244,8 @@ class _UpdateAppointmentPageState extends State { return ShowFillButton( title: LocaleKeys.arrived.tr(), maxWidth: double.infinity, + txtColor: MyColors.white, + backgroundColor: MyColors.greenColor, onPressed: () async { Utils.showLoading(context); bool status = await appointmentsVM.updateAppointmentStatus(appointmentId: appointmentListModel.id!, appointmentStatusEnum: AppointmentStatusEnum.arrived); @@ -280,21 +286,26 @@ class _UpdateAppointmentPageState extends State { ); } - Widget showCancelButton(BuildContext context, AppointmentsVM appointmentsVM) { + Widget showCancelButton(BuildContext pContext, AppointmentsVM appointmentsVM) { return ShowFillButton( title: LocaleKeys.cancel.tr(), maxWidth: double.infinity, - isFilled: false, - txtColor: MyColors.redColor, - borderColor: MyColors.redColor, + txtColor: MyColors.white, + backgroundColor: MyColors.redColor, onPressed: () { - showMyBottomSheet( - context, - child: ShowCollectPaymentSheet( - onClickYes: () {}, - onClickNo: () {}, - ), - ); + showModalBottomSheet( + context: pContext, + isScrollControlled: true, + builder: (context) => CancelAppointmentReasonSheet( + 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); + }); + }, + )); }, ); } diff --git a/lib/views/appoinments/widget/sheets.dart b/lib/views/appoinments/widget/sheets.dart index 375c296..25e0925 100644 --- a/lib/views/appoinments/widget/sheets.dart +++ b/lib/views/appoinments/widget/sheets.dart @@ -1,23 +1,22 @@ 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/string_extensions.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/utils/navigator.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/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:easy_localization/easy_localization.dart'; - class ShowCollectPaymentSheet extends StatelessWidget { - Function() onClickYes; - Function() onClickNo; + final Function() onClickYes; + final Function() onClickNo; - ShowCollectPaymentSheet( - {required this.onClickYes, required this.onClickNo, Key? key}) - : super(key: key); + const ShowCollectPaymentSheet({required this.onClickYes, required this.onClickNo, super.key}); @override Widget build(BuildContext context) { @@ -26,9 +25,9 @@ class ShowCollectPaymentSheet extends StatelessWidget { child: Column( children: [ LocaleKeys.collectMoneyBefore.tr().toText( - fontSize: 24, - isBold: true, - ), + fontSize: 24, + isBold: true, + ), 21.height, Row( children: [ @@ -55,134 +54,91 @@ class ShowCollectPaymentSheet extends StatelessWidget { } } -class Reason { - String title; - bool isSelected; - - Reason(this.title, this.isSelected); -} - class CancelAppointmentReasonSheet extends StatefulWidget { - Function(String) onCancelClick; + final Function(String) onCancelClick; - CancelAppointmentReasonSheet({required this.onCancelClick, Key? key}) - : super(key: key); + const CancelAppointmentReasonSheet({required this.onCancelClick, super.key}); @override - State createState() => - _CancelAppointmentReasonSheetState(); + State createState() => _CancelAppointmentReasonSheetState(); } -class _CancelAppointmentReasonSheetState - extends State { +class _CancelAppointmentReasonSheetState extends State { String reason = ""; - List reasonList = [ - Reason("Operational Issue", true), - Reason("Material Issue", false), - Reason("The customer no longer responding", false), - Reason("Other", false), + List reasonList = [ + OfferRequestCommentModel(title: LocaleKeys.operationalIssue.tr(), isSelected: true, index: 0), + OfferRequestCommentModel(title: LocaleKeys.materialIssue.tr(), isSelected: false, index: 1), + OfferRequestCommentModel(title: LocaleKeys.customerNotResponding.tr(), isSelected: false, index: 2), + OfferRequestCommentModel(title: LocaleKeys.otherVar.tr(), isSelected: false, index: 3), ]; @override Widget build(BuildContext context) { - return Container( - padding: const EdgeInsets.only(left: 21, right: 21, top: 12, bottom: 21), - width: double.infinity, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - LocaleKeys.reason.tr().toText(fontSize: 24, isBold: true), - ListView.separated( - itemBuilder: (context, index) { - return Padding( - padding: const EdgeInsets.only(top: 12, bottom: 12), - child: Row( - children: [ - Container( - width: 14, - height: 14, - decoration: BoxDecoration( - color: reasonList[index].isSelected - ? MyColors.darkPrimaryColor - : Colors.transparent, - borderRadius: BorderRadius.circular(122), - border: Border.all( - color: reasonList[index].isSelected - ? MyColors.darkPrimaryColor - : borderColor, - width: 1), - ), - child: const Icon( - Icons.done, - size: 12, - color: Colors.white, - ), + return InfoBottomSheet( + title: LocaleKeys.pleaseSpecify.tr().toText(fontSize: 28, isBold: true, letterSpacing: -1.44, height: 1), + description: Padding( + padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.selectReasonBeforeCancel.tr().toText(fontSize: 13, color: MyColors.lightTextColor, fontWeight: MyFonts.Medium), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + 12.height, + ListView.separated( + shrinkWrap: true, + itemCount: reasonList.length, + separatorBuilder: (BuildContext context, int index) { + return const Divider(thickness: 0.5); + }, + itemBuilder: (BuildContext context, int index) { + OfferRequestCommentModel offerRequestCommentModel = reasonList[index]; + return CircleCheckBoxWithTitle( + isChecked: offerRequestCommentModel.isSelected ?? false, + title: '${offerRequestCommentModel.title}', + onSelected: () { + for (var element in reasonList) { + element.isSelected = false; + } + + setState(() { + reason = reasonList[index].title ?? ""; + 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, - Expanded( - child: ShowFillButton( - title: LocaleKeys.yes.tr(), - onPressed: () { - if (reason.isEmpty || reason == "Other") { - Utils.showToast(LocaleKeys.pleaseSelectReason.tr()); - } else { - widget.onCancelClick(reason); - pop(context); - } - }, - ), + 25.height, + ShowFillButton( + title: LocaleKeys.cancel.tr(), + onPressed: () { + if (reason.isEmpty && reason == LocaleKeys.otherVar.tr()) { + Utils.showToast(LocaleKeys.pleaseSelectReason.tr()); + } else { + widget.onCancelClick(reason); + } + }, + maxWidth: double.infinity, ), + 19.height, ], - ) - ], - ), - ); + ), + )); } } diff --git a/lib/views/branch_management/branch/define_branch_view.dart b/lib/views/branch_management/branch/define_branch_view.dart index 087bb7b..b682daa 100644 --- a/lib/views/branch_management/branch/define_branch_view.dart +++ b/lib/views/branch_management/branch/define_branch_view.dart @@ -180,7 +180,7 @@ class _DefineBranchViewState extends State { text: LocaleKeys.attachImage.tr(), icon: MyAssets.attachmentIcon.buildSvg(), ), - ], + ], if (serviceVM.branchImageError != "") ...[ 10.height, Row( @@ -249,8 +249,8 @@ class _DefineBranchViewState extends State { closedTime: serviceVM.closedTime, cityID: serviceVM.cityId, address: serviceVM.address, - latitude: widget.branchData!.latitude ?? "0", - longitude: widget.branchData!.longitude ?? "0", + latitude: (serviceVM.latitude).toString(), + longitude: (serviceVM.longitude).toString(), ); }, ).horPaddingMain(), diff --git a/lib/views/branch_management/schedule/add_schedules_page.dart b/lib/views/branch_management/schedule/add_schedules_page.dart index 810417c..19fdec1 100644 --- a/lib/views/branch_management/schedule/add_schedules_page.dart +++ b/lib/views/branch_management/schedule/add_schedules_page.dart @@ -207,7 +207,7 @@ class _AddSchedulesPageState extends State { size: 16, ), value: endDate, - isNeedClickAll: true, + isNeedClickAll: true, onTap: () async { DateTime? firstDate; DateTime? sDate; diff --git a/lib/views/branch_management/services/create_services_page3.dart b/lib/views/branch_management/services/create_services_page3.dart index 8c1a8e4..44cf01a 100644 --- a/lib/views/branch_management/services/create_services_page3.dart +++ b/lib/views/branch_management/services/create_services_page3.dart @@ -133,19 +133,26 @@ class _CreateServicesPage3State extends State { description: LocaleKeys.bookAppointmentForServices.tr(), onSelection: (bool v) { isAppointmentAvailable = v; + if (!isAppointmentAvailable) { + isHomeAppointmentAvailable = false; + } model.setState(ViewState.idle); }, ), 20.height, - CheckBoxWithTitleDescription( - isSelected: isHomeAppointmentAvailable, - title: LocaleKeys.allowingHomeService.tr(), - description: LocaleKeys.bookAppointmentAtLocation.tr(), - onSelection: (bool v) { - isHomeAppointmentAvailable = v; - model.setState(ViewState.idle); - }, - ), + if (isAppointmentAvailable) + CheckBoxWithTitleDescription( + isSelected: isHomeAppointmentAvailable, + title: LocaleKeys.allowingHomeService.tr(), + description: LocaleKeys.bookAppointmentAtLocation.tr(), + onSelection: (bool v) { + isHomeAppointmentAvailable = v; + if (isHomeAppointmentAvailable && !isAppointmentAvailable) { + isAppointmentAvailable = true; + } + model.setState(ViewState.idle); + }, + ), 20.height, if (isHomeAppointmentAvailable) Column( @@ -268,6 +275,13 @@ class _CreateServicesPage3State extends State { updateService(BuildContext context, ServiceVM model) async { List> map = []; + + if (isHomeAppointmentAvailable) { + if (serviceRage == 0 || chargersPerKm.isEmpty || double.parse(chargersPerKm) < 1) { + Utils.showToast(LocaleKeys.chargesAndServiceRangeGreaterThanZero.tr()); + return; + } + } if (isHomeAppointmentAvailable) { map = [ { From cbbc86d9987d9db03ad71556d69d1261b1c5aab8 Mon Sep 17 00:00:00 2001 From: Faiz Hashmi Date: Thu, 28 Nov 2024 17:35:38 +0300 Subject: [PATCH 05/10] Dropped the JIRA Count to 18 --- .../appoinments/update_appointment_page.dart | 26 ++-- .../branch/branch_detail_page.dart | 2 + .../branch/branch_list_page.dart | 7 +- .../services/create_services_page3.dart | 97 ++++++++++--- .../services/services_list_page.dart | 131 ++++++++++-------- .../widget/general_appointment_widget.dart | 34 +++++ 6 files changed, 202 insertions(+), 95 deletions(-) diff --git a/lib/views/appoinments/update_appointment_page.dart b/lib/views/appoinments/update_appointment_page.dart index 1b00327..8fa99d9 100644 --- a/lib/views/appoinments/update_appointment_page.dart +++ b/lib/views/appoinments/update_appointment_page.dart @@ -54,6 +54,7 @@ class _UpdateAppointmentPageState extends State { isNeedTotalPayment: true, isNeedToShowItems: true, isNeedToShowToMoreText: false, + isFromUpdateAppointmentPage: true, onTap: () {}, ), 21.height, @@ -294,18 +295,19 @@ class _UpdateAppointmentPageState extends State { backgroundColor: MyColors.redColor, onPressed: () { showModalBottomSheet( - context: pContext, - isScrollControlled: true, - builder: (context) => CancelAppointmentReasonSheet( - 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); - }); - }, - )); + context: pContext, + isScrollControlled: true, + builder: (context) => CancelAppointmentReasonSheet( + 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); + }); + }, + ), + ); }, ); } diff --git a/lib/views/branch_management/branch/branch_detail_page.dart b/lib/views/branch_management/branch/branch_detail_page.dart index 45479bf..ce8a2c4 100644 --- a/lib/views/branch_management/branch/branch_detail_page.dart +++ b/lib/views/branch_management/branch/branch_detail_page.dart @@ -370,6 +370,8 @@ class _BranchDetailPageState extends State { serviceVM.categories[pIndex].branchId = widget.branchData.id.toString(); serviceVM.categories[pIndex].branchName = widget.branchData.branchName.toString(); // CategoryData categoryData = serviceVM.categories[pIndex]; + serviceVM.applyFilterOnBranchServices(serviceStatusEnum: ServiceStatusEnum.approvedOrActive); + CategoryData categoryData = CategoryData( id: serviceVM.categories[pIndex].id, branchId: serviceVM.categories[pIndex].branchId, diff --git a/lib/views/branch_management/branch/branch_list_page.dart b/lib/views/branch_management/branch/branch_list_page.dart index f9fb18a..388aa0e 100644 --- a/lib/views/branch_management/branch/branch_list_page.dart +++ b/lib/views/branch_management/branch/branch_list_page.dart @@ -139,7 +139,7 @@ class BranchListPage extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Utils.statusContainerChip( - text: branchModel.branchStatusLabel ?? "", + text: (branchModel.branchStatusLabel ?? "").replaceFirst("ApprovedOrActive", "Active"), chipColor: Utils.getChipColorByBranchStatus(branchModel.branchStatus!), ), ], @@ -168,7 +168,7 @@ class BranchListPage extends StatelessWidget { children: [ (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( fontSize: 10, overflow: TextOverflow.ellipsis, @@ -180,6 +180,9 @@ class BranchListPage extends StatelessWidget { ), ], ).toWhiteContainer(width: double.infinity, pading: const EdgeInsets.all(12)).onPress(() async { + if (branchModel.branchStatus == BranchStatusEnum.blocked) { + return; + } branchModel.countryID = serviceVM.branches!.data!.countryID; branchModel.countryName = serviceVM.branches!.data!.countryName; serviceVM.updateSelectedBranchId(branchModel.id); diff --git a/lib/views/branch_management/services/create_services_page3.dart b/lib/views/branch_management/services/create_services_page3.dart index 44cf01a..d3dca90 100644 --- a/lib/views/branch_management/services/create_services_page3.dart +++ b/lib/views/branch_management/services/create_services_page3.dart @@ -1,5 +1,7 @@ import 'dart:async'; import 'dart:developer'; +import 'package:car_provider_app/main.dart'; +import 'package:flutter/cupertino.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart'; import 'package:mc_common_app/models/general_models/generic_resp_model.dart'; import 'package:mc_common_app/utils/navigator.dart'; @@ -38,6 +40,7 @@ class CreateServicesPage3 extends StatefulWidget { class _CreateServicesPage3State extends State { bool isAppointmentAvailable = false; bool isHomeAppointmentAvailable = false; + ServiceStatusEnum serviceStatusEnum = ServiceStatusEnum.pending; int serviceRage = 0; String chargersPerKm = ""; int? categoryId = -1; @@ -45,6 +48,9 @@ class _CreateServicesPage3State extends State { DropValue? category; DropValue? service; + bool isEditDisabled = false; + bool isServiceActive = true; + @override void initState() { super.initState(); @@ -57,6 +63,9 @@ class _CreateServicesPage3State extends State { service = serviceVM.servicesDropList.firstWhere((element) => element.id == widget.branchModel!.serviceProviderService!.serviceId); isAppointmentAvailable = widget.branchModel?.serviceProviderService?.isAllowAppointment ?? false; serviceRage = widget.branchModel?.serviceProviderService?.customerLocationRange ?? 0; + serviceStatusEnum = widget.branchModel?.serviceProviderService?.serviceStatusEnum ?? ServiceStatusEnum.pending; + isServiceActive = widget.branchModel?.serviceProviderService?.isActive ?? true; + isEditDisabled = serviceStatusEnum == ServiceStatusEnum.blocked; if (serviceRage > 0) { isHomeAppointmentAvailable = true; } @@ -101,7 +110,43 @@ class _CreateServicesPage3State extends State { list: model.categoryDropList, hint: category != null ? category!.value : LocaleKeys.selectServiceCategory.tr(), ), - 12.height, + if (widget.branchModel!.isForEdit) ...[ + 22.height, + 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) { + if (isEditDisabled) return; + isServiceActive = value; + setState(() {}); + }, + ), + ), + ), + ], + ), + ), + ] else ...[ + 12.height, + ], (model.state == ViewState.idle) ? categoryId != -1 && model.servicesDropList.isNotEmpty ? DropdownField( @@ -128,6 +173,7 @@ class _CreateServicesPage3State extends State { children: [ 20.height, CheckBoxWithTitleDescription( + isDisabled: isEditDisabled, isSelected: isAppointmentAvailable, title: LocaleKeys.availableforAppointment.tr(), description: LocaleKeys.bookAppointmentForServices.tr(), @@ -142,6 +188,7 @@ class _CreateServicesPage3State extends State { 20.height, if (isAppointmentAvailable) CheckBoxWithTitleDescription( + isDisabled: isEditDisabled, isSelected: isHomeAppointmentAvailable, title: LocaleKeys.allowingHomeService.tr(), description: LocaleKeys.bookAppointmentAtLocation.tr(), @@ -209,20 +256,24 @@ class _CreateServicesPage3State extends State { ), ), if (serviceId != -1) - ShowFillButton( - title: LocaleKeys.save.tr(), - maxWidth: double.infinity, - margin: const EdgeInsets.all(20), - onPressed: () { - if (widget.branchModel!.serviceProviderService != null) { - updateService(context, model); - } else { - if (model.services != null) { - createService(context, model); + if (isEditDisabled) ...[ + Utils.buildStatusContainer(LocaleKeys.blockedByAdmin.tr()), + ] else ...[ + ShowFillButton( + title: LocaleKeys.save.tr(), + maxWidth: double.infinity, + margin: const EdgeInsets.all(20), + onPressed: () { + if (widget.branchModel!.serviceProviderService != null) { + updateService(context, model); + } else { + if (model.services != null) { + createService(context, model); + } } - } - }, - ), + }, + ), + ], ], ); }, @@ -231,7 +282,7 @@ class _CreateServicesPage3State extends State { ); } - 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()); @@ -239,7 +290,7 @@ class _CreateServicesPage3State extends State { } } List> map = []; - model.services!.data?.forEach((element) { + serviceVM.services!.data?.forEach((element) { if (serviceId == element.id) { element.isSelected = true; } else { @@ -247,12 +298,12 @@ class _CreateServicesPage3State extends State { } }); - for (int i = 0; i < model.services!.data!.length; i++) { - if (model.services!.data![i].isSelected ?? false) { + for (int i = 0; i < serviceVM.services!.data!.length; i++) { + if (serviceVM.services!.data![i].isSelected ?? false) { var postParams = { // "id": services!.data![i].id, "providerBranchID": widget.branchModel!.branchId, - "serviceID": model.services!.data![i].id, + "serviceID": serviceVM.services!.data![i].id, "isAllowAppointment": isAppointmentAvailable, "isActive": true, "customerLocationRange": serviceRage, @@ -263,8 +314,8 @@ class _CreateServicesPage3State extends State { } // print(map); Utils.showLoading(context); - GenericRespModel mResponse = await model.createService(map); - await model.getBranchAndServices(); + GenericRespModel mResponse = await serviceVM.createService(map); + await serviceVM.getBranchAndServices(); Utils.hideLoading(context); Utils.showToast(mResponse.message ?? ""); if (mResponse.messageStatus == 1) { @@ -287,7 +338,7 @@ class _CreateServicesPage3State extends State { { "id": widget.branchModel!.serviceProviderService!.serviceProviderServiceId.toString(), "isAllowAppointment": isAppointmentAvailable, - "isActive": true, + "isActive": isServiceActive, "customerLocationRange": serviceRage, "rangePricePerKm": chargersPerKm.isEmpty ? "0.0" : chargersPerKm, } @@ -297,7 +348,7 @@ class _CreateServicesPage3State extends State { { "id": widget.branchModel!.serviceProviderService!.serviceProviderServiceId.toString(), "isAllowAppointment": isAppointmentAvailable, - "isActive": true, + "isActive": isServiceActive, } ]; } diff --git a/lib/views/branch_management/services/services_list_page.dart b/lib/views/branch_management/services/services_list_page.dart index da02e70..f414ee1 100644 --- a/lib/views/branch_management/services/services_list_page.dart +++ b/lib/views/branch_management/services/services_list_page.dart @@ -19,6 +19,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/widgets/bottom_sheet.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/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/tab/role_type_tab.dart'; @@ -43,16 +44,14 @@ class CreateBranchModel { } class ServicesListPage extends StatefulWidget { - const ServicesListPage({Key? key}) : super(key: key); + const ServicesListPage({super.key}); @override State createState() => _ServicesListPageState(); } class _ServicesListPageState extends State { - int selectedTab = 0; ServiceStatusEnum selectedService = ServiceStatusEnum.approvedOrActive; - List filteredServices = []; late CategoryData categoryData; @@ -61,37 +60,22 @@ class _ServicesListPageState extends State { @override void initState() { scheduleMicrotask(() async { - await _fetchServices(ServiceStatusEnum.approvedOrActive); + await _onRefresh(ServiceStatusEnum.approvedOrActive); }); super.initState(); } - Future _fetchServices(ServiceStatusEnum status) async { - categoryData.services = await context.read().fetchProviderServicesModelByCategoryIdAndBranchID( - branchID: categoryData.branchId.toString(), - categoryId: categoryData.id.toString(), - ); - filteredServices = categoryData.services!.where((i) => i.serviceStatus == status.index + 1).toList(); - - screenState = ViewState.idle; - setState(() {}); - } - - Future _onRefresh(ServiceStatusEnum status, int tab) async { + Future _onRefresh(ServiceStatusEnum status) async { + log("status: $status"); screenState = ViewState.busy; - selectedService = status; - selectedTab = tab; setState(() {}); categoryData.services = await context.read().fetchProviderServicesModelByCategoryIdAndBranchID( branchID: categoryData.branchId.toString(), categoryId: categoryData.id.toString(), ); + context.read().applyFilterOnBranchServices(serviceStatusEnum: status); + filteredServices = categoryData.services!.where((i) => i.serviceStatusEnum == status).toList(); - 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(() {}); } @@ -99,12 +83,14 @@ class _ServicesListPageState extends State { @override Widget build(BuildContext context) { categoryData = ModalRoute.of(context)!.settings.arguments as CategoryData; + final serviceVM = context.read(); - if (context.read().isNeedRefreshServicesList) { + if (serviceVM.isNeedRefreshServicesList) { WidgetsBinding.instance.addPostFrameCallback((_) { if (mounted) { - _onRefresh(ServiceStatusEnum.pending, 1); - context.read().isNeedRefreshServicesList = false; + selectedService = ServiceStatusEnum.pending; + _onRefresh(ServiceStatusEnum.pending); + serviceVM.isNeedRefreshServicesList = false; } }); } @@ -130,33 +116,56 @@ class _ServicesListPageState extends State { width: double.infinity, child: Column( children: [ - Padding( - padding: const EdgeInsets.only(left: 20, right: 20, top: 20), - child: RoleTypeTab( - selectedTab, - [ - DropValue(0, 'Active', ''), - DropValue(1, 'Requested', ''), - ], - width: (MediaQuery.of(context).size.width / 2) - 26, - onSelect: (DropValue value) { - 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(); - } - }); - }, - ), + 20.height, + Consumer( + builder: (BuildContext context, ServiceVM serviceVM, Widget? child) { + return FiltersList( + filterList: serviceVM.branchServicesFilterOptions, + onFilterTapped: (index, selectedFilterId) { + selectedService = selectedFilterId.toServiceStatusEnum(); + serviceVM.applyFilterOnBranchServices(serviceStatusEnum: selectedFilterId.toServiceStatusEnum()); + filteredServices = categoryData.services!.where((i) => i.serviceStatusEnum == selectedFilterId.toServiceStatusEnum()).toList(); + setState(() {}); + }, + ); + }, ), + + // Padding( + // padding: const EdgeInsets.only(left: 20, right: 20, top: 20), + // child: RoleTypeTab( + // selectedTab, + // [ + // DropValue(0, 'Active', ''), + // DropValue(1, 'Requested', ''), + // DropValue(2, 'Deactivated', ''), + // ], + // width: (MediaQuery.of(context).size.width / 3) - 26, + // onSelect: (DropValue value) { + // setState(() { + // selectedTab = value.id; + // + // if (selectedTab == 0) { + // selectedService = ServiceStatusEnum.approvedOrActive; + // filteredServices = categoryData.services!.where((i) => i.serviceStatusEnum == ServiceStatusEnum.approvedOrActive).toList(); + // } else if (selectedTab == 2) { + // selectedService = ServiceStatusEnum.deactivated; + // filteredServices = categoryData.services!.where((i) => i.serviceStatusEnum == ServiceStatusEnum.deactivated).toList(); + // } else { + // selectedService = value.id.toServiceStatusEnum(); + // filteredServices = + // categoryData.services!.where((i) => (i.serviceStatusEnum != ServiceStatusEnum.approvedOrActive && i.serviceStatusEnum != ServiceStatusEnum.deactivated)).toList(); + // } + // }); + // }, + // ), + // ), const SizedBox(height: 10), Expanded( child: RefreshIndicator( - onRefresh: () async => _onRefresh(selectedService, selectedTab), + onRefresh: () async { + _onRefresh(selectedService); + }, child: screenState == ViewState.busy ? const Center( child: CircularProgressIndicator(), @@ -172,14 +181,14 @@ class _ServicesListPageState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - if (filteredServices[index].serviceStatus == 1) ...[ - Utils.statusContainerChip(text: "Pending", chipColor: MyColors.adPendingStatusColor), - 5.height, - ], + // if (filteredServices[index].serviceStatusEnum == ServiceStatusEnum.pending) ...[ + // Utils.statusContainerChip(text: "Pending", chipColor: MyColors.adPendingStatusColor), + // 5.height, + // ], Row( children: [ Expanded(child: (filteredServices[index].serviceDescription ?? "").toText(fontSize: 16)), - if (filteredServices[index].serviceStatus != 1) ...[ + if (filteredServices[index].serviceStatusEnum != ServiceStatusEnum.pending) ...[ Padding( padding: const EdgeInsets.all(4.0), child: SvgPicture.asset( @@ -222,14 +231,20 @@ class _ServicesListPageState extends State { ], ), ), - const Icon(Icons.arrow_forward_rounded, size: 20), + if (filteredServices[index].serviceStatusEnum != ServiceStatusEnum.blocked) ...[ + const Icon(Icons.arrow_forward_rounded, size: 20), + ], ], ), ], ), - ).toWhiteContainer(width: double.infinity, allPading: 12).onPress( - () => navigateWithName(context, AppRoutes.itemsList, arguments: filteredServices[index]), - ); + ).toWhiteContainer(width: double.infinity, allPading: 12).onPress(() { + if (filteredServices[index].serviceStatusEnum == ServiceStatusEnum.blocked) { + Utils.showToast(LocaleKeys.blockedByAdmin.tr()); + return; + } + navigateWithName(context, AppRoutes.itemsList, arguments: filteredServices[index]); + }); }, separatorBuilder: (context, index) { return const SizedBox(height: 12); diff --git a/lib/views/dashboard/widget/general_appointment_widget.dart b/lib/views/dashboard/widget/general_appointment_widget.dart index 331a684..7570f13 100644 --- a/lib/views/dashboard/widget/general_appointment_widget.dart +++ b/lib/views/dashboard/widget/general_appointment_widget.dart @@ -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/theme/colors.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:flutter_svg/flutter_svg.dart'; import 'package:easy_localization/easy_localization.dart'; @@ -16,6 +17,7 @@ class GeneralAppointmentWidget extends StatelessWidget { final bool isNeedToShowItems; final bool isNeedToShowToMoreText; final bool isSelectable; + final bool isFromUpdateAppointmentPage; final bool isNeedToShowAppointmentStatus; final bool isNeedToShowMergeStatus; final Function()? onTap; @@ -28,6 +30,7 @@ class GeneralAppointmentWidget extends StatelessWidget { this.isNeedToShowToMoreText = true, this.isSelectable = false, this.isNeedToShowAppointmentStatus = false, + this.isFromUpdateAppointmentPage = false, this.isNeedToShowMergeStatus = false, super.key, }); @@ -193,6 +196,37 @@ class GeneralAppointmentWidget extends StatelessWidget { 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); + }), + ] ], ), ), From ed7ed902d26ee5daaee4eee0e24361c347c79221 Mon Sep 17 00:00:00 2001 From: Faiz Hashmi Date: Mon, 2 Dec 2024 18:01:49 +0300 Subject: [PATCH 06/10] Duration Dis --- lib/main.dart | 2 -- .../fragments/branch_appointment_fragment.dart | 10 ++++------ 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index d017a79..b686918 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -190,5 +190,3 @@ class MyApp extends StatelessWidget { ); } } - - diff --git a/lib/views/dashboard/fragments/branch_appointment_fragment.dart b/lib/views/dashboard/fragments/branch_appointment_fragment.dart index 2ec84bd..4af787d 100644 --- a/lib/views/dashboard/fragments/branch_appointment_fragment.dart +++ b/lib/views/dashboard/fragments/branch_appointment_fragment.dart @@ -1,4 +1,3 @@ - import 'package:flutter/material.dart'; import 'package:mc_common_app/classes/consts.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'; class BranchAppointmentFragment extends StatelessWidget { - const BranchAppointmentFragment({ - Key? key, - }) : super(key: key); + const BranchAppointmentFragment({super.key}); @override Widget build(BuildContext context) { @@ -45,7 +42,9 @@ class BranchAppointmentFragment extends StatelessWidget { return RefreshIndicator( onRefresh: () async => serviceVM.getBranchAndServices(), 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( itemBuilder: (context, index) { return Row( @@ -71,7 +70,6 @@ class BranchAppointmentFragment extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ - // Row( // children: [ // const Icon( From 0215abbff825477482d43adf70f49da55137dbdb Mon Sep 17 00:00:00 2001 From: Faiz Hashmi Date: Tue, 3 Dec 2024 17:21:27 +0300 Subject: [PATCH 07/10] Duration Dis --- .../services/create_services_page3.dart | 110 +++++++++++++----- .../services/services_list_page.dart | 7 +- 2 files changed, 86 insertions(+), 31 deletions(-) diff --git a/lib/views/branch_management/services/create_services_page3.dart b/lib/views/branch_management/services/create_services_page3.dart index d3dca90..48cf0d7 100644 --- a/lib/views/branch_management/services/create_services_page3.dart +++ b/lib/views/branch_management/services/create_services_page3.dart @@ -3,6 +3,7 @@ import 'dart:developer'; import 'package:car_provider_app/main.dart'; import 'package:flutter/cupertino.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/utils/navigator.dart'; import 'package:mc_common_app/view_models/service_view_model.dart'; @@ -49,14 +50,13 @@ class _CreateServicesPage3State extends State { DropValue? service; bool isEditDisabled = false; - bool isServiceActive = true; + bool isServiceActive = false; @override void initState() { super.initState(); scheduleMicrotask(() async { ServiceVM serviceVM = context.read(); - log("widget.branchModel!.categoryId: ${widget.branchModel!.categoryId}"); if (widget.branchModel!.categoryId != null) { await serviceVM.fetchServicesByCategoryId(int.parse(widget.branchModel!.categoryId ?? "0")); category = DropValue(int.parse(widget.branchModel!.categoryId ?? "0"), widget.branchModel!.categoryName ?? "", ""); @@ -64,7 +64,7 @@ class _CreateServicesPage3State extends State { isAppointmentAvailable = widget.branchModel?.serviceProviderService?.isAllowAppointment ?? false; serviceRage = widget.branchModel?.serviceProviderService?.customerLocationRange ?? 0; serviceStatusEnum = widget.branchModel?.serviceProviderService?.serviceStatusEnum ?? ServiceStatusEnum.pending; - isServiceActive = widget.branchModel?.serviceProviderService?.isActive ?? true; + isServiceActive = widget.branchModel?.serviceProviderService?.serviceStatusEnum != ServiceStatusEnum.deactivated; isEditDisabled = serviceStatusEnum == ServiceStatusEnum.blocked; if (serviceRage > 0) { isHomeAppointmentAvailable = true; @@ -86,7 +86,7 @@ class _CreateServicesPage3State extends State { width: double.infinity, height: double.infinity, child: Consumer( - builder: (context, model, _) { + builder: (context, serviceVM, _) { return Column( children: [ Expanded( @@ -104,10 +104,10 @@ class _CreateServicesPage3State extends State { serviceId = -1; isAppointmentAvailable = false; isHomeAppointmentAvailable = false; - model.fetchServicesByCategoryId(value.id); + serviceVM.fetchServicesByCategoryId(value.id); }, dropdownValue: category, - list: model.categoryDropList, + list: serviceVM.categoryDropList, hint: category != null ? category!.value : LocaleKeys.selectServiceCategory.tr(), ), if (widget.branchModel!.isForEdit) ...[ @@ -133,9 +133,10 @@ class _CreateServicesPage3State extends State { trackColor: MyColors.white, thumbColor: MyColors.greyACColor, value: isServiceActive, - onChanged: (value) { + onChanged: (value) async { if (isEditDisabled) return; - isServiceActive = value; + + isServiceActive = await updateServiceStatus(context, value); setState(() {}); }, ), @@ -147,23 +148,23 @@ class _CreateServicesPage3State extends State { ] else ...[ 12.height, ], - (model.state == ViewState.idle) - ? categoryId != -1 && model.servicesDropList.isNotEmpty + (serviceVM.state == ViewState.idle) + ? categoryId != -1 && serviceVM.servicesDropList.isNotEmpty ? DropdownField( (DropValue value) { service = value; serviceId = value.id; isAppointmentAvailable = false; isHomeAppointmentAvailable = false; - model.setState(ViewState.idle); + serviceVM.setState(ViewState.idle); }, dropdownValue: service, - list: model.servicesDropList, + list: serviceVM.servicesDropList, hint: LocaleKeys.defineServices.tr(), ) : categoryId == -1 ? const SizedBox() - : model.state == ViewState.idle + : serviceVM.state == ViewState.idle ? EmptyWidget(text: LocaleKeys.noServicesAvailable.tr()) : const SizedBox() : const CircularProgressIndicator(), @@ -182,7 +183,7 @@ class _CreateServicesPage3State extends State { if (!isAppointmentAvailable) { isHomeAppointmentAvailable = false; } - model.setState(ViewState.idle); + serviceVM.setState(ViewState.idle); }, ), 20.height, @@ -197,7 +198,7 @@ class _CreateServicesPage3State extends State { if (isHomeAppointmentAvailable && !isAppointmentAvailable) { isAppointmentAvailable = true; } - model.setState(ViewState.idle); + serviceVM.setState(ViewState.idle); }, ), 20.height, @@ -265,10 +266,10 @@ class _CreateServicesPage3State extends State { margin: const EdgeInsets.all(20), onPressed: () { if (widget.branchModel!.serviceProviderService != null) { - updateService(context, model); + updateService(context, serviceVM); } else { - if (model.services != null) { - createService(context, model); + if (serviceVM.services != null) { + createService(context, serviceVM); } } }, @@ -338,7 +339,7 @@ class _CreateServicesPage3State extends State { { "id": widget.branchModel!.serviceProviderService!.serviceProviderServiceId.toString(), "isAllowAppointment": isAppointmentAvailable, - "isActive": isServiceActive, + "isActive": true, "customerLocationRange": serviceRage, "rangePricePerKm": chargersPerKm.isEmpty ? "0.0" : chargersPerKm, } @@ -348,21 +349,70 @@ class _CreateServicesPage3State extends State { { "id": widget.branchModel!.serviceProviderService!.serviceProviderServiceId.toString(), "isAllowAppointment": isAppointmentAvailable, - "isActive": isServiceActive, + "isActive": true, } ]; } + 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().filterUserBranchCategories(); + context.read().isNeedRefreshServicesList = true; + pop(context); + } + } catch (e) { + Utils.hideLoading(context); + log(e.toString()); + Utils.showToast(e.toString() ?? ""); + } + } - // 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().filterUserBranchCategories(); - context.read().isNeedRefreshServicesList = true; - pop(context); + Future updateServiceStatus(BuildContext context, bool value) async { + List> map = [ + { + "id": widget.branchModel!.serviceProviderService!.serviceProviderServiceId.toString(), + "isActive": true, + + //TODO: ZAHOOR WILL ADD SERVICE STATUS HERE TO UPDATE + } + ]; + try { + final serviceVM = context.read(); + List list = await serviceVM.getAppointmentsByServiceID( + context: context, + branchId: int.parse(widget.branchModel!.branchId), + serviceId: widget.branchModel!.serviceProviderService!.serviceProviderServiceId!, + ); + + List 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; } } } diff --git a/lib/views/branch_management/services/services_list_page.dart b/lib/views/branch_management/services/services_list_page.dart index f414ee1..f49dfc7 100644 --- a/lib/views/branch_management/services/services_list_page.dart +++ b/lib/views/branch_management/services/services_list_page.dart @@ -231,7 +231,7 @@ class _ServicesListPageState extends State { ], ), ), - if (filteredServices[index].serviceStatusEnum != ServiceStatusEnum.blocked) ...[ + if (filteredServices[index].serviceStatusEnum != ServiceStatusEnum.blocked && filteredServices[index].serviceStatusEnum != ServiceStatusEnum.deactivated) ...[ const Icon(Icons.arrow_forward_rounded, size: 20), ], ], @@ -243,6 +243,11 @@ class _ServicesListPageState extends State { 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]); }); }, From e4bfc045411243cfffb7eb8a8b67bfa330f4b478 Mon Sep 17 00:00:00 2001 From: Faiz Hashmi Date: Wed, 4 Dec 2024 17:47:56 +0300 Subject: [PATCH 08/10] addnew service fix --- .../add_new_service_appointment_page.dart | 78 +++++------ .../widget/select_items_sheet.dart | 18 ++- .../services/services_list_page.dart | 122 +++++++++++++----- 3 files changed, 137 insertions(+), 81 deletions(-) diff --git a/lib/views/appoinments/add_new_service_appointment_page.dart b/lib/views/appoinments/add_new_service_appointment_page.dart index 112d6a8..2c44a04 100644 --- a/lib/views/appoinments/add_new_service_appointment_page.dart +++ b/lib/views/appoinments/add_new_service_appointment_page.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:developer'; 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: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/common_widgets/app_bar.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:provider/provider.dart'; import 'package:easy_localization/easy_localization.dart'; @@ -43,6 +45,8 @@ class _AddNewServiceAppointmentPageState extends State selectedList = []; + double totalPrice = 0.0; + List? pickedItems; ServiceVM? serviceVM; @@ -56,6 +60,29 @@ class _AddNewServiceAppointmentPageState extends State 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 Widget build(BuildContext context) { return Scaffold( @@ -116,23 +143,7 @@ class _AddNewServiceAppointmentPageState extends State 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(); - }, - ), - ); + openItemsSelectionBottomSheet(); }, dropdownValue: service, list: serviceVm.servicesDropList, @@ -141,7 +152,7 @@ class _AddNewServiceAppointmentPageState extends State selectedList) { - pickedItems = []; - for (var element in selectedList) { - pickedItems!.add( - PickerItem(id: element.id ?? 0, title: element.name ?? ""), - ); - } - serviceVm.notifyListeners(); - }, - ), - ); + openItemsSelectionBottomSheet(); }, ) : service != null - ? Text(LocaleKeys.noItemSelectedYet.tr()) + ? EmptyWidget(text: LocaleKeys.noItemSelectedYet.tr()) : const SizedBox(), if ((service != null && pickedItems != null && pickedItems!.isNotEmpty)) Column( @@ -183,7 +179,7 @@ class _AddNewServiceAppointmentPageState extends State) onSelectItems; - List? list; + final int serviceId; + final Function(List) onSelectItems; + final List? 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 Widget build(BuildContext context) { @@ -72,10 +74,11 @@ class SelectItemsSheet extends StatelessWidget { controlAffinity: ListTileControlAffinity.leading, title: itemsVM.serviceItems!.data![index].name!.toText(fontSize: 16), subtitle: itemsVM.serviceItems!.data![index].price.toString().toText(fontSize: 14, color: MyColors.lightTextColor), - value: itemsVM.serviceItems!.data![index].isUpdateOrSelected, onChanged: (bool? v) { itemsVM.serviceItems!.data![index].isUpdateOrSelected = v; + + log("itemsVM.serviceItems!.data![index].isUpdateOrSelected: ${itemsVM.serviceItems!.data![index].isUpdateOrSelected}"); itemsVM.notifyListeners(); }, ); @@ -97,9 +100,10 @@ class SelectItemsSheet extends StatelessWidget { maxWidth: double.infinity, margin: const EdgeInsets.all(20), onPressed: () { - if (context.read().serviceItems != null) { + final itemsVM = context.read(); + if (itemsVM.serviceItems != null) { List list = []; - for (var element in context.read().serviceItems!.data!) { + for (var element in itemsVM.serviceItems!.data!) { if (element.isUpdateOrSelected ?? false) { list.add(element); } diff --git a/lib/views/branch_management/services/services_list_page.dart b/lib/views/branch_management/services/services_list_page.dart index f49dfc7..5e2b47e 100644 --- a/lib/views/branch_management/services/services_list_page.dart +++ b/lib/views/branch_management/services/services_list_page.dart @@ -3,6 +3,7 @@ import 'dart:developer'; 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:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:mc_common_app/classes/consts.dart'; @@ -80,6 +81,96 @@ class _ServicesListPageState extends State { 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: [ + categoryData.categoryName.toString().toText(fontSize: 16), + ], + ), + // 5.height, + if (categoryData.services != null) ...[ + Container( + child: ("${LocaleKeys.totalNumberOfServices.tr()}: ${categoryData.services!.length}").toText( + fontSize: 12, + color: MyColors.lightTextColor, + ), + ), + ], + Container( + child: ("${LocaleKeys.branchName.tr()}: ${categoryData.branchName}").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 Widget build(BuildContext context) { categoryData = ModalRoute.of(context)!.settings.arguments as CategoryData; @@ -116,6 +207,7 @@ class _ServicesListPageState extends State { width: double.infinity, child: Column( children: [ + buildCategoryTileWidget().paddingOnly(left: 20, right: 20, top: 10), 20.height, Consumer( builder: (BuildContext context, ServiceVM serviceVM, Widget? child) { @@ -130,36 +222,6 @@ class _ServicesListPageState extends State { ); }, ), - - // Padding( - // padding: const EdgeInsets.only(left: 20, right: 20, top: 20), - // child: RoleTypeTab( - // selectedTab, - // [ - // DropValue(0, 'Active', ''), - // DropValue(1, 'Requested', ''), - // DropValue(2, 'Deactivated', ''), - // ], - // width: (MediaQuery.of(context).size.width / 3) - 26, - // onSelect: (DropValue value) { - // setState(() { - // selectedTab = value.id; - // - // if (selectedTab == 0) { - // selectedService = ServiceStatusEnum.approvedOrActive; - // filteredServices = categoryData.services!.where((i) => i.serviceStatusEnum == ServiceStatusEnum.approvedOrActive).toList(); - // } else if (selectedTab == 2) { - // selectedService = ServiceStatusEnum.deactivated; - // filteredServices = categoryData.services!.where((i) => i.serviceStatusEnum == ServiceStatusEnum.deactivated).toList(); - // } else { - // selectedService = value.id.toServiceStatusEnum(); - // filteredServices = - // categoryData.services!.where((i) => (i.serviceStatusEnum != ServiceStatusEnum.approvedOrActive && i.serviceStatusEnum != ServiceStatusEnum.deactivated)).toList(); - // } - // }); - // }, - // ), - // ), const SizedBox(height: 10), Expanded( child: RefreshIndicator( From cf13f4b44e396b921ae74fa472b4813a9c0dca2e Mon Sep 17 00:00:00 2001 From: faizatflutter Date: Thu, 5 Dec 2024 01:58:39 +0300 Subject: [PATCH 09/10] Added Services Widget on HomeScreen --- .../branch/branch_list_page.dart | 17 ++-- .../services/create_services_page3.dart | 1 - .../duplication/matched_services_page.dart | 93 +++++++++---------- .../sheet/approved_branches_list_sheet.dart | 66 ++++--------- .../services/services_list_page.dart | 2 +- .../dashboard/fragments/home_fragment.dart | 35 +++---- pubspec.yaml | 4 +- 7 files changed, 87 insertions(+), 131 deletions(-) diff --git a/lib/views/branch_management/branch/branch_list_page.dart b/lib/views/branch_management/branch/branch_list_page.dart index 388aa0e..67c7725 100644 --- a/lib/views/branch_management/branch/branch_list_page.dart +++ b/lib/views/branch_management/branch/branch_list_page.dart @@ -1,26 +1,25 @@ +import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/gestures.dart'; +import 'package:flutter/material.dart'; import 'package:mc_common_app/classes/consts.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/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/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/navigator.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/common_widgets/app_bar.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/tab/role_type_tab.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'; class BranchListPage extends StatelessWidget { @@ -144,7 +143,7 @@ class BranchListPage extends StatelessWidget { ), ], ), - 2.height, + 5.height, // branchModel.distanceKm == null // ? const SizedBox() // : Row( diff --git a/lib/views/branch_management/services/create_services_page3.dart b/lib/views/branch_management/services/create_services_page3.dart index d3dca90..7508fbc 100644 --- a/lib/views/branch_management/services/create_services_page3.dart +++ b/lib/views/branch_management/services/create_services_page3.dart @@ -1,6 +1,5 @@ import 'dart:async'; import 'dart:developer'; -import 'package:car_provider_app/main.dart'; import 'package:flutter/cupertino.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart'; import 'package:mc_common_app/models/general_models/generic_resp_model.dart'; diff --git a/lib/views/branch_management/services/duplication/matched_services_page.dart b/lib/views/branch_management/services/duplication/matched_services_page.dart index 541c404..ef5ae76 100644 --- a/lib/views/branch_management/services/duplication/matched_services_page.dart +++ b/lib/views/branch_management/services/duplication/matched_services_page.dart @@ -1,15 +1,16 @@ -import 'package:mc_common_app/generated/locale_keys.g.dart'; -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/items_selection_sheet.dart'; +import 'package:easy_localization/easy_localization.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/extensions/int_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/theme/colors.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/button/show_fill_button.dart'; import 'package:mc_common_app/widgets/common_widgets/app_bar.dart'; @@ -17,12 +18,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/extensions/extensions_widget.dart'; import 'package:provider/provider.dart'; -import 'package:easy_localization/easy_localization.dart'; class MatchedServicesPage extends StatefulWidget { final MatchServicesArguments? matchServicesArguments; - const MatchedServicesPage(this.matchServicesArguments, {Key? key}) : super(key: key); + const MatchedServicesPage(this.matchServicesArguments, {super.key}); @override State createState() => _MatchedServicesPageState(); @@ -39,7 +39,11 @@ class _MatchedServicesPageState extends State { } getMatchedServices() { - serviceVM.getAllMatchedServices(widget.matchServicesArguments!.oldBranch, widget.matchServicesArguments!.newBranch, widget.matchServicesArguments!.categoryId); + serviceVM.getAllMatchedServices( + widget.matchServicesArguments!.oldBranch, + widget.matchServicesArguments!.newBranch, + widget.matchServicesArguments!.categoryId, + ); } @override @@ -53,47 +57,41 @@ class _MatchedServicesPageState extends State { height: double.infinity, child: Column( children: [ - DropDownText(widget.matchServicesArguments!.oldBranchName).toContainer( - padding: const EdgeInsets.only( - left: 14, - right: 14, - top: 21, - ), + 12.height, + DropDownText( + title: widget.matchServicesArguments!.oldBranchName, + showDropDownIcon: false, ), 12.height, - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - Checkbox( + GestureDetector( + onTap: () { + // Toggle the checkbox value when the row is tapped + bool newValue = !context.read().isAllSelected; + serviceVM.selectAllServices(newValue); + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + SizedBox( + height: 30, + width: 30, + child: Checkbox( value: context.watch().isAllSelected, onChanged: (v) { serviceVM.selectAllServices(v ?? false); }, ), - LocaleKeys.selectAll.tr().toText(isBold: true) - ], - ), - 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); - }), - ], + ), + LocaleKeys.selectAll.tr().toText(fontSize: 14), + ], + ), ), 12.height, Expanded( - child: Consumer(builder: (context, model, _) { - if (model.matchedServices == null) { + child: Consumer(builder: (context, ServiceVM serviceVM, _) { + if (serviceVM.matchedServices == null) { return const Center(child: CircularProgressIndicator()); - } else if (model.matchedServices!.isEmpty) { + } else if (serviceVM.matchedServices!.isEmpty) { return EmptyWidget(text: LocaleKeys.noServicesAvailable.tr(), isWrappedColumn: false); } return ListView.separated( @@ -103,13 +101,13 @@ class _MatchedServicesPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Checkbox( - value: model.matchedServices![index].isExpandedOrSelected, + value: serviceVM.matchedServices![index].isExpandedOrSelected, onChanged: (v) { - if (model.matchedServices![index].serviceItems!.isEmpty) { - Utils.showToast(LocaleKeys.noItemsToShow.tr()); + if (serviceVM.matchedServices![index].serviceItems!.isEmpty) { + Utils.showToast(LocaleKeys.noAvailableItems.tr()); } else { - model.matchedServices![index].isExpandedOrSelected = v ?? false; - model.updateServiceItem(index, model.matchedServices![index].isExpandedOrSelected); + serviceVM.matchedServices![index].isExpandedOrSelected = v ?? false; + serviceVM.updateServiceItem(index, serviceVM.matchedServices![index].isExpandedOrSelected); } }, ), @@ -118,8 +116,9 @@ class _MatchedServicesPageState extends State { mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ - model.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].serviceDescription.toString().toText(fontSize: 16, isBold: true), + "${serviceVM.matchedServices![index].serviceItems!.where((c) => c.isUpdateOrSelected == true).length} items selected out of ${serviceVM.matchedServices![index].serviceItems!.length}" + .toText(color: MyColors.lightTextColor) ], ), ), @@ -134,9 +133,9 @@ class _MatchedServicesPageState extends State { showMyBottomSheet( context, child: ItemsSelectionSheet( - model.matchedServices![index].serviceItems ?? [], + serviceVM.matchedServices![index].serviceItems ?? [], onItemCopied: (List selected) { - model.copyItems(index, selected); + serviceVM.copyItems(index, selected); }, ), ); @@ -147,7 +146,7 @@ class _MatchedServicesPageState extends State { return 8.height; }, padding: const EdgeInsets.symmetric(horizontal: 14), - itemCount: model.matchedServices!.length, + itemCount: serviceVM.matchedServices!.length, ); }), ), @@ -164,7 +163,7 @@ class _MatchedServicesPageState extends State { }, ), ], - ), + ).padding(const EdgeInsets.symmetric(horizontal: 14)), ), ); } diff --git a/lib/views/branch_management/services/duplication/sheet/approved_branches_list_sheet.dart b/lib/views/branch_management/services/duplication/sheet/approved_branches_list_sheet.dart index 23fd781..d6c62d7 100644 --- a/lib/views/branch_management/services/duplication/sheet/approved_branches_list_sheet.dart +++ b/lib/views/branch_management/services/duplication/sheet/approved_branches_list_sheet.dart @@ -1,8 +1,6 @@ -import 'package:mc_common_app/config/routes.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/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/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.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/utils/enums.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:provider/provider.dart'; -import 'package:easy_localization/easy_localization.dart'; -import 'package:flutter_svg/svg.dart'; -import 'package:geolocator/geolocator.dart'; class MatchServicesArguments { int oldBranch, newBranch, categoryId; @@ -24,9 +20,9 @@ class MatchServicesArguments { } 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 Widget build(BuildContext context) { @@ -37,10 +33,8 @@ class ApprovedBranchesListSheet extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - "Select Branch".toText(fontSize: 20, isBold: true), - "Select the branch to copy their items to this branch. You can modify the selection at any time.".toText( - fontSize: 12, - ), + LocaleKeys.selectBranch.tr().toText(fontSize: 20, isBold: true), + LocaleKeys.selectBranchToCopyServices.tr().toText(fontSize: 12), 12.height, Expanded( child: Consumer( @@ -50,25 +44,20 @@ class ApprovedBranchesListSheet extends StatelessWidget { } else { List branches = []; 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 - ? Center(child: Text(LocaleKeys.no_branch.tr())) + ? Center(child: Text(LocaleKeys.noBranchFound.tr())) : ListView.separated( itemBuilder: (context, index) { return Row( children: [ - Container( - width: 74, - height: 50, - decoration: const BoxDecoration( - color: MyColors.darkPrimaryColor, - borderRadius: BorderRadius.all(Radius.circular(8)), - ), - padding: const EdgeInsets.all(6), - child: SvgPicture.asset( - MyAssets.icBranches, - color: Colors.white, + SizedBox( + width: 70, + height: 55, + child: ClipRRect( + borderRadius: const BorderRadius.all(Radius.circular(8)), + child: branches[index].branchProfileImage.buildNetworkImage(fit: BoxFit.cover), ), ), 12.width, @@ -77,22 +66,6 @@ class ApprovedBranchesListSheet extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, 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( branches[index].branchName ?? "", style: const TextStyle( @@ -100,15 +73,12 @@ class ApprovedBranchesListSheet extends StatelessWidget { 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, - const Icon( - Icons.arrow_forward_rounded, - size: 16, - ), + const Icon(Icons.arrow_forward_rounded, size: 16), ], ).toContainer(isShadowEnabled: true).onPress(() async { // branches[index].countryID = model.branchs!.data!.countryID; @@ -119,7 +89,7 @@ class ApprovedBranchesListSheet extends StatelessWidget { arguments: MatchServicesArguments( oldBranch: branches[index].id ?? 0, oldBranchName: branches[index].branchName ?? "", - newBranch: newBranch, + newBranch: branchId, categoryId: categoryId, ), ); diff --git a/lib/views/branch_management/services/services_list_page.dart b/lib/views/branch_management/services/services_list_page.dart index f414ee1..343011d 100644 --- a/lib/views/branch_management/services/services_list_page.dart +++ b/lib/views/branch_management/services/services_list_page.dart @@ -104,7 +104,7 @@ class _ServicesListPageState extends State { showMyBottomSheet( context, child: ApprovedBranchesListSheet( - newBranch: int.parse(categoryData.branchId ?? ''), + branchId: int.parse(categoryData.branchId ?? ''), categoryId: categoryData.id ?? 0, ), ); diff --git a/lib/views/dashboard/fragments/home_fragment.dart b/lib/views/dashboard/fragments/home_fragment.dart index 9235339..1c4241c 100644 --- a/lib/views/dashboard/fragments/home_fragment.dart +++ b/lib/views/dashboard/fragments/home_fragment.dart @@ -1,17 +1,13 @@ 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: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/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/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/navigator.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/views/advertisement/components/ads_list_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/extensions/extensions_widget.dart'; import 'package:provider/provider.dart'; -import 'package:easy_localization/easy_localization.dart'; class HomeFragment extends StatelessWidget { - const HomeFragment({Key? key}) : super(key: key); + const HomeFragment({super.key}); @override Widget build(BuildContext context) { @@ -64,23 +59,15 @@ class HomeFragment extends StatelessWidget { context.read().onNavbarTapped(1); }, ).horPaddingMain(), - // const AppointmentSliderWidget().horPaddingMain(), - - //TODO TESTING PENDING - if (AppState().currentAppType == AppType.provider && context.read().myUpComingAppointments.isEmpty) ...[ - LocaleKeys.noUpcomingAppointments.tr().toText(fontSize: 16, color: MyColors.lightTextColor, fontWeight: MyFonts.Medium).paddingAll(21), - ] else ...[ - CommonAppointmentSliderWidget( - onAppointmentClick: (AppointmentListModel value) { - navigateWithName(context, AppRoutes.appointmentDetailList, arguments: value); - }, - ) - .toWhiteContainer( - width: double.infinity, - backgroundColor: Colors.transparent, - ) - .margin(left: 21, right: 21), - ], + CommonAppointmentSliderWidget( + onAppointmentClick: (AppointmentListModel value) => navigateWithName( + context, + AppRoutes.appointmentDetailList, + arguments: value, + )).toWhiteContainer(width: double.infinity, backgroundColor: Colors.transparent).margin( + left: 21, + right: 21, + ), 24.height, ViewAllWidget( title: LocaleKeys.myBranches.tr(), diff --git a/pubspec.yaml b/pubspec.yaml index 9bf8d2d..49dd9ca 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -42,7 +42,9 @@ dependencies: mc_common_app: # path: D:\Development\car_common_app # path: /Users/amir/StudioProjects/car_common_app - path: /Volumes/Data/Projects/Flutter/car_common_app + # path: /Volumes/Data/Projects/Flutter/car_common_app + path: /Users/faizhashmi/Development/Projects/MyProjects/CloudSolutions/car_common_app + From 8cdbaf3007c7ae36cc4c18c7e408248f9b5572d4 Mon Sep 17 00:00:00 2001 From: Faiz Hashmi Date: Thu, 5 Dec 2024 18:00:31 +0300 Subject: [PATCH 10/10] Added --- .../services/create_services_page3.dart | 8 - .../duplication/matched_services_page.dart | 19 +-- .../sheet/approved_branches_list_sheet.dart | 4 +- .../sheet/items_selection_sheet.dart | 147 ++++++++---------- .../services/services_list_page.dart | 16 +- pubspec.yaml | 4 +- 6 files changed, 86 insertions(+), 112 deletions(-) diff --git a/lib/views/branch_management/services/create_services_page3.dart b/lib/views/branch_management/services/create_services_page3.dart index abf19c6..7b0a796 100644 --- a/lib/views/branch_management/services/create_services_page3.dart +++ b/lib/views/branch_management/services/create_services_page3.dart @@ -372,14 +372,6 @@ class _CreateServicesPage3State extends State { } Future updateServiceStatus(BuildContext context, bool value) async { - List> map = [ - { - "id": widget.branchModel!.serviceProviderService!.serviceProviderServiceId.toString(), - "isActive": true, - - //TODO: ZAHOOR WILL ADD SERVICE STATUS HERE TO UPDATE - } - ]; try { final serviceVM = context.read(); List list = await serviceVM.getAppointmentsByServiceID( diff --git a/lib/views/branch_management/services/duplication/matched_services_page.dart b/lib/views/branch_management/services/duplication/matched_services_page.dart index ef5ae76..407a0a3 100644 --- a/lib/views/branch_management/services/duplication/matched_services_page.dart +++ b/lib/views/branch_management/services/duplication/matched_services_page.dart @@ -1,3 +1,5 @@ +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/items_selection_sheet.dart'; import 'package:easy_localization/easy_localization.dart'; @@ -40,9 +42,9 @@ class _MatchedServicesPageState extends State { getMatchedServices() { serviceVM.getAllMatchedServices( - widget.matchServicesArguments!.oldBranch, - widget.matchServicesArguments!.newBranch, - widget.matchServicesArguments!.categoryId, + oldBranchId: widget.matchServicesArguments!.oldBranch, + newBranchId: widget.matchServicesArguments!.newBranch, + categoryId: widget.matchServicesArguments!.categoryId, ); } @@ -65,7 +67,6 @@ class _MatchedServicesPageState extends State { 12.height, GestureDetector( onTap: () { - // Toggle the checkbox value when the row is tapped bool newValue = !context.read().isAllSelected; serviceVM.selectAllServices(newValue); }, @@ -118,15 +119,11 @@ class _MatchedServicesPageState extends State { children: [ serviceVM.matchedServices![index].serviceDescription.toString().toText(fontSize: 16, isBold: true), "${serviceVM.matchedServices![index].serviceItems!.where((c) => c.isUpdateOrSelected == true).length} items selected out of ${serviceVM.matchedServices![index].serviceItems!.length}" - .toText(color: MyColors.lightTextColor) + .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( () { @@ -145,7 +142,7 @@ class _MatchedServicesPageState extends State { separatorBuilder: (context, index) { return 8.height; }, - padding: const EdgeInsets.symmetric(horizontal: 14), + // padding: const EdgeInsets.symmetric(horizontal: 14), itemCount: serviceVM.matchedServices!.length, ); }), diff --git a/lib/views/branch_management/services/duplication/sheet/approved_branches_list_sheet.dart b/lib/views/branch_management/services/duplication/sheet/approved_branches_list_sheet.dart index d6c62d7..375ed78 100644 --- a/lib/views/branch_management/services/duplication/sheet/approved_branches_list_sheet.dart +++ b/lib/views/branch_management/services/duplication/sheet/approved_branches_list_sheet.dart @@ -34,7 +34,7 @@ class ApprovedBranchesListSheet extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ LocaleKeys.selectBranch.tr().toText(fontSize: 20, isBold: true), - LocaleKeys.selectBranchToCopyServices.tr().toText(fontSize: 12), + LocaleKeys.noteCopyItemsExplanation.tr().toText(fontSize: 12), 12.height, Expanded( child: Consumer( @@ -87,9 +87,9 @@ class ApprovedBranchesListSheet extends StatelessWidget { context, AppRoutes.matchServices, arguments: MatchServicesArguments( - oldBranch: branches[index].id ?? 0, oldBranchName: branches[index].branchName ?? "", newBranch: branchId, + oldBranch: branches[index].id ?? 0, categoryId: categoryId, ), ); diff --git a/lib/views/branch_management/services/duplication/sheet/items_selection_sheet.dart b/lib/views/branch_management/services/duplication/sheet/items_selection_sheet.dart index 0b88dc3..0c6c8ee 100644 --- a/lib/views/branch_management/services/duplication/sheet/items_selection_sheet.dart +++ b/lib/views/branch_management/services/duplication/sheet/items_selection_sheet.dart @@ -1,18 +1,21 @@ import 'package:flutter/material.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/models/services_models/item_model.dart'; import 'package:mc_common_app/theme/colors.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/checkbox_with_title_desc.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/txt_field.dart'; +import 'package:easy_localization/easy_localization.dart'; class ItemsSelectionSheet extends StatefulWidget { final List serviceItems; final Function(List) onItemCopied; - const ItemsSelectionSheet(this.serviceItems, {required this.onItemCopied, Key? key}) : super(key: key); + const ItemsSelectionSheet(this.serviceItems, {required this.onItemCopied, super.key}); @override State createState() => _ItemsSelectionSheetState(); @@ -21,34 +24,39 @@ class ItemsSelectionSheet extends StatefulWidget { class _ItemsSelectionSheetState extends State { bool isAllItemsSelected = false; List? tempItems; + List? filteredItems; // To store filtered items based on search query + String searchQuery = ""; // To store the search query @override void initState() { super.initState(); - //tempItems=List.from(widget.serviceItems); - // tempItems=[...widget.serviceItems]; - //tempItems.addAll(widget.serviceItems); - tempItems = widget.serviceItems - .map( - (item) => ItemData.fromJson(item.toJson()) + tempItems = widget.serviceItems.map((item) => ItemData.fromJson(item.toJson())).toList(); + filteredItems = List.from(tempItems!); // Initially show all items + } + + // Method to filter items based on search query + 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( - // id: item.id, - // name: item.name, - // 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(); + updateTempItem(int index, bool value) { + filteredItems![index].isUpdateOrSelected = value; + setState(() {}); } @override @@ -60,69 +68,58 @@ class _ItemsSelectionSheetState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - "Select Items To Copy".toText(fontSize: 16, isBold: true), + LocaleKeys.pleaseSelectItems.tr().toText(fontSize: 18, isBold: true), 12.height, TxtField( - hint: "Search Items", - onChanged: (v) {}, + value: searchQuery, + hint: LocaleKeys.searchItems.tr(), + onChanged: (v) { + filterItems(v); // Filter items when the user types in the text field + }, ), 6.height, - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - Checkbox( - // value: context.watch().isAllSelected, + GestureDetector( + onTap: () { + isAllItemsSelected = false; + selectAllTempItems(false); + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + SizedBox( + height: 30, + width: 30, + child: Checkbox( value: isAllItemsSelected, onChanged: (v) { - isAllItemsSelected = v ?? false; - selectAllTempItems(v ?? false); + if (v == null) return; + 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), - ).onPress(() { - isAllItemsSelected = false; - selectAllTempItems(false); - }), - ], + LocaleKeys.selectAll.tr().toText(fontSize: 14), + ], + ), ), Flexible( child: ListView.separated( itemBuilder: (context, index) { - return Row( - mainAxisAlignment: MainAxisAlignment.start, + return CheckBoxWithTitleDescription( crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Checkbox( - value: tempItems![index].isUpdateOrSelected, - onChanged: (v) { - isAllItemsSelected = false; - updateTempItem(index, v ?? false); - }, - ), - Expanded( - child: tempItems![index].name.toString().toText(fontSize: 16, isBold: true), - ), - ], + isSelected: filteredItems![index].isUpdateOrSelected ?? false, + title: filteredItems![index].name.toString(), + description: filteredItems![index].description.toString(), + onSelection: (bool v) { + isAllItemsSelected = false; + updateTempItem(index, v); + }, ); }, separatorBuilder: (context, index) { return const Divider(); }, - itemCount: tempItems!.length, + itemCount: filteredItems!.length, // Use filtered items list ).toWhiteContainer(width: double.infinity), ), 12.height, @@ -130,7 +127,7 @@ class _ItemsSelectionSheetState extends State { title: "Copy Selected Item", maxWidth: double.infinity, onPressed: () { - widget.onItemCopied(tempItems ?? []); + widget.onItemCopied(filteredItems ?? []); pop(context); }, ), @@ -138,16 +135,4 @@ class _ItemsSelectionSheetState extends State { ), ); } - - selectAllTempItems(bool value) { - for (var element in tempItems ?? []) { - element.isUpdateOrSelected = value; - } - setState(() {}); - } - - updateTempItem(int index, bool value) { - tempItems![index].isUpdateOrSelected = value; - setState(() {}); - } } diff --git a/lib/views/branch_management/services/services_list_page.dart b/lib/views/branch_management/services/services_list_page.dart index 2f57361..12c96fb 100644 --- a/lib/views/branch_management/services/services_list_page.dart +++ b/lib/views/branch_management/services/services_list_page.dart @@ -111,24 +111,24 @@ class _ServicesListPageState extends State { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - categoryData.categoryName.toString().toText(fontSize: 16), + 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( + child: ("${LocaleKeys.totalNumberOfServices.tr()} ${categoryData.services!.length}").toText( fontSize: 12, color: MyColors.lightTextColor, ), ), ], - Container( - child: ("${LocaleKeys.branchName.tr()}: ${categoryData.branchName}").toText( - fontSize: 12, - color: MyColors.lightTextColor, - ), - ), ], ), ), diff --git a/pubspec.yaml b/pubspec.yaml index 49dd9ca..bfaeab5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -42,8 +42,8 @@ dependencies: mc_common_app: # path: D:\Development\car_common_app # path: /Users/amir/StudioProjects/car_common_app - # path: /Volumes/Data/Projects/Flutter/car_common_app - path: /Users/faizhashmi/Development/Projects/MyProjects/CloudSolutions/car_common_app + path: /Volumes/Data/Projects/Flutter/car_common_app +# path: /Users/faizhashmi/Development/Projects/MyProjects/CloudSolutions/car_common_app