From 1e22570a1c86f088a3c80901de269c76ab01880e Mon Sep 17 00:00:00 2001 From: "Fatimah.Alshammari" Date: Mon, 26 Oct 2026 10:10:59 +0300 Subject: [PATCH] fixed select item and add more than one services in appointment --- .../add_new_service_appointment_page.dart | 430 ++++++++++-------- .../add_appointment_service_bottom_sheet.dart | 224 +++++++++ .../widget/select_items_sheet.dart | 137 ++++-- .../branch/branch_detail_page.dart | 2 +- 4 files changed, 555 insertions(+), 238 deletions(-) create mode 100644 lib/views/appoinments/widget/add_appointment_service_bottom_sheet.dart diff --git a/lib/views/appoinments/add_new_service_appointment_page.dart b/lib/views/appoinments/add_new_service_appointment_page.dart index ae092cc..a864ede 100644 --- a/lib/views/appoinments/add_new_service_appointment_page.dart +++ b/lib/views/appoinments/add_new_service_appointment_page.dart @@ -1,57 +1,53 @@ import 'dart:async'; + 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'; -import 'package:flutter/widgets.dart'; -import 'package:mc_common_app/classes/consts.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/view_models/service_view_model.dart'; -import 'package:car_provider_app/views/appoinments/widget/select_items_sheet.dart'; import 'package:flutter/material.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:provider/provider.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/appointments_models/appointment_list_model.dart'; -import 'package:mc_common_app/models/services_models/item_model.dart'; +import 'package:mc_common_app/models/general_models/generic_resp_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/utils/enums.dart'; import 'package:mc_common_app/utils/utils.dart'; import 'package:mc_common_app/view_models/appointments_view_model.dart'; -import 'package:mc_common_app/widgets/bottom_sheet.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/empty_widget.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'; +import 'package:mc_common_app/models/appointments_models/selected_appointment_service_model.dart'; +import 'package:car_provider_app/views/appoinments/widget/add_appointment_service_bottom_sheet.dart'; -class AddNewServiceAppointmentPage extends StatefulWidget { - final AppointmentListModel appointmentListModel; - const AddNewServiceAppointmentPage(this.appointmentListModel, {Key? key}) : super(key: key); - @override - State createState() => _AddNewServiceAppointmentPageState(); -} -class _AddNewServiceAppointmentPageState extends State { - DropValue? category; - DropValue? service; +class AddNewServiceAppointmentPage extends StatefulWidget { + final AppointmentListModel appointmentListModel; - List selectedList = []; + const AddNewServiceAppointmentPage(this.appointmentListModel, {Key? key}) + : super(key: key); - double totalPrice = 0.0; + @override + State createState() => + _AddNewServiceAppointmentPageState(); +} - List? pickedItems; +class _AddNewServiceAppointmentPageState + extends State { + final List appointmentSelectedServices = []; ServiceVM? serviceVM; + bool isSubmitting = false; - // Currency dropdown + // Keep the existing Custom Service currency dropdown unchanged. DropValue? selectedCurrency; - List currencies = [ + final List currencies = [ DropValue(1, 'SAR', 'SAR'), DropValue(2, 'AED', 'AED'), DropValue(3, 'USD', 'USD'), @@ -59,44 +55,121 @@ class _AddNewServiceAppointmentPageState extends State(); - serviceVM!.fetchBranchCategory(EasyLocalization.of(context)?.currentLocale?.countryCode ?? "SA"); + serviceVM!.fetchBranchCategory( + EasyLocalization.of(context)?.currentLocale?.countryCode ?? 'SA', + ); }); } - openItemsSelectionBottomSheet() async { - return showMyBottomSheet( - context, - child: SelectItemsSheet( - serviceId: service?.id ?? 0, - list: pickedItems, - onSelectItems: (List 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(() {}); - }, + Future _openAddServiceSheet({int? editIndex}) async { + if (isSubmitting) return; + final existing = editIndex == null + ? null + : appointmentSelectedServices[editIndex]; + + final result = await showModalBottomSheet( + context: context, + isScrollControlled: true, + enableDrag: true, + builder: (_) => AddAppointmentServiceBottomSheet( + branchId: widget.appointmentListModel.branchId ?? 0, + initialService: existing, ), ); + + if (!mounted || result == null) return; + setState(() { + if (editIndex == null) { + appointmentSelectedServices.add(result); + } else { + appointmentSelectedServices[editIndex] = result; + } + }); + } + + double get _totalItemsPrice => appointmentSelectedServices.fold( + 0, + (sum, selected) => sum + selected.totalPrice, + ); + + List get _allSelectedItemIds => appointmentSelectedServices + .expand((selected) => selected.itemIds) + .where((id) => id > 0) + .toSet() + .toList(); + + Future _submit() async { + if (isSubmitting) return; + final vm = serviceVM ?? context.read(); + Map postParams; + + if (vm.customServiceEnabledStatus) { + // Original Custom Service behavior, intentionally unchanged. + if (!vm.isCustomServiceDetailValidated()) return; + postParams = { + 'providerBranchID': widget.appointmentListModel.branchId, + 'appointmentID': widget.appointmentListModel.id, + 'serviceItemsFreeText': [ + { + 'name': vm.customServiceTitle, + 'price': vm.customServicePrice, + 'tax': vm.customerServiceTax, + } + ], + }; + } else { + final ids = _allSelectedItemIds; + if (ids.isEmpty) { + Utils.showToast(LocaleKeys.pleaseSelectItems.tr()); + return; + } + postParams = { + 'providerBranchID': widget.appointmentListModel.branchId, + 'appointmentID': widget.appointmentListModel.id, + 'serviceItemID': ids, + }; + } + + setState(() => isSubmitting = true); + bool loadingVisible = false; + try { + Utils.showLoading(context); + loadingVisible = true; + final GenericRespModel res = + await vm.addNewServiceInAppointment(postParams); + if (!mounted) return; + Utils.hideLoading(context); + loadingVisible = false; + + if (res.messageStatus == 1) { + vm.resetCustomServiceForm(); + await _updateAppointment(context, widget.appointmentListModel.branchId ?? 0); + if (!mounted) return; + Utils.showToast(LocaleKeys.itemsAddedSuccessfully.tr()); + // Return to the previous page after the successful API call. + // Original code popped twice; confirm whether your navigation stack + // still needs a second pop before adding it here. + pop(context); + } else { + Utils.showToast(res.message.toString()); + } + } catch (e) { + if (mounted) Utils.showToast(e.toString()); + } finally { + if (mounted && loadingVisible) Utils.hideLoading(context); + if (mounted) setState(() => isSubmitting = false); + } } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: MyColors.white, - appBar: CustomAppBar( - title: LocaleKeys.addService.tr(), - ), + appBar: CustomAppBar(title: LocaleKeys.addService.tr()), body: Padding( padding: const EdgeInsets.all(21.0), child: Stack( @@ -127,11 +200,15 @@ class _AddNewServiceAppointmentPageState extends State selectedCurrency = value); }, dropdownValue: selectedCurrency, list: currencies, @@ -184,7 +259,12 @@ class _AddNewServiceAppointmentPageState extends State _openAddServiceSheet(), + icon: const Icon(Icons.add_circle_outline), + label: Text(LocaleKeys.addServices.tr()), + style: OutlinedButton.styleFrom( + minimumSize: const Size.fromHeight(52), + foregroundColor: MyColors.darkPrimaryColor, + side: const BorderSide(color: MyColors.darkPrimaryColor), + ), + ), + ), + 12.height, + ...appointmentSelectedServices.asMap().entries.map((entry) { + final index = entry.key; + final selected = entry.value; + return Card( + margin: const EdgeInsets.only(bottom: 12), + child: Padding( + padding: const EdgeInsets.all(12), + child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - 16.height, - LocaleKeys.totalAdditionalAmount.tr().toText( - fontSize: 14, - isBold: true, - color: MyColors.lightTextColor, - ), Row( - crossAxisAlignment: CrossAxisAlignment.end, children: [ - totalPrice.toString().toText( - fontSize: 29, - isBold: true, - ), - 2.width, - LocaleKeys.sar - .tr() - .toText( + Expanded( + child: Text( + selected.service.value, + style: const TextStyle( fontSize: 16, - isBold: true, - color: MyColors.lightTextColor, - ) - .paddingOnly(bottom: 5), + fontWeight: FontWeight.bold, + ), + ), + ), + + // Edit + MyAssets.icEdit.buildSvg( + height: 17, + width: 17, + ).onPress(() { + _openAddServiceSheet(editIndex: index); + }), + const SizedBox(width: 10), + // Delete + MyAssets.closeWithOrangeBg.buildSvg( + height: 30, + width: 30, + ).onPress(() { + setState(() { + appointmentSelectedServices.removeAt(index); + }); + }), ], ), - 10.height, + Text( + selected.category.value, + style: const TextStyle(color: Colors.grey), + ), + 8.height, + ...selected.items.map( + (item) => Padding( + padding: const EdgeInsets.only(bottom: 4), + child: Row( + children: [ + Expanded(child: Text(item.name ?? '')), + Text('${item.price ?? '0'} SAR'), + ], + ), + ), + ), + const Divider(), + Text( + '${selected.totalPrice.toStringAsFixed(2)} SAR', + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 18, + ), + ), ], ), - ], - ), + ), + ); + }), + if (appointmentSelectedServices.isNotEmpty) ...[ + 12.height, + LocaleKeys.totalAdditionalAmount.tr().toText( + fontSize: 14, + isBold: true, + color: MyColors.lightTextColor, + ), + Text( + '${_totalItemsPrice.toStringAsFixed(2)} SAR', + style: const TextStyle( + fontSize: 28, + fontWeight: FontWeight.bold, + ), + ), + ], ], ], ).toWhiteContainer(width: double.infinity, allPading: 12); }, ), - 55.height, + 85.height, ], ), ), @@ -306,10 +405,8 @@ class _AddNewServiceAppointmentPageState extends State()) + .resetCustomServiceForm(); pop(context); }, ), @@ -319,58 +416,7 @@ class _AddNewServiceAppointmentPageState extends State postParams = {}; - if (serviceVM!.customServiceEnabledStatus) { - if (serviceVM!.isCustomServiceDetailValidated()) { - postParams = { - "providerBranchID": widget.appointmentListModel.branchId, - "appointmentID": widget.appointmentListModel.id, - "serviceItemsFreeText": [ - { - "name": serviceVM!.customServiceTitle, - "price": serviceVM!.customServicePrice, - "tax": serviceVM!.customerServiceTax, - } - ], - }; - } else { - return; - } - } else { - if (pickedItems != null && pickedItems!.isNotEmpty) { - List items = []; - pickedItems?.forEach((element) { - items.add(element.id); - }); - postParams = { - "providerBranchID": widget.appointmentListModel.branchId, - "appointmentID": widget.appointmentListModel.id, - "serviceItemID": items, - }; - } else { - Utils.showToast(LocaleKeys.pleaseSelectItems.tr()); - return; - } - } - try { - Utils.showLoading(context); - GenericRespModel res = await serviceVM!.addNewServiceInAppointment(postParams); - Utils.hideLoading(context); - if (res.messageStatus == 1) { - serviceVM!.resetCustomServiceForm(); - _updateAppointment(context, widget.appointmentListModel.branchId ?? 0); - Utils.showToast(LocaleKeys.itemsAddedSuccessfully.tr()); - pop(context); - pop(context); - } else { - Utils.showToast(res.message.toString()); - } - } catch (e) { - Utils.showToast(e.toString()); - Utils.hideLoading(context); - } - }, + onPressed: _submit, ), ), ], @@ -384,9 +430,9 @@ class _AddNewServiceAppointmentPageState extends State _updateAppointment(BuildContext context, int branchId) async { await context.read().applyFilterOnAppointmentsVMForProviders( - branchID: branchId, - appointmentStatusEnum: AppointmentStatusEnum.allAppointments, - isNeedCustomerFilter: true, - ); + branchID: branchId, + appointmentStatusEnum: AppointmentStatusEnum.allAppointments, + isNeedCustomerFilter: true, + ); } } diff --git a/lib/views/appoinments/widget/add_appointment_service_bottom_sheet.dart b/lib/views/appoinments/widget/add_appointment_service_bottom_sheet.dart new file mode 100644 index 0000000..1d9d35d --- /dev/null +++ b/lib/views/appoinments/widget/add_appointment_service_bottom_sheet.dart @@ -0,0 +1,224 @@ + + +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:easy_localization/easy_localization.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/view_models/service_view_model.dart'; +import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart'; +import 'package:mc_common_app/widgets/bottom_sheet.dart'; +import 'package:car_provider_app/views/appoinments/widget/select_items_sheet.dart'; +import 'package:car_provider_app/views/branch_management/schedule/widgets/chips_picker_item.dart'; +import 'package:mc_common_app/models/appointments_models/selected_appointment_service_model.dart'; +import 'package:car_provider_app/views/branch_management/schedule/widgets/chips_picker_item.dart'; + + +class AddAppointmentServiceBottomSheet extends StatefulWidget { + final int branchId; + final SelectedAppointmentServiceModel? initialService; + + const AddAppointmentServiceBottomSheet({ + super.key, + required this.branchId, + this.initialService, + }); + + @override + State createState() => + _AddAppointmentServiceBottomSheetState(); +} + +class _AddAppointmentServiceBottomSheetState + extends State { + DropValue? category; + DropValue? service; + List selectedItems = []; + bool isLoadingServices = false; + String? loadError; + + @override + void initState() { + super.initState(); + category = widget.initialService?.category; + service = widget.initialService?.service; + selectedItems = List.of(widget.initialService?.items ?? []); + if (category != null) { + WidgetsBinding.instance.addPostFrameCallback((_) { + if (mounted) _loadServices(category!.id); + }); + } + } + + Future _loadServices(int categoryId) async { + setState(() { + isLoadingServices = true; + loadError = null; + }); + try { + await context.read().fetchProviderServices( + widget.branchId.toString(), + categoryId.toString(), + ); + } catch (e) { + if (mounted) loadError = e.toString(); + } finally { + if (mounted) setState(() => isLoadingServices = false); + } + } + + Future _openItemsSheet() async { + if (service == null) return; + final serviceId = service!.id; + final pickedItems = selectedItems + .map((item) => PickerItem(id: item.id ?? 0, title: item.name ?? '')) + .toList(); + + showMyBottomSheet( + context, + child: SelectItemsSheet( + serviceId: serviceId, + list: pickedItems, + onSelectItems: (items) { + if (!mounted) return; + setState(() => selectedItems = List.of(items)); + }, + ), + ); + } + + void _confirm() { + if (category == null || service == null || selectedItems.isEmpty) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text(LocaleKeys.pleaseSelectItems.tr())), + ); + return; + } + Navigator.of(context).pop( + SelectedAppointmentServiceModel( + category: category!, + service: service!, + items: List.of(selectedItems), + ), + ); + } + + @override + Widget build(BuildContext context) { + return SizedBox( + height: MediaQuery.of(context).size.height * 0.85, + child: SafeArea( + top: false, + child: Padding( + padding: const EdgeInsets.all(20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Center( + child: Container( + width: 60, + height: 6, + decoration: BoxDecoration( + color: Colors.grey.shade300, + borderRadius: BorderRadius.circular(20), + ), + ), + ), + const SizedBox(height: 20), + Text( + LocaleKeys.selectServiceDetails.tr(), + style: const TextStyle(fontSize: 22, fontWeight: FontWeight.bold), + ), + const SizedBox(height: 20), + Expanded( + child: SingleChildScrollView( + child: Consumer( + builder: (context, serviceVm, _) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + DropdownField( + (value) { + setState(() { + category = value; + service = null; + selectedItems.clear(); + }); + _loadServices(value.id); + }, + dropdownValue: category, + list: serviceVm.categoryDropList, + hint: LocaleKeys.selectServiceCategory.tr(), + isSelectAble: !isLoadingServices, + ), + if (category != null) ...[ + const SizedBox(height: 16), + if (isLoadingServices) + const Center(child: CircularProgressIndicator()) + else if (loadError != null) + TextButton( + onPressed: () => _loadServices(category!.id), + child: const Text('Retry loading services'), + ) + else + DropdownField( + (value) { + setState(() { + service = value; + selectedItems.clear(); + }); + }, + dropdownValue: service, + list: serviceVm.servicesDropList, + hint: LocaleKeys.defineServices.tr(), + ), + ], + if (service != null) ...[ + const SizedBox(height: 16), + ChipsPickerItem( + isNeedLabelOnTop: true, + hint: LocaleKeys.selectItems.tr(), + itemsList: selectedItems.map((item) { + return PickerItem( + id: item.id ?? 0, + title: item.name ?? "", + ); + }).toList(), + onClick: () { + _openItemsSheet(); + }, + ), + ...selectedItems.map( + (item) => ListTile( + contentPadding: EdgeInsets.zero, + title: Text(item.name ?? ''), + trailing: Text('${item.price ?? '0'} SAR'), + ), + ), + ], + ], + ); + }, + ), + ), + ), + SizedBox( + width: double.infinity, + child: ElevatedButton( + onPressed: isLoadingServices ? null : _confirm, + style: ElevatedButton.styleFrom( + backgroundColor: MyColors.darkPrimaryColor, + foregroundColor: Colors.white, + minimumSize: const Size.fromHeight(50), + ), + child: Text(LocaleKeys.next.tr()), + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/views/appoinments/widget/select_items_sheet.dart b/lib/views/appoinments/widget/select_items_sheet.dart index 50b57d3..8d18108 100644 --- a/lib/views/appoinments/widget/select_items_sheet.dart +++ b/lib/views/appoinments/widget/select_items_sheet.dart @@ -14,16 +14,52 @@ import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:provider/provider.dart'; import 'package:easy_localization/easy_localization.dart'; -class SelectItemsSheet extends StatelessWidget { +class SelectItemsSheet extends StatefulWidget { final int serviceId; final Function(List) onSelectItems; final List? list; - const SelectItemsSheet({super.key, required this.serviceId, required this.onSelectItems, this.list}); + const SelectItemsSheet({ + super.key, + required this.serviceId, + required this.onSelectItems, + this.list, + }); + + @override + State createState() => _SelectItemsSheetState(); +} + +class _SelectItemsSheetState extends State { + bool _loading = true; + String? _error; + + @override + void initState() { + super.initState(); + WidgetsBinding.instance.addPostFrameCallback((_) => _fetchItems()); + } + + Future _fetchItems() async { + if (!mounted) return; + setState(() { + _loading = true; + _error = null; + }); + try { + await context.read().getServiceItems( + widget.serviceId, + list: widget.list, + ); + } catch (e) { + _error = e.toString(); + } finally { + if (mounted) setState(() => _loading = false); + } + } @override Widget build(BuildContext context) { - context.read().getServiceItems(serviceId, list: list); return SizedBox( width: double.infinity, height: MediaQuery.of(context).size.height / 1.4, @@ -32,6 +68,11 @@ class SelectItemsSheet extends StatelessWidget { Expanded( child: Consumer( builder: (_, itemsVM, child) { + final items = itemsVM.serviceItems?.data; + final selectedCount = items + ?.where((element) => element.isUpdateOrSelected == true) + .length ?? + 0; return Padding( padding: const EdgeInsets.only(left: 20, right: 20, top: 6), child: Column( @@ -39,10 +80,13 @@ class SelectItemsSheet extends StatelessWidget { Row( children: [ Expanded( - child: LocaleKeys.selectItems.tr().toText(fontSize: 24, isBold: true), + child: LocaleKeys.selectItems.tr().toText( + fontSize: 24, + isBold: true, + ), ), Center( - child: (itemsVM.serviceItems == null ? "0" : itemsVM.serviceItems!.data!.where((element) => element.isUpdateOrSelected == true).toList().length.toString()).toText( + child: selectedCount.toString().toText( fontSize: 10, isBold: true, color: Colors.white, @@ -56,38 +100,46 @@ class SelectItemsSheet extends StatelessWidget { ), ], ), - // 12.height, - // TxtField( - // hint: LocaleKeys.searchItems.tr(), - // onChanged: (v) {}, - // ), 12.height, Expanded( - child: itemsVM.serviceItems?.data == null + child: _loading ? const Center(child: CircularProgressIndicator()) - : itemsVM.serviceItems?.data!.length == 0 - ? Center(child: EmptyWidget(text: LocaleKeys.noItemsToShow.tr())) - : ListView.separated( - itemBuilder: (BuildContext context, int index) { - return CheckboxListTile( - contentPadding: EdgeInsets.zero, - 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(); - }, - ); - }, - separatorBuilder: (BuildContext context, int index) { - return const Divider(height: 1); - }, - itemCount: itemsVM.serviceItems?.data?.length ?? 0, - ), + : _error != null + ? Center( + child: TextButton( + onPressed: _fetchItems, + child: Text('Failed to load items. Retry: $_error'), + ), + ) + : items == null || items.isEmpty + ? Center( + child: EmptyWidget( + text: LocaleKeys.noItemsToShow.tr(), + ), + ) + : ListView.separated( + itemBuilder: (context, index) { + final item = items[index]; + return CheckboxListTile( + contentPadding: EdgeInsets.zero, + controlAffinity: ListTileControlAffinity.leading, + title: (item.name ?? '').toText(fontSize: 16), + subtitle: item.price.toString().toText( + fontSize: 14, + color: MyColors.lightTextColor, + ), + value: item.isUpdateOrSelected ?? false, + onChanged: (bool? value) { + item.isUpdateOrSelected = value; + log('Item selected: ${item.isUpdateOrSelected}'); + itemsVM.notifyListeners(); + }, + ); + }, + separatorBuilder: (_, __) => + const Divider(height: 1), + itemCount: items.length, + ), ), ], ), @@ -100,20 +152,15 @@ class SelectItemsSheet extends StatelessWidget { maxWidth: double.infinity, margin: const EdgeInsets.all(20), onPressed: () { + if (_loading || _error != null) return; final itemsVM = context.read(); - if (itemsVM.serviceItems != null) { - List list = []; - for (var element in itemsVM.serviceItems!.data!) { - if (element.isUpdateOrSelected ?? false) { - list.add(element); - } - } - onSelectItems(list); - } - + final selected = (itemsVM.serviceItems?.data ?? []) + .where((element) => element.isUpdateOrSelected == true) + .toList(); + widget.onSelectItems(selected); Navigator.pop(context); }, - ) + ), ], ), ); diff --git a/lib/views/branch_management/branch/branch_detail_page.dart b/lib/views/branch_management/branch/branch_detail_page.dart index bc34a58..149c702 100644 --- a/lib/views/branch_management/branch/branch_detail_page.dart +++ b/lib/views/branch_management/branch/branch_detail_page.dart @@ -274,7 +274,7 @@ class _BranchDetailPageState extends State { children: [ showData("${LocaleKeys.location.tr()}:", "${isArabic ? widget.branchData.cityNameN.toString() : widget.branchData.cityName.toString()}, ${isArabic ? widget.branchData.countryNameN.toString() : widget.branchData.countryName.toString()}"), - showData("${LocaleKeys.provider.tr()}:", widget.branchData.serviceProviderName.toString()), + showData("${LocaleKeys.companyName.tr()}:", widget.branchData.serviceProviderName.toString()), showData("${LocaleKeys.time.tr()}:", "${widget.branchData.openTime.toString()} - ${widget.branchData.closeTime.toString()}"), showData("${LocaleKeys.address.tr()}:", widget.branchData.address.toString()), ],