From 7a93004fba7efd8af330ba63e2ee7816e4d7811d Mon Sep 17 00:00:00 2001 From: Aamir Date: Mon, 13 Jan 2025 09:36:24 +0300 Subject: [PATCH] changes --- assets/langs/ar-SA.json | 6 +- assets/langs/en-US.json | 5 +- lib/api/api_client.dart | 20 ++++- lib/classes/app_state.dart | 13 ++- lib/classes/consts.dart | 44 ++++++++++ lib/config/routes.dart | 82 ++++++++++++++++--- lib/generated/codegen_loader.g.dart | 14 +++- lib/generated/locale_keys.g.dart | 3 + lib/utils/utils.dart | 35 ++++++++ lib/view_models/ad_view_model.dart | 8 +- .../dashboard_view_model_customer.dart | 4 + lib/view_models/user_view_model.dart | 1 + .../ads_detail_view/components.dart | 4 +- .../ads_damage_part_pictures_sheet.dart | 29 ++++--- .../components/ads_list_widget.dart | 4 +- lib/views/common_fragments/ads_fragment.dart | 81 ++++++++++-------- .../common_fragments/requests_fragment.dart | 12 ++- lib/views/user/register_selection_page.dart | 13 +++ lib/widgets/extensions/extensions_widget.dart | 48 ++++++++++- 19 files changed, 347 insertions(+), 79 deletions(-) diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 5cb1115..54d73af 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -785,6 +785,8 @@ "tapToView": "انقر لعرض", "noServicesAvailableToCopy": "لا توجد خدمات متاحة في هذا الفرع لنسخها.", "copySelectedItems": "نسخ العناصر المحددة", - "companyNameMandatory": "اسم الشركة إلزامي" - + "companyNameMandatory": "اسم الشركة إلزامي", + "connectionProblem": "مشكلة في الاتصال", + "pleaseCheckConnection": "يرجى التحقق من اتصالك بالإنترنت والمحاولة مرة أخرى", + "ok": "نعم" } \ No newline at end of file diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 865ef94..aa9793b 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -783,5 +783,8 @@ "tapToView": "Tap to view", "noServicesAvailableToCopy": "There are no services available in this branch to copy.", "copySelectedItems": "Copy Selected Items", - "companyNameMandatory": "Company Name is mandatory" + "companyNameMandatory": "Company Name is mandatory", + "connectionProblem": "Connection Problem", + "pleaseCheckConnection": "Please check your internet connection and try again.", + "ok": "Ok" } \ No newline at end of file diff --git a/lib/api/api_client.dart b/lib/api/api_client.dart index b9da65b..333d3d1 100644 --- a/lib/api/api_client.dart +++ b/lib/api/api_client.dart @@ -4,15 +4,18 @@ import 'dart:developer'; import 'dart:io'; import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; import 'package:http/http.dart'; import 'package:http/io_client.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/exceptions/api_exception.dart'; import 'package:mc_common_app/main.dart'; import 'package:mc_common_app/models/user_models/refresh_token.dart'; import 'package:mc_common_app/models/user_models/user.dart'; import 'package:mc_common_app/utils/shared_prefrence.dart'; +import 'package:mc_common_app/utils/utils.dart'; typedef FactoryConstructor = U Function(dynamic); @@ -56,7 +59,8 @@ class APIError { } abstract class ApiClient { - Future postJsonForObject(FactoryConstructor factoryConstructor, String url, T jsonObject, {String? token, Map? queryParameters, Map? headers, int retryTimes = 0}); + Future postJsonForObject(FactoryConstructor factoryConstructor, String url, T jsonObject, + {String? token, Map? queryParameters, Map? headers, int retryTimes = 0}); Future postJsonForResponse(String url, T jsonObject, {String? token, Map? queryParameters, Map? headers, int retryTimes = 0}); @@ -67,7 +71,8 @@ abstract class ApiClient { class ApiClientImp implements ApiClient { @override - Future postJsonForObject(FactoryConstructor factoryConstructor, String url, T jsonObject, {String? token, Map? queryParameters, Map? headers, int retryTimes = 0}) async { + Future postJsonForObject(FactoryConstructor factoryConstructor, String url, T jsonObject, + {String? token, Map? queryParameters, Map? headers, int retryTimes = 0}) async { var headers0 = {'Accept': 'application/json'}; if (headers != null && headers.isNotEmpty) { headers0.addAll(headers); @@ -163,6 +168,10 @@ class ApiClientImp implements ApiClient { throw APIException(APIException.OTHER, arguments: e); } } on TimeoutException catch (e) { + BuildContext? context = navigatorKey.currentContext; + if (context != null) { + NoInternetDialog.show(context); + } throw APIException(APIException.TIMEOUT, arguments: e); } on ClientException catch (e) { if (retryTimes > 0) { @@ -193,7 +202,8 @@ class ApiClientImp implements ApiClient { Future _post(url, {Map? headers, body, Encoding? encoding}) => _withClient((client) => client.post(url, headers: headers, body: body, encoding: encoding)); @override - Future getJsonForObject(FactoryConstructor factoryConstructor, String url, {String? token, Map? queryParameters, Map? headers, int retryTimes = 0}) async { + Future getJsonForObject(FactoryConstructor factoryConstructor, String url, + {String? token, Map? queryParameters, Map? headers, int retryTimes = 0}) async { var headers0 = {'Accept': 'application/json'}; if (headers != null && headers.isNotEmpty) { headers0.addAll(headers); @@ -272,6 +282,10 @@ class ApiClientImp implements ApiClient { throw APIException(APIException.OTHER, arguments: e); } } on TimeoutException catch (e) { + final context = navigatorKey.currentContext; + if (context != null) { + NoInternetDialog.show(context); + } throw APIException(APIException.TIMEOUT, arguments: e); } on ClientException catch (e) { if (retryTimes > 0) { diff --git a/lib/classes/app_state.dart b/lib/classes/app_state.dart index 09ddd54..ce1bf3f 100644 --- a/lib/classes/app_state.dart +++ b/lib/classes/app_state.dart @@ -72,12 +72,21 @@ class AppState { _providerSubscription = value; } - - DropValue? _userRegisterCountrySelection ; + DropValue? _userRegisterCountrySelection; DropValue get getUserRegisterCountrySelection => _userRegisterCountrySelection!; set setUserRegisterCountrySelection(DropValue value) { _userRegisterCountrySelection = value; } + + bool _isViewOnly = false; + + bool get getIsViewOnly => _isViewOnly; + + set setIsViewOnly(bool value) { + _isViewOnly = value; + } + + } diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index 7f9ee48..2dcaa42 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'package:flutter/cupertino.dart'; import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/generated/codegen_loader.g.dart'; +import 'package:mc_common_app/models/user_models/user.dart'; import 'package:mc_common_app/utils/enums.dart'; class ApiConsts { @@ -408,3 +409,46 @@ class SignalrConsts { static String sendMessageGeneral = "SendMessageGeneral"; static String receiveMessageGeneral = "ReceiveMessageGeneral"; } + + + +class GuestConsts { + UserInfo userInfo = UserInfo.fromJson({ + "id": -1, + "userID": null, + "firstName": "Guest", + "lastName": "User", + "companyName": null, + "accountStatus": "2", + "activityStatus": "Offline", + "accountStatusText": null, + "subscriptionDate": null, + "mobileNo": "966123456789", + "email": "mowatter@gmail.com", + "userImageUrl": "https://ms.hmg.com/api/ProfileImage?imageName=User_Default.png", + "roleID": 4, + "roleName": "Customer", + "isEmailVerified": false, + "serviceProviderBranch": [], + "isVerified": true, + "userRoles": [], + "isProviderDealership": false, + "isProviderIndividual": false, + "isProvider": false, + "providerID": null, + "isCustomer": true, + "customerID": 25, + "countryID": 1, + "countryName": "Saudi Arabia", + "cityID": 1, + "cityName": "Riyadh", + "dealershipUserID": null, + "serviceProviderBranchID": null, + "createdOn": "2024-12-24T09:20:47.6733333", + "genderID": 1, + "genderName": "Male", + "serviceProviderPayment": [], + "deviceType": "1", + "deviceToken": null, + }); +} \ No newline at end of file diff --git a/lib/config/routes.dart b/lib/config/routes.dart index d23a216..e952d54 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -50,7 +50,11 @@ import 'package:mc_common_app/views/user/vertify_password_page.dart'; import 'package:flutter/material.dart'; import 'package:mc_common_app/widgets/image_viewer/image_viewer_screen.dart'; +final GlobalKey navigatorKey = GlobalKey(); + + class AppRoutes { + //User static const String splash = "/splash"; static const String registerSelection = "/registerSelection"; @@ -184,11 +188,27 @@ class AppRoutes { forgetPassword: (context) => const ForgetPasswordPage(), loginVerification: (context) => const LoginVerificationPage(), loginWithPassword: (context) => const LoginWithPassword(), - loginMethodSelection: (context) => LoginMethodSelectionPage(ModalRoute.of(context)!.settings.arguments as String), - completeProfile: (context) => CompleteProfilePage(ModalRoute.of(context)!.settings.arguments as RegisterUserRespModel), + loginMethodSelection: (context) => + LoginMethodSelectionPage(ModalRoute + .of(context)! + .settings + .arguments as String), + completeProfile: (context) => + CompleteProfilePage(ModalRoute + .of(context)! + .settings + .arguments as RegisterUserRespModel), verifyPassword: (context) => VerifyPasswordPage(), - confirmNewPasswordPage: (context) => ConfirmNewPasswordPage(ModalRoute.of(context)!.settings.arguments as String), - forgetPasswordMethodPage: (context) => ForgetPasswordMethodPage(ModalRoute.of(context)!.settings.arguments as String), + confirmNewPasswordPage: (context) => + ConfirmNewPasswordPage(ModalRoute + .of(context)! + .settings + .arguments as String), + forgetPasswordMethodPage: (context) => + ForgetPasswordMethodPage(ModalRoute + .of(context)! + .settings + .arguments as String), changeMobilePage: (context) => ChangeMobilePage(), changeEmailPage: (context) => const ChangeEmailPage(), updateUserDetails: (context) => const UpdateUserDetails(), @@ -201,30 +221,66 @@ class AppRoutes { providerLicensePage: (context) => const ProviderLicensePage(), // common pages - AppRoutes.adsDetailView: (context) => AdsDetailView(adDetails: ModalRoute.of(context)!.settings.arguments as AdDetailsModel), + AppRoutes.adsDetailView: (context) => + AdsDetailView(adDetails: ModalRoute + .of(context)! + .settings + .arguments as AdDetailsModel), AppRoutes.createAdView: (context) => const CreateAdView(), AppRoutes.adsFilterView: (context) => const AdsFilterView(), - AppRoutes.selectAdTypeView: (context) => SelectAdTypeView(arguments: ModalRoute.of(context)!.settings.arguments as List), - AppRoutes.chatView: (context) => ChatView(chatViewArguments: ModalRoute.of(context)!.settings.arguments as ChatViewArguments), - AppRoutes.adsBuyerChatsListView: (context) => AdsBuyerChatsView(buyersListViewArguments: ModalRoute.of(context)!.settings.arguments as List), + AppRoutes.selectAdTypeView: (context) => + SelectAdTypeView(arguments: ModalRoute + .of(context)! + .settings + .arguments as List), + AppRoutes.chatView: (context) => + ChatView(chatViewArguments: ModalRoute + .of(context)! + .settings + .arguments as ChatViewArguments), + AppRoutes.adsBuyerChatsListView: (context) => + AdsBuyerChatsView(buyersListViewArguments: ModalRoute + .of(context)! + .settings + .arguments as List), AppRoutes.settingOptionsFaqs: (context) => const SettingOptionsFAQs(), AppRoutes.settingOptionsContactUs: (context) => const SettingOptionsContactUs(), AppRoutes.settingOptionsAppInfo: (context) => const SettingOptionsAppInfo(), AppRoutes.settingOptionsTermsAndConditions: (context) => const SettingOptionsTermsAndConditions(), AppRoutes.settingOptionsInviteFriends: (context) => const SettingOptionsInviteFriends(), - AppRoutes.paymentMethodsView: (context) => PaymentMethodsView(paymentType: ModalRoute.of(context)!.settings.arguments as PaymentTypes), + AppRoutes.paymentMethodsView: (context) => + PaymentMethodsView(paymentType: ModalRoute + .of(context)! + .settings + .arguments as PaymentTypes), //Requests - AppRoutes.requestsDetailPage: (context) => RequestDetailPage(requestDetailPageArguments: ModalRoute.of(context)!.settings.arguments as RequestDetailPageArguments), + AppRoutes.requestsDetailPage: (context) => + RequestDetailPage(requestDetailPageArguments: ModalRoute + .of(context)! + .settings + .arguments as RequestDetailPageArguments), AppRoutes.createRequestPage: (context) => const CreateRequestPage(), - AppRoutes.offersListPage: (context) => OfferListPage(requestId: ModalRoute.of(context)!.settings.arguments as int), + AppRoutes.offersListPage: (context) => + OfferListPage(requestId: ModalRoute + .of(context)! + .settings + .arguments as int), AppRoutes.reviewRequestOffer: (context) => const ReviewRequestOffer(), AppRoutes.requestsFilterView: (context) => const RequestsFilterView(), //MediaViewer - AppRoutes.mediaViewerScreen: (context) => MediaViewerScreen(images: ModalRoute.of(context)!.settings.arguments as List), + AppRoutes.mediaViewerScreen: (context) => + MediaViewerScreen(images: ModalRoute + .of(context)! + .settings + .arguments as List), // ChatsList Provider - AppRoutes.generalChatsListForProvider: (context) => OfferListPage(requestId: ModalRoute.of(context)!.settings.arguments as int), + AppRoutes.generalChatsListForProvider: (context) => + OfferListPage(requestId: ModalRoute + .of(context)! + .settings + .arguments as int), //Shipping AppRoutes.shippingManagementView: (context) => const ShippingManagementView(), diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index 18d8869..5443d18 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -736,7 +736,7 @@ class CodegenLoader extends AssetLoader{ "ownerInformation": "معلومات المالك", "acceptedRequests": "الطلبات المقبولة", "specialRequestChat": "دردشة الطلب الخاص", - "companyName": "اسم الشركة *", + "companyName": "اسم الشركة", "noAvailableItems": "لا توجد عناصر متاحة.", "serviceDeliveryType": "نوع تقديم الخدمة", "noImagesToShow": "لا توجد صور للعرض", @@ -801,7 +801,10 @@ class CodegenLoader extends AssetLoader{ "tapToView": "انقر لعرض", "noServicesAvailableToCopy": "لا توجد خدمات متاحة في هذا الفرع لنسخها.", "copySelectedItems": "نسخ العناصر المحددة", - "companyNameMandatory": "اسم الشركة إلزامي" + "companyNameMandatory": "اسم الشركة إلزامي", + "connectionProblem": "مشكلة في الاتصال", + "pleaseCheckConnection": "يرجى التحقق من اتصالك بالإنترنت والمحاولة مرة أخرى", + "ok": "نعم" }; static const Map en_US = { "firstTimeLogIn": "First Time Log In", @@ -1519,7 +1522,7 @@ static const Map en_US = { "noItemsToShow": "There are no Items no show.", "acceptedRequests": "Accepted Requests", "specialRequestChat": "Special Request Chat", - "companyName": "Company Name *", + "companyName": "Company Name", "noAvailableItems": "There are no available items.", "serviceDeliveryType": "Service Delivery Type", "noImagesToShow": "No Images to Show", @@ -1588,7 +1591,10 @@ static const Map en_US = { "tapToView": "Tap to view", "noServicesAvailableToCopy": "There are no services available in this branch to copy.", "copySelectedItems": "Copy Selected Items", - "companyNameMandatory": "Company Name is mandatory" + "companyNameMandatory": "Company Name is mandatory", + "connectionProblem": "Connection Problem", + "pleaseCheckConnection": "Please check your internet connection and try again.", + "ok": "Ok" }; static const Map> mapLocales = {"ar_SA": ar_SA, "en_US": en_US}; } diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 16d573f..0db25d3 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -765,5 +765,8 @@ abstract class LocaleKeys { static const noServicesAvailableToCopy = 'noServicesAvailableToCopy'; static const copySelectedItems = 'copySelectedItems'; static const companyNameMandatory = 'companyNameMandatory'; + static const connectionProblem = 'connectionProblem'; + static const pleaseCheckConnection = 'pleaseCheckConnection'; + static const ok = 'ok'; } diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart index 0389b78..91d8710 100644 --- a/lib/utils/utils.dart +++ b/lib/utils/utils.dart @@ -4,6 +4,8 @@ import 'dart:typed_data'; 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/config/routes.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart'; import 'package:mc_common_app/utils/date_helper.dart'; @@ -693,3 +695,36 @@ class Utils { ); } } + +class NoInternetDialog { + static void show(BuildContext context) { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: const Text( + LocaleKeys.connectionProblem, + textAlign: TextAlign.center, + ), + content: const Text( + LocaleKeys.pleaseCheckConnection, + textAlign: TextAlign.center, + ), + actions: [ + ElevatedButton( + onPressed: () { + // // if (AppState().currentAppType == AppType.provider) { + // Navigator.of(context).pop(); + Navigator.of(context).pushNamedAndRemoveUntil(AppRoutes.registerSelection, (Route route) => true); + }, + child: const Text( + LocaleKeys.ok, + style: TextStyle(color: Colors.white), + ), + ), + ], + ); + }, + ); + } +} diff --git a/lib/view_models/ad_view_model.dart b/lib/view_models/ad_view_model.dart index 0cd6a00..065347c 100644 --- a/lib/view_models/ad_view_model.dart +++ b/lib/view_models/ad_view_model.dart @@ -1496,8 +1496,12 @@ class AdVM extends BaseVM { // } // } - Future onAdSSBookAppointmentPressed(BuildContext context, {required AdDetailsModel adDetailsModel, required int adsSpecialServiceID}) async { + Future onAdSSBookAppointmentPressed(BuildContext context, {required AdDetailsModel adDetailsModel}) async { bool isValidated = false; + int specialSServideId = 1; + if (adDetailsModel.specialservice != null && adDetailsModel.specialservice!.isNotEmpty) { + specialSServideId = adDetailsModel.specialservice!.first.specialServiceID ?? 1; + } if (selectedPhotoSSSchedulesByOffice.photoOfficeID == null) { isValidated = false; @@ -1523,7 +1527,7 @@ class AdVM extends BaseVM { adId: adDetailsModel.id ?? 0, photoOfficeID: photoOfficeSelectedId.selectedId, photoOfficeSlotID: selectedPhotoOfficeSlotDateTime ?? 0, - adsSpecialServiceID: adsSpecialServiceID, + adsSpecialServiceID: specialSServideId, ); Utils.hideLoading(context); diff --git a/lib/view_models/dashboard_view_model_customer.dart b/lib/view_models/dashboard_view_model_customer.dart index 2f4b7fc..3a47690 100644 --- a/lib/view_models/dashboard_view_model_customer.dart +++ b/lib/view_models/dashboard_view_model_customer.dart @@ -63,6 +63,10 @@ class DashboardVmCustomer extends BaseVM { AppointmentsVM appointmentsVM = Provider.of(context, listen: false); RequestsVM requestsVM = Provider.of(context, listen: false); ChatVM chatVM = Provider.of(context, listen: false); + + + + appointmentsVM.populateBranchesFilterList(); appointmentsVM.populateAppointmentsFilterList(); adVM.populateAdsFilterList(); diff --git a/lib/view_models/user_view_model.dart b/lib/view_models/user_view_model.dart index 24a983e..513208e 100644 --- a/lib/view_models/user_view_model.dart +++ b/lib/view_models/user_view_model.dart @@ -404,6 +404,7 @@ class UserVM extends BaseVM { } Future performBasicOtpLoginSelectionPage(BuildContext context, {required String userToken, required AppType appType, String? loginType}) async { + AppState().setIsViewOnly = false; log("loginType: $loginType"); if (loginType == "3" || loginType == "4") { //Utils.showLoading(context); diff --git a/lib/views/advertisement/ads_detail_view/components.dart b/lib/views/advertisement/ads_detail_view/components.dart index dc379f6..d1e8472 100644 --- a/lib/views/advertisement/ads_detail_view/components.dart +++ b/lib/views/advertisement/ads_detail_view/components.dart @@ -302,6 +302,8 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget { var element = adVM.photoSSSchedulesByOffices[i]; vehicleCitiesDrop.add(DropValue(element.photoOfficeID?.toInt() ?? 0, element.photoOfficeName ?? "", i.toString())); } + + print(adVM.photoOfficeSelectedId.selectedId); return DropdownField( (DropValue value) => adVM.updatePhotoOfficeSelectedId(SelectionModel(selectedId: value.id, selectedOption: value.value, itemPrice: value.subValue)), list: vehicleCitiesDrop, @@ -345,7 +347,7 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget { title: LocaleKeys.bookAndPay.tr(), fontSize: 15, onPressed: () { - adVM.onAdSSBookAppointmentPressed(context, adDetailsModel: adDetailsModel, adsSpecialServiceID: 1); //1 for photography Service + adVM.onAdSSBookAppointmentPressed(context, adDetailsModel: adDetailsModel); }, ), ), diff --git a/lib/views/advertisement/bottom_sheets/ads_damage_part_pictures_sheet.dart b/lib/views/advertisement/bottom_sheets/ads_damage_part_pictures_sheet.dart index af3352d..fc685cf 100644 --- a/lib/views/advertisement/bottom_sheets/ads_damage_part_pictures_sheet.dart +++ b/lib/views/advertisement/bottom_sheets/ads_damage_part_pictures_sheet.dart @@ -35,19 +35,26 @@ class _AdDamagePartPicturesSheetState extends State { } void populateDamagePartPictures() { - for (var element in widget.adDamageReportList) { - ImageModel imageModel = ImageModel(id: element.id!, filePath: element.imageUrl!, isFromNetwork: true); + List adDamageReportList = widget.adDamageReportList; // Assuming this is your data source. + Map groupedDamageCards = {}; - VehicleDamageCard vehicleDamageCard = VehicleDamageCard( - partSelectedId: SelectionModel( - selectedId: element.vehicleDamagePartID!, - selectedOption: element.partName ?? "", - ), - damagePartDescription: element.comment ?? "", - partImages: [imageModel], - ); - vehicleDamageCards.add(vehicleDamageCard); + for (var element in adDamageReportList) { + String partName = element.partName ?? "Unknown"; + ImageModel imageModel = ImageModel(id: element.id!, filePath: element.imageUrl!, isFromNetwork: true); + if (groupedDamageCards.containsKey(partName)) { + groupedDamageCards[partName]!.partImages!.add(imageModel); + } else { + groupedDamageCards[partName] = VehicleDamageCard( + partSelectedId: SelectionModel( + selectedId: element.vehicleDamagePartID!, + selectedOption: partName, + ), + damagePartDescription: element.comment ?? "", + partImages: [imageModel]); + } } + + vehicleDamageCards = groupedDamageCards.values.toList(); setState(() {}); } diff --git a/lib/views/advertisement/components/ads_list_widget.dart b/lib/views/advertisement/components/ads_list_widget.dart index d3fce48..6d6c03d 100644 --- a/lib/views/advertisement/components/ads_list_widget.dart +++ b/lib/views/advertisement/components/ads_list_widget.dart @@ -64,7 +64,9 @@ class AdsListWidget extends StatelessWidget { adDetails: adsList[index], isAdsFragment: isAdsFragment, shouldShowAdStatus: shouldShowAdStatus, - ).onPress(() => navigateWithName(context, AppRoutes.adsDetailView, arguments: adsList[index])); + ).onPress(() => navigateWithName(context, AppRoutes.adsDetailView, arguments: adsList[index])).toViewOnly(context, onTap: () { + navigateWithName(context, AppRoutes.loginWithPassword); + }); }, separatorBuilder: (BuildContext context, int index) { return 12.height; diff --git a/lib/views/common_fragments/ads_fragment.dart b/lib/views/common_fragments/ads_fragment.dart index df84976..55641d7 100644 --- a/lib/views/common_fragments/ads_fragment.dart +++ b/lib/views/common_fragments/ads_fragment.dart @@ -58,7 +58,9 @@ class AdsFragment extends StatelessWidget { navigateWithName(context, AppRoutes.adsFilterView); }) ], - ), + ).toViewOnly(context, onTap: () { + navigateWithName(context, AppRoutes.loginWithPassword); + }), body: SizedBox( width: double.infinity, height: double.infinity, @@ -89,8 +91,8 @@ class AdsFragment extends StatelessWidget { }, ), ), - 12.width, - Expanded( + if(!AppState().getIsViewOnly) 12.width, + if(!AppState().getIsViewOnly) Expanded( child: ShowFillButton( isFilled: !adVM.isExploreAdsTapped, txtColor: !adVM.isExploreAdsTapped ? MyColors.white : MyColors.darkTextColor, @@ -115,16 +117,17 @@ class AdsFragment extends StatelessWidget { needLeftPadding: false, ).paddingOnly(left: 21), ] - ] else ...[ - 16.height, - FiltersList( - filterList: adVM.myAdsFilterOptions, - onFilterTapped: (index, selectedFilterId) { - adVM.applyFilterOnMyAds(adPostStatusEnum: selectedFilterId.toAdPostEnum()); - }, - needLeftPadding: false, - ).paddingOnly(left: 21), - ], + ] else + ...[ + 16.height, + FiltersList( + filterList: adVM.myAdsFilterOptions, + onFilterTapped: (index, selectedFilterId) { + adVM.applyFilterOnMyAds(adPostStatusEnum: selectedFilterId.toAdPostEnum()); + }, + needLeftPadding: false, + ).paddingOnly(left: 21), + ], ], ); }, @@ -134,38 +137,46 @@ class AdsFragment extends StatelessWidget { child: RefreshIndicator( onRefresh: () async { if (adVM.isExploreAdsTapped) { - int vehicleBrandId = adVM.exploreAdsFilterOptions.firstWhere((element) => element.isSelected).id; + int vehicleBrandId = adVM.exploreAdsFilterOptions + .firstWhere((element) => element.isSelected) + .id; adVM.applyFilterOnExploreAds(vehicleBrandId: vehicleBrandId); } else { - AdPostStatus adPostStatusEnum = adVM.myAdsFilterOptions.firstWhere((element) => element.isSelected).id.toAdPostEnum(); + AdPostStatus adPostStatusEnum = adVM.myAdsFilterOptions + .firstWhere((element) => element.isSelected) + .id + .toAdPostEnum(); adVM.applyFilterOnMyAds(adPostStatusEnum: adPostStatusEnum); } }, child: adVM.state == ViewState.busy ? const Center(child: CircularProgressIndicator()) : AdsListWidget( - isAdsFragment: true, - shouldShowAdStatus: !adVM.isExploreAdsTapped, - adsList: getAdsList(adVM), - hasMoreData: adVM.isExploreAdsTapped ? adVM.hasMoreDataForExploreAds : adVM.hasMoreDataForMyAds, - onFetchMoreAds: () async { - AdPostStatus adPostStatusEnum = adVM.myAdsFilterOptions.firstWhere((element) => element.isSelected).id.toAdPostEnum(); + isAdsFragment: true, + shouldShowAdStatus: !adVM.isExploreAdsTapped, + adsList: getAdsList(adVM), + hasMoreData: adVM.isExploreAdsTapped ? adVM.hasMoreDataForExploreAds : adVM.hasMoreDataForMyAds, + onFetchMoreAds: () async { + AdPostStatus adPostStatusEnum = adVM.myAdsFilterOptions + .firstWhere((element) => element.isSelected) + .id + .toAdPostEnum(); - if (adVM.isExploreAdsTapped) { - await adVM.fetchMoreExploreAds(); - } else { - await adVM.fetchMoreMyAds(adsStatus: adPostStatusEnum); - } - }, - ), + if (adVM.isExploreAdsTapped) { + await adVM.fetchMoreExploreAds(); + } else { + await adVM.fetchMoreMyAds(adsStatus: adPostStatusEnum); + } + }, + ), ), ), if (adVM.isLoadingMore) ...[ const Center( child: Padding( - padding: EdgeInsets.all(8.0), - child: CircularProgressIndicator(), - )) + padding: EdgeInsets.all(8.0), + child: CircularProgressIndicator(), + )) ] ], ), @@ -185,11 +196,15 @@ class AdsFragment extends StatelessWidget { } } - navigateWithName(context, AppRoutes.selectAdTypeView, arguments: [injector.get().currentAppType == AppType.provider, false, -1]); + navigateWithName(context, AppRoutes.selectAdTypeView, arguments: [injector + .get() + .currentAppType == AppType.provider, false, -1]); }, backgroundColor: MyColors.darkPrimaryColor, child: const Icon(Icons.add, color: MyColors.white), - ), + ).toViewOnly(context, onTap: () { + navigateWithName(context, AppRoutes.loginWithPassword); + }), ); }, ); diff --git a/lib/views/common_fragments/requests_fragment.dart b/lib/views/common_fragments/requests_fragment.dart index a1f397a..8a00940 100644 --- a/lib/views/common_fragments/requests_fragment.dart +++ b/lib/views/common_fragments/requests_fragment.dart @@ -94,7 +94,9 @@ class MyRequestsFragment extends StatelessWidget { navigateWithName(context, AppRoutes.requestsFilterView); }) ], - ), + ).toViewOnly(context, onTap: () { + navigateWithName(context, AppRoutes.loginWithPassword); + }), body: Container( color: MyColors.backgroundColor, width: double.infinity, @@ -175,7 +177,9 @@ class MyRequestsFragment extends StatelessWidget { requestsVM.notifyListeners(); navigateWithName(context, AppRoutes.offersListPage, arguments: request.id); } - }), + }).toViewOnly(context, onTap: () { + navigateWithName(context, AppRoutes.loginWithPassword); + }), ); }, separatorBuilder: (context, index) { @@ -196,7 +200,9 @@ class MyRequestsFragment extends StatelessWidget { Icons.add, color: MyColors.white, ), - ) + ).toViewOnly(context, onTap: () { + navigateWithName(context, AppRoutes.loginWithPassword); + }) : null, ); }); diff --git a/lib/views/user/register_selection_page.dart b/lib/views/user/register_selection_page.dart index bf139e9..ef47cde 100644 --- a/lib/views/user/register_selection_page.dart +++ b/lib/views/user/register_selection_page.dart @@ -7,6 +7,7 @@ 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/user_models/user.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'; @@ -90,6 +91,18 @@ class _RegisterSelectionPageState extends State { } }, ), + + 20.height, + ShowFillButton( + title: "Guest View", + maxWidth: double.infinity, + horizontalMargin: 20, + onPressed: () { + appState.setIsViewOnly = true; + AppState().setUser = User(data: UserData(userInfo: GuestConsts().userInfo, accessToken: null, expiryDate: DateTime.now())); + navigateReplaceWithName(context, AppRoutes.dashboard); + }, + ), 10.height, Utils.mFlex(3), // TextButton( diff --git a/lib/widgets/extensions/extensions_widget.dart b/lib/widgets/extensions/extensions_widget.dart index 4bdc8b5..e63091b 100644 --- a/lib/widgets/extensions/extensions_widget.dart +++ b/lib/widgets/extensions/extensions_widget.dart @@ -1,6 +1,7 @@ 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/app_state.dart'; import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/main.dart'; import 'package:mc_common_app/theme/colors.dart'; @@ -25,7 +26,8 @@ extension ExtendedText on Widget { } extension ContainerExt on Widget { - Widget toWhiteContainer({required double width, double? allPading, EdgeInsets? pading, EdgeInsets? margin, VoidCallback? onTap, Color? backgroundColor, bool isBorderRequired = false, double borderRadius = 0}) { + Widget toWhiteContainer( + {required double width, double? allPading, EdgeInsets? pading, EdgeInsets? margin, VoidCallback? onTap, Color? backgroundColor, bool isBorderRequired = false, double borderRadius = 0}) { return InkWell( onTap: onTap, child: Container( @@ -234,7 +236,8 @@ extension WidgetExt on Widget { ); } - Widget paddingOnly({double left = 0.0, double right = 0.0, double top = 0.0, double bottom = 0.0}) => Padding(padding: EdgeInsets.only(left: left, right: right, top: top, bottom: bottom), child: this); + Widget paddingOnly({double left = 0.0, double right = 0.0, double top = 0.0, double bottom = 0.0}) => + Padding(padding: EdgeInsets.only(left: left, right: right, top: top, bottom: bottom), child: this); // Widget onTap(VoidCallback onTap, {double corners = 0}) { // return Clickable.widget(child: this, corners: corners, onTap: onTap); @@ -407,10 +410,49 @@ extension BuildSVG on String? { extension LocaleSetup on MultiProvider { Widget setupLocale() { - return EasyLocalization(supportedLocales: MyLocales.supportedLocales, fallbackLocale: MyLocales.fallBackLocale, startLocale: MyLocales.startLocale, assetLoader: MyLocales.assetLoader, path: MyLocales.localesAssetPath, child: this); + return EasyLocalization( + supportedLocales: MyLocales.supportedLocales, + fallbackLocale: MyLocales.fallBackLocale, + startLocale: MyLocales.startLocale, + assetLoader: MyLocales.assetLoader, + path: MyLocales.localesAssetPath, + child: this); } } extension WidgetExtensions on Widget { Widget onPress(VoidCallback onTap) => InkWell(onTap: onTap, child: this); } + +extension ViewOnlyExtension on Widget { + Widget toViewOnly(BuildContext context, {required Function() onTap}) { + return GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: () { + if (AppState().getIsViewOnly) { + onTap(); + } + }, + child: AbsorbPointer(absorbing: AppState().getIsViewOnly, child: this)); + } +} + +extension PreferredSizeWidgetViewOnlyExtension on PreferredSizeWidget { + PreferredSizeWidget toViewOnly(BuildContext context, {required Function() onTap}) { + return PreferredSize( + preferredSize: this.preferredSize, + child: GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: () { + if (AppState().getIsViewOnly) { + onTap(); + } + }, + child: AbsorbPointer( + absorbing: AppState().getIsViewOnly, + child: this, + ), + ), + ); + } +}