From 64e2631cffc156991cf98f7aedc786f1d998f3c8 Mon Sep 17 00:00:00 2001 From: FaizHashmi Date: Sun, 30 Aug 2026 14:32:02 +0300 Subject: [PATCH] Fixed Bugs --- lib/api/api_client.dart | 22 +++---- lib/services/firebase_service.dart | 18 +++--- lib/view_models/ad_view_model.dart | 14 ++++- .../dashboard_view_model_customer.dart | 44 +++++++++----- .../dashboard_view_model_provider.dart | 58 ++++++++++++------- lib/view_models/subscriptions_view_model.dart | 19 +++--- .../ads_detail_view/ads_detail_view.dart | 22 +++---- lib/views/advertisement/ads_filter_view.dart | 2 + .../components/ads_list_widget.dart | 17 +++--- .../book_appointment_services_view.dart | 9 ++- ...appointment_service_pick_bottom_sheet.dart | 10 ++-- lib/views/requests/request_detail_page.dart | 27 +++++---- lib/widgets/extensions/extensions_widget.dart | 19 +++--- 13 files changed, 170 insertions(+), 111 deletions(-) diff --git a/lib/api/api_client.dart b/lib/api/api_client.dart index 5d812b8..54aeebb 100644 --- a/lib/api/api_client.dart +++ b/lib/api/api_client.dart @@ -124,17 +124,16 @@ class ApiClientImp implements ApiClient { return await _postForResponse(url, requestBody, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes); } - Future _postForResponse( - String url, - requestBody, { - String? token, - Map? queryParameters, - Map? headers, - int retryTimes = 0, - }) async { + Future _postForResponse(String url, + requestBody, { + String? token, + Map? queryParameters, + Map? headers, + int retryTimes = 0, + }) async { try { var headers0 = {}; - + // Add Accept-Language header based on current locale headers0['Accept-Language'] = _getCurrentLanguage(); @@ -211,7 +210,8 @@ class ApiClientImp implements ApiClient { bool _certificateCheck(X509Certificate cert, String host, int port) => true; Future _withClient(Future Function(Client) fn) async { - var httpClient = HttpClient()..badCertificateCallback = _certificateCheck; + var httpClient = HttpClient() + ..badCertificateCallback = _certificateCheck; var client = IOClient(httpClient); try { return await fn(client); @@ -254,7 +254,7 @@ class ApiClientImp implements ApiClient { Future _getForResponse(String url, {String? token, Map? queryParameters, Map? headers, int retryTimes = 0}) async { try { var headers0 = {}; - + // Add Accept-Language header based on current locale headers0['Accept-Language'] = _getCurrentLanguage(); diff --git a/lib/services/firebase_service.dart b/lib/services/firebase_service.dart index a714024..5a16329 100644 --- a/lib/services/firebase_service.dart +++ b/lib/services/firebase_service.dart @@ -61,16 +61,15 @@ class FirebaseMessagingServiceImp implements FirebaseMessagingService { 'mowater_chat_channel', // More descriptive channel ID 'Chat Notifications', description: 'Notifications for chat messages', - importance: Importance.max, // Changed to max for Android 14 + importance: Importance.max, + // Changed to max for Android 14 playSound: true, enableVibration: true, showBadge: true, ); - await flutterLocalNotifications - .resolvePlatformSpecificImplementation() - ?.createNotificationChannel(channel); - + await flutterLocalNotifications.resolvePlatformSpecificImplementation()?.createNotificationChannel(channel); + log("✅ Android notification channel created: ${channel.id}"); } @@ -141,6 +140,7 @@ class FirebaseMessagingServiceImp implements FirebaseMessagingService { log("Data payload: ${message.data}"); log("Message ID: ${message.messageId}"); log("Sent time: ${message.sentTime}"); + log("Android config: ${message.toMap()}"); log("======================================================"); // Just display notification - DON'T navigate automatically @@ -192,7 +192,7 @@ class FirebaseMessagingServiceImp implements FirebaseMessagingService { // Backend sends NotiType as string: "1" = Request, "2" = Ads, "3" = General String? notiTypeStr = data['NotiType']; int? notiType = int.tryParse(notiTypeStr ?? ''); - + log("NotiType from backend: $notiTypeStr (parsed: $notiType)"); if (notiType == null || notiType < 1 || notiType > 3) { @@ -264,7 +264,7 @@ class FirebaseMessagingServiceImp implements FirebaseMessagingService { try { // Try both backend format and our format int requestId = int.tryParse(data['RequestID']?.toString() ?? data['request_id']?.toString() ?? '0') ?? 0; - + if (requestId == 0) { log("❌ Invalid or missing RequestID in notification data"); return; @@ -273,7 +273,7 @@ class FirebaseMessagingServiceImp implements FirebaseMessagingService { log("✅ Navigating to providers chat list for request: $requestId"); navigateWithName(context, AppRoutes.providersChatListPage); - // TODO: If backend sends all required data (ProviderId, CustomerId), + // TODO: If backend sends all required data (ProviderId, CustomerId), // we can navigate directly to the chat screen } catch (e) { logger.e("Error navigating to request chat: $e"); @@ -327,7 +327,7 @@ class FirebaseMessagingServiceImp implements FirebaseMessagingService { try { // Try both backend format and our format int requestId = int.tryParse(data['RequestID']?.toString() ?? data['request_id']?.toString() ?? '0') ?? 0; - + if (requestId == 0) { log("❌ Invalid or missing RequestID in notification data"); return; diff --git a/lib/view_models/ad_view_model.dart b/lib/view_models/ad_view_model.dart index 458ba7a..ff2b415 100644 --- a/lib/view_models/ad_view_model.dart +++ b/lib/view_models/ad_view_model.dart @@ -2178,7 +2178,7 @@ class AdVM extends BaseVM { } VehiclePosting vehiclePosting = VehiclePosting( - id: isAdEditEnabled ? previousAdDetails!.vehiclePostingID : null, + id: isExtendAdEditEnabled ? null : (isAdEditEnabled ? previousAdDetails!.vehiclePostingID : null), userID: appState.getUser.data!.userInfo!.userId, vehicleType: vehicleTypeId.selectedId, vehicleModelID: vehicleModelId.selectedId, @@ -2647,6 +2647,11 @@ class AdVM extends BaseVM { setState(ViewState.busy); } + // Auto-add current typed Ad ID to history if not empty and not already in list + if (currentAdIDFilter.isNotEmpty && !ifAlreadyExistForStringValue(list: adsFilterAdIDSearchHistory, value: currentAdIDFilter)) { + addAdFilterAdIDSearchHistory(value: currentAdIDFilter); + } + List adIdsList = []; if (adsFilterAdIDSearchHistory.isNotEmpty) { for (var element in adsFilterAdIDSearchHistory) { @@ -2700,6 +2705,11 @@ class AdVM extends BaseVM { } } + // Auto-add current typed phone number to history if not empty and not already in list + if (currentAdMobilePhoneFilter.isNotEmpty && !ifAlreadyExistForStringValue(list: adFilterMobilePhoneSearchHistory, value: currentAdMobilePhoneFilter)) { + addAdFilterMobilePhoneSearchHistory(value: currentAdMobilePhoneFilter); + } + List phoneNumbersList = []; if (adFilterMobilePhoneSearchHistory.isNotEmpty) { for (var element in adFilterMobilePhoneSearchHistory) { @@ -2753,7 +2763,7 @@ class AdVM extends BaseVM { void onEditUpdateAdPressed({required BuildContext context, required AdDetailsModel previousDetails, required bool isFromExtendAd, bool isForDraft = false}) { isAdEditEnabled = true; - isDraftEditEnabled = true; + isDraftEditEnabled = isForDraft; // Only true if editing a draft isExtendAdEditEnabled = isFromExtendAd; previousAdDetails = previousDetails; autoFillSelectedVehicleType(); diff --git a/lib/view_models/dashboard_view_model_customer.dart b/lib/view_models/dashboard_view_model_customer.dart index 8dfee34..b0c7908 100644 --- a/lib/view_models/dashboard_view_model_customer.dart +++ b/lib/view_models/dashboard_view_model_customer.dart @@ -107,21 +107,39 @@ class DashboardVmCustomer extends BaseVM with WidgetsBindingObserver { RequestsVM requestsVM = Provider.of(context, listen: false); ChatVM chatVM = Provider.of(context, listen: false); + // Set loading state immediately to prevent "No data" flash + adVM.setState(ViewState.busy); + appointmentsVM.setState(ViewState.busy); + requestsVM.setState(ViewState.busy); + // ✅ Inject ViewModels into ChatVM (only needs to be done once, but safe to repeat) chatVM.setViewModels(requestsVM: requestsVM, adVM: adVM); - await appointmentsVM.populateBranchesFilterList(); - await appointmentsVM.populateAppointmentsFilterList(); - await adVM.populateAdsFilterList(); - await requestsVM.populateDataForRequestsFilter(); - await requestsVM.populateDeliveryOptionEnums(); - await appointmentsVM.applyFilterOnAppointmentsVMForCustomers(appointmentStatusEnum: AppointmentStatusEnum.allAppointments, shouldPopulateUpcoming: true); - await appointmentsVM.applyFilterOnBranches(index: 0); // to get all branches! - await appointmentsVM.getMyRecentBranches(); // to get my recent branches - + // Call independent filter population APIs in parallel + await Future.wait([ + appointmentsVM.populateBranchesFilterList(), + appointmentsVM.populateAppointmentsFilterList(), + adVM.populateAdsFilterList(), + requestsVM.populateDataForRequestsFilter(), + requestsVM.populateDeliveryOptionEnums(), + adVM.getVehicleTypes(), + adVM.getVehicleAdsDuration(), + ]); + + // Call data APIs in parallel + await Future.wait([ + appointmentsVM.applyFilterOnAppointmentsVMForCustomers(appointmentStatusEnum: AppointmentStatusEnum.allAppointments, shouldPopulateUpcoming: true), + appointmentsVM.applyFilterOnBranches(index: 0), // to get all branches! + appointmentsVM.getMyRecentBranches(), // to get my recent branches + requestsVM.getRequests(), + ]); + + // Call ads APIs in parallel (conditionally) if (dashboardRouteEnum != DashboardRouteEnum.fromAdsPayment && dashboardRouteEnum != DashboardRouteEnum.fromAdsSubmit && dashboardRouteEnum != DashboardRouteEnum.fromReserveAdsPayment) { - await adVM.getMyAds(); - await adVM.getExploreAds(); + await Future.wait([ + adVM.getMyAds(), + adVM.getExploreAds(), + ]); } // Handle different payment completion scenarios @@ -143,9 +161,7 @@ class DashboardVmCustomer extends BaseVM with WidgetsBindingObserver { log("✅ Successfully navigated to Appointments after payment"); } - await requestsVM.getRequests(); - await adVM.getVehicleTypes(); - await adVM.getVehicleAdsDuration(); + // Build chat hub connection last await chatVM.buildHubConnection(context: context); // if (appointmentsVM.myAppointments.isEmpty) { diff --git a/lib/view_models/dashboard_view_model_provider.dart b/lib/view_models/dashboard_view_model_provider.dart index d0b1743..f822b13 100644 --- a/lib/view_models/dashboard_view_model_provider.dart +++ b/lib/view_models/dashboard_view_model_provider.dart @@ -131,21 +131,46 @@ class DashboardVMProvider extends BaseVM with WidgetsBindingObserver { final adVM = context.read(); final subscriptionsVM = context.read(); + // Set loading state immediately to prevent "No data" flash + adVM.setState(ViewState.busy); + appointmentVM.setState(ViewState.busy); + requestsVM.setState(ViewState.busy); + serviceVM.setState(ViewState.busy); + // ✅ Inject ViewModels into ChatVM (only needs to be done once, but safe to repeat) chatVM.setViewModels(requestsVM: requestsVM, adVM: adVM); - await requestsVM.populateDataForRequestsFilter(); - await requestsVM.populateDeliveryOptionEnums(); - await appointmentVM.populateAppointmentsFilterList(); - await adVM.populateAdsFilterList(); - await serviceVM.populateBranchServiceFilters(); - await serviceVM.getBranchAndServices(); - await requestsVM.getRequests(); - await subscriptionsVM.getSubscriptionBySP(AppState().getUser.data?.userInfo?.providerId.toString() ?? "", true); - + // Call independent filter population APIs in parallel + await Future.wait([ + requestsVM.populateDataForRequestsFilter(), + requestsVM.populateDeliveryOptionEnums(), + appointmentVM.populateAppointmentsFilterList(), + adVM.populateAdsFilterList(), + serviceVM.populateBranchServiceFilters(), + shippingManagementVM.populateShippingRequestFilterList(), + shippingManagementVM.populateSelfPickupRequestFilterList(), + adVM.getVehicleTypes(), + adVM.getVehicleAdsDuration(), + ]); + + // Call data APIs in parallel + await Future.wait([ + serviceVM.getBranchAndServices(), + requestsVM.getRequests(), + subscriptionsVM.getSubscriptionBySP(AppState().getUser.data?.userInfo?.providerId.toString() ?? "", true), + appointmentVM.applyFilterOnAppointmentsVMForProviders( + appointmentStatusEnum: AppointmentStatusEnum.allAppointments, + isNeedCustomerFilter: true, + shouldPopulateUpcoming: true, + ), + ]); + + // Call ads APIs in parallel (conditionally) if (dashboardRouteEnum != DashboardRouteEnum.fromAdsPayment && dashboardRouteEnum != DashboardRouteEnum.fromAdsSubmit && dashboardRouteEnum != DashboardRouteEnum.fromReserveAdsPayment) { - await adVM.getMyAds(); - await adVM.getExploreAds(); + await Future.wait([ + adVM.getMyAds(), + adVM.getExploreAds(), + ]); } // Handle reserve ads payment completion @@ -156,16 +181,7 @@ class DashboardVMProvider extends BaseVM with WidgetsBindingObserver { log("✅ Successfully navigated to Reserved Ads after payment"); } - await shippingManagementVM.populateShippingRequestFilterList(); - await shippingManagementVM.populateSelfPickupRequestFilterList(); - await appointmentVM.applyFilterOnAppointmentsVMForProviders( - appointmentStatusEnum: AppointmentStatusEnum.allAppointments, - isNeedCustomerFilter: true, - shouldPopulateUpcoming: true, - ); - - await adVM.getVehicleTypes(); - await adVM.getVehicleAdsDuration(); + // Build chat hub connection last await chatVM.buildHubConnection(context: context); } diff --git a/lib/view_models/subscriptions_view_model.dart b/lib/view_models/subscriptions_view_model.dart index 21a87de..642492b 100644 --- a/lib/view_models/subscriptions_view_model.dart +++ b/lib/view_models/subscriptions_view_model.dart @@ -85,7 +85,8 @@ class SubscriptionsVM extends BaseVM { } } - Future payForSubscription(int subscriptionId, bool isStartNow, bool isReview, String amount, {bool isDegrade = false, List? listOfBranches, List? listOfUsers}) async { + Future payForSubscription( + {required int subscriptionId, required bool isStartNow, required bool isRenew, required String amount, bool isDegrade = false, List? listOfBranches, List? listOfUsers}) async { Map map; if (isDegrade) { map = { @@ -95,7 +96,7 @@ class SubscriptionsVM extends BaseVM { "subscriptionID": subscriptionId.toString(), "isStartNow": isStartNow.toString(), "subscriptionAmount": amount, - "isRenew": isReview.toString(), + "isRenew": isRenew.toString(), "listOfBranches": listOfBranches, "listOfUsers": listOfUsers }; @@ -107,7 +108,7 @@ class SubscriptionsVM extends BaseVM { "subscriptionID": subscriptionId.toString(), "isStartNow": isStartNow.toString(), "subscriptionAmount": amount, - "isRenew": isReview.toString() + "isRenew": isRenew.toString() // "listOfBranches": [], // "listOfUsers": [] }; @@ -116,8 +117,14 @@ class SubscriptionsVM extends BaseVM { return genericRespModel; } - Future createSubscriptionOrder(int subscriptionId, bool isStartNow, bool isRenew, {bool isDegrade = false, List? listOfBranches, List? listOfUsers}) async { - Map map = {"providerID": AppState().getUser.data?.userInfo?.providerId.toString() ?? "", "subscriptionID": subscriptionId.toString(), "isStartNow": isStartNow.toString(), "isRenew": isRenew.toString()}; + Future createSubscriptionOrder( + {required int subscriptionId, required bool isStartNow, required bool isRenew, bool isDegrade = false, List? listOfBranches, List? listOfUsers}) async { + Map map = { + "providerID": AppState().getUser.data?.userInfo?.providerId.toString() ?? "", + "subscriptionID": subscriptionId.toString(), + "isStartNow": isStartNow.toString(), + "isRenew": isRenew.toString() + }; GenericRespModel genericRespModel = await subscriptionRepo.payForProviderSubscription(map); return genericRespModel; } @@ -190,9 +197,7 @@ class SubscriptionsVM extends BaseVM { mySubscriptionsBySp.clear(); setState(ViewState.busy); // allSubscriptions.data - print("====================== SUB ============="); for (var element in allSubscriptions.data!) { - print("SuBBB "+ element.subscriptionType.toString()); if (element.subscriptionTypeEnum == SubscriptionTypeEnum.current) { mySubscriptionsBySp.add(element); } diff --git a/lib/views/advertisement/ads_detail_view/ads_detail_view.dart b/lib/views/advertisement/ads_detail_view/ads_detail_view.dart index 90131c2..d8d66bd 100644 --- a/lib/views/advertisement/ads_detail_view/ads_detail_view.dart +++ b/lib/views/advertisement/ads_detail_view/ads_detail_view.dart @@ -148,7 +148,7 @@ class _AdsDetailViewState extends State { Row( children: [ ("${LocaleKeys.mileage.tr()}: ").toText(fontSize: 12, color: MyColors.lightTextColor), - "${widget.adDetails.vehicle!.mileage!.mileageEnd} ${LocaleKeys.km.tr()}".toText(fontSize: 12), + "${widget.adDetails.vehicle?.mileage?.mileageStart ?? ""} - ${widget.adDetails.vehicle?.mileage?.mileageEnd ?? ""} (${LocaleKeys.km.tr()})".toText(fontSize: 12), ], ), widget.adDetails.createdOn != null ? DateTime.parse(widget.adDetails.createdOn!).getTimeAgo().toText(fontSize: 10, color: MyColors.lightTextColor) : const SizedBox(), @@ -166,12 +166,14 @@ class _AdsDetailViewState extends State { "${widget.adDetails.vehicle!.odometer ?? 0} ${LocaleKeys.km.tr()}".toText(fontSize: 12), ], ), - Row( - children: [ - ("${LocaleKeys.vehicleCondition.tr()}: ").toText(fontSize: 12, color: MyColors.lightTextColor), - (widget.adDetails.vehicle!.isInUsed == 0 ? LocaleKeys.brandNew.tr() : LocaleKeys.used.tr()).toText(fontSize: 12), - ], - ), + if (widget.adDetails.vehicle!.condition != null && widget.adDetails.vehicle!.condition?.id != null) ...[ + Row( + children: [ + ("${LocaleKeys.vehicleCondition.tr()}: ").toText(fontSize: 12, color: MyColors.lightTextColor), + (widget.adDetails.vehicle!.condition?.id == 2 ? LocaleKeys.used.tr() : LocaleKeys.used.tr()).toText(fontSize: 12), + ], + ), + ], Row( children: [ ("${LocaleKeys.accidentFree.tr()}: ").toText(fontSize: 12, color: MyColors.lightTextColor), @@ -602,8 +604,8 @@ class _FavoriteAdButtonState extends State with SingleTickerPr bool success = await context.read().toggleAdFavorite( adsID: isFavorite && widget.adDetails.favouriteAdID != null - ? widget.adDetails.favouriteAdID! // Use favoriteAdsID when unfavoriting - : widget.adDetails.id!, // Use regular ad ID when favoriting + ? widget.adDetails.favouriteAdID! // Use favoriteAdsID when unfavoriting + : widget.adDetails.id!, // Use regular ad ID when favoriting isFavorite: isFavorite, ); @@ -679,7 +681,7 @@ class ShareAdButton extends StatelessWidget { // Vehicle details shareMessage += '${vehicle.vehicleTitle ?? ""}\n'; shareMessage += '${LocaleKeys.model.tr()}: ${vehicle.modelyear?.label ?? ""}\n'; - shareMessage += '${LocaleKeys.mileage.tr()}: ${vehicle.mileage?.mileageEnd ?? ""}\n'; + shareMessage += '${LocaleKeys.mileage.tr()}: ${vehicle.mileage?.mileageStart ?? ""} - ${vehicle.mileage?.mileageEnd ?? ""}\n'; shareMessage += '${LocaleKeys.price.tr()}: ${vehicle.demandAmount?.toInt()} ${vehicle.currency ?? ""}\n'; if (vehicle.cityName != null && vehicle.cityName!.isNotEmpty) { shareMessage += '${LocaleKeys.location.tr()}: ${vehicle.cityName}\n'; diff --git a/lib/views/advertisement/ads_filter_view.dart b/lib/views/advertisement/ads_filter_view.dart index dab1f1d..05ec994 100644 --- a/lib/views/advertisement/ads_filter_view.dart +++ b/lib/views/advertisement/ads_filter_view.dart @@ -315,6 +315,8 @@ class _AdsFilterViewState extends State { onChanged: (value) => adVM.onCurrentAdMobilePhoneFilterChanged(value), value: adVM.currentAdMobilePhoneFilter, hint: LocaleKeys.enterMobileNumber.tr(), + keyboardType: TextInputType.phone, + numbersOnly: true, postfixWidget: Consumer( builder: (BuildContext context, AdVM adVM, Widget? child) { if (adVM.currentAdMobilePhoneFilter.isEmpty) { diff --git a/lib/views/advertisement/components/ads_list_widget.dart b/lib/views/advertisement/components/ads_list_widget.dart index 129cd7c..dfcf988 100644 --- a/lib/views/advertisement/components/ads_list_widget.dart +++ b/lib/views/advertisement/components/ads_list_widget.dart @@ -341,11 +341,14 @@ class _AdCardState extends State { height: 18 / 12, ), 2.width, - (widget.adDetails.vehicle!.mileage!.mileageEnd ?? "").toText( - fontSize: 12, - letterSpacing: -0.48, - height: 18 / 12, - ), + Expanded( + child: "${widget.adDetails.vehicle?.mileage?.mileageStart ?? ""} - ${widget.adDetails.vehicle?.mileage?.mileageEnd ?? ""}km".toText( + overflow: TextOverflow.ellipsis, + fontSize: 12, + letterSpacing: -0.48, + height: 18 / 12, + ), + ) ], ), ], @@ -355,8 +358,8 @@ class _AdCardState extends State { crossAxisAlignment: CrossAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.start, children: [ - (widget.adDetails.vehicle!.cityName ?? "").toText(color: MyColors.lightTextColor, fontSize: 8), - widget.adDetails.createdOn != null ? DateTime.parse(widget.adDetails.createdOn!).getTimeAgo().toText(color: MyColors.lightTextColor, fontSize: 8) : const SizedBox(), + (widget.adDetails.vehicle!.cityName ?? "").toText(color: MyColors.lightTextColor, fontSize: 4), + widget.adDetails.createdOn != null ? DateTime.parse(widget.adDetails.createdOn!).getTimeAgo().toText(color: MyColors.lightTextColor, fontSize: 4) : const SizedBox(), ], ), ], diff --git a/lib/views/appointments/book_appointment_services_view.dart b/lib/views/appointments/book_appointment_services_view.dart index a8cf8e3..cd1940e 100644 --- a/lib/views/appointments/book_appointment_services_view.dart +++ b/lib/views/appointments/book_appointment_services_view.dart @@ -120,10 +120,15 @@ class BookAppointmentServicesView extends StatelessWidget { LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, fontSize: 16, isBold: true).paddingOnly(bottom: 5), const Icon(Icons.arrow_drop_down, size: 30) ], - ).onPress(() => appointmentsVM.priceBreakDownClicked(context, serviceData)), + ), ], ], - ).toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 10)); + ).toWhiteContainer( + width: double.infinity, + allPading: 12, + margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 10), + onTap: () => appointmentsVM.priceBreakDownClicked(context, serviceData), + ); }, ).expand(), Row( diff --git a/lib/views/appointments/widgets/appointment_service_pick_bottom_sheet.dart b/lib/views/appointments/widgets/appointment_service_pick_bottom_sheet.dart index 61257df..9fd67d6 100644 --- a/lib/views/appointments/widgets/appointment_service_pick_bottom_sheet.dart +++ b/lib/views/appointments/widgets/appointment_service_pick_bottom_sheet.dart @@ -78,9 +78,7 @@ class AppointmentServicePickBottomSheet extends StatelessWidget { if (element.categoryId == appointmentsVM.branchSelectedCategoryId.selectedId) { serviceCategories.add(DropValue( element.serviceProviderServiceId ?? 0, - isArabic - ? element.serviceDescriptionN! - : element.serviceDescription!, + isArabic ? element.serviceDescriptionN! : element.serviceDescription!, // element.serviceDescription!, "", )); @@ -218,7 +216,9 @@ class AppointmentServicePickBottomSheet extends StatelessWidget { appointmentsVM.currentServiceSelection!.rangePricePerKm.toString().toText(fontSize: 30, isBold: true), "${LocaleKeys.sar.tr()}/km".toText(fontSize: 15, isBold: true, color: MyColors.lightTextColor).paddingOnly(bottom: 5), ] else ...[ - (appointmentsVM.currentServiceSelection!.servicelocationInfo.homeChargesInCurrentService * appointmentsVM.currentServiceSelection!.servicelocationInfo.distanceToBranch) + // Calculate using rounded values so displayed math matches the result + (double.parse(appointmentsVM.currentServiceSelection!.servicelocationInfo.homeChargesInCurrentService.toStringAsFixed(2)) * + double.parse(appointmentsVM.currentServiceSelection!.servicelocationInfo.distanceToBranch.toStringAsFixed(2))) .toStringAsFixed(2) .toText( fontSize: 30, @@ -226,7 +226,7 @@ class AppointmentServicePickBottomSheet extends StatelessWidget { ), LocaleKeys.sar.tr().toText(fontSize: 15, isBold: true, color: MyColors.lightTextColor).paddingOnly(bottom: 5), 10.width, - ("(${(appointmentsVM.currentServiceSelection!.servicelocationInfo.homeChargesInCurrentService).toStringAsFixed(2)} ${LocaleKeys.sar.tr()} x ${appointmentsVM.currentServiceSelection!.servicelocationInfo.distanceToBranch.toStringAsFixed(2)} KMs )") + ("(${appointmentsVM.currentServiceSelection!.servicelocationInfo.homeChargesInCurrentService.toStringAsFixed(2)} ${LocaleKeys.sar.tr()} x ${appointmentsVM.currentServiceSelection!.servicelocationInfo.distanceToBranch.toStringAsFixed(2)} KMs )") .toText(fontSize: 13, color: MyColors.lightTextColor) .paddingOnly(bottom: 5), ], diff --git a/lib/views/requests/request_detail_page.dart b/lib/views/requests/request_detail_page.dart index 1de723c..ef55b0f 100644 --- a/lib/views/requests/request_detail_page.dart +++ b/lib/views/requests/request_detail_page.dart @@ -141,9 +141,7 @@ class RequestDetailPage extends StatelessWidget { }) { switch (requestStatus) { case RequestStatusEnum.submitted: - String chatButtonText = requestTypeEnum == RequestsTypeEnum.specialCarRequest - ? LocaleKeys.specialCarRequestChat.tr() - : LocaleKeys.sparePartRequestChat.tr(); + String chatButtonText = requestTypeEnum == RequestsTypeEnum.specialCarRequest ? LocaleKeys.specialCarRequestChat.tr() : LocaleKeys.sparePartRequestChat.tr(); return ShowFillButton( maxWidth: double.infinity, @@ -176,7 +174,7 @@ class RequestDetailPage extends StatelessWidget { if (status) { await requestVM.getRequests(isNeedToRebuild: true); pop(context); - } + } }, ); } @@ -303,16 +301,17 @@ class RequestDetailPage extends StatelessWidget { appBar: CustomAppBar( title: LocaleKeys.requestDetail.tr(), actions: [ - requestDetailPageArguments.requestModel.isChatted - ? Padding( - padding: const EdgeInsets.only(top: 8, bottom: 8, right: 21), - child: const Icon(Icons.messenger_outline_rounded, color: Colors.black, size: 18).toContainer( - borderRadius: 100, - borderColor: MyColors.lightGreyEFColor, - isEnabledBorder: true, - ), - ).onPress(() => onViewChatTapped(context)) - : const SizedBox(), + // requestDetailPageArguments.requestModel.isChatted + // ? + Padding( + padding: const EdgeInsets.only(top: 8, bottom: 8, right: 21), + child: const Icon(Icons.messenger_outline_rounded, color: Colors.black, size: 18).toContainer( + borderRadius: 100, + borderColor: MyColors.lightGreyEFColor, + isEnabledBorder: true, + ), + ).onPress(() => onViewChatTapped(context)) + // : const SizedBox(), ], ), body: SizedBox( diff --git a/lib/widgets/extensions/extensions_widget.dart b/lib/widgets/extensions/extensions_widget.dart index e869e20..0d49049 100644 --- a/lib/widgets/extensions/extensions_widget.dart +++ b/lib/widgets/extensions/extensions_widget.dart @@ -1,3 +1,5 @@ +import 'dart:developer'; + import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -382,15 +384,14 @@ extension BuildSVG on String? { this!, errorBuilder: (BuildContext context, Object obj, StackTrace? s) { return Container( - height: height, - width: width, - decoration: BoxDecoration(border: Border.all(color: MyColors.roundedCrossBgColor)), - child: Icon( - Icons.image_not_supported_outlined, - color: MyColors.roundedCrossBgColor, - size: width, - ), - ); + height: height, + width: width, + decoration: BoxDecoration(border: Border.all(color: MyColors.roundedCrossBgColor)), + child: const Icon( + Icons.image_not_supported_outlined, + color: MyColors.roundedCrossBgColor, + // size: width, + )); }, loadingBuilder: (BuildContext context, Widget? child, ImageChunkEvent? imageChunk) { if (imageChunk == null) {