From ee4e7a7c2b78ba66d05634a85925c2501a0067d2 Mon Sep 17 00:00:00 2001 From: Faiz Hashmi Date: Wed, 30 Oct 2024 18:03:39 +0300 Subject: [PATCH] Bug Fixed --- assets/langs/ar-SA.json | 9 +- assets/langs/en-US.json | 9 +- lib/config/dependency_injection.dart | 2 + lib/generated/codegen_loader.g.dart | 18 ++- lib/generated/locale_keys.g.dart | 8 +- .../advertisment_models/ad_details_model.dart | 59 +++++---- lib/models/user_models/user.dart | 5 + lib/repositories/ads_repo.dart | 4 +- lib/repositories/branch_repo.dart | 12 +- lib/utils/location/Location.dart | 44 +++++-- lib/utils/utils.dart | 5 +- lib/view_models/ad_view_model.dart | 4 + lib/view_models/appointments_view_model.dart | 36 ++++-- .../dashboard_view_model_provider.dart | 12 +- lib/view_models/requests_view_model.dart | 22 +++- lib/view_models/service_view_model.dart | 29 +++-- lib/view_models/subscriptions_view_model.dart | 6 +- .../ads_detail_view/ads_detail_view.dart | 24 +--- .../ads_detail_view/components.dart | 4 +- .../ads_damage_part_pictures_sheet.dart | 19 ++- .../damage_pictures_bottom_sheet.dart | 2 +- .../book_appointment_services_view.dart | 18 +-- .../book_appointments_item_view.dart | 2 +- lib/views/chat/chat_view.dart | 1 + .../location_views/map_selection_widget.dart | 16 ++- .../location_views/pick_location_page.dart | 24 ++-- lib/views/requests/create_request_page.dart | 28 +++-- lib/views/requests/offer_list_page.dart | 7 +- lib/views/requests/request_bottomsheets.dart | 8 +- lib/views/requests/request_detail_page.dart | 64 +++++----- lib/views/requests/review_request_offer.dart | 116 ++++++++++++++++-- .../provider_license_page.dart | 104 +++++++++------- .../setting_options/setting_options_more.dart | 5 +- .../common_widgets/branch_details_card.dart | 17 +-- lib/widgets/dropdown/dropdow_field.dart | 2 +- 35 files changed, 492 insertions(+), 253 deletions(-) diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 5324a6f..995b20f 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -242,6 +242,7 @@ "payLater": "ادفع لاحقًا", "complete": "اكتمل", "makeAnOffer": "قدم عرضًا", + "provideOffer": "تقديم العرض", "enterAmount": "أدخل المبلغ", "submit": "إرسال", "viewChat": "عرض الدردشة", @@ -515,7 +516,6 @@ "itemsSelected": "العناصر المحددة", "workshopFullAccessServices": "بعض الخدمات غير متوفرة في الموقع المنزلي. قم بتغيير الموقع إلى ورشة العمل للوصول الكامل إلى الخدمات", "changeLocationService": "تغيير الموقع أو الخدمة:", - "noItemstoShow": "لا توجد عناصر لعرضها.", "someDescriptionSubServices": "بعض الوصف عن الخدمات الفرعية", "selectServicesYouWant": "اختر الخدمات التي تريدها", "selectServiceType": "اختر نوع الخدمة", @@ -680,5 +680,10 @@ "noFAQsToShow": "لا توجد أسئلة شائعة في الوقت الحالي. يرجى الاتصال بنا إذا كان لديك أي استفسار.", "appInfo": "معلومات التطبيق", "users": "المستخدمين", - "adsRemaining": "الإعلانات المتبقية" + "adsRemaining": "الإعلانات المتبقية", + "attachPDF": "إرفاق PDF", + "noItemsToShow": "لا توجد عناصر لعرضها.", + "serviceItem": "عنصر الخدمة", + "createdBy": "تم الإنشاء بواسطة", + "createGroupServices": "إنشاء خدمات المجموعة" } \ No newline at end of file diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 0158029..f73f875 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -242,6 +242,7 @@ "payLater": "Pay Later", "complete": "Complete", "makeAnOffer": "Make an offer", + "provideOffer": "Provider Offer", "enterAmount": "Enter amount", "submit": "Submit", "viewChat": "View Chat", @@ -516,7 +517,6 @@ "itemsSelected": "Item(s) Selected", "workshopFullAccessServices": "Few services are not available on home location. Change the location to workshop to full access the services", "changeLocationService": "Change location or service:", - "noItemstoShow": "No Items to show.", "someDescriptionSubServices": "Some description about the sub-services", "selectServicesYouWant": "Select services you want", "selectServiceType": "Select service type", @@ -678,5 +678,10 @@ "noFAQsToShow": "There are no Frequently asked Questions Right now. Please contact us if you have any query.", "appInfo": "App Info", "users": "Users", - "adsRemaining": "Ads Remaining" + "adsRemaining": "Ads Remaining", + "attachPDF": "Attach PDF", + "noItemsToShow": "No Items to show.", + "serviceItem" : "Service Item", + "createdBy" : "Created By", + "createGroupServices": "Create Group Services" } \ No newline at end of file diff --git a/lib/config/dependency_injection.dart b/lib/config/dependency_injection.dart index 8a42acd..970a88a 100644 --- a/lib/config/dependency_injection.dart +++ b/lib/config/dependency_injection.dart @@ -18,6 +18,7 @@ import 'package:mc_common_app/repositories/user_repo.dart'; import 'package:mc_common_app/services/common_services.dart'; import 'package:mc_common_app/services/firebase_service.dart'; import 'package:mc_common_app/services/payments_service.dart'; +import 'package:mc_common_app/utils/location/Location.dart'; import '../repositories/request_repo.dart'; @@ -30,6 +31,7 @@ class AppDependencies { injector.registerSingleton(() => ApiClientImp()); injector.registerSingleton(() => CommonServicesImp()); injector.registerSingleton(() => PaymentServiceImp()); + injector.registerSingleton(() => LocationService()); injector.registerSingleton(() => FirebaseMessagingServiceImp( firebaseMessaging: FirebaseMessaging.instance, flutterLocalNotifications: FlutterLocalNotificationsPlugin(), diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index c1bc3ca..02e47a3 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -258,6 +258,7 @@ class CodegenLoader extends AssetLoader{ "payLater": "ادفع لاحقًا", "complete": "اكتمل", "makeAnOffer": "قدم عرضًا", + "provideOffer": "تقديم العرض", "enterAmount": "أدخل المبلغ", "submit": "إرسال", "viewChat": "عرض الدردشة", @@ -531,7 +532,6 @@ class CodegenLoader extends AssetLoader{ "itemsSelected": "العناصر المحددة", "workshopFullAccessServices": "بعض الخدمات غير متوفرة في الموقع المنزلي. قم بتغيير الموقع إلى ورشة العمل للوصول الكامل إلى الخدمات", "changeLocationService": "تغيير الموقع أو الخدمة:", - "noItemstoShow": "لا توجد عناصر لعرضها.", "someDescriptionSubServices": "بعض الوصف عن الخدمات الفرعية", "selectServicesYouWant": "اختر الخدمات التي تريدها", "selectServiceType": "اختر نوع الخدمة", @@ -696,7 +696,12 @@ class CodegenLoader extends AssetLoader{ "noFAQsToShow": "لا توجد أسئلة شائعة في الوقت الحالي. يرجى الاتصال بنا إذا كان لديك أي استفسار.", "appInfo": "معلومات التطبيق", "users": "المستخدمين", - "adsRemaining": "الإعلانات المتبقية" + "adsRemaining": "الإعلانات المتبقية", + "attachPDF": "إرفاق PDF", + "noItemsToShow": "لا توجد عناصر لعرضها.", + "serviceItem": "عنصر الخدمة", + "createdBy": "تم الإنشاء بواسطة", + "createGroupServices": "إنشاء خدمات المجموعة" }; static const Map en_US = { "firstTimeLogIn": "First Time Log In", @@ -942,6 +947,7 @@ static const Map en_US = { "payLater": "Pay Later", "complete": "Complete", "makeAnOffer": "Make an offer", + "provideOffer": "Provider Offer", "enterAmount": "Enter amount", "submit": "Submit", "viewChat": "View Chat", @@ -1216,7 +1222,6 @@ static const Map en_US = { "itemsSelected": "Item(s) Selected", "workshopFullAccessServices": "Few services are not available on home location. Change the location to workshop to full access the services", "changeLocationService": "Change location or service:", - "noItemstoShow": "No Items to show.", "someDescriptionSubServices": "Some description about the sub-services", "selectServicesYouWant": "Select services you want", "selectServiceType": "Select service type", @@ -1378,7 +1383,12 @@ static const Map en_US = { "noFAQsToShow": "There are no Frequently asked Questions Right now. Please contact us if you have any query.", "appInfo": "App Info", "users": "Users", - "adsRemaining": "Ads Remaining" + "adsRemaining": "Ads Remaining", + "attachPDF": "Attach PDF", + "noItemsToShow": "No Items to show.", + "serviceItem": "Service Item", + "createdBy": "Created By", + "createGroupServices": "Create Group Services" }; 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 77e667d..a0a0423 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -222,6 +222,7 @@ abstract class LocaleKeys { static const payLater = 'payLater'; static const complete = 'complete'; static const makeAnOffer = 'makeAnOffer'; + static const provideOffer = 'provideOffer'; static const enterAmount = 'enterAmount'; static const submit = 'submit'; static const viewChat = 'viewChat'; @@ -494,7 +495,6 @@ abstract class LocaleKeys { static const itemsSelected = 'itemsSelected'; static const workshopFullAccessServices = 'workshopFullAccessServices'; static const changeLocationService = 'changeLocationService'; - static const noItemstoShow = 'noItemstoShow'; static const someDescriptionSubServices = 'someDescriptionSubServices'; static const selectServicesYouWant = 'selectServicesYouWant'; static const selectServiceType = 'selectServiceType'; @@ -660,5 +660,11 @@ abstract class LocaleKeys { static const appInfo = 'appInfo'; static const users = 'users'; static const adsRemaining = 'adsRemaining'; + static const attachPDF = 'attachPDF'; + static const noItemsToShow = 'noItemsToShow'; + static const serviceItem = 'serviceItem'; + static const createdBy = 'createdBy'; + static const createGroupServices = 'createGroupServices'; + } diff --git a/lib/models/advertisment_models/ad_details_model.dart b/lib/models/advertisment_models/ad_details_model.dart index 29881a3..f239903 100644 --- a/lib/models/advertisment_models/ad_details_model.dart +++ b/lib/models/advertisment_models/ad_details_model.dart @@ -134,11 +134,11 @@ class AdDetailsModel { priceExcludingDiscount = json['priceExcludingDiscount']; reservePrice = json['reservePrice']; isMCHandled = json['isMCHandled']; - modifiedOn = json['modifiedOn']; - phoneNo = json['phoneNo']; - whatsAppNo = json['whatsAppNo']; + modifiedOn = json['modifiedOn']; + phoneNo = json['vehicle'] != null ? (json['vehicle']['mobileNo'] ?? "") : ""; + whatsAppNo = json['vehicle'] != null ? (json['vehicle']['whatsAppNo'] ?? "") : ""; + warrantyYears = json['vehicle'] != null ? (json['vehicle']['warantyYears'] != null ? ((json['vehicle']['warantyYears']).toString()) : "") : ""; adOwnerName = json['adOwnerName'] ?? ""; - warrantyYears = json['warantyYears'] ?? ""; adPostStatus = (json['statusID'] as int).toAdPostEnum(); adReserveStatus = AdReserveStatus.defaultStatus; createdByRoleEnum = (json['createdByRole'] as int).toCreatedByRoleEnum(); @@ -174,32 +174,31 @@ class Vehicle { int? countryID; String? currency; - Vehicle( - {this.id, - this.cityID, - this.cityName, - this.demandAmount, - this.isActive, - this.isFinanceAvailable, - this.status, - this.statustext, - this.category, - this.color, - this.condition, - this.mileage, - this.model, - this.modelyear, - this.sellertype, - this.transmission, - this.duration, - this.image, - this.damagereport, - this.vehicleDescription, - this.vehicleTitle, - this.vehicleType, - this.vehicleVIN, - this.countryID, - this.currency}); + Vehicle({this.id, + this.cityID, + this.cityName, + this.demandAmount, + this.isActive, + this.isFinanceAvailable, + this.status, + this.statustext, + this.category, + this.color, + this.condition, + this.mileage, + this.model, + this.modelyear, + this.sellertype, + this.transmission, + this.duration, + this.image, + this.damagereport, + this.vehicleDescription, + this.vehicleTitle, + this.vehicleType, + this.vehicleVIN, + this.countryID, + this.currency}); Vehicle.fromJson(Map json) { id = json['id']; diff --git a/lib/models/user_models/user.dart b/lib/models/user_models/user.dart index 049ca47..1efe6db 100644 --- a/lib/models/user_models/user.dart +++ b/lib/models/user_models/user.dart @@ -187,4 +187,9 @@ class UserInfo { "customerID": customerId, "dealershipID": dealershipId, }; + + @override + String toString() { + return 'UserInfo{id: $id, userId: $userId, firstName: $firstName, lastName: $lastName, mobileNo: $mobileNo, email: $email, userImageUrl: $userImageUrl, roleId: $roleId, roleName: $roleName, isEmailVerified: $isEmailVerified, serviceProviderBranch: $serviceProviderBranch, isVerified: $isVerified, userRoles: $userRoles, isCustomer: $isCustomer, isProviderDealership: $isProviderDealership, isDealershipUser: $isDealershipUser, providerId: $providerId, customerId: $customerId, dealershipId: $dealershipId, userLocalImage: $userLocalImage}'; + } } diff --git a/lib/repositories/ads_repo.dart b/lib/repositories/ads_repo.dart index 4a8b868..39ce5a6 100644 --- a/lib/repositories/ads_repo.dart +++ b/lib/repositories/ads_repo.dart @@ -124,7 +124,9 @@ class AdsRepoImp implements AdsRepo { "demandAmount": adsCreationPayloadModel.vehiclePosting!.demandAmount, // "adStatus": 1, "vehiclePostingImages": vehiclePostingImages, - "vehiclePostingDamageParts": vehiclePostingDamageParts + "vehiclePostingDamageParts": vehiclePostingDamageParts, + "mobileNo": adsCreationPayloadModel.vehiclePosting!.phoneNo, + "whatsAppNo": adsCreationPayloadModel.vehiclePosting!.whatsAppNo, } }; diff --git a/lib/repositories/branch_repo.dart b/lib/repositories/branch_repo.dart index ebfaaed..ba2ede7 100644 --- a/lib/repositories/branch_repo.dart +++ b/lib/repositories/branch_repo.dart @@ -81,7 +81,7 @@ abstract class BranchRepo { Future addNewServicesInAppointment(Map map); - Future> getAllNearBranchAndServices(); + Future> getAllNearBranchAndServices({required double latitude, required double longitude}); Future> getServiceItems(int serviceId); @@ -362,10 +362,12 @@ class BranchRepoImp implements BranchRepo { } @override - Future> getAllNearBranchAndServices() async { + Future> getAllNearBranchAndServices({required double latitude, required double longitude}) async { var queryParameters = { "isActive": "true", "Status": "3", + "latitude": latitude.toString(), + "longitude": longitude.toString(), }; GenericRespModel adsGenericModel = await apiClient.getJsonForObject( (json) => GenericRespModel.fromJson(json), @@ -379,7 +381,11 @@ class BranchRepoImp implements BranchRepo { @override Future> getMyRecentBranchesWithServices() async { - GenericRespModel adsGenericModel = await apiClient.getJsonForObject((json) => GenericRespModel.fromJson(json), ApiConsts.getMyRecentBranches, token: appState.getUser.data!.accessToken); + GenericRespModel adsGenericModel = await apiClient.getJsonForObject( + (json) => GenericRespModel.fromJson(json), + ApiConsts.getMyRecentBranches, + token: appState.getUser.data!.accessToken, + ); List recentBranches = List.generate(adsGenericModel.data.length, (index) => BranchDetailModel.fromJson(adsGenericModel.data[index])); return recentBranches; } diff --git a/lib/utils/location/Location.dart b/lib/utils/location/Location.dart index bdb67b4..0b08abe 100644 --- a/lib/utils/location/Location.dart +++ b/lib/utils/location/Location.dart @@ -7,17 +7,29 @@ import 'package:flutter/rendering.dart'; import 'package:geolocator/geolocator.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/utils/app_permission_handler.dart'; import 'package:mc_common_app/utils/utils.dart'; // import 'package:geodesy/geodesy.dart' as geodesy; -//Created By Mr.Zohaib -class Location { +abstract class Location { + void handleLocationPermission(); + + void havePermission(Function(bool) callback); + + void isEnabled(Function(bool) callback); + + void listenGPS({bool change = true, Function(bool)? onChange}); + + void getCurrentLocation(Function(LatLng?) callback); +} + +class LocationService implements Location { static _Map map = _Map(); - static void havePermission(Function(bool) callback) { + void havePermission(Function(bool) callback) { Geolocator.checkPermission().then((value) async { if (value == LocationPermission.denied) { value = await Geolocator.requestPermission(); @@ -28,13 +40,26 @@ class Location { }); } - static void isEnabled(Function(bool) callback) { + void isEnabled(Function(bool) callback) { Geolocator.isLocationServiceEnabled().then((value) => callback(value)); } + void handleLocationPermission() { + havePermission((val) { + if (val) { + print(val); + getCurrentLocation((LatLng? latlng) { + print(latlng); + AppState().currentLocation = latlng ?? const LatLng(0, 0); + print("App State Location${AppState().currentLocation.toJson()}"); + }); + } + }); + } + static bool _listeningSettingChange = true; - static void listenGPS({bool change = true, Function(bool)? onChange}) async { + void listenGPS({bool change = true, Function(bool)? onChange}) async { _listeningSettingChange = change; if (change == false) return; @@ -46,10 +71,8 @@ class Location { }); } - static void getCurrentLocation(Function(LatLng?) callback) { + void getCurrentLocation(Function(LatLng?) callback) { void done(Position position) { - //AppStorage.sp.saveLocation(position); - LatLng? myCurrentLocation = LatLng(position.latitude, position.longitude); callback(myCurrentLocation); } @@ -88,8 +111,7 @@ class Location { } class _Map { - Marker createMarker( - String id, { + Marker createMarker(String id, { required LatLng coordinates, BitmapDescriptor? icon, VoidCallback? onTap, @@ -139,7 +161,7 @@ class _Map { } void goToCurrentLocation({Completer? mapController, double? direction = 0.0, bool? animation}) { - Location.getCurrentLocation((location) { + LocationService().getCurrentLocation((location) { moveTo(location!, zoom: 17, mapController: mapController!, animation: animation, direction: direction!); }); } diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart index 3412f22..2fe7109 100644 --- a/lib/utils/utils.dart +++ b/lib/utils/utils.dart @@ -7,6 +7,7 @@ import 'package:flutter/material.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart'; import 'package:mc_common_app/utils/date_helper.dart'; import 'package:mc_common_app/utils/dialogs_and_bottomsheets.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/extensions/extensions_widget.dart'; import 'package:path/path.dart' as p; @@ -567,7 +568,9 @@ class Utils { maxHeight: 55, title: LocaleKeys.callNow.tr(), fontSize: 18, - onPressed: () {}, + onPressed: () { + pop(context); + }, ), ), actionButtonNo: const SizedBox(), diff --git a/lib/view_models/ad_view_model.dart b/lib/view_models/ad_view_model.dart index 1c33200..11bc0ef 100644 --- a/lib/view_models/ad_view_model.dart +++ b/lib/view_models/ad_view_model.dart @@ -1302,6 +1302,10 @@ class AdVM extends BaseVM { warrantyDuration = ""; vehicleDescription = ""; selectionDurationStartDate = ""; + isPhoneNumberShown = false; + isNumberOnWhatsApp = false; + adPhoneNumberDialCode = ""; + adPhoneNumber = ""; clearSpecialServiceCard(); updateFinanceAvailableStatus(false); notifyListeners(); diff --git a/lib/view_models/appointments_view_model.dart b/lib/view_models/appointments_view_model.dart index 2336b1b..0cbc64f 100644 --- a/lib/view_models/appointments_view_model.dart +++ b/lib/view_models/appointments_view_model.dart @@ -707,6 +707,10 @@ class AppointmentsVM extends BaseVM { } void onServicesNextPressed(BuildContext context) async { + if (allSelectedItemsInAppointments.isEmpty) { + Utils.showToast("Please select at least one service."); + return; + } Utils.showLoading(context); List serviceItemIdsForHome = []; @@ -837,14 +841,24 @@ class AppointmentsVM extends BaseVM { log("selectedFilter: ${selectedFilter.id}"); if (selectedFilter.id == 0) { - nearbyBranches = await branchRepo.getAllNearBranchAndServices(); + nearbyBranches = await branchRepo.getAllNearBranchAndServices( + latitude: AppState().currentLocation.latitude, + longitude: AppState().currentLocation.longitude, + ); } else { - nearbyBranches = await branchRepo.getBranchesByFilters(categoryIdsList: [selectedFilter.id]); + nearbyBranches = await branchRepo.getBranchesByFilters( + categoryIdsList: [selectedFilter.id], + latitude: AppState().currentLocation.latitude, + longitude: AppState().currentLocation.longitude, + ); } setState(ViewState.idle); return; } - nearbyBranches = await branchRepo.getAllNearBranchAndServices(); + nearbyBranches = await branchRepo.getAllNearBranchAndServices( + latitude: AppState().currentLocation.latitude, + longitude: AppState().currentLocation.longitude, + ); setState(ViewState.idle); } @@ -1171,8 +1185,8 @@ class AppointmentsVM extends BaseVM { serviceIdsList: servicesIdsList.isNotEmpty ? servicesIdsList : null, distanceKm: branchFilterCurrentDistance.toInt(), rating: branchFilterByRating.toInt(), - latitude: 24.694969, - longitude: 46.724129, + latitude: AppState().currentLocation.latitude, + longitude: AppState().currentLocation.longitude, ); setState(ViewState.idle); } @@ -1184,7 +1198,11 @@ class AppointmentsVM extends BaseVM { return; } nearbyBranches.clear(); - nearbyBranches = await branchRepo.getBranchesByFilters(categoryIdsList: [categoryId]); + nearbyBranches = await branchRepo.getBranchesByFilters( + categoryIdsList: [categoryId], + latitude: AppState().currentLocation.latitude, + longitude: AppState().currentLocation.longitude, + ); setState(ViewState.idle); } @@ -1195,7 +1213,11 @@ class AppointmentsVM extends BaseVM { Future fetchAllBranchesBySelectedProviderId({required List providersIdsList}) async { branchesDropList.clear(); setOnlyState(ViewState.busy); - List providers = await branchRepo.getBranchesByFilters(providerIdsList: providersIdsList); + List providers = await branchRepo.getBranchesByFilters( + providerIdsList: providersIdsList, + latitude: AppState().currentLocation.latitude, + longitude: AppState().currentLocation.longitude, + ); for (var element in providers) { branchesDropList.add(DropValue(element.id ?? 0, element.branchName ?? "N/A", "")); } diff --git a/lib/view_models/dashboard_view_model_provider.dart b/lib/view_models/dashboard_view_model_provider.dart index 4f14fc6..a051790 100644 --- a/lib/view_models/dashboard_view_model_provider.dart +++ b/lib/view_models/dashboard_view_model_provider.dart @@ -71,16 +71,6 @@ class DashboardVMProvider extends BaseVM { return await userRepo.updateUserImage(image); } - fetchUsernameAndLocation() async { - // String userName = await SharedPrefManager.getPhoneOrEmail(); - Location.getCurrentLocation( - (LatLng? latlng) { - AppState().currentLocation = latlng ?? const LatLng(0, 0); - }, - ); - notifyListeners(); - } - Future onRefresh(BuildContext context) async { final requestsVM = context.read(); final chatVM = context.read(); @@ -95,6 +85,7 @@ class DashboardVMProvider extends BaseVM { await serviceVM.getBranchAndServices(); await appointmentVM.getMyAppointmentsForProvider({"ServiceProviderID": injector.get().getUser.data?.userInfo?.providerId.toString() ?? "0"}); adVm.populateAdsFilterList(); + await subscriptionsVM.getSubscriptionBySP(AppState().getUser.data?.userInfo?.providerId.toString() ?? "", true); await chatVM.buildHubConnection(context); await adVm.getMyAds(); await adVm.getExploreAds(); @@ -102,7 +93,6 @@ class DashboardVMProvider extends BaseVM { await adVm.getVehicleAdsDuration(); await requestsVM.getRequests(); // await subscriptionsVM.getMySubscriptionsBySP(AppState().getUser.data?.userInfo?.providerId.toString() ?? ""); - await subscriptionsVM.getSubscriptionBySP(AppState().getUser.data?.userInfo?.providerId.toString() ?? "", true); // await subscriptionsVM.getMySubscriptionsBySP(AppState().getUser.data?.userInfo?.providerId.toString() ?? ""); } diff --git a/lib/view_models/requests_view_model.dart b/lib/view_models/requests_view_model.dart index db3d130..9d21f92 100644 --- a/lib/view_models/requests_view_model.dart +++ b/lib/view_models/requests_view_model.dart @@ -15,6 +15,7 @@ import 'package:mc_common_app/models/chat_models/chat_message_model.dart'; import 'package:mc_common_app/models/general_models/enums_model.dart'; import 'package:mc_common_app/models/general_models/generic_resp_model.dart'; import 'package:mc_common_app/models/requests_models/offers_model.dart'; +import 'package:mc_common_app/models/requests_models/provider_offers_model.dart'; import 'package:mc_common_app/models/requests_models/request_model.dart'; import 'package:mc_common_app/models/general_models/widgets_models.dart'; import 'package:mc_common_app/repositories/common_repo.dart'; @@ -60,6 +61,8 @@ class RequestsVM extends BaseVM { notifyListeners(); } + ServiceProvidersOffers? currentSelectedOffer; + String? acceptedRequestOfferProviderName; updateAcceptedRequestOfferProviderName(String value) { @@ -67,6 +70,19 @@ class RequestsVM extends BaseVM { notifyListeners(); } + String addressSparePartRequestDelivery = ""; + String additionalAddressSparePartRequestDelivery = ""; + + void updateAddressSparePartRequestDelivery(String value) { + addressSparePartRequestDelivery = value; + notifyListeners(); + } + + void updateAdditionalAddressSparePartRequestDelivery(String value) { + additionalAddressSparePartRequestDelivery = value; + notifyListeners(); + } + Future getRequests({bool isNeedToRebuild = false}) async { if (isNeedToRebuild) setState(ViewState.busy); applyFilterOnRequestsVM(requestsTypeEnum: RequestsTypeEnum.specialCarRequest); @@ -76,9 +92,7 @@ class RequestsVM extends BaseVM { Future getRequestsBasedOnFilters() async { myFilteredRequests.clear(); setState(ViewState.busy); - int requestTypeIdApi = requestsTypeFilterOptions - .firstWhere((element) => element.isSelected) - .id; + int requestTypeIdApi = requestsTypeFilterOptions.firstWhere((element) => element.isSelected).id; int requestCityIdApi = 0; if (vehicleCityId.selectedId != -1) { @@ -612,7 +626,7 @@ class RequestsVM extends BaseVM { bool isCountryFetching = false; //Request Management - String price = ""; + String price = "0.0"; String description = ""; String address = ""; String model = ""; diff --git a/lib/view_models/service_view_model.dart b/lib/view_models/service_view_model.dart index c1cc094..8d41a6b 100644 --- a/lib/view_models/service_view_model.dart +++ b/lib/view_models/service_view_model.dart @@ -93,15 +93,18 @@ class ServiceVM extends BaseVM { Future getServiceProviderDocument(int providerId) async { setState(ViewState.busy); + commerceCertificates.clear(); + commercialCertificates.clear(); + vatCertificates.clear(); document = await branchRepo.getServiceProviderDocument(providerId); - if (document != null && document!.data != null && document!.data!.isNotEmpty) { - for (var doc in document!.data!) { - log("doc: ${doc.status}"); - if (doc.status != 3) { - updateIsAllDocsApproved(false); - } - } - } + // if (document != null && document!.data != null && document!.data!.isNotEmpty) { + // for (var doc in document!.data!) { + // log("doc: ${doc.status}"); + // if (doc.status != 3) { + // updateIsAllDocsApproved(false); + // } + // } + // } setState(ViewState.idle); } @@ -218,10 +221,10 @@ class ServiceVM extends BaseVM { // return null; // } - bool isAllDocsApproved = false; + bool isShowContinue = true; - updateIsAllDocsApproved(var value) { - isAllDocsApproved = value; + updateIsShowContinue(var value) { + isShowContinue = value; notifyListeners(); } @@ -231,6 +234,10 @@ class ServiceVM extends BaseVM { context, allowMultiple: false, ); + if (files != null && files.any((element) => element.path.split('.').last.toLowerCase() != 'pdf')) { + Utils.showToast("Only PDF Files are allowed"); + return; + } if (files == null) return; for (var element in files) { imageModels.add(ImageModel( diff --git a/lib/view_models/subscriptions_view_model.dart b/lib/view_models/subscriptions_view_model.dart index a5c9e22..aa57cc1 100644 --- a/lib/view_models/subscriptions_view_model.dart +++ b/lib/view_models/subscriptions_view_model.dart @@ -63,15 +63,15 @@ class SubscriptionsVM extends BaseVM { monthlyTabs.first.isEnabled = true; selectedMonthlyTab = monthlyTabs.first; - filterSubscriptions(); - getMySubscriptionsBySP(); + await filterSubscriptions(); + await getMySubscriptionsBySP(); setState(ViewState.idle); } else { setState(ViewState.error); } } - String newPrice = ""; + String newPrice = "0.0"; calculationUpgradePrice(String? serviceProviderID, String? newSubscription) async { setState(ViewState.busy); 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 5b1564c..4c61f0d 100644 --- a/lib/views/advertisement/ads_detail_view/ads_detail_view.dart +++ b/lib/views/advertisement/ads_detail_view/ads_detail_view.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:developer'; import 'package:flutter/material.dart'; import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; @@ -34,15 +35,12 @@ class AdsDetailView extends StatefulWidget { class _AdsDetailViewState extends State { late AdVM adVM; - late List damagePartsPictures; @override void initState() { adVM = context.read(); - damagePartsPictures = []; scheduleMicrotask(() { onAdDetailsLoaded(); - populateDamagePartPictures(); }); super.initState(); } @@ -54,24 +52,6 @@ class _AdsDetailViewState extends State { } } - void populateDamagePartPictures() { - if (widget.adDetails.vehicle!.damagereport != null && widget.adDetails.vehicle!.damagereport!.isNotEmpty) { - for (var element in widget.adDetails.vehicle!.damagereport!) { - int index = -1; - ImageModel imageModel = ImageModel(id: element.id!, filePath: element.imageUrl!, isFromNetwork: true); - - VehicleDamageCard vehicleDamageCard = VehicleDamageCard( - partSelectedId: SelectionModel( - selectedId: element.vehicleDamagePartID!, - selectedOption: element.partName ?? "", - ), - partImages: [imageModel], - ); - damagePartsPictures.add(vehicleDamageCard); - } - } - } - void deleteAdBottomSheet(BuildContext context) { return actionConfirmationBottomSheet( context: context, @@ -304,6 +284,8 @@ class _AdsDetailViewState extends State { @override Widget build(BuildContext context) { + log("widget.adDetails: ${widget.adDetails.phoneNo}"); + log("widget.adDetails: ${widget.adDetails.whatsAppNo}"); Widget actionWidget = const SizedBox(); if ((widget.adDetails.isMyAd ?? false) && (widget.adDetails.adPostStatus != AdPostStatus.reserved) && (widget.adDetails.adPostStatus != AdPostStatus.active) && (widget.adDetails.adPostStatus != AdPostStatus.pendingForPost)) { actionWidget = IconButton( diff --git a/lib/views/advertisement/ads_detail_view/components.dart b/lib/views/advertisement/ads_detail_view/components.dart index 9216b4f..0d580b9 100644 --- a/lib/views/advertisement/ads_detail_view/components.dart +++ b/lib/views/advertisement/ads_detail_view/components.dart @@ -218,7 +218,7 @@ class BuildAdDetailsActionButtonForExploreAds extends StatelessWidget { } Widget defaultActionForProviderAndCustomer(BuildContext context, AdDetailsModel adDetailsModel) { - return (adDetailsModel.phoneNo == null) + return (adDetailsModel.phoneNo != null && adDetailsModel.phoneNo!.isNotEmpty) ? Row( children: [ Expanded( @@ -236,7 +236,7 @@ class BuildAdDetailsActionButtonForExploreAds extends StatelessWidget { }, ), ), - if (adDetailsModel.whatsAppNo == null) ...[ + if (adDetailsModel.whatsAppNo != null && adDetailsModel.whatsAppNo!.isNotEmpty) ...[ 8.width, Container(height: 55, width: 55, alignment: Alignment.center, decoration: BoxDecoration(border: Border.all(color: MyColors.black, width: 2)), child: MyAssets.whatsAppIcon.buildSvg(height: 33, width: 35)).onPress(() { Utils.openNumberViaWhatsApp(phoneNumber: adDetailsModel.whatsAppNo ?? ""); 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 44aaca8..b77a58a 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 @@ -1,8 +1,11 @@ import 'dart:async'; import 'dart:developer'; +import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/models/advertisment_models/ad_details_model.dart'; +import 'package:mc_common_app/models/chat_models/chat_message_model.dart'; import 'package:mc_common_app/models/general_models/widgets_models.dart'; +import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/view_models/ad_view_model.dart'; import 'package:flutter/material.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; @@ -65,7 +68,21 @@ class _AdDamagePartPicturesSheetState extends State { onCrossPressedSecondary: (imageIndex, filePath) {}, index: index, onAddFilePressed: () {}, - ), + ).onPress(() { + if (vehicleDamageCard.partImages == null) { + return; + } + List images = []; + for (var image in vehicleDamageCard.partImages!) { + images.add(MessageImageModel( + id: image.id, + isFromNetwork: true, + imageUrl: image.filePath, + + )); + } + navigateWithName(context, AppRoutes.mediaViewerScreen, arguments: images); + }), ], ).toWhiteContainer( width: double.infinity, diff --git a/lib/views/advertisement/components/damage_pictures_bottom_sheet.dart b/lib/views/advertisement/components/damage_pictures_bottom_sheet.dart index 8943661..c3572d2 100644 --- a/lib/views/advertisement/components/damage_pictures_bottom_sheet.dart +++ b/lib/views/advertisement/components/damage_pictures_bottom_sheet.dart @@ -37,7 +37,7 @@ class _DamagePicturesListState extends State { return const Center(child: CircularProgressIndicator()); } return appointmentsVM.serviceItemsFromApi.isEmpty - ? EmptyWidget(text: LocaleKeys.noItemstoShow.tr(), isWrappedColumn: false) + ? EmptyWidget(text: LocaleKeys.noItemsToShow.tr(), isWrappedColumn: false) : ListView.separated( itemCount: appointmentsVM.serviceItemsFromApi.length, itemBuilder: (BuildContext context, int index) { diff --git a/lib/views/appointments/book_appointment_services_view.dart b/lib/views/appointments/book_appointment_services_view.dart index cb0d265..ec933d2 100644 --- a/lib/views/appointments/book_appointment_services_view.dart +++ b/lib/views/appointments/book_appointment_services_view.dart @@ -61,15 +61,6 @@ class BookAppointmentServicesView extends StatelessWidget { ], ), if (true) ...[ - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - (LocaleKeys.serviceLocation.tr()).toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), - 4.width, - (serviceData.isHomeSelected ? serviceData.homeLocation : LocaleKeys.workshop.tr()).toText(fontSize: 12, isBold: true).expand(), - ], - ), - 5.height, Column( children: List.generate(serviceData.serviceItems!.length, (itemIndex) { ItemData itemData = serviceData.serviceItems![itemIndex]; @@ -83,6 +74,15 @@ class BookAppointmentServicesView extends StatelessWidget { }), ), 8.height, + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + (LocaleKeys.serviceLocation.tr()).toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), + 4.width, + (serviceData.isHomeSelected ? serviceData.homeLocation : LocaleKeys.workshop.tr()).toText(fontSize: 12, isBold: true).expand(), + ], + ), + 5.height, Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ diff --git a/lib/views/appointments/book_appointments_item_view.dart b/lib/views/appointments/book_appointments_item_view.dart index 284d348..bf38c2e 100644 --- a/lib/views/appointments/book_appointments_item_view.dart +++ b/lib/views/appointments/book_appointments_item_view.dart @@ -64,7 +64,7 @@ class BookAppointmentsItemView extends StatelessWidget { ], ).horPaddingMain(), appointmentsVM.serviceItemsFromApi.isEmpty - ? Expanded(child: Center(child: LocaleKeys.noItemstoShow.toText(fontSize: 16, color: MyColors.lightTextColor))) + ? Expanded(child: Center(child: LocaleKeys.noItemsToShow.toText(fontSize: 16, color: MyColors.lightTextColor))) : ListView.separated( separatorBuilder: (BuildContext context, int index) => const Divider(), itemCount: appointmentsVM.serviceItemsFromApi.length, diff --git a/lib/views/chat/chat_view.dart b/lib/views/chat/chat_view.dart index fb7eb9c..b2557d0 100644 --- a/lib/views/chat/chat_view.dart +++ b/lib/views/chat/chat_view.dart @@ -200,6 +200,7 @@ class _ChatViewState extends State { ] else if (chatTypeEnum == ChatTypeEnum.requestOffer && requestVM.currentSelectedRequest!.requestType.toRequestTypeStatusEnum() == RequestsTypeEnum.specialCarRequest && requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.inProgress && + requestVM.currentSelectedOffer!.requestOfferStatusEnum == RequestOfferStatusEnum.accepted && AppState().currentAppType == AppType.customer) ...[ Expanded( child: ShowFillButton( diff --git a/lib/views/location_views/map_selection_widget.dart b/lib/views/location_views/map_selection_widget.dart index dc28656..79a11fe 100644 --- a/lib/views/location_views/map_selection_widget.dart +++ b/lib/views/location_views/map_selection_widget.dart @@ -7,27 +7,26 @@ import 'package:google_maps_flutter/google_maps_flutter.dart'; class AppMap extends StatefulWidget { final CameraPositionCallback onCameraMove; + final VoidCallback onCameraIdle; Map initialCamera; late AppMapState _state; final Function onMapCreated; - AppMap(this.initialCamera, - {required this.onCameraMove, required this.onMapCreated}); + AppMap(this.initialCamera, {required this.onCameraMove, required this.onCameraIdle, required this.onMapCreated}); @override State createState() => _state = AppMapState(); moveTo({required CameraPosition cameraPostion}) { - _state.googleMapController - .animateCamera(CameraUpdate.newCameraPosition(cameraPostion)); + _state.googleMapController.animateCamera(CameraUpdate.newCameraPosition(cameraPostion)); } } class AppMapState extends State { bool isHuawei = false; - Completer _googleMapControllerComp = Completer(); + final Completer _googleMapControllerComp = Completer(); late GoogleMapController googleMapController; checkIsHuawei() async { @@ -45,7 +44,7 @@ class AppMapState extends State { @override Widget build(BuildContext context) { - if (isHuawei == null) return CircularProgressIndicator(); + if (isHuawei == null) return const CircularProgressIndicator(); return googleMap(); } @@ -55,10 +54,9 @@ class AppMapState extends State { zoomControlsEnabled: true, myLocationButtonEnabled: true, myLocationEnabled: true, - initialCameraPosition: CameraPosition.fromMap(widget.initialCamera) ?? - const CameraPosition( - target: LatLng(-26.1711459, 27.9002758), zoom: 2.0), + initialCameraPosition: CameraPosition.fromMap(widget.initialCamera) ?? const CameraPosition(target: LatLng(-26.1711459, 27.9002758), zoom: 2.0), onCameraMove: widget.onCameraMove, + onCameraIdle: widget.onCameraIdle, onMapCreated: (GoogleMapController controller) { googleMapController = controller; _googleMapControllerComp.complete(controller); diff --git a/lib/views/location_views/pick_location_page.dart b/lib/views/location_views/pick_location_page.dart index a4d4176..db0dcef 100644 --- a/lib/views/location_views/pick_location_page.dart +++ b/lib/views/location_views/pick_location_page.dart @@ -6,6 +6,7 @@ import 'package:flutter/material.dart'; import 'package:geolocator/geolocator.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart'; import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/widgets/button/show_fill_button.dart'; @@ -32,10 +33,7 @@ class _PickLocationPageState extends State { final Set markers = {}; late AppMap appMap; - static CameraPosition _kGooglePlex = const CameraPosition( - target: LatLng(37.42796133580664, -122.085749655962), - zoom: 14.4746, - ); + static CameraPosition _kGooglePlex = CameraPosition(target: AppState().currentLocation, zoom: 14.4746); late LatLng currentPosition; Completer mapController = Completer(); final ValueNotifier _counter = ValueNotifier(""); @@ -47,6 +45,9 @@ class _PickLocationPageState extends State { onCameraMove: (camera) { _updatePosition(camera); }, + onCameraIdle: () { + updateAddress(latitude, longitude); + }, onMapCreated: () { // goToCurrentLocation(); _getUserLocation(); @@ -127,7 +128,7 @@ class _PickLocationPageState extends State { longitude = position.target.longitude; log(latitude.toString()); log(latitude.toString()); - updateAddress(latitude, longitude); + // updateAddress(latitude, longitude); } void _getUserLocation() async { @@ -152,6 +153,7 @@ class _PickLocationPageState extends State { }, ); } + setState(() {}); } updateAddress(double latitude, double longitude) async { @@ -160,13 +162,11 @@ class _PickLocationPageState extends State { } setMap() { - setState(() { - _kGooglePlex = CameraPosition( - target: currentPosition, - zoom: 14.4746, - ); - appMap.moveTo(cameraPostion: _kGooglePlex); - }); + _kGooglePlex = CameraPosition( + target: currentPosition, + zoom: 14.4746, + ); + appMap.moveTo(cameraPostion: _kGooglePlex); } Future getCurrentAddress() async { diff --git a/lib/views/requests/create_request_page.dart b/lib/views/requests/create_request_page.dart index a79819a..af66080 100644 --- a/lib/views/requests/create_request_page.dart +++ b/lib/views/requests/create_request_page.dart @@ -1,3 +1,6 @@ +import 'dart:developer'; + +import 'package:mc_common_app/classes/app_state.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'; @@ -23,6 +26,7 @@ class CreateRequestPage extends StatelessWidget { @override Widget build(BuildContext context) { + log("AppState().getUser.data!.userInfo :${AppState().getUser.data!.userInfo.toString()}"); return Scaffold( appBar: CustomAppBar( title: LocaleKeys.createRequest.tr(), @@ -42,6 +46,16 @@ class CreateRequestPage extends StatelessWidget { child: CircularProgressIndicator(), ), ] else ...[ + if (AppState().getUser.data!.userInfo != null) ...[ + TxtField( + value: "${AppState().getUser.data!.userInfo!.firstName ?? ""} ${AppState().getUser.data!.userInfo!.lastName ?? ""}", + isBackgroundEnabled: true, + isNeedClickAll: true, + hint: '', + onTap: () {}, + ), + ], + 8.height, Builder(builder: (context) { List requestTypeDrop = []; for (var element in requestsVM.myRequestsTypeEnum) { @@ -165,13 +179,13 @@ class CreateRequestPage extends StatelessWidget { }), ], ], - 8.height, - TxtField( - hint: LocaleKeys.price.tr(), - value: requestsVM.price, - keyboardType: TextInputType.number, - onChanged: (e) => requestsVM.updatePrice(e), - ), + // 8.height, + // TxtField( + // hint: LocaleKeys.price.tr(), + // value: requestsVM.price, + // keyboardType: TextInputType.number, + // onChanged: (e) => requestsVM.updatePrice(e), + // ), 8.height, TxtField( hint: LocaleKeys.description.tr(), diff --git a/lib/views/requests/offer_list_page.dart b/lib/views/requests/offer_list_page.dart index 0cb44d0..f3ca520 100644 --- a/lib/views/requests/offer_list_page.dart +++ b/lib/views/requests/offer_list_page.dart @@ -12,6 +12,7 @@ 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/chat_view_model.dart'; +import 'package:mc_common_app/view_models/requests_view_model.dart'; import 'package:mc_common_app/widgets/common_widgets/app_bar.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:provider/provider.dart'; @@ -37,7 +38,10 @@ class OfferListPage extends StatelessWidget { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Utils.statusContainerChip(text: "Offer ${Utils.getNameByRequestOfferStatusEnum(offersModel.requestOfferStatusEnum!)}", chipColor: Utils.getChipColorByRequestOfferStatusEnum(offersModel.requestOfferStatusEnum!)), + Utils.statusContainerChip( + text: "Offer ${Utils.getNameByRequestOfferStatusEnum(offersModel.requestOfferStatusEnum!)}", + chipColor: Utils.getChipColorByRequestOfferStatusEnum(offersModel.requestOfferStatusEnum!), + ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, @@ -80,6 +84,7 @@ class OfferListPage extends StatelessWidget { ), ], ).onPress(() async { + context.read().currentSelectedOffer = offersModel; ChatViewArgumentsForRequest chatViewArgumentsForRequest = ChatViewArgumentsForRequest( chatTypeEnum: ChatTypeEnum.requestOffer, receiverId: "${offersModel.providerUserId}", diff --git a/lib/views/requests/request_bottomsheets.dart b/lib/views/requests/request_bottomsheets.dart index cc30ef7..00fada3 100644 --- a/lib/views/requests/request_bottomsheets.dart +++ b/lib/views/requests/request_bottomsheets.dart @@ -25,7 +25,7 @@ Future buildSendOfferBottomSheet({required BuildContext context, required Reques builder: (BuildContext context) { return Consumer(builder: (BuildContext context, RequestsVM requestsVM, Widget? child) { return InfoBottomSheet( - title: LocaleKeys.makeAnOffer.tr().toText(fontSize: 28, isBold: true, letterSpacing: -1.44), + title: LocaleKeys.provideOffer.tr().toText(fontSize: 28, isBold: true, letterSpacing: -1.44), description: Padding( padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), child: Column( @@ -49,7 +49,7 @@ Future buildSendOfferBottomSheet({required BuildContext context, required Reques value: requestsVM.serviceItem, errorValue: requestsVM.offerPriceError, keyboardType: TextInputType.number, - hint: "Service Item", + hint: LocaleKeys.serviceItem.tr(), onChanged: (v) => requestsVM.updateServiceItem(v), ), 12.height, @@ -57,13 +57,13 @@ Future buildSendOfferBottomSheet({required BuildContext context, required Reques value: requestsVM.itemManufacturer, errorValue: requestsVM.offerPriceError, keyboardType: TextInputType.number, - hint: LocaleKeys.manufacturer.tr(), + hint: LocaleKeys.createdBy.tr(), onChanged: (v) => requestsVM.updateItemManufacturer(v), ), 12.height, TxtField( errorValue: "", - hint: LocaleKeys.manufacturedOn.tr(), + hint: LocaleKeys.createdOn.tr(), value: requestsVM.serviceItemCreatedOn, isNeedClickAll: true, postfixData: Icons.calendar_month_rounded, diff --git a/lib/views/requests/request_detail_page.dart b/lib/views/requests/request_detail_page.dart index 598859b..d0e41e1 100644 --- a/lib/views/requests/request_detail_page.dart +++ b/lib/views/requests/request_detail_page.dart @@ -149,7 +149,7 @@ class RequestDetailPage extends StatelessWidget { maxWidth: double.infinity, margin: const EdgeInsets.all(15), maxHeight: 55, - title: LocaleKeys.sendOffer.tr(), + title: LocaleKeys.provideOffer.tr(), isBold: false, fontSize: 18, onPressed: () => buildSendOfferBottomSheet(context: context, requestDetailPageArguments: requestDetailPageArguments, isFromChatScreen: false), @@ -208,37 +208,37 @@ class RequestDetailPage extends StatelessWidget { showItem("${LocaleKeys.customerName.tr()}: ", requestDetail.customerName), showItem("${LocaleKeys.description.tr()}: ", requestDetail.description), 16.height, - showItem("${LocaleKeys.priceRange.tr()}:", ""), - Row( - children: [ - Expanded( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - "${requestDetail.price.toInt()}".toText(fontSize: 19, isBold: true, letterSpacing: -1.16), - 2.width, - LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, fontSize: 10, letterSpacing: -0.4), - ], - ), - Row( - children: [ - Utils.statusContainerChip( - text: (requestDetail.requestStatusName), - chipColor: MyColors.grey98Color.withOpacity(0.1), - textColor: MyColors.lightTextColor, - ), - ], - ), - ], - ), - ), - // const Icon(Icons.arrow_forward) - ], - ), + // showItem("${LocaleKeys.priceRange.tr()}:", ""), + // Row( + // children: [ + // Expanded( + // child: Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // crossAxisAlignment: CrossAxisAlignment.end, + // children: [ + // Row( + // crossAxisAlignment: CrossAxisAlignment.end, + // children: [ + // "${requestDetail.price.toInt()}".toText(fontSize: 19, isBold: true, letterSpacing: -1.16), + // 2.width, + // LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, fontSize: 10, letterSpacing: -0.4), + // ], + // ), + // Row( + // children: [ + // Utils.statusContainerChip( + // text: (requestDetail.requestStatusName), + // chipColor: MyColors.grey98Color.withOpacity(0.1), + // textColor: MyColors.lightTextColor, + // ), + // ], + // ), + // ], + // ), + // ), + // // const Icon(Icons.arrow_forward) + // ], + // ), ], ); } diff --git a/lib/views/requests/review_request_offer.dart b/lib/views/requests/review_request_offer.dart index 4d37502..2fc20ce 100644 --- a/lib/views/requests/review_request_offer.dart +++ b/lib/views/requests/review_request_offer.dart @@ -8,19 +8,40 @@ 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/date_helper.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/chat_view_model.dart'; import 'package:mc_common_app/view_models/requests_view_model.dart'; import 'package:mc_common_app/views/advertisement/ad_creation_steps/ad_review_containers.dart'; +import 'package:mc_common_app/views/location_views/pick_location_page.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'; -class ReviewRequestOffer extends StatelessWidget { +class ReviewRequestOffer extends StatefulWidget { const ReviewRequestOffer({super.key}); + @override + State createState() => _ReviewRequestOfferState(); +} + +class _ReviewRequestOfferState extends State { + @override + void initState() { + final requestVM = context.read(); + + if (requestVM.currentSelectedRequest != null && requestVM.currentSelectedRequest!.address.isEmpty) { + requestVM.addressSparePartRequestDelivery = ""; + WidgetsBinding.instance.addPostFrameCallback((_) async => buildLocationInformationEditBottomSheet(context, requestVM)); + } + super.initState(); + } + Widget buildPersonalInformation() { UserInfo userInfo = AppState().getUser.data!.userInfo!; return Column( @@ -30,7 +51,7 @@ class ReviewRequestOffer extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ LocaleKeys.personalInformation.tr().toText(fontSize: 18), - MyAssets.icEdit.buildSvg().onPress(() {}), + const SizedBox(), ], ), 8.height, @@ -44,6 +65,7 @@ class ReviewRequestOffer extends StatelessWidget { children: [ SingleDetailWidget(text: "${userInfo.firstName ?? ""} ${userInfo.lastName ?? ""}", type: LocaleKeys.name.tr()), 16.height, + SingleDetailWidget(text: userInfo.email ?? "", type: LocaleKeys.email.tr()), ], ), ), @@ -52,8 +74,9 @@ class ReviewRequestOffer extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - SingleDetailWidget(text: userInfo.email ?? "", type: "${LocaleKeys.email.tr()} / ${LocaleKeys.phone.tr()}"), + SingleDetailWidget(text: userInfo.mobileNo ?? "", type: LocaleKeys.phone.tr()), 16.height, + const SingleDetailWidget(text: "", type: ""), ], ), ), @@ -64,7 +87,8 @@ class ReviewRequestOffer extends StatelessWidget { } Widget buildLocationInformation(BuildContext context) { - final requestVM = context.read(); + final requestVM = context.watch(); + return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -72,7 +96,7 @@ class ReviewRequestOffer extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ LocaleKeys.locationInformation.tr().toText(fontSize: 18), - MyAssets.icEdit.buildSvg().onPress(() {}), + MyAssets.icEdit.buildSvg().onPress(() => buildLocationInformationEditBottomSheet(context, requestVM)), ], ), 8.height, @@ -81,7 +105,7 @@ class ReviewRequestOffer extends StatelessWidget { children: [ SingleDetailWidget(text: requestVM.currentSelectedRequest!.address ?? "", type: LocaleKeys.location.tr()), 16.height, - SingleDetailWidget(text: "N/A", type: "${LocaleKeys.email.tr()} / ${LocaleKeys.additionalAddressDetails.tr()}"), + SingleDetailWidget(text: requestVM.additionalAddressSparePartRequestDelivery.isNotEmpty ? requestVM.additionalAddressSparePartRequestDelivery : "N/A", type: LocaleKeys.additionalAddressDetails.tr()), ], ), ], @@ -100,9 +124,9 @@ class ReviewRequestOffer extends StatelessWidget { children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ + children: [ LocaleKeys.serviceInformation.tr().toText(fontSize: 18), - MyAssets.icEdit.buildSvg().onPress(() {}), + const SizedBox(), ], ), 8.height, @@ -155,6 +179,82 @@ class ReviewRequestOffer extends StatelessWidget { ); } + Future buildLocationInformationEditBottomSheet(BuildContext context, RequestsVM requestsVM) async { + String additionalDetails = ""; + return showModalBottomSheet( + context: context, + isScrollControlled: true, + enableDrag: true, + builder: (BuildContext context) { + return InfoBottomSheet( + title: LocaleKeys.locationInformation.tr().toText(fontSize: 28, isBold: true, letterSpacing: -1.44), + description: Padding( + padding: MediaQuery.of(context).viewInsets, + child: StatefulBuilder( + builder: (BuildContext context, setState) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + "Update your location information".toText(fontSize: 14, fontWeight: MyFonts.Medium), + 8.height, + TxtField( + hint: LocaleKeys.address.tr(), + isNeedClickAll: false, + value: requestsVM.addressSparePartRequestDelivery, + postfixWidget: IconButton( + icon: const Icon( + size: 28, + Icons.add_location_outlined, + ), + onPressed: () { + navigateTo( + context, + PickLocationPage( + onPickAddress: (double latitude, double longitude, String address) { + requestsVM.updateAddressSparePartRequestDelivery(address); + setState(() {}); + }, + ), + ); + }), + onChanged: (e) => requestsVM.updateAddressSparePartRequestDelivery(e), + ), + 8.height, + TxtField( + hint: LocaleKeys.additionalAddressDetails.tr(), + isNeedClickAll: false, + value: requestsVM.additionalAddressSparePartRequestDelivery, + onChanged: (e) { + additionalDetails = e; + }), + 19.height, + Row( + children: [ + Expanded( + child: ShowFillButton( + title: LocaleKeys.submit.tr(), + onPressed: () { + // TODO: Call some api here to update this info for this specific request. + requestsVM.currentSelectedRequest!.address = requestsVM.addressSparePartRequestDelivery; + requestsVM.updateAdditionalAddressSparePartRequestDelivery(additionalDetails); + requestsVM.notifyListeners(); + pop(context); + }, + ), + ) + ], + ), + 25.height, + ], + ); + }, + ), + ), + ); + }, + ); + } + @override Widget build(BuildContext context) { return Scaffold( diff --git a/lib/views/setting_options/provider_license_page.dart b/lib/views/setting_options/provider_license_page.dart index 9d17e99..94bcd61 100644 --- a/lib/views/setting_options/provider_license_page.dart +++ b/lib/views/setting_options/provider_license_page.dart @@ -45,6 +45,19 @@ class _ProviderLicensePageState extends State { }); } + bool isAllowContinue(ServiceVM model) { + bool isShow = false; + if (model.document != null && model.document!.data != null && model.document!.data!.isNotEmpty) { + for (var doc in model.document!.data!) { + log("doc: ${doc.status}"); + if (doc.status == 4 || doc.status == 0) { + isShow = true; + } + } + } + return isShow; + } + @override Widget build(BuildContext context) { return Scaffold( @@ -58,40 +71,43 @@ class _ProviderLicensePageState extends State { child: CircularProgressIndicator(), ); } - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: SingleChildScrollView(child: buildContent(serviceVM)), - ), - if (!serviceVM.isAllDocsApproved) ...[ - Padding( - padding: const EdgeInsets.all(12.0), - child: ShowFillButton( - title: LocaleKeys.continu.tr(), - maxWidth: double.infinity, - onPressed: () async { - bool status = false; - if (AppState().getUser.data!.userInfo!.roleId == 5) { - if (validateDocuments(serviceVM)) { - status = await updateDocument(serviceVM); + return GestureDetector( + onTap: () => FocusScope.of(context).focusedChild!.unfocus(), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: SingleChildScrollView(child: buildContent(serviceVM)), + ), + if (isAllowContinue(serviceVM)) ...[ + Padding( + padding: const EdgeInsets.all(12.0), + child: ShowFillButton( + title: LocaleKeys.continu.tr(), + maxWidth: double.infinity, + onPressed: () async { + bool status = false; + if (AppState().getUser.data!.userInfo!.roleId == 5) { + if (validateDocuments(serviceVM)) { + status = await updateDocument(serviceVM); + } else { + Utils.showToast(LocaleKeys.allDocumentMandatoryDealershipProvider.tr()); + return; + } } else { - Utils.showToast(LocaleKeys.allDocumentMandatoryDealershipProvider.tr()); - return; - } - } else { - status = await updateDocument(serviceVM); - } - Future.delayed(const Duration(seconds: 1), () { - if (status) { - pop(context); + status = await updateDocument(serviceVM); } - }); - }, + Future.delayed(const Duration(seconds: 1), () { + if (status) { + pop(context); + } + }); + }, + ), ), - ), + ], ], - ], + ), ); }), ); @@ -153,21 +169,21 @@ class _ProviderLicensePageState extends State { ], ], ), - if (document.status != 1 && document.status != 3) ...[ - Padding( - padding: const EdgeInsets.only(top: 4, bottom: 8), - child: LocaleKeys.enter_licence_detail.tr().toText(fontSize: 14, color: MyColors.lightTextColor), - ), - TxtField( - hint: LocaleKeys.description.tr(), - maxLines: 3, - isBackgroundEnabled: true, - ), - ], + // if (document.status != 1 && document.status != 3) ...[ + // Padding( + // padding: const EdgeInsets.only(top: 4, bottom: 8), + // child: LocaleKeys.enter_licence_detail.tr().toText(fontSize: 14, color: MyColors.lightTextColor), + // ), + // TxtField( + // hint: LocaleKeys.description.tr(), + // maxLines: 3, + // isBackgroundEnabled: true, + // ), + // ], 10.height, if (isNeedToShow(model: serviceVM, document: document)) ...[ PickedFilesContainer( - isReview: document.status == 4, + isReview: document.status != 0 && (document.status == 1 || document.status == 3), allowAdButton: false, pickedFiles: isLocalOrNetworkFiles(model: serviceVM, document: document), onCrossPressedPrimary: isNetworkImage(document: document) @@ -177,7 +193,7 @@ class _ProviderLicensePageState extends State { : document.documentId == 2 ? serviceVM.commercialRemove : serviceVM.vatRemove, - isPdf: serviceVM.document!.data![index].fileExt == "pdf", + isPdf: true, isFromNetwork: !(document.isLocalFile ?? false), onAddFilePressed: () { serviceVM.pickPdfReceiptFile(context, document.documentId!, index); @@ -188,7 +204,7 @@ class _ProviderLicensePageState extends State { 10.height, DottedRectContainer( onTap: () => serviceVM.pickPdfReceiptFile(context, document.documentId!, index) ?? "", - text: LocaleKeys.attachImage.tr(), + text: LocaleKeys.attachPDF.tr(), icon: MyAssets.attachmentIcon.buildSvg(), ), ], diff --git a/lib/views/setting_options/setting_options_more.dart b/lib/views/setting_options/setting_options_more.dart index 39aa21b..8f0642d 100644 --- a/lib/views/setting_options/setting_options_more.dart +++ b/lib/views/setting_options/setting_options_more.dart @@ -68,7 +68,6 @@ class _SettingOptionsMoreState extends State { needBorderBelow: false, onTap: () => navigateWithName(context, AppRoutes.settingOptionsInviteFriends), ), - ], ).toWhiteContainer(width: double.infinity, pading: const EdgeInsets.all(12), borderRadius: 0), 10.height, @@ -99,7 +98,7 @@ class _SettingOptionsMoreState extends State { ), ), titleText: LocaleKeys.mySubscription.tr(), - subTitle: AppState().getproviderSubscription.first.name ?? "", + subTitle: AppState().getproviderSubscription.isNotEmpty ? (AppState().getproviderSubscription.first.name ?? "") : "", isForLanguage: false, needBorderBelow: true, onTap: () { @@ -208,3 +207,5 @@ class _SettingOptionsMoreState extends State { ); } } + + diff --git a/lib/widgets/common_widgets/branch_details_card.dart b/lib/widgets/common_widgets/branch_details_card.dart index e376714..f5fd70c 100644 --- a/lib/widgets/common_widgets/branch_details_card.dart +++ b/lib/widgets/common_widgets/branch_details_card.dart @@ -1,5 +1,6 @@ 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/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; @@ -56,13 +57,15 @@ class BranchDetailCard extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.start, children: [ title.toText(fontSize: 16, isBold: true), - Row( - children: [ - ("${LocaleKeys.location.tr()}:").toText(color: MyColors.lightTextColor, fontSize: 12), - 4.width, - providerLocation.toText(fontSize: 12, isBold: true), - ], - ), + if (AppState().currentLocation.latitude != 0 && AppState().currentLocation.longitude != 0) ...[ + Row( + children: [ + ("${LocaleKeys.location.tr()}:").toText(color: MyColors.lightTextColor, fontSize: 12), + 4.width, + providerLocation.toText(fontSize: 12, isBold: true), + ], + ), + ], if (providerName != null) Row( children: [ diff --git a/lib/widgets/dropdown/dropdow_field.dart b/lib/widgets/dropdown/dropdow_field.dart index 2926cbf..8a2bed5 100644 --- a/lib/widgets/dropdown/dropdow_field.dart +++ b/lib/widgets/dropdown/dropdow_field.dart @@ -64,7 +64,7 @@ class _DropdownFieldState extends State { width: widget.showAppointmentPickerVariant ? 170 : null, child: DropdownButton( value: dropdownValue, - icon: Icon(Icons.keyboard_arrow_down_sharp, color: !widget.isSelectAble ? Colors.transparent : null), + icon: Icon(Icons.keyboard_arrow_down_sharp, color: !widget.isSelectAble ? Colors.transparent : null, size: 21,), elevation: 16, iconSize: widget.showAppointmentPickerVariant ? 26 : 16, iconEnabledColor: borderColor,