From f0a9c294c29ff5ca0ca4086370dbfc9b7dcd4f2c Mon Sep 17 00:00:00 2001 From: Faiz Hashmi Date: Tue, 1 Oct 2024 15:00:03 +0300 Subject: [PATCH] Fixed the notes list --- assets/langs/ar-SA.json | 17 +- assets/langs/en-US.json | 17 +- lib/api/api_client.dart | 9 +- lib/classes/consts.dart | 2 + lib/config/routes.dart | 3 + lib/extensions/string_extensions.dart | 6 +- lib/generated/codegen_loader.g.dart | 34 +- lib/generated/locale_keys.g.dart | 15 + .../provider_offers_model.dart | 16 +- lib/models/requests_models/request_model.dart | 3 + lib/repositories/ads_repo.dart | 20 +- lib/repositories/appointment_repo.dart | 5 +- lib/repositories/common_repo.dart | 29 +- lib/repositories/request_repo.dart | 126 ++++- lib/utils/dialogs_and_bottomsheets.dart | 6 +- lib/utils/enums.dart | 2 + lib/utils/utils.dart | 34 +- lib/view_models/ad_view_model.dart | 2 +- lib/view_models/appointments_view_model.dart | 34 +- .../dashboard_view_model_customer.dart | 5 +- lib/view_models/requests_view_model.dart | 535 +++++++++++++++--- lib/view_models/service_view_model.dart | 4 +- lib/view_models/user_view_model.dart | 3 +- .../vehicle_details_container.dart | 1 - .../ads_detail_view/ads_detail_view.dart | 70 +-- .../ads_detail_view/components.dart | 45 +- .../components/ads_list_widget.dart | 43 +- .../appointments/appointment_detail_view.dart | 2 +- .../book_appointments_item_view.dart | 74 +-- .../appointments/review_appointment_view.dart | 39 +- .../common_appointment_slider_widget.dart | 2 +- .../chat/widgets/chat_bottom_sheets.dart | 2 +- .../common_fragments/requests_fragment.dart | 86 ++- lib/views/requests/create_request_page.dart | 60 +- lib/views/requests/offer_list_page.dart | 29 +- lib/views/requests/request_bottomsheets.dart | 4 +- lib/views/requests/requests_filter_view.dart | 272 +++++++++ lib/views/requests/review_request_offer.dart | 12 +- lib/views/requests/widget/request_item.dart | 6 +- lib/views/user/complete_profile_page.dart | 46 +- lib/views/user/register_page.dart | 26 +- lib/views/user/register_provider_page.dart | 4 + lib/widgets/button/show_fill_button.dart | 84 +-- .../custom_add_button_widget.dart | 1 - .../common_widgets/custom_rectangle_chip.dart | 3 +- lib/widgets/dropdown/dropdow_field.dart | 7 +- lib/widgets/extensions/extensions_widget.dart | 2 +- lib/widgets/txt_field.dart | 4 +- 48 files changed, 1362 insertions(+), 489 deletions(-) create mode 100644 lib/views/requests/requests_filter_view.dart diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index fce9fc2..58e689f 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -630,5 +630,20 @@ "cancelRequestPrompt": "هل تريد إلغاء هذا الطلب؟", "requestPermanentlyCancelled": "سيتم إلغاء طلبك بشكل نهائي. لا يمكنك التراجع عن هذا الإجراء.", "awaitingResponseFromCustomer": "في انتظار الرد من العميل", - "acknowledgePaymentToMowater": "أقر بأنه عند إكمال هذه الصفقة، سأدفع 2٪ من إجمالي هذه الصفقة لشركة مواتر مقابل خدماتهم." + "acknowledgePaymentToMowater": "أقر بأنه عند إكمال هذه الصفقة، سأدفع 2٪ من إجمالي هذه الصفقة لشركة مواتر مقابل خدماتهم.", + "requestsFilter": "تصفية الطلبات", + "searchByCondition": "البحث حسب الحالة", + "selectCondition": "حدد الحالة", + "searchByRequestType": "البحث حسب نوع الطلب", + "searchByCustomerName": "البحث حسب اسم العميل", + "searchByProviderName": "البحث حسب اسم المزود", + "searchByRequestStatus": "البحث حسب حالة الطلب", + "selectRequestType": "اختر نوع الطلب", + "selectRequestStatus": "اختر حالة الطلب", + "searchByRequestedDate": "البحث حسب تاريخ الطلب", + "selectDate": "اختر التاريخ", + "searchByVehicleModel": "البحث حسب طراز المركبة", + "customerCarePrompt": "هل لديك أي استفسار؟ نحن هنا لخدمتك. انقر هنا للتحدث مع خدمة العملاء لدينا الآن.", + "callNow": "اتصل الآن", + "condition": "الحالة" } \ No newline at end of file diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 9f0821f..cdec152 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -631,5 +631,20 @@ "cancelRequestPrompt": "Do you want to cancel this request?", "requestPermanentlyCancelled": "Your request will be permanently cancelled. You cannot undo this action.", "awaitingResponseFromCustomer": "Awaiting Response From Customer", - "acknowledgePaymentToMowater": "I acknowledge that upon completion of this deal, I will pay 2% of this total deal to the Mowater company for their service." + "acknowledgePaymentToMowater": "I acknowledge that upon completion of this deal, I will pay 2% of this total deal to the Mowater company for their service.", + "requestsFilter": "Requests Filter", + "searchByCondition": "Search By Condition", + "selectCondition": "Select Condition", + "searchByRequestType": "Search By Request Type", + "searchByCustomerName": "Search By Customer Name", + "searchByProviderName": "Search By Provider Name", + "searchByRequestStatus": "Search By Request Status", + "selectRequestStatus": "Select Request Status", + "selectRequestType": "Select Request Type", + "searchByRequestedDate": "Search by Requested Date", + "selectDate": "Select Date", + "searchByVehicleModel": "Search By Vehicle Model", + "customerCarePrompt": "Got any question? We are here to service. Click here to talk to our customer care right now.", + "callNow": "Call Now", + "condition": "Condition" } \ No newline at end of file diff --git a/lib/api/api_client.dart b/lib/api/api_client.dart index 2c0db39..b9da65b 100644 --- a/lib/api/api_client.dart +++ b/lib/api/api_client.dart @@ -56,8 +56,7 @@ 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}); @@ -68,8 +67,7 @@ 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); @@ -195,8 +193,7 @@ 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); diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index 05bd880..79e5d87 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -123,6 +123,7 @@ class ApiConsts { static String adsMCBankAccountAdGet = "${baseUrlServices}api/Advertisement/MCBankAccountAd_Get"; static String adsReserveCreate = "${baseUrlServices}api/Advertisement/AdsReserve_Create"; static String reserveAdPaymentOnDealDoneCreate = "${baseUrlServices}api/Advertisement/ReserveAdPaymentOnDealDone_Create"; + static String adsExtendDurationCreate = "${baseUrlServices}api/Advertisement/Ads_ExtendDuration_Create"; //Subscription static String getMySubscriptions = "${baseUrlServices}api/ServiceProviders/ProviderSubscription_Get"; @@ -196,6 +197,7 @@ class GlobalConsts { static String adReservablePriceErrorConst = "Ad Reservable price cannot be empty"; static String homeLocationEmptyError = "Home location cannot be empty"; static String fillAllFields = "Please fill out all the fields."; + static String requestTypeCannotBeEmpty = "Request type cannot be empty."; static String reserveAdPriceInfo = "Some dummy description to explain the following concept. This price will be for 24 hours and if a user cancels the reservations before 24 hours then the amount will be automatically refunded to the buyer."; } diff --git a/lib/config/routes.dart b/lib/config/routes.dart index 3b7de2d..4c59feb 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -15,6 +15,7 @@ import 'package:mc_common_app/views/profile/profile_view.dart'; import 'package:mc_common_app/views/requests/create_request_page.dart'; import 'package:mc_common_app/views/requests/offer_list_page.dart'; import 'package:mc_common_app/views/requests/request_detail_page.dart'; +import 'package:mc_common_app/views/requests/requests_filter_view.dart'; import 'package:mc_common_app/views/requests/review_request_offer.dart'; import 'package:mc_common_app/views/setting_options/provider_license_page.dart'; import 'package:mc_common_app/views/setting_options/setting_option_help.dart'; @@ -96,6 +97,7 @@ class AppRoutes { //Requests static const String myRequestsPage = "/myRequestsPage"; + static const String requestsFilterView = "/requestsFilterView"; static const String createRequestPage = "/createRequestPage"; static const String offersListPage = "/offersListPage"; static const String requestsDetailPage = "/requestsDetailPage"; @@ -160,6 +162,7 @@ class AppRoutes { AppRoutes.createRequestPage: (context) => const CreateRequestPage(), AppRoutes.offersListPage: (context) => OfferListPage(offerListPageArguments: ModalRoute.of(context)!.settings.arguments as OfferListPageArguments), AppRoutes.reviewRequestOffer: (context) => const ReviewRequestOffer(), + AppRoutes.requestsFilterView: (context) => const RequestsFilterView(), }; } diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index 677490d..58208c7 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -5,6 +5,7 @@ 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'; +import 'package:mc_common_app/utils/date_helper.dart'; import 'package:mc_common_app/utils/enums.dart'; extension EmailValidator on String { @@ -575,8 +576,9 @@ extension DateTimeConversions on DateTime { String getTimeAgo({bool numericDates = true}) { final date2 = DateTime.now(); final difference = date2.difference(this); - - if ((difference.inDays / 7).floor() >= 1) { + if ((difference.inDays / 7).floor() >= 2) { + return DateHelper.formatAsDayMonthYear(date2); + } else if ((difference.inDays / 7).floor() >= 1) { return (numericDates) ? '1 week ago' : 'Last week'; } else if (difference.inDays >= 2) { return '${difference.inDays} days ago'; diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index be36937..92f745e 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -646,7 +646,22 @@ class CodegenLoader extends AssetLoader{ "cancelRequestPrompt": "هل تريد إلغاء هذا الطلب؟", "requestPermanentlyCancelled": "سيتم إلغاء طلبك بشكل نهائي. لا يمكنك التراجع عن هذا الإجراء.", "awaitingResponseFromCustomer": "في انتظار الرد من العميل", - "acknowledgePaymentToMowater": "أقر بأنه عند إكمال هذه الصفقة، سأدفع 2٪ من إجمالي هذه الصفقة لشركة مواتر مقابل خدماتهم." + "acknowledgePaymentToMowater": "أقر بأنه عند إكمال هذه الصفقة، سأدفع 2٪ من إجمالي هذه الصفقة لشركة مواتر مقابل خدماتهم.", + "requestsFilter": "تصفية الطلبات", + "searchByCondition": "البحث حسب الحالة", + "selectCondition": "حدد الحالة", + "searchByRequestType": "البحث حسب نوع الطلب", + "searchByCustomerName": "البحث حسب اسم العميل", + "searchByProviderName": "البحث حسب اسم المزود", + "searchByRequestStatus": "البحث حسب حالة الطلب", + "selectRequestType": "اختر نوع الطلب", + "selectRequestStatus": "اختر حالة الطلب", + "searchByRequestedDate": "البحث حسب تاريخ الطلب", + "selectDate": "اختر التاريخ", + "searchByVehicleModel": "البحث حسب طراز المركبة", + "customerCarePrompt": "هل لديك أي استفسار؟ نحن هنا لخدمتك. انقر هنا للتحدث مع خدمة العملاء لدينا الآن.", + "callNow": "اتصل الآن", + "condition": "الحالة" }; static const Map en_US = { "firstTimeLogIn": "First Time Log In", @@ -1281,7 +1296,22 @@ static const Map en_US = { "cancelRequestPrompt": "Do you want to cancel this request?", "requestPermanentlyCancelled": "Your request will be permanently cancelled. You cannot undo this action.", "awaitingResponseFromCustomer": "Awaiting Response From Customer", - "acknowledgePaymentToMowater": "I acknowledge that upon completion of this deal, I will pay 2% of this total deal to the Mowater company for their service." + "acknowledgePaymentToMowater": "I acknowledge that upon completion of this deal, I will pay 2% of this total deal to the Mowater company for their service.", + "requestsFilter": "Requests Filter", + "searchByCondition": "Search By Condition", + "selectCondition": "Select Condition", + "searchByRequestType": "Search By Request Type", + "searchByCustomerName": "Search By Customer Name", + "searchByProviderName": "Search By Provider Name", + "searchByRequestStatus": "Search By Request Status", + "selectRequestStatus": "Select Request Status", + "selectRequestType": "Select Request Type", + "searchByRequestedDate": "Search by Requested Date", + "selectDate": "Select Date", + "searchByVehicleModel": "Search By Vehicle Model", + "customerCarePrompt": "Got any question? We are here to service. Click here to talk to our customer care right now.", + "callNow": "Call Now", + "condition": "Condition" }; 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 44c3c36..9693a8e 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -610,5 +610,20 @@ abstract class LocaleKeys { static const requestPermanentlyCancelled = 'requestPermanentlyCancelled'; static const awaitingResponseFromCustomer = 'awaitingResponseFromCustomer'; static const acknowledgePaymentToMowater = 'acknowledgePaymentToMowater'; + static const requestsFilter = 'requestsFilter'; + static const searchByCondition = 'searchByCondition'; + static const selectCondition = 'selectCondition'; + static const searchByRequestType = 'searchByRequestType'; + static const searchByCustomerName = 'searchByCustomerName'; + static const searchByProviderName = 'searchByProviderName'; + static const searchByRequestStatus = 'searchByRequestStatus'; + static const selectRequestType = 'selectRequestType'; + static const selectRequestStatus = 'selectRequestStatus'; + static const searchByRequestedDate = 'searchByRequestedDate'; + static const selectDate = 'selectDate'; + static const searchByVehicleModel = 'searchByVehicleModel'; + static const customerCarePrompt = 'customerCarePrompt'; + static const callNow = 'callNow'; + static const condition = 'condition'; } diff --git a/lib/models/requests_models/provider_offers_model.dart b/lib/models/requests_models/provider_offers_model.dart index d566b9b..a101485 100644 --- a/lib/models/requests_models/provider_offers_model.dart +++ b/lib/models/requests_models/provider_offers_model.dart @@ -60,10 +60,21 @@ class ServiceProvidersOffers { String? mobileNo; String? email; String? companyName; + String? createdOn; int? offerCount; List? chatMessages; - ServiceProvidersOffers({this.providerId, this.name, this.mobileNo, this.email, this.companyName, this.offerCount, this.chatMessages, this.providerUserId}); + ServiceProvidersOffers({ + this.providerId, + this.name, + this.mobileNo, + this.email, + this.companyName, + this.offerCount, + this.chatMessages, + this.providerUserId, + this.createdOn, + }); ServiceProvidersOffers.fromJson(Map json) { providerId = json['providerID']; @@ -73,11 +84,12 @@ class ServiceProvidersOffers { email = json['email']; companyName = json['companyName']; offerCount = json['offerCount']; + createdOn = json['createdOn']; chatMessages = []; } @override String toString() { - return 'ServiceProvidersOffers{providerUserId: $providerUserId, providerId: $providerId, name: $name, mobileNo: $mobileNo, email: $email, companyName: $companyName, offerCount: $offerCount, chatMessages: $chatMessages}'; + return 'ServiceProvidersOffers{providerUserId: $providerUserId, providerId: $providerId, name: $name, mobileNo: $mobileNo, email: $email, companyName: $companyName,offeredItemCreatedOn: $createdOn, offerCount: $offerCount, chatMessages: $chatMessages}'; } } diff --git a/lib/models/requests_models/request_model.dart b/lib/models/requests_models/request_model.dart index 845fb40..95eb502 100644 --- a/lib/models/requests_models/request_model.dart +++ b/lib/models/requests_models/request_model.dart @@ -13,6 +13,7 @@ class RequestModel { String countryName; String customerName; String customerID; + String address; dynamic serviceProviders; int offerCount; int id; @@ -57,6 +58,7 @@ class RequestModel { required this.isChatted, required this.customerUserID, required this.customer, + required this.address, required this.brand, required this.model, required this.year, @@ -98,6 +100,7 @@ class RequestModel { vehicleTypeName: json["vehicleTypeName"], countryName: json["countryName"], customerName: json["customerName"] ?? "", + address: json["address"] ?? "", customerID: json["customerUserID"], serviceProviders: json["serviceProviders"], offerCount: json["offerCount"], diff --git a/lib/repositories/ads_repo.dart b/lib/repositories/ads_repo.dart index 6aa0cd3..6cf1a29 100644 --- a/lib/repositories/ads_repo.dart +++ b/lib/repositories/ads_repo.dart @@ -70,8 +70,7 @@ class AdsRepoImp implements AdsRepo { var params = { "SpecialServiceType": specialServiceId.toString(), }; - GenericRespModel adsGenericModel = - await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleAdsSpecialServicesGet, queryParameters: params); + GenericRespModel adsGenericModel = await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleAdsSpecialServicesGet, queryParameters: params); List vehicleAdsDuration = List.generate(adsGenericModel.data.length, (index) => SpecialServiceModel.fromJson(adsGenericModel.data[index])); return vehicleAdsDuration; } @@ -93,14 +92,7 @@ class AdsRepoImp implements AdsRepo { List vehiclePostingDamageParts = []; adsCreationPayloadModel.vehiclePosting!.vehiclePostingDamageParts?.forEach((element) { - var imageMap = { - "id": element.id ?? 0, - "comment": element.comment, - "vehicleImageBase64": element.vehicleImageBase64, - "vehicleDamagePartID": element.vehicleDamagePartID, - "vehiclePostingID": element.vehiclePostingID ?? 0, - "isActive": true - }; + var imageMap = {"id": element.id ?? 0, "comment": element.comment, "vehicleImageBase64": element.vehicleImageBase64, "vehicleDamagePartID": element.vehicleDamagePartID, "vehiclePostingID": element.vehiclePostingID ?? 0, "isActive": true}; vehiclePostingDamageParts.add(imageMap); }); var postParams = { @@ -172,8 +164,12 @@ class AdsRepoImp implements AdsRepo { } @override - Future> getExploreAdsBasedOnFilters( - {List? cityIdsList, List? vehicleModelYearIdsList, List? vehicleBrandIdsList, List? createdByRolesIdsList}) async { + Future> getExploreAdsBasedOnFilters({ + List? cityIdsList, + List? vehicleModelYearIdsList, + List? vehicleBrandIdsList, + List? createdByRolesIdsList, + }) async { var parameters = { "CityIDs": cityIdsList ?? [], "VehicleBrandIDs": vehicleBrandIdsList ?? [], diff --git a/lib/repositories/appointment_repo.dart b/lib/repositories/appointment_repo.dart index 9803fe4..09b8293 100644 --- a/lib/repositories/appointment_repo.dart +++ b/lib/repositories/appointment_repo.dart @@ -48,8 +48,6 @@ abstract class AppointmentRepo { Future createServiceAppointment({required List schedules, required int serviceProviderID}); Future cancelOrRescheduleServiceAppointment({required int serviceAppointmentID, required int serviceSlotID, required int appointmentScheduleAction}); - - } class AppointmentRepoImp implements AppointmentRepo { @@ -102,6 +100,7 @@ class AppointmentRepoImp implements AppointmentRepo { return await apiClient.postJsonForObject((json) => GenericRespModel.fromJson(json), ApiConsts.updateGroup, map, token: t); } + @override Future> mergeServiceIntoAvailableSchedules({ required List serviceItemIdsForHome, required List serviceItemIdsForWorkshop, @@ -251,6 +250,4 @@ class AppointmentRepoImp implements AppointmentRepo { String t = appState.getUser.data!.accessToken ?? ""; return await apiClient.postJsonForObject((json) => GenericRespModel.fromJson(json), ApiConsts.createMergeAppointment, map, token: t); } - - } diff --git a/lib/repositories/common_repo.dart b/lib/repositories/common_repo.dart index 5580913..bd83be8 100644 --- a/lib/repositories/common_repo.dart +++ b/lib/repositories/common_repo.dart @@ -45,7 +45,6 @@ abstract class CommonRepo { Future getRoles(); - Future getCarCheckServiceScheduleDetails({required double lat, required double long}); Future> getPhotographyServiceScheduleListByOffices({required double lat, required double long}); @@ -78,8 +77,6 @@ class CommonRepoImp implements CommonRepo { return await apiClient.getJsonForObject((json) => Role.fromJson(json), ApiConsts.GetProviderRoles); } - - @override Future getCarCheckServiceScheduleDetails({required double lat, required double long}) async { var params = { @@ -124,6 +121,17 @@ class CommonRepoImp implements CommonRepo { @override Future> getEnumTypeValues({int? enumTypeID, String? enumTypeName}) async { + if (enumTypeID == -1) { + // This is for the vehicle type condition (old, new) which will be added to API later + final Map json = { + "data": [ + {"id": 1, "enumTypeID": 0, "enumValueStr": "New", "enumValue": 1, "isActive": true}, + {"id": 2, "enumTypeID": 0, "enumValueStr": "Used", "enumValue": 2, "isActive": true}, + ], + }; + List enums = List.generate((json['data'] as List).length, (index) => EnumsModel.fromJson(json['data'][index])); + return enums; + } var postParams = {"enumTypeID": (enumTypeID ?? 0).toString(), "enumTypeName": enumTypeName ?? ""}; GenericRespModel enumGenericModel = await apiClient.postJsonForObject( (json) => GenericRespModel.fromJson(json), @@ -141,8 +149,7 @@ class CommonRepoImp implements CommonRepo { var postParams = { "VehicleType": vehicleTypeId.toString(), }; - GenericRespModel adsGenericModel = - await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleCategoryGet, queryParameters: postParams); + GenericRespModel adsGenericModel = await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleCategoryGet, queryParameters: postParams); List vehicleCategories = List.generate(adsGenericModel.data.length, (index) => VehicleCategoryModel.fromJson(adsGenericModel.data[index])); return vehicleCategories; } @@ -152,8 +159,7 @@ class CommonRepoImp implements CommonRepo { var postParams = { "CountryID": countryId.toString(), }; - GenericRespModel adsGenericModel = await apiClient.getJsonForObject( - token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleCityGet, queryParameters: countryId != -1 ? postParams : null); + GenericRespModel adsGenericModel = await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleCityGet, queryParameters: countryId != -1 ? postParams : null); List vehicleCities = List.generate(adsGenericModel.data.length, (index) => VehicleCityModel.fromJson(adsGenericModel.data[index])); return vehicleCities; } @@ -163,8 +169,7 @@ class CommonRepoImp implements CommonRepo { var postParams = { "VehicleType": vehicleTypeId.toString(), }; - GenericRespModel adsGenericModel = - await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleColorGet, queryParameters: postParams); + GenericRespModel adsGenericModel = await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleColorGet, queryParameters: postParams); List vehicleColors = List.generate(adsGenericModel.data.length, (index) => VehicleColorModel.fromJson(adsGenericModel.data[index])); return vehicleColors; } @@ -174,8 +179,7 @@ class CommonRepoImp implements CommonRepo { var postParams = { "VehicleType": vehicleTypeId.toString(), }; - GenericRespModel adsGenericModel = - await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleConditionGet, queryParameters: postParams); + GenericRespModel adsGenericModel = await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleConditionGet, queryParameters: postParams); List vehicleConditions = List.generate(adsGenericModel.data.length, (index) => VehicleConditionModel.fromJson(adsGenericModel.data[index])); return vehicleConditions; } @@ -196,8 +200,7 @@ class CommonRepoImp implements CommonRepo { var postParams = { "VehicleType": vehicleTypeId.toString(), }; - GenericRespModel adsGenericModel = - await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleMileageGet, queryParameters: postParams); + GenericRespModel adsGenericModel = await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleMileageGet, queryParameters: postParams); List vehicleMileages = List.generate(adsGenericModel.data.length, (index) => VehicleMileageModel.fromJson(adsGenericModel.data[index])); return vehicleMileages; } diff --git a/lib/repositories/request_repo.dart b/lib/repositories/request_repo.dart index e74631f..c3547c2 100644 --- a/lib/repositories/request_repo.dart +++ b/lib/repositories/request_repo.dart @@ -1,8 +1,11 @@ +import 'dart:developer'; + import 'package:mc_common_app/api/api_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/dependency_injection.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; +import 'package:mc_common_app/main.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'; @@ -16,6 +19,7 @@ abstract class RequestRepo { required String brand, required String model, required String year, + required bool isNew, required int countryID, required int cityID, required String price, @@ -31,6 +35,19 @@ abstract class RequestRepo { Future> getRequests({required int providerOrCustomerID}); + Future> getRequestsBasedOnFilters({ + required int requestTypeId, + int requestStatusId = 0, + int? cityId = 0, + int? vehicleYearId = 0, + String? vehicleModel = "", + String? vehicleBrand = "", + String? requestedDate = "", + int? conditionId = 0, + int pageIndex = 0, + int pageSize = 100, + }); + Future> getServiceRequestsForProviders({required int serviceProviderID}); Future updateRequestStatus({required RequestStatusEnum requestStatusEnum, required int requestId}); @@ -49,6 +66,7 @@ class RequestRepoImp implements RequestRepo { required String brand, required String model, required String year, + required bool isNew, required int countryID, required int cityID, required String price, @@ -58,13 +76,13 @@ class RequestRepoImp implements RequestRepo { required List requestImages, }) async { Map postParams = { - "customerID": AppState().getUser.data!.userInfo!.customerId ?? 0, + "customerID": appState.getUser.data!.userInfo!.customerId ?? 0, "requestType": requestTypeId, "vehicleTypeID": vehicleTypeId, "brand": brand, "model": model, "year": year, - "isNew": true, + "isNew": isNew, "countryID": countryID, "cityID": cityID, "price": price, @@ -89,7 +107,7 @@ class RequestRepoImp implements RequestRepo { "pageIndex": 0, }; - if (AppState().currentAppType == AppType.provider) { + if (appState.currentAppType == AppType.provider) { paramsForGetRequests.addEntries([MapEntry("providerID", providerOrCustomerID)]); } else { paramsForGetRequests.addEntries([MapEntry("customerID", providerOrCustomerID)]); @@ -109,6 +127,106 @@ class RequestRepoImp implements RequestRepo { return requests; } + @override + Future> getRequestsBasedOnFilters({ + required int requestTypeId, + int requestStatusId = 0, + int? cityId = 0, + int? vehicleYearId = 0, + String? vehicleModel = "", + String? vehicleBrand = "", + String? requestedDate = "", + int? conditionId = 0, + int pageIndex = 0, + int pageSize = 100, + }) async { + final paramsForGetRequests = { + "pageIndex": pageIndex, + "pageSize": pageSize, + "doPagination": true, + "requestType": requestTypeId.toString(), + "requestStatus": requestStatusId.toString(), + "brand": vehicleBrand.toString(), + "requestedDate": requestedDate, + "model": vehicleModel.toString(), + "year": vehicleYearId.toString(), + "cityID": cityId.toString(), + "isNew": conditionId == 0 ? "" : conditionId == 1, + }; + + if (appState.currentAppType == AppType.customer) { + paramsForGetRequests.addEntries([MapEntry("customerID", appState.getUser.data!.userInfo!.customerId ?? 0)]); + } else { + paramsForGetRequests.addEntries([MapEntry("providerID", appState.getUser.data!.userInfo!.providerId.toString())]); + } + + paramsForGetRequests.removeWhere((key, value) => value == "" || value == "0"); + + if (appState.currentAppType == AppType.provider && requestTypeId == 2) { + List requests = await getRequestBasedOnFiltersForProvidersServiceRequest(paramsForGetRequests); + return requests; + } + + GenericRespModel enumGenericModel = await apiClient.postJsonForObject( + (json) => GenericRespModel.fromJson(json), + ApiConsts.getRequest, + paramsForGetRequests, + token: appState.getUser.data!.accessToken, + ); + + List requests = List.generate( + enumGenericModel.data.length, + (index) => RequestModel.fromJson(enumGenericModel.data[index]), + ); + return requests; + } + + Future> getRequestBasedOnFiltersForProvidersServiceRequest(Map parameters) async { + List requestStatusList = [ + RequestStatusEnum.submitted.getIdFromRequestStatusEnum().toString(), + RequestStatusEnum.completed.getIdFromRequestStatusEnum().toString(), + RequestStatusEnum.inProgress.getIdFromRequestStatusEnum().toString(), + RequestStatusEnum.paid.getIdFromRequestStatusEnum().toString(), + RequestStatusEnum.delivery.getIdFromRequestStatusEnum().toString(), + RequestStatusEnum.shipping.getIdFromRequestStatusEnum().toString(), + ]; + + if (parameters['requestStatus'] != null && parameters['requestStatus'] != "0") { + parameters.addEntries([ + MapEntry("RequestStatuses", [parameters['requestStatus'].toString()]) + ]); + } else { + parameters.removeWhere((key, value) => key == "requestStatus"); + parameters.addEntries([MapEntry("RequestStatuses", requestStatusList)]); + } + + parameters.removeWhere((key, value) => key == "providerID"); + parameters.removeWhere((key, value) => key == "pageIndex"); + parameters.removeWhere((key, value) => key == "pageSize"); + parameters.removeWhere((key, value) => key == "doPagination"); + parameters.addEntries([MapEntry("ServiceProviderId", appState.getUser.data!.userInfo!.providerId.toString())]); + + log("parameters: ${parameters}"); + // final parameters = { + // "ServiceProviderId": serviceProviderID.toString(), + // "RequestType": "2", // Only to get the Service Request + // "RequestStatuses": requestStatusList, + // }; + GenericRespModel genericRespModel = await apiClient.getJsonForObject( + (json) => GenericRespModel.fromJson(json), + ApiConsts.getServiceRequestsForProvider, + queryParameters: parameters, + token: appState.getUser.data!.accessToken, + ); + List requests = List.generate( + genericRespModel.data.length, + (index) => RequestModel.fromJson( + genericRespModel.data[index], + ), + ); + return requests; + } + @override Future> getServiceRequestsForProviders({required int serviceProviderID}) async { List requestStatusList = [ @@ -121,7 +239,7 @@ class RequestRepoImp implements RequestRepo { ]; final parameters = { "ServiceProviderId": serviceProviderID.toString(), - "RequestTypeId": "2", // Only to get the Service Request + "RequestType": "2", // Only to get the Service Request "RequestStatuses": requestStatusList, }; GenericRespModel genericRespModel = await apiClient.getJsonForObject( diff --git a/lib/utils/dialogs_and_bottomsheets.dart b/lib/utils/dialogs_and_bottomsheets.dart index cc4896f..262aa53 100644 --- a/lib/utils/dialogs_and_bottomsheets.dart +++ b/lib/utils/dialogs_and_bottomsheets.dart @@ -37,7 +37,7 @@ Future showConfirmDialogs(context, msg, positiveText, negativeTe ); } -void actionConfirmationBottomSheet({required BuildContext context, required Widget title, required subtitle, required Widget actionButtonYes, required Widget actionButtonNo, Widget? confirmationWidget, bool isOnlyOneButton = false}) { +void actionConfirmationBottomSheet({required BuildContext context, required Widget title, required subtitle, required Widget actionButtonYes, required Widget actionButtonNo, Widget? checkBoxConfirmationWidget, bool isOnlyOneButton = false}) { showModalBottomSheet( context: context, isScrollControlled: true, @@ -49,9 +49,9 @@ void actionConfirmationBottomSheet({required BuildContext context, required Widg crossAxisAlignment: CrossAxisAlignment.start, children: [ "$subtitle".toText(fontSize: 14, fontWeight: MyFonts.Medium), - if (confirmationWidget != null) ...[ + if (checkBoxConfirmationWidget != null) ...[ 10.height, - confirmationWidget, + checkBoxConfirmationWidget, ], 25.height, if (isOnlyOneButton) ...[ diff --git a/lib/utils/enums.dart b/lib/utils/enums.dart index 94224e5..b214b10 100644 --- a/lib/utils/enums.dart +++ b/lib/utils/enums.dart @@ -14,6 +14,8 @@ class AppEnums { static const int myAdsFilterEnumId = 18; // My Ads Filter Enums static const int exploreAdsFilterEnumId = 23; // Explore Ads Filter Enums static const int appointmentsFilterEnumId = 13; // Appointments Filter Enums + static const int requestStatusesFilterEnumId = 15; // Appointments Filter Enums + static const int conditionEnumId = -1; // to get the Condition Filter Enums } enum VehicleType { diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart index 00eb22e..0d7464b 100644 --- a/lib/utils/utils.dart +++ b/lib/utils/utils.dart @@ -2,8 +2,12 @@ import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; +import 'package:easy_localization/easy_localization.dart'; 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/widgets/button/show_fill_button.dart'; import 'package:path/path.dart' as p; import 'package:fluttertoast/fluttertoast.dart'; @@ -473,15 +477,25 @@ class Utils { } static String getAdsPaymentBrowserForm({required int paymentId, required int adId}) { - return ' ' + - '' + - '' + - '
' + - '' + - '' + - '
' + - '' + - '' + - ''; + return '
'; + } + + // BOTTOM SHEETS + static void showHelpBottomSheet(BuildContext context) { + return actionConfirmationBottomSheet( + context: context, + title: LocaleKeys.help.tr().toText(fontSize: 28, isBold: true, letterSpacing: -1.44), + subtitle: LocaleKeys.customerCarePrompt.tr(), + isOnlyOneButton: true, + actionButtonYes: Expanded( + child: ShowFillButton( + maxHeight: 55, + title: LocaleKeys.callNow.tr(), + fontSize: 18, + onPressed: () {}, + ), + ), + actionButtonNo: const SizedBox(), + ); } } diff --git a/lib/view_models/ad_view_model.dart b/lib/view_models/ad_view_model.dart index fcd7756..da11c17 100644 --- a/lib/view_models/ad_view_model.dart +++ b/lib/view_models/ad_view_model.dart @@ -1554,7 +1554,7 @@ class AdVM extends BaseVM { if (isForSearch) { EnumsModel owner = exploreAdsEnums.firstWhere((element) => element.enumValue == id.selectedId); DropValue ownerValue = DropValue(owner.enumValue, "${owner.enumValueStr} Ads", ""); - if (!ifAlreadyExist(list: vehicleYearAdSearchHistory, value: ownerValue)) { + if (!ifAlreadyExist(list: vehicleAdOwnerSearchHistory, value: ownerValue)) { addToVehicleAdOwnerSearchHistory(value: ownerValue); } notifyListeners(); diff --git a/lib/view_models/appointments_view_model.dart b/lib/view_models/appointments_view_model.dart index 04791d4..b1d8d7e 100644 --- a/lib/view_models/appointments_view_model.dart +++ b/lib/view_models/appointments_view_model.dart @@ -74,6 +74,8 @@ class AppointmentsVM extends BaseVM { List serviceAppointmentScheduleList = []; + List allSelectedItemsInAppointments = []; + bool ifItemAlreadySelected(int id) { int indexFound = allSelectedItemsInAppointments.indexWhere((element) => element.id == id); if (indexFound != -1) { @@ -82,18 +84,6 @@ class AppointmentsVM extends BaseVM { return false; } - List allSelectedItemsInAppointments = []; - - // setupProviderAppointmentFilter() { - // appointmentsFilterOptions.clear(); - // appointmentsFilterOptions.add(FilterListModel(id: 0, title: "All Appointments", isSelected: true)); - // appointmentsFilterOptions.add(FilterListModel(id: 2, title: "Confirmed", isSelected: false)); - // appointmentsFilterOptions.add(FilterListModel(id: 3, title: "Arrived", isSelected: false)); - // appointmentsFilterOptions.add(FilterListModel(id: 7, title: "Work In Progress", isSelected: false)); - // appointmentsFilterOptions.add(FilterListModel(id: 8, title: "Completed", isSelected: false)); - // appointmentsFilterOptions.add(FilterListModel(id: 4, title: "Canceled", isSelected: false)); - // } - Future onItemsSelectedInService() async { if (currentServiceSelection != null) { int index = servicesInCurrentAppointment.indexWhere((element) => element.serviceId == currentServiceSelection!.serviceId!); @@ -483,12 +473,17 @@ class AppointmentsVM extends BaseVM { int selectedSubServicesCounter = 0; - onItemUpdateOrSelected(int index, bool selected, int itemId) { + void onItemUpdateOrSelected(int index, bool selected, int itemId) { int serviceIndex = servicesInCurrentAppointment.indexWhere((element) => element.serviceId == currentServiceSelection!.serviceId!); // print("servicesInCurrentAppointment: ${servicesInCurrentAppointment.length}"); - // if (serviceIndex == -1) { - // return; - // } + if (serviceIndex == -1) { + return; + } + + log("index: $index"); + log("selected: $selected"); + log("itemId: $itemId"); + log("servicesInCurrentAppointment: ${servicesInCurrentAppointment.length}"); serviceItemsFromApi[index].isUpdateOrSelected = selected; serviceItemsFromApi[index].isHomeSelected = isHomeTapped; @@ -503,10 +498,13 @@ class AppointmentsVM extends BaseVM { servicesInCurrentAppointment[serviceIndex].currentTotalServicePrice = servicesInCurrentAppointment[serviceIndex].currentTotalServicePrice + double.parse((serviceItemsFromApi[index].price) ?? "0.0"); } } - } - if (!selected) { + } else { + log("currentServiceSelection!.serviceItems: ${currentServiceSelection!.serviceItems!.length}"); + selectedSubServicesCounter = selectedSubServicesCounter - 1; currentServiceSelection!.serviceItems!.removeWhere((element) => element.id == itemId); + log("currentServiceSelection!.serviceItems: ${currentServiceSelection!.serviceItems!.length}"); + allSelectedItemsInAppointments.removeWhere((element) => element.id == itemId); servicesInCurrentAppointment[serviceIndex].currentTotalServicePrice = servicesInCurrentAppointment[serviceIndex].currentTotalServicePrice - double.parse((serviceItemsFromApi[index].price) ?? "0.0"); servicesInCurrentAppointment[serviceIndex].serviceItems!.removeWhere((element) => element.id == itemId); diff --git a/lib/view_models/dashboard_view_model_customer.dart b/lib/view_models/dashboard_view_model_customer.dart index 97e0b67..819b425 100644 --- a/lib/view_models/dashboard_view_model_customer.dart +++ b/lib/view_models/dashboard_view_model_customer.dart @@ -69,14 +69,13 @@ class DashboardVmCustomer extends BaseVM { appointmentsVM.populateBranchesFilterList(); appointmentsVM.populateAppointmentsFilterList(); adVM.populateAdsFilterList(); - requestsVM.populateRequestsFilterList(); - + requestsVM.populateDataForRequestsFilter(); await appointmentsVM.getMyAppointments(); await appointmentsVM.applyFilterOnBranches(index: 0); // to get all branches! await appointmentsVM.getMyRecentBranches(); // to get my recent branches! await adVM.getMyAds(); await adVM.getExploreAds(); - await requestsVM.getRequests(appType: AppType.customer); + await requestsVM.getRequests(); await adVM.getVehicleTypes(); await adVM.getVehicleAdsDuration(); await chatVM.buildHubConnection(context); diff --git a/lib/view_models/requests_view_model.dart b/lib/view_models/requests_view_model.dart index 56c9ba8..6d7df0b 100644 --- a/lib/view_models/requests_view_model.dart +++ b/lib/view_models/requests_view_model.dart @@ -20,13 +20,13 @@ import 'package:mc_common_app/models/general_models/widgets_models.dart'; import 'package:mc_common_app/repositories/common_repo.dart'; import 'package:mc_common_app/repositories/request_repo.dart'; import 'package:mc_common_app/services/common_services.dart'; -import 'package:mc_common_app/utils/date_helper.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/ad_view_model.dart'; import 'package:mc_common_app/view_models/base_view_model.dart'; import 'package:mc_common_app/view_models/chat_view_model.dart'; +import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart'; import 'package:provider/provider.dart'; import 'package:easy_localization/easy_localization.dart'; @@ -44,6 +44,9 @@ class RequestsVM extends BaseVM { List myRequestsTypeEnum = []; + List vehicleConditionsEnum = []; + List requestStatusesEnum = []; + RequestModel? currentSelectedRequest; void updateCurrentSelectedRequest(RequestModel value) { @@ -64,32 +67,61 @@ class RequestsVM extends BaseVM { notifyListeners(); } - populateRequestsFilterList() async { - if (requestsTypeFilterOptions.isNotEmpty) return; - - if (myRequestsTypeEnum.isEmpty) { - myRequestsTypeEnum = await commonRepo.getEnumTypeValues(enumTypeID: AppEnums.requestFilterEnumId); - } - for (int i = 0; i < myRequestsTypeEnum.length; i++) { - requestsTypeFilterOptions.add(FilterListModel(title: myRequestsTypeEnum[i].enumValueStr, isSelected: false, id: myRequestsTypeEnum[i].enumValue)); - } - - notifyListeners(); + Future getRequests({bool isNeedToRebuild = false}) async { + if (isNeedToRebuild) setState(ViewState.busy); + applyFilterOnRequestsVM(requestsTypeEnum: RequestsTypeEnum.specialCarRequest); + setState(ViewState.idle); } - Future getRequests({bool isNeedToRebuild = false, required AppType appType}) async { - if (isNeedToRebuild) setState(ViewState.busy); + Future getRequestsBasedOnFilters() async { + myFilteredRequests.clear(); + setState(ViewState.busy); + int requestTypeIdApi = requestsTypeFilterOptions.firstWhere((element) => element.isSelected).id; - int providerOrCustomerID = 0; - if (appType == AppType.provider) { - providerOrCustomerID = AppState().getUser.data!.userInfo!.providerId ?? 0; - } else { - providerOrCustomerID = AppState().getUser.data!.userInfo!.customerId ?? 0; + int requestCityIdApi = 0; + if (vehicleCityId.selectedId != -1) { + requestCityIdApi = vehicleCityId.selectedId; } - myRequests = await requestRepo.getRequests(providerOrCustomerID: providerOrCustomerID); - applyFilterOnRequestsVM(requestsTypeEnum: RequestsTypeEnum.specialCarRequest); + int requestConditionIdApi = 0; + if (vehicleConditionId.selectedId != -1) { + requestConditionIdApi = vehicleConditionId.selectedId; + } + int requestVehicleYearIdApi = 0; + if (vehicleYearId.selectedId != -1) { + requestVehicleYearIdApi = vehicleYearId.selectedId; + } + int requestStatusIdApi = 0; + if (requestStatusId.selectedId != -1) { + requestStatusIdApi = requestStatusId.selectedId; + } + + log("requestTypeIdApi: $requestTypeIdApi"); + log("requestCityIdApi: $requestCityIdApi"); + log("requestConditionIdApi: $requestConditionIdApi"); + log("requestVehicleBrandApi: $brand"); + log("requestVehicleModelApi: $model"); + log("requestVehicleYearIdApi: $requestVehicleYearIdApi"); + log("requestStatusIdApi: $requestStatusIdApi"); + + // try { + myFilteredRequests = await requestRepo.getRequestsBasedOnFilters( + requestTypeId: requestTypeIdApi, + cityId: requestCityIdApi, + conditionId: requestConditionIdApi, + vehicleBrand: brandForSearch, + vehicleModel: modelForSearch, + vehicleYearId: requestVehicleYearIdApi, + requestStatusId: requestStatusIdApi, + requestedDate: requestedDateFilter, + ); setState(ViewState.idle); - notifyListeners(); + return true; + // } catch (e, s) { + // logger.i("e: ${e.toString()}"); + // Utils.showToast("Need to ask Zahoor Bhai to add params for this API: /api/RequestManagement/Request_ServiceProvider"); + // setState(ViewState.idle); + // return false; + // } } Future> getServiceRequestsForProviders() async { @@ -127,11 +159,7 @@ class RequestsVM extends BaseVM { value.isSelected = false; } requestsTypeFilterOptions[requestsTypeEnum.getIdFromRequestTypeStatusEnum() - 1].isSelected = true; // -1 to match with the index - if (AppState().currentAppType == AppType.provider && requestsTypeEnum == RequestsTypeEnum.serviceRequest) { - myFilteredRequests = await getServiceRequestsForProviders(); - return; - } - myFilteredRequests = myRequests.where((element) => element.requestType == requestsTypeEnum.getIdFromRequestTypeStatusEnum()).toList(); + await getRequestsBasedOnFilters(); notifyListeners(); } @@ -165,18 +193,362 @@ class RequestsVM extends BaseVM { VehicleDetailsModel? vehicleDetails; List vehicleBrands = []; List vehicleModels = []; - List vehicleModelYears = []; + List vehicleYears = []; List vehicleCountries = []; List vehicleCities = []; + // ************ REQUESTS SEARCH FILTER **************** + + Future populateDataForRequestsFilter() async { + setState(ViewState.busy); + if (myRequestsTypeEnum.isEmpty) { + myRequestsTypeEnum = await commonRepo.getEnumTypeValues(enumTypeID: AppEnums.requestFilterEnumId); + } + + if (vehicleConditionsEnum.isEmpty) { + vehicleConditionsEnum = await commonRepo.getEnumTypeValues(enumTypeID: AppEnums.conditionEnumId); // to get the vehicle Condition Enum + } + if (requestStatusesEnum.isEmpty) { + requestStatusesEnum = await commonRepo.getEnumTypeValues(enumTypeID: AppEnums.requestStatusesFilterEnumId); + } + + if (requestsTypeFilterOptions.isEmpty) { + for (int i = 0; i < myRequestsTypeEnum.length; i++) { + requestsTypeFilterOptions.add(FilterListModel(title: myRequestsTypeEnum[i].enumValueStr, isSelected: false, id: myRequestsTypeEnum[i].enumValue)); + } + } + + if (vehicleBrands.isEmpty) { + vehicleBrands = await commonRepo.getVehicleBrands(vehicleTypeId: -1); + } + + if (vehicleYears.isEmpty) { + vehicleYears = await commonRepo.getVehicleModelYears(vehicleTypeId: -1); + } + + if (vehicleCities.isEmpty) { + vehicleCities = await commonRepo.getVehicleCities(countryId: -1); // fetch all the cities + } + setState(ViewState.idle); + } + + ifAlreadyExist({required List list, required DropValue value}) { + int index = list.indexWhere((element) { + return element.id == value.id; + }); + + if (index != -1) { + return true; + } + + return false; + } + + String requestedDateFilter = ""; + + void updateRequestedDate(String v) { + if (v.isNotEmpty) { + updateRequestsFiltersCounter(requestsFiltersCounter + 1); + } else { + updateRequestsFiltersCounter(requestsFiltersCounter - 1); + } + + requestedDateFilter = v; + notifyListeners(); + } + SelectionModel requestTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); - void updateSelectionRequestTypeId(SelectionModel id) async { - requestTypeId = id; - getVehicleTypes(); + void updateSelectionRequestTypeId(SelectionModel id, {bool isForSearch = false, bool shouldCallVehicleTypes = true, bool showSelectionInDropValue = true}) async { + if (isForSearch) { + EnumsModel requestEnum = myRequestsTypeEnum.firstWhere((element) => element.id == id.selectedId); + DropValue cityValue = DropValue(requestEnum.id, requestEnum.enumValueStr, ""); + if (!ifAlreadyExist(list: requestTypeSearchHistory, value: cityValue)) { + addToRequestTypeSearchHistory(value: cityValue); + } + } + if (showSelectionInDropValue) { + requestTypeId = id; + } + if (shouldCallVehicleTypes) { + getVehicleTypes(); + } notifyListeners(); } + SelectionModel requestStatusId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); + + void updateRequestStatusId(SelectionModel id, {bool isForSearch = false, bool showSelectionInDropValue = true}) async { + if (isForSearch) { + EnumsModel requestStatues = requestStatusesEnum.firstWhere((element) => element.enumValue == id.selectedId); + DropValue cityValue = DropValue(requestStatues.id, requestStatues.enumValueStr, ""); + if (!ifAlreadyExist(list: requestStatusesSearchHistory, value: cityValue)) { + addToRequestStatusesSearchHistory(value: cityValue); + } + } + if (showSelectionInDropValue) { + requestStatusId = id; + } + notifyListeners(); + } + + //BRANDS + List vehicleBrandsSearchHistory = []; + + void removeVehicleBrandsAdSearchHistory({bool isClear = false, required int index}) { + if (isClear) { + vehicleBrandsSearchHistory.clear(); + notifyListeners(); + return; + } + vehicleBrandsSearchHistory.removeAt(index); + if (vehicleBrandsSearchHistory.isEmpty) { + updateRequestsFiltersCounter(requestsFiltersCounter - 1); + } + notifyListeners(); + } + + void addToVehicleBrandsAdSearchHistory({required DropValue value}) { + if (vehicleBrandsSearchHistory.isEmpty) { + updateRequestsFiltersCounter(requestsFiltersCounter + 1); + } + vehicleBrandsSearchHistory.add(value); + notifyListeners(); + } //BRANDS + + List requestStatusesSearchHistory = []; + + void removeRequestStatusesSearchHistory({bool isClear = false, required int index}) { + if (isClear) { + requestStatusesSearchHistory.clear(); + notifyListeners(); + return; + } + requestStatusesSearchHistory.removeAt(index); + if (requestStatusesSearchHistory.isEmpty) { + updateRequestsFiltersCounter(requestsFiltersCounter - 1); + } + notifyListeners(); + } + + void addToRequestStatusesSearchHistory({required DropValue value}) { + if (requestStatusesSearchHistory.isEmpty) { + updateRequestsFiltersCounter(requestsFiltersCounter + 1); + } + requestStatusesSearchHistory.add(value); + notifyListeners(); + } + + // REQUEST TYPE + + List requestTypeSearchHistory = []; + + void removeRequestTypeSearchHistory({bool isClear = false, required int index}) { + if (isClear) { + requestTypeSearchHistory.clear(); + notifyListeners(); + return; + } + requestTypeSearchHistory.removeAt(index); + if (requestTypeSearchHistory.isEmpty) { + updateRequestsFiltersCounter(requestsFiltersCounter - 1); + } + notifyListeners(); + } + + void addToRequestTypeSearchHistory({required DropValue value}) { + if (requestTypeSearchHistory.isEmpty) { + updateRequestsFiltersCounter(requestsFiltersCounter + 1); + } + requestTypeSearchHistory.add(value); + notifyListeners(); + } + + // LOCATION + List vehicleLocationSearchHistory = []; + + void removeVehicleLocationAdSearchHistory({bool isClear = false, required int index}) { + if (isClear) { + vehicleLocationSearchHistory.clear(); + notifyListeners(); + return; + } + vehicleLocationSearchHistory.removeAt(index); + if (vehicleLocationSearchHistory.isEmpty) { + updateRequestsFiltersCounter(requestsFiltersCounter - 1); + } + notifyListeners(); + } + + void addToVehicleLocationAdSearchHistory({required DropValue value}) { + if (vehicleLocationSearchHistory.isEmpty) { + updateRequestsFiltersCounter(requestsFiltersCounter + 1); + } + vehicleLocationSearchHistory.add(value); + notifyListeners(); + } + + // OWNER + SelectionModel vehicleConditionId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); + + void updateSelectionVehicleConditionId(SelectionModel id, {bool isForSearch = false, bool showSelectionInDropValue = true}) { + if (isForSearch) { + EnumsModel owner = vehicleConditionsEnum.firstWhere((element) => element.enumValue == id.selectedId); + DropValue ownerValue = DropValue(owner.enumValue, owner.enumValueStr, ""); + if (!ifAlreadyExist(list: vehicleConditionSearchHistory, value: ownerValue)) { + addToVehicleConditionSearchHistory(value: ownerValue); + } + } + if (showSelectionInDropValue) { + vehicleConditionId = id; + } + notifyListeners(); + } + + List vehicleConditionSearchHistory = []; + + void removeVehicleConditionSearchHistory({bool isClear = false, required int index}) { + if (isClear) { + vehicleConditionSearchHistory.clear(); + notifyListeners(); + return; + } + vehicleConditionSearchHistory.removeAt(index); + if (vehicleConditionSearchHistory.isEmpty) { + updateRequestsFiltersCounter(requestsFiltersCounter - 1); + } + notifyListeners(); + } + + void addToVehicleConditionSearchHistory({required DropValue value}) { + if (vehicleConditionSearchHistory.isEmpty) { + updateRequestsFiltersCounter(requestsFiltersCounter + 1); + } + vehicleConditionSearchHistory.add(value); + notifyListeners(); + } + + // YEAR + List vehicleYearSearchHistory = []; + + void removeVehicleYearAdSearchHistory({bool isClear = false, required int index}) { + if (isClear) { + vehicleYearSearchHistory.clear(); + notifyListeners(); + return; + } + vehicleYearSearchHistory.removeAt(index); + if (vehicleYearSearchHistory.isEmpty) { + updateRequestsFiltersCounter(requestsFiltersCounter - 1); + } + notifyListeners(); + } + + void addToVehicleYearAdSearchHistory({required DropValue value}) { + if (vehicleYearSearchHistory.isEmpty) { + updateRequestsFiltersCounter(requestsFiltersCounter + 1); + } + vehicleYearSearchHistory.add(value); + notifyListeners(); + } + + int requestsFiltersCounter = 0; + + updateRequestsFiltersCounter(int value) { + requestsFiltersCounter = value; + notifyListeners(); + } + + SelectionModel vehicleBrandId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); + + void updateSelectionVehicleBrandId(SelectionModel id, {bool isForSearch = false, bool showSelectionInDropValue = true}) { + if (isForSearch) { + VehicleBrandsModel brand = vehicleBrands.firstWhere((element) => element.id == id.selectedId); + DropValue brandValue = DropValue(brand.id ?? 0, brand.vehicleBrandDescription ?? "", ""); + if (!ifAlreadyExist(list: vehicleBrandsSearchHistory, value: brandValue)) { + addToVehicleBrandsAdSearchHistory(value: brandValue); + } + } + if (showSelectionInDropValue) { + vehicleBrandId = id; + } + vehicleModelId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); + vehicleYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); + notifyListeners(); + } + + SelectionModel vehicleModelId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); + + void updateSelectionVehicleModelId(SelectionModel id) { + vehicleModelId = id; + vehicleYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); + notifyListeners(); + } + + SelectionModel vehicleYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); + + void updateSelectionVehicleYearId(SelectionModel id, {bool isForSearch = false, bool shouldSelectionInDropValue = true}) { + if (isForSearch) { + VehicleYearModel year = vehicleYears.firstWhere((element) => element.id == id.selectedId); + DropValue yearValue = DropValue(year.id ?? 0, year.modelYear ?? "", ""); + if (!ifAlreadyExist(list: vehicleYearSearchHistory, value: yearValue)) { + addToVehicleYearAdSearchHistory(value: yearValue); + } + } + if (shouldSelectionInDropValue) { + vehicleYearId = id; + } + notifyListeners(); + } + + SelectionModel vehicleCountryId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); + + void updateSelectionVehicleCountryId(SelectionModel id) async { + vehicleCountryId = id; + isCountryFetching = true; + notifyListeners(); + vehicleCities = await commonRepo.getVehicleCities(countryId: vehicleCountryId.selectedId); + isCountryFetching = false; + notifyListeners(); + } + + SelectionModel vehicleCityId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); + + void updateSelectionVehicleCityId(SelectionModel id, {bool isForSearch = false, bool shouldSelectionInDropValue = true}) async { + if (isForSearch) { + VehicleCityModel city = vehicleCities.firstWhere((element) => element.id == id.selectedId); + DropValue cityValue = DropValue(city.id ?? 0, city.cityName ?? "", ""); + if (!ifAlreadyExist(list: vehicleLocationSearchHistory, value: cityValue)) { + addToVehicleLocationAdSearchHistory(value: cityValue); + } + } + if (shouldSelectionInDropValue) { + vehicleCityId = id; + } + notifyListeners(); + } + + void clearRequestsFilters() { + clearRequestFilterSelections(); + vehicleBrandsSearchHistory.clear(); + vehicleConditionSearchHistory.clear(); + vehicleLocationSearchHistory.clear(); + vehicleYearSearchHistory.clear(); + requestStatusesSearchHistory.clear(); + requestsFiltersCounter = 0; + notifyListeners(); + } + + void clearRequestFilterSelections() { + requestedDateFilter = ''; + vehicleCityId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); + vehicleYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); + vehicleConditionId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); + requestStatusId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); + brandForSearch = ""; + modelForSearch = ""; + } + SelectionModel vehicleTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); Future getVehicleTypes() async { @@ -191,12 +563,16 @@ class RequestsVM extends BaseVM { vehicleTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleBrandId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleModelId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); - vehicleModelYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); + vehicleYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleCountryId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); vehicleCityId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); + vehicleConditionId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); pickedVehicleImages.clear(); price = ''; + model = ""; + brand = ""; description = ''; + address = ''; } void updateSelectionVehicleTypeId(SelectionModel id) async { @@ -216,37 +592,14 @@ class RequestsVM extends BaseVM { if (vehicleDetails != null) { vehicleBrands = vehicleDetails!.vehicleBrands!; vehicleModels = vehicleDetails!.vehicleModels!; - vehicleModelYears = vehicleDetails!.vehicleModelYears!; + vehicleYears = vehicleDetails!.vehicleModelYears!; vehicleCountries = vehicleDetails!.vehicleCountries!; + vehicleConditionsEnum = await commonRepo.getEnumTypeValues(enumTypeID: AppEnums.conditionEnumId); } isFetchingVehicleDetail = false; notifyListeners(); } - SelectionModel vehicleBrandId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); - - void updateSelectionVehicleBrandId(SelectionModel id) { - vehicleBrandId = id; - vehicleModelId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); - vehicleModelYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); - notifyListeners(); - } - - SelectionModel vehicleModelId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); - - void updateSelectionVehicleModelId(SelectionModel id) { - vehicleModelId = id; - vehicleModelYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); - notifyListeners(); - } - - SelectionModel vehicleModelYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); - - void updateSelectionVehicleModelYearId(SelectionModel id) { - vehicleModelYearId = id; - notifyListeners(); - } - bool shippingEnabled = false; void updateShippingEnabled(bool v) { @@ -255,28 +608,16 @@ class RequestsVM extends BaseVM { } bool isCountryFetching = false; - SelectionModel vehicleCountryId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); - - void updateSelectionVehicleCountryId(SelectionModel id) async { - vehicleCountryId = id; - isCountryFetching = true; - notifyListeners(); - vehicleCities = await commonRepo.getVehicleCities(countryId: vehicleCountryId.selectedId); - isCountryFetching = false; - notifyListeners(); - } - - SelectionModel vehicleCityId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); - - void updateSelectionVehicleCityId(SelectionModel id) { - vehicleCityId = id; - notifyListeners(); - } //Request Management String price = ""; String description = ""; String address = ""; + String model = ""; + String brand = ""; + + String modelForSearch = ""; + String brandForSearch = ""; void updatePrice(String v) { price = v; @@ -290,6 +631,32 @@ class RequestsVM extends BaseVM { address = v; } + void updateModel(String v) { + model = v; + } + + void updateBrand(String v) { + brand = v; + } + + void updateModelForSearch(String v) { + if (v.isNotEmpty) { + updateRequestsFiltersCounter(requestsFiltersCounter + 1); + } else { + updateRequestsFiltersCounter(requestsFiltersCounter - 1); + } + modelForSearch = v; + } + + void updateBrandForSearch(String v) { + if (v.isNotEmpty) { + updateRequestsFiltersCounter(requestsFiltersCounter + 1); + } else { + updateRequestsFiltersCounter(requestsFiltersCounter - 1); + } + brandForSearch = v; + } + Future convertFileToRequestPostingImages({required File file}) async { List imageBytes = await file.readAsBytes(); String image = base64Encode(imageBytes); @@ -299,7 +666,6 @@ class RequestsVM extends BaseVM { Future> getVehiclePostingImageList() async { List requestImages = []; - log("requestImages: ${pickedVehicleImages.length}"); for (var image in pickedVehicleImages) { var value = await convertFileToRequestPostingImages(file: File(image.filePath!)); @@ -323,9 +689,11 @@ class RequestsVM extends BaseVM { GenericRespModel respModel = await requestRepo.createRequest( requestTypeId: requestTypeId.selectedId, vehicleTypeId: vehicleTypeId.selectedId, - brand: vehicleBrandId.selectedOption, - model: vehicleModelId.selectedOption, - year: vehicleModelYearId.selectedOption, + brand: brand, + model: model, + year: vehicleYearId.selectedOption, + isNew: vehicleConditionId.selectedId == 1, + // 1 for new, 2 for Used countryID: vehicleCountryId.selectedId, cityID: vehicleCityId.selectedId, price: price, @@ -339,7 +707,7 @@ class RequestsVM extends BaseVM { Utils.showToast(LocaleKeys.requestSuccessfullyCreated.tr()); Navigator.pop(context); resetRequestCreationForm(); - await getRequests(appType: AppType.customer); + await getRequests(); } else { Utils.showToast(respModel.message.toString()); } @@ -358,15 +726,6 @@ class RequestsVM extends BaseVM { } else if (vehicleTypeId.selectedId == -1) { Utils.showToast(LocaleKeys.vehicle_selectValidVehicleType.tr()); isValid = false; - } else if (vehicleBrandId.selectedId == -1) { - Utils.showToast(LocaleKeys.selectValidBrand.tr()); - isValid = false; - } else if (vehicleModelId.selectedId == -1) { - Utils.showToast(LocaleKeys.selectValidModel.tr()); - isValid = false; - } else if (vehicleModelYearId.selectedId == -1) { - Utils.showToast(LocaleKeys.selectValidYear.tr()); - isValid = false; } else if (vehicleCountryId.selectedId == -1) { Utils.showToast(LocaleKeys.selectValidCountry.tr()); isValid = false; diff --git a/lib/view_models/service_view_model.dart b/lib/view_models/service_view_model.dart index 6e154f6..bf62eb7 100644 --- a/lib/view_models/service_view_model.dart +++ b/lib/view_models/service_view_model.dart @@ -6,7 +6,6 @@ import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart'; import 'package:mc_common_app/models/general_models/generic_resp_model.dart'; import 'package:mc_common_app/repositories/branch_repo.dart'; -import 'package:file_picker/file_picker.dart'; import 'package:flutter/cupertino.dart'; import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart'; import 'package:mc_common_app/models/provider_branches_models/profile/categroy.dart'; @@ -20,7 +19,6 @@ import 'package:mc_common_app/models/user_models/cities.dart'; import 'package:mc_common_app/models/user_models/country.dart'; import 'package:mc_common_app/repositories/common_repo.dart'; import 'package:mc_common_app/services/common_services.dart'; -import 'package:mc_common_app/utils/app_permission_handler.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'; @@ -65,6 +63,7 @@ class ServiceVM extends BaseVM { List commerceCertificates = []; List commercialCertificates = []; List vatCertificates = []; + List homePageBranches = []; void updateSelectionOpenTime(String date) { openTime = date; @@ -219,6 +218,7 @@ class ServiceVM extends BaseVM { Future getBranchAndServices() async { setState(ViewState.busy); branches = await branchRepo.getBranchAndServices(); + homePageBranches = branches!.data!.serviceProviderBranch!.where((element) => element.branchStatus == BranchStatusEnum.approvedOrActive).toList(); setState(ViewState.idle); } diff --git a/lib/view_models/user_view_model.dart b/lib/view_models/user_view_model.dart index d8e9a15..601bf10 100644 --- a/lib/view_models/user_view_model.dart +++ b/lib/view_models/user_view_model.dart @@ -647,7 +647,8 @@ class UserVM extends BaseVM { void otherLogin(BuildContext context) { _loginOtherAccount = true; - navigateReplaceWithName(context, AppRoutes.loginWithPassword); + navigateReplaceWithName(context, AppRoutes.registerSelection); + // navigateReplaceWithName(context, AppRoutes.loginWithPassword); } void changeLanguage(BuildContext context) { diff --git a/lib/views/advertisement/ad_creation_steps/vehicle_details_container.dart b/lib/views/advertisement/ad_creation_steps/vehicle_details_container.dart index 0e98a69..d82fa97 100644 --- a/lib/views/advertisement/ad_creation_steps/vehicle_details_container.dart +++ b/lib/views/advertisement/ad_creation_steps/vehicle_details_container.dart @@ -8,7 +8,6 @@ import 'package:mc_common_app/models/general_models/widgets_models.dart'; import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/view_models/ad_view_model.dart'; import 'package:mc_common_app/views/advertisement/ad_creation_steps/ad_creation_steps_containers.dart'; -import 'package:mc_common_app/views/advertisement/components/network_images_container_widget.dart'; import 'package:mc_common_app/views/advertisement/components/picked_images_container_widget.dart'; import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; 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 ba25f52..3d42cd6 100644 --- a/lib/views/advertisement/ads_detail_view/ads_detail_view.dart +++ b/lib/views/advertisement/ads_detail_view/ads_detail_view.dart @@ -113,13 +113,9 @@ class _AdsDetailViewState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Flexible( - child: "${widget.adDetails.vehicle!.vehicleTitle} | ${widget.adDetails.vehicle!.color!.label} | ${widget.adDetails.id}".toText( - fontSize: 18, - isBold: true, - maxLines: 2, - ), + child: "${widget.adDetails.vehicle!.vehicleTitle} | ${widget.adDetails.vehicle!.color!.label}".toText(fontSize: 16, maxLines: 2), ), - (widget.adDetails.vehicle!.cityName ?? "").toText(fontSize: 10, isBold: true, color: MyColors.lightTextColor), + (widget.adDetails.vehicle!.cityName ?? "").toText(fontSize: 10, color: MyColors.lightTextColor), ], ), Row( @@ -127,14 +123,11 @@ class _AdsDetailViewState extends State { children: [ Row( children: [ - ("${LocaleKeys.model.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor), - "${widget.adDetails.vehicle!.modelyear!.label}".toText( - fontSize: 14, - isBold: true, - ), + ("${LocaleKeys.model.tr()}: ").toText(fontSize: 12, color: MyColors.lightTextColor), + "${widget.adDetails.vehicle!.modelyear!.label}".toText(fontSize: 12), ], ), - "${widget.adDetails.vehicle!.countryID}".toText(fontSize: 10, isBold: true, color: MyColors.lightTextColor), + "${widget.adDetails.vehicle!.countryID}".toText(fontSize: 10, color: MyColors.lightTextColor), ], ), Row( @@ -142,39 +135,30 @@ class _AdsDetailViewState extends State { children: [ Row( children: [ - ("${LocaleKeys.mileage.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor), - "${widget.adDetails.vehicle!.mileage!.mileageEnd}Km".toText( - fontSize: 14, - isBold: true, - ), + ("${LocaleKeys.mileage.tr()}: ").toText(fontSize: 12, color: MyColors.lightTextColor), + "${widget.adDetails.vehicle!.mileage!.mileageEnd} Km".toText(fontSize: 12), ], ), - widget.adDetails.createdOn != null ? DateTime.parse(widget.adDetails.createdOn!).getTimeAgo().toText(fontSize: 10, isBold: true, color: MyColors.lightTextColor) : const SizedBox(), + widget.adDetails.createdOn != null ? DateTime.parse(widget.adDetails.createdOn!).getTimeAgo().toText(fontSize: 10, color: MyColors.lightTextColor) : const SizedBox(), ], ), Row( children: [ - ("${LocaleKeys.transmission.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor), - "${widget.adDetails.vehicle!.transmission!.label}".toText( - fontSize: 14, - isBold: true, - ), + ("${LocaleKeys.transmission.tr()}: ").toText(fontSize: 12, color: MyColors.lightTextColor), + "${widget.adDetails.vehicle!.transmission!.label}".toText(fontSize: 12), ], ), 8.height, - ("${LocaleKeys.description.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor), - "${widget.adDetails.vehicle!.vehicleDescription}".toText( - fontSize: 14, - isBold: true, - ), + ("${LocaleKeys.description.tr()}: ").toText(fontSize: 12, color: MyColors.lightTextColor), + "${widget.adDetails.vehicle!.vehicleDescription}".toText(fontSize: 14), if (widget.adDetails.isMyAd ?? false) ...[ 8.height, - ("${LocaleKeys.demand.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor), + ("${LocaleKeys.demand.tr()}: ").toText(fontSize: 12, color: MyColors.lightTextColor), Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ widget.adDetails.vehicle!.demandAmount!.toInt().toString().toText(fontSize: 30, height: 1.2, isBold: true), - LocaleKeys.sar.tr().toText(fontSize: 15, isBold: true, color: MyColors.lightTextColor).paddingOnly(bottom: 5), + LocaleKeys.sar.tr().toText(fontSize: 15, color: MyColors.lightTextColor).paddingOnly(bottom: 5), ], ), if (widget.adDetails.adPostStatus == AdPostStatus.expired) ...[ @@ -199,7 +183,7 @@ class _AdsDetailViewState extends State { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - LocaleKeys.bankDetails.tr().toText(fontSize: 18, isBold: true), + LocaleKeys.bankDetails.tr().toText(fontSize: 18), // Row( // children: [ // "Full Name: ".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor), @@ -211,20 +195,14 @@ class _AdsDetailViewState extends State { // ), Row( children: [ - ("${LocaleKeys.bankName.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor), - (adVM.adsBankDetailsModel!.bankName ?? "").toText( - fontSize: 14, - isBold: true, - ), + ("${LocaleKeys.bankName.tr()}: ").toText(fontSize: 14, color: MyColors.lightTextColor), + (adVM.adsBankDetailsModel!.bankName ?? "").toText(fontSize: 14), ], ), Row( children: [ - ("${LocaleKeys.iban.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor), - (adVM.adsBankDetailsModel!.iban ?? "").toText( - fontSize: 14, - isBold: true, - ), + ("${LocaleKeys.iban.tr()}: ").toText(fontSize: 14, color: MyColors.lightTextColor), + (adVM.adsBankDetailsModel!.iban ?? "").toText(fontSize: 14), ], ), ], @@ -243,12 +221,12 @@ class _AdsDetailViewState extends State { crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - LocaleKeys.rejectionComments.tr().toText(fontSize: 13, isBold: true, color: MyColors.lightTextColor), + LocaleKeys.rejectionComments.tr().toText(fontSize: 12), Row( children: [ - LocaleKeys.editAd.tr().toText(fontSize: 10, isBold: true), - 2.width, - const Icon(Icons.edit, size: 15), + LocaleKeys.editAd.tr().toText(fontSize: 12), + 6.width, + MyAssets.icEdit.buildSvg(height: 12).paddingOnly(bottom: 5), ], ).onPress(() async { Utils.showLoading(context); @@ -283,7 +261,7 @@ class _AdsDetailViewState extends State { children: [ MyAssets.carHitIcon.buildSvg(color: MyColors.darkTextColor), 10.width, - LocaleKeys.damagePartPictures.tr().toText(fontSize: 16), + LocaleKeys.damagePartPictures.tr().toText(fontSize: 14), ], ), const Icon(Icons.arrow_forward_ios_rounded, size: 20) diff --git a/lib/views/advertisement/ads_detail_view/components.dart b/lib/views/advertisement/ads_detail_view/components.dart index 10b8f39..efd1163 100644 --- a/lib/views/advertisement/ads_detail_view/components.dart +++ b/lib/views/advertisement/ads_detail_view/components.dart @@ -496,22 +496,35 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget { } Widget pendingForReviewAction({required String pendingText}) { - return Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Row( - children: [ - Expanded( - child: ShowFillButton( - isDisabled: true, - maxHeight: 55, - title: pendingText, - onPressed: () {}, - ), - ), - ], - ), - ], + bool isForShippingOrDelivery = false; + return Center( + child: pendingText.toText( + color: isForShippingOrDelivery ? MyColors.lightTextColor : MyColors.adPendingStatusColor, + fontSize: isForShippingOrDelivery ? 14 : 16, + // isItalic: true, + ), + ).toContainer( + marginAll: 5, + paddingAll: 12, + borderRadius: 8, + width: double.infinity, + backgroundColor: isForShippingOrDelivery ? MyColors.grey98Color.withOpacity(0.1) : MyColors.adPendingStatusColor.withOpacity(0.16), + ); + } + + Widget buildStatusContainer(String text, {bool isForShippingOrDelivery = true}) { + return Center( + child: text.toText( + color: isForShippingOrDelivery ? MyColors.lightTextColor : MyColors.adPendingStatusColor, + fontSize: isForShippingOrDelivery ? 14 : 16, + // isItalic: true, + ), + ).toContainer( + marginAll: 12, + paddingAll: 12, + borderRadius: 8, + width: double.infinity, + backgroundColor: isForShippingOrDelivery ? MyColors.grey98Color.withOpacity(0.1) : MyColors.adPendingStatusColor.withOpacity(0.16), ); } diff --git a/lib/views/advertisement/components/ads_list_widget.dart b/lib/views/advertisement/components/ads_list_widget.dart index df8c2c0..45d921f 100644 --- a/lib/views/advertisement/components/ads_list_widget.dart +++ b/lib/views/advertisement/components/ads_list_widget.dart @@ -90,30 +90,44 @@ class AdCard extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ - if (isAdsFragment && !context - .read() - .isExploreAdsTapped) ...[ + if (isAdsFragment && !context.read().isExploreAdsTapped) ...[ Utils.statusContainerChip(text: adDetails.statuslabel!, chipColor: Utils.getChipColorByAdStatus(adDetails.adPostStatus!)), ], - (adDetails.vehicle!.vehicleTitle ?? "").toText(fontSize: 16, letterSpacing: -0.64, height: 25 / 16,), + (adDetails.vehicle!.vehicleTitle ?? "").toText( + fontSize: 16, + letterSpacing: -0.64, + height: 25 / 16, + ), Row( children: [ ("${LocaleKeys.model.tr()}:").toText( + fontSize: 12, color: MyColors.lightTextColor, - letterSpacing: -0.48, height: 18 / 12, + letterSpacing: -0.48, + height: 18 / 12, ), 2.width, - (adDetails.vehicle!.modelyear!.label ?? "").toText(fontSize: 12, letterSpacing: -0.48, height: 18 / 12,), + (adDetails.vehicle!.modelyear!.label ?? "").toText( + fontSize: 12, + letterSpacing: -0.48, + height: 18 / 12, + ), ], ), Row( children: [ ("${LocaleKeys.mileage.tr()}:").toText( color: MyColors.lightTextColor, - fontSize: 12, letterSpacing: -0.48, height: 18 / 12, + fontSize: 12, + letterSpacing: -0.48, + height: 18 / 12, ), 2.width, - (adDetails.vehicle!.mileage!.mileageEnd ?? "").toText(fontSize: 12, letterSpacing: -0.48, height: 18 / 12,), + (adDetails.vehicle!.mileage!.mileageEnd ?? "").toText( + fontSize: 12, + letterSpacing: -0.48, + height: 18 / 12, + ), ], ), ], @@ -128,8 +142,8 @@ class AdCard extends StatelessWidget { ), adDetails.createdOn != null ? DateTime.parse(adDetails.createdOn!).getTimeAgo().toText( - color: MyColors.lightTextColor, - ) + color: MyColors.lightTextColor, + ) : const SizedBox(), ], ), @@ -143,13 +157,9 @@ class AdCard extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.end, children: [ - (adDetails.vehicle!.demandAmount!.toInt().toString()).toText(fontSize: 19, isBold: true, letterSpacing: -1.16, height: 29/19), + (adDetails.vehicle!.demandAmount!.toInt().toString()).toText(fontSize: 19, isBold: true, letterSpacing: -1.16, height: 29 / 19), 2.width, - LocaleKeys.sar.tr().toText( - color: MyColors.lightTextColor, - fontSize: 10, - letterSpacing: -0.4,height: 16/10 - ), + LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, fontSize: 10, letterSpacing: -0.4, height: 16 / 10), ], ), ), @@ -159,7 +169,6 @@ class AdCard extends StatelessWidget { width: 13, ), - // const Icon(Icons.arrow_forward) ], ), diff --git a/lib/views/appointments/appointment_detail_view.dart b/lib/views/appointments/appointment_detail_view.dart index cd86fea..1f0046e 100644 --- a/lib/views/appointments/appointment_detail_view.dart +++ b/lib/views/appointments/appointment_detail_view.dart @@ -46,7 +46,7 @@ class AppointmentDetailView extends StatelessWidget { child: Row( children: [ getBaseActionButtonWidget( - color: MyColors.grey98Color.withOpacity(0.3), + color: MyColors.grey98Color.withOpacity(0.1), textColor: MyColors.lightTextColor, onPressed: () {}, text: LocaleKeys.workInProgress.tr(), diff --git a/lib/views/appointments/book_appointments_item_view.dart b/lib/views/appointments/book_appointments_item_view.dart index f234a60..30c871c 100644 --- a/lib/views/appointments/book_appointments_item_view.dart +++ b/lib/views/appointments/book_appointments_item_view.dart @@ -28,8 +28,7 @@ class BookAppointmentsItemView extends StatelessWidget { onBackButtonTapped: () => Navigator.pop(context), ), body: Consumer( - builder: (BuildContext context, AppointmentsVM appointmentsVM, - Widget? child) { + builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -38,74 +37,46 @@ class BookAppointmentsItemView extends StatelessWidget { width: double.infinity, color: MyColors.darkTextColor, alignment: Alignment.centerLeft, - child: ("${appointmentsVM.selectedSubServicesCounter} " + - LocaleKeys.itemsSelected.tr()) - .toText(fontSize: 16, color: MyColors.white) - .horPaddingMain(), + child: ("${appointmentsVM.selectedSubServicesCounter} " + LocaleKeys.itemsSelected.tr()).toText(fontSize: 16, color: MyColors.white).horPaddingMain(), ), 16.height, Column( children: [ - LocaleKeys.workshopFullAccessServices.tr().toText( - fontSize: 12, - isItalic: true, - color: MyColors.lightTextColor), + LocaleKeys.workshopFullAccessServices.tr().toText(fontSize: 12, isItalic: true, color: MyColors.lightTextColor), 8.height, Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ - LocaleKeys.changeLocationService - .tr() - .toText(fontSize: 14, isBold: true), - LocaleKeys.edit.tr().toText( - fontSize: 14, - isBold: true, - isUnderLine: true, - color: MyColors.adPendingStatusColor), + LocaleKeys.changeLocationService.tr().toText(fontSize: 14, isBold: true), + LocaleKeys.edit.tr().toText(fontSize: 14, isBold: true, isUnderLine: true, color: MyColors.adPendingStatusColor), 5.width, MyAssets.icEdit.buildSvg(width: 17), ], ).onPress(() {}), 16.height, - Divider(), + const Divider(), ], ).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) => - Divider(), + separatorBuilder: (BuildContext context, int index) => const Divider(), itemCount: appointmentsVM.serviceItemsFromApi.length, itemBuilder: (BuildContext context, int index) { - ItemData itemData = - appointmentsVM.serviceItemsFromApi[index]; + ItemData itemData = appointmentsVM.serviceItemsFromApi[index]; return ServiceItemWithPriceCheckBox( - description: itemData.description ?? - LocaleKeys.someDescriptionSubServices.tr(), + description: itemData.description ?? LocaleKeys.someDescriptionSubServices.tr(), title: itemData.name!, isSelected: itemData.isUpdateOrSelected!, onSelection: (bool value) { print("itemId: ${itemData.id}"); - appointmentsVM.onItemUpdateOrSelected(index, - !itemData.isUpdateOrSelected!, itemData.id!); + appointmentsVM.onItemUpdateOrSelected(index, !itemData.isUpdateOrSelected!, itemData.id!); }, priceWidget: Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ - itemData.price! - .split(".") - .first - .toText(fontSize: 30, isBold: true), - LocaleKeys.sar - .tr() - .toText( - fontSize: 15, - isBold: true, - color: MyColors.lightTextColor) - .paddingOnly(bottom: 5), + itemData.price!.split(".").first.toText(fontSize: 30, isBold: true), + LocaleKeys.sar.tr().toText(fontSize: 15, isBold: true, color: MyColors.lightTextColor).paddingOnly(bottom: 5), ], ), ); @@ -113,17 +84,13 @@ class BookAppointmentsItemView extends StatelessWidget { ).expand(), Column( children: [ - Divider( - height: 1, - thickness: 0.7, - ), + const Divider(height: 1, thickness: 0.7), 8.height, if (appointmentsVM.selectSubServicesError != "") Row( mainAxisAlignment: MainAxisAlignment.end, children: [ - appointmentsVM.selectSubServicesError - .toText(fontSize: 14, color: Colors.red), + appointmentsVM.selectSubServicesError.toText(fontSize: 14, color: Colors.red), ], ).paddingOnly(right: 10), 8.height, @@ -135,8 +102,7 @@ class BookAppointmentsItemView extends StatelessWidget { maxHeight: 55, title: LocaleKeys.cancel.tr(), onPressed: () { - appointmentsVM - .resetCategorySelectionBottomSheet(); + appointmentsVM.resetCategorySelectionBottomSheet(); pop(context); }, backgroundColor: MyColors.greyButtonColor, @@ -150,8 +116,7 @@ class BookAppointmentsItemView extends StatelessWidget { maxHeight: 55, title: LocaleKeys.next.tr(), onPressed: () async { - bool resp = - appointmentsVM.validateItemsSelection(); + bool resp = appointmentsVM.validateItemsSelection(); if (resp) { appointmentsVM.onItemsSelectedInService(); Navigator.pop(context); @@ -165,10 +130,7 @@ class BookAppointmentsItemView extends StatelessWidget { // Navigator.of(context).pushReplacementNamed(AppRoutes.bookAppointmenServicesView); // } }, - backgroundColor: !appointmentsVM - .isServiceSelectionValidated() - ? MyColors.lightTextColor.withOpacity(0.6) - : MyColors.darkPrimaryColor, + backgroundColor: !appointmentsVM.isServiceSelectionValidated() ? MyColors.lightTextColor.withOpacity(0.6) : MyColors.darkPrimaryColor, ); }, ), diff --git a/lib/views/appointments/review_appointment_view.dart b/lib/views/appointments/review_appointment_view.dart index ba2a56e..f50b6ee 100644 --- a/lib/views/appointments/review_appointment_view.dart +++ b/lib/views/appointments/review_appointment_view.dart @@ -49,27 +49,30 @@ class ReviewAppointment extends StatelessWidget { children: [ (appointmentsVM.selectedBranchModel!.branchName ?? "").toText(fontSize: 16, isBold: true), Row( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - LocaleKeys.location.tr().toText(color: MyColors.lightTextColor, fontSize: 12), - 2.width, - ": ${appointmentsVM.selectedBranchModel!.branchDescription ?? ""}".toText(fontSize: 12), + Flexible( + child: (appointmentsVM.selectedBranchModel!.branchDescription ?? "").toText(fontSize: 12), + ), ], ), ], ), ), - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - "4.9".toText( - isUnderLine: true, - isBold: true, - fontSize: 12, - ), - 2.width, - MyAssets.starIcon.buildSvg(width: 12), - ], - ), + if (appointmentsVM.selectedBranchModel!.branchRateAvg != null && appointmentsVM.selectedBranchModel!.branchRateAvg != 0.0) ...[ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + "${appointmentsVM.selectedBranchModel!.branchRateAvg}".toText( + isUnderLine: true, + isBold: true, + fontSize: 12, + ), + 2.width, + MyAssets.starIcon.buildSvg(width: 12), + ], + ), + ] ], ), ], @@ -152,11 +155,11 @@ class ReviewAppointment extends StatelessWidget { LocaleKeys.timeLocation.tr().toText(fontSize: 16, isBold: true), 3.height, Row(children: [ - LocaleKeys.dateAndTime.tr().toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), + "${LocaleKeys.dateAndTime.tr()}: ".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), "${scheduleData.selectedCustomTimeDateSlotModel!.date!.date} at ${selectedTimeSlot}".toText(fontSize: 12, isBold: true), ]), Row(children: [ - ("${LocaleKeys.location.tr()} ").toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), + ("${LocaleKeys.location.tr()}: ").toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), (scheduleData.appointmentType == 2 ? LocaleKeys.home.tr() : LocaleKeys.workshop.tr()).toText(fontSize: 12, isBold: true), ]), ], @@ -202,7 +205,7 @@ class ReviewAppointment extends StatelessWidget { ], ), ], - ).toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.fromLTRB(21 , 0, 21, 12)); + ).toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.fromLTRB(21, 0, 21, 12)); }, ); } diff --git a/lib/views/appointments/widgets/common_appointment_slider_widget.dart b/lib/views/appointments/widgets/common_appointment_slider_widget.dart index a1e94c1..5e2339b 100644 --- a/lib/views/appointments/widgets/common_appointment_slider_widget.dart +++ b/lib/views/appointments/widgets/common_appointment_slider_widget.dart @@ -78,7 +78,7 @@ class CommonAppointmentSliderWidget extends StatelessWidget { decoration: const BoxDecoration(shape: BoxShape.circle, color: MyColors.darkTextColor), child: const Icon(Icons.add, color: MyColors.white), ), - ).padding(const EdgeInsets.symmetric(vertical: 10, horizontal: 21)); + ).padding(const EdgeInsets.symmetric(vertical: 10, horizontal: 0)); } else { return getCarouselSliderWidget(AppState().currentAppType, model); } diff --git a/lib/views/chat/widgets/chat_bottom_sheets.dart b/lib/views/chat/widgets/chat_bottom_sheets.dart index eb80295..2ee31af 100644 --- a/lib/views/chat/widgets/chat_bottom_sheets.dart +++ b/lib/views/chat/widgets/chat_bottom_sheets.dart @@ -23,7 +23,7 @@ void dealCompletedConfirmationBottomSheet({required BuildContext mainContext, re context: mainContext, title: LocaleKeys.doYouWantToCompleteThisDeal.tr().toText(fontSize: 26, isBold: true, letterSpacing: -1.44), subtitle: AppState().currentAppType == AppType.provider ? LocaleKeys.providerCompletingDealMeansThat.tr() : LocaleKeys.customerCompletingDealMeansThat.tr(), - confirmationWidget: Consumer(builder: (BuildContext context, ChatVM chatVM, Widget? child) { + checkBoxConfirmationWidget: Consumer(builder: (BuildContext context, ChatVM chatVM, Widget? child) { return Row( children: [ Expanded( diff --git a/lib/views/common_fragments/requests_fragment.dart b/lib/views/common_fragments/requests_fragment.dart index 5980ab9..608d373 100644 --- a/lib/views/common_fragments/requests_fragment.dart +++ b/lib/views/common_fragments/requests_fragment.dart @@ -3,7 +3,6 @@ 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/generated/locale_keys.g.dart'; -import 'package:mc_common_app/models/requests_models/request_model.dart'; import 'package:mc_common_app/utils/dialogs_and_bottomsheets.dart'; import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/view_models/requests_view_model.dart'; @@ -40,7 +39,7 @@ class MyRequestsFragment extends StatelessWidget { bool status = await requestVM.onActionRequestTapped(context: context, requestStatusEnum: RequestStatusEnum.cancelled, requestId: requestId); if (status) { - await requestVM.getRequests(isNeedToRebuild: true, appType: AppType.provider); + await requestVM.getRequests(isNeedToRebuild: true); } }, ), @@ -70,22 +69,36 @@ class MyRequestsFragment extends StatelessWidget { return true; } return false; - ; } @override Widget build(BuildContext context) { - return Scaffold( - appBar: CustomAppBar( - title: LocaleKeys.myRequests.tr(), - isRemoveBackButton: true, - ), - body: Container( - color: MyColors.backgroundColor, - width: double.infinity, - height: double.infinity, - child: Consumer(builder: (BuildContext context, RequestsVM requestsVM, Widget? child) { - return Column( + return Consumer(builder: (BuildContext context, RequestsVM requestsVM, Widget? child) { + return Scaffold( + appBar: CustomAppBar( + title: LocaleKeys.myRequests.tr(), + isRemoveBackButton: true, + actions: [ + Padding( + padding: EdgeInsets.only(top: requestsVM.requestsFiltersCounter > 0 ? 20 : 0, right: 21), + child: Badge( + isLabelVisible: requestsVM.requestsFiltersCounter > 0, + largeSize: 15, + smallSize: 20, + backgroundColor: MyColors.darkPrimaryColor, + label: Text('${requestsVM.requestsFiltersCounter}'), + child: MyAssets.searchIcon.buildSvg(), + ), + ).onPress(() { + navigateWithName(context, AppRoutes.requestsFilterView); + }) + ], + ), + body: Container( + color: MyColors.backgroundColor, + width: double.infinity, + height: double.infinity, + child: Column( children: [ 16.height, FiltersList( @@ -97,7 +110,7 @@ class MyRequestsFragment extends StatelessWidget { 8.height, Expanded( child: RefreshIndicator( - onRefresh: () async => await requestsVM.getRequests(isNeedToRebuild: true, appType: AppType.provider), + onRefresh: () async => await requestsVM.getRequests(isNeedToRebuild: true), child: requestsVM.state == ViewState.busy ? const Center(child: CircularProgressIndicator()) : requestsVM.myFilteredRequests.isEmpty @@ -105,6 +118,20 @@ class MyRequestsFragment extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ LocaleKeys.noRequeststoShow.tr().toText(fontSize: 16, color: MyColors.lightTextColor), + if (requestsVM.requestsFiltersCounter > 0) ...[ + 8.height, + InkWell( + onTap: () async { + requestsVM.clearRequestsFilters(); + await requestsVM.getRequestsBasedOnFilters(); + }, + child: LocaleKeys.clearFilters.tr().toText( + fontSize: 14, + isBold: true, + color: MyColors.darkPrimaryColor, + ), + ), + ], ], ) : ListView.separated( @@ -126,6 +153,7 @@ class MyRequestsFragment extends StatelessWidget { direction: shouldDismiss(requestsVM.myFilteredRequests[index].requestStatus) ? DismissDirection.endToStart : DismissDirection.none, confirmDismiss: (DismissDirection direction) async { cancelRequestBottomSheet(context, requestsVM.myFilteredRequests[index].id); + return; }, child: RequestItem(request: requestsVM.myFilteredRequests[index], appType: AppState().currentAppType, requestIndex: index), ); @@ -138,19 +166,19 @@ class MyRequestsFragment extends StatelessWidget { ), )) ], - ); - }), - ), - floatingActionButton: AppState().currentAppType == AppType.customer - ? FloatingActionButton( - onPressed: () => navigateWithName(context, AppRoutes.createRequestPage), - backgroundColor: MyColors.darkPrimaryColor, - child: const Icon( - Icons.add, - color: MyColors.white, - ), - ) - : null, - ); + ), + ), + floatingActionButton: AppState().currentAppType == AppType.customer + ? FloatingActionButton( + onPressed: () => navigateWithName(context, AppRoutes.createRequestPage), + backgroundColor: MyColors.darkPrimaryColor, + child: const Icon( + Icons.add, + color: MyColors.white, + ), + ) + : null, + ); + }); } } diff --git a/lib/views/requests/create_request_page.dart b/lib/views/requests/create_request_page.dart index fe289d6..74a614f 100644 --- a/lib/views/requests/create_request_page.dart +++ b/lib/views/requests/create_request_page.dart @@ -87,49 +87,49 @@ class CreateRequestPage extends StatelessWidget { ] else ...[ Column( children: [ - Builder(builder: (context) { - List vehicleBrandsDrop = []; - for (var element in requestsVM.vehicleBrands) { - vehicleBrandsDrop.add(DropValue(element.id?.toInt() ?? 0, element.vehicleBrandDescription ?? "", "")); - } - return DropdownField( - (DropValue value) => requestsVM.updateSelectionVehicleBrandId(SelectionModel(selectedId: value.id, selectedOption: value.value)), - list: vehicleBrandsDrop, - dropdownValue: requestsVM.vehicleBrandId.selectedId != -1 ? DropValue(requestsVM.vehicleBrandId.selectedId, requestsVM.vehicleBrandId.selectedOption, "") : null, - hint: LocaleKeys.brand.tr(), - errorValue: requestsVM.vehicleBrandId.errorValue, - ); - }), + TxtField( + hint: LocaleKeys.brand.tr(), + value: requestsVM.brand, + onChanged: (e) => requestsVM.updateBrand(e), + ), 8.height, - Builder(builder: (context) { - List vehicleModelsDrop = []; - for (var element in requestsVM.vehicleModels) { - if (requestsVM.vehicleBrandId.selectedId == element.vehicleBrandID) vehicleModelsDrop.add(DropValue(element.id?.toInt() ?? 0, element.model ?? "", "")); - } - return DropdownField( - (DropValue value) => requestsVM.updateSelectionVehicleModelId(SelectionModel(selectedId: value.id, selectedOption: value.value)), - list: vehicleModelsDrop, - dropdownValue: requestsVM.vehicleModelId.selectedId != -1 ? DropValue(requestsVM.vehicleModelId.selectedId, requestsVM.vehicleModelId.selectedOption, "") : null, - hint: LocaleKeys.model.tr(), - errorValue: requestsVM.vehicleModelId.errorValue, - ); - }), + TxtField( + hint: LocaleKeys.model.tr(), + value: requestsVM.model, + onChanged: (e) => requestsVM.updateModel(e), + ), 8.height, Builder(builder: (context) { List vehicleYearModelsDrop = []; - for (var element in requestsVM.vehicleModelYears) { + for (var element in requestsVM.vehicleYears) { vehicleYearModelsDrop.add(DropValue(element.id?.toInt() ?? 0, element.modelYear ?? "", "")); } return DropdownField( - (DropValue value) => requestsVM.updateSelectionVehicleModelYearId(SelectionModel(selectedId: value.id, selectedOption: value.value)), + (DropValue value) => requestsVM.updateSelectionVehicleYearId(SelectionModel(selectedId: value.id, selectedOption: value.value)), list: vehicleYearModelsDrop, - dropdownValue: requestsVM.vehicleModelYearId.selectedId != -1 ? DropValue(requestsVM.vehicleModelYearId.selectedId, requestsVM.vehicleModelYearId.selectedOption, "") : null, + dropdownValue: requestsVM.vehicleYearId.selectedId != -1 ? DropValue(requestsVM.vehicleYearId.selectedId, requestsVM.vehicleYearId.selectedOption, "") : null, hint: LocaleKeys.year.tr(), - errorValue: requestsVM.vehicleModelYearId.errorValue, + errorValue: requestsVM.vehicleYearId.errorValue, ); }), 8.height, + Builder( + builder: (context) { + List vehicleOwnerDrop = []; + for (var element in requestsVM.vehicleConditionsEnum) { + vehicleOwnerDrop.add(DropValue(element.id.toInt(), element.enumValueStr, "")); + } + return DropdownField( + (DropValue value) => requestsVM.updateSelectionVehicleConditionId(SelectionModel(selectedId: value.id, selectedOption: value.value), isForSearch: true), + list: vehicleOwnerDrop, + dropdownValue: requestsVM.vehicleConditionId.selectedId != -1 ? DropValue(requestsVM.vehicleConditionId.selectedId, requestsVM.vehicleConditionId.selectedOption, "") : null, + hint: LocaleKeys.condition.tr(), + errorValue: requestsVM.vehicleConditionId.errorValue, + ); + }, + ), + 8.height, Builder(builder: (context) { List vehicleCountriesDrop = []; for (var element in requestsVM.vehicleCountries) { diff --git a/lib/views/requests/offer_list_page.dart b/lib/views/requests/offer_list_page.dart index 5ce13c7..031de54 100644 --- a/lib/views/requests/offer_list_page.dart +++ b/lib/views/requests/offer_list_page.dart @@ -62,28 +62,17 @@ class OfferListPage extends StatelessWidget { children: [ Row( children: [ - "${offersModel.companyName}".toText( - color: MyColors.lightTextColor, - fontSize: 12, - ), - - //TODO: createdOn parameter need to be added in the backend - // if (offersModel.createdOn != null) ...[ - // DateTime.parse(offersModel.createdOn!).getTimeAgo().toText( - // color: MyColors.lightTextColor, - // ), - // ], - " | 1 hour ago".toText( - color: MyColors.lightTextColor, - fontSize: 12, - ), + "${offersModel.companyName}".toText(color: MyColors.lightTextColor, fontSize: 14), + if (offersModel.createdOn != null && offersModel.createdOn!.isNotEmpty) ...[ + " | ${DateTime.parse(offersModel.createdOn!).getTimeAgo()}".toText(color: MyColors.lightTextColor, fontSize: 14), + ], + // " | 1 hour ago".toText( + // color: MyColors.lightTextColor, + // fontSize: 12, + // ), ], ), - const Icon( - Icons.arrow_forward, - color: MyColors.darkIconColor, - size: 18, - ), + const Icon(Icons.arrow_forward, color: MyColors.darkIconColor, size: 18), ], ), ], diff --git a/lib/views/requests/request_bottomsheets.dart b/lib/views/requests/request_bottomsheets.dart index 8837df5..cc30ef7 100644 --- a/lib/views/requests/request_bottomsheets.dart +++ b/lib/views/requests/request_bottomsheets.dart @@ -8,8 +8,6 @@ import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/utils/utils.dart'; -import 'package:mc_common_app/view_models/chat_view_model.dart'; -import 'package:mc_common_app/view_models/dashboard_view_model_customer.dart'; import 'package:mc_common_app/view_models/requests_view_model.dart'; import 'package:mc_common_app/widgets/button/show_fill_button.dart'; import 'package:mc_common_app/widgets/checkbox_with_title_desc.dart'; @@ -168,7 +166,7 @@ Future buildRequestStatusUpdateSheetForProvider({required BuildContext mainConte status = await requestVM.onActionRequestTapped(context: mainContext, requestStatusEnum: RequestStatusEnum.delivery, requestId: requestId); } if (status) { - await requestVM.getRequests(isNeedToRebuild: true, appType: AppType.provider); + await requestVM.getRequests(isNeedToRebuild: true); pop(mainContext); } }, diff --git a/lib/views/requests/requests_filter_view.dart b/lib/views/requests/requests_filter_view.dart new file mode 100644 index 0000000..c7c07a6 --- /dev/null +++ b/lib/views/requests/requests_filter_view.dart @@ -0,0 +1,272 @@ +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'; +import 'package:mc_common_app/extensions/string_extensions.dart'; +import 'package:mc_common_app/generated/locale_keys.g.dart'; +import 'package:mc_common_app/main.dart'; +import 'package:mc_common_app/models/general_models/widgets_models.dart'; +import 'package:mc_common_app/theme/colors.dart'; +import 'package:mc_common_app/utils/enums.dart'; +import 'package:mc_common_app/utils/utils.dart'; +import 'package:mc_common_app/view_models/requests_view_model.dart'; +import 'package:mc_common_app/widgets/button/show_fill_button.dart'; +import 'package:mc_common_app/widgets/common_widgets/app_bar.dart'; +import 'package:mc_common_app/widgets/common_widgets/search_entity_widget.dart'; +import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart'; +import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; +import 'package:mc_common_app/widgets/txt_field.dart'; +import 'package:provider/provider.dart'; +import 'package:easy_localization/easy_localization.dart'; + +class RequestsFilterView extends StatefulWidget { + const RequestsFilterView({super.key}); + + @override + State createState() => _RequestsFilterViewState(); +} + +class _RequestsFilterViewState extends State { + late RequestsVM requestsVM; + + @override + void initState() { + requestsVM = context.read(); + scheduleMicrotask(() async { + await requestsVM.populateDataForRequestsFilter(); + }); + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: CustomAppBar( + title: LocaleKeys.requestsFilter.tr(), + profileImageUrl: MyAssets.bnCar, + isRemoveBackButton: false, + isDrawerEnabled: false, + onBackButtonTapped: () { + // context.read().resetValues(); + Navigator.pop(context); + }, + ), + body: Consumer( + builder: (BuildContext context, RequestsVM requestVM, Widget? child) { + if (requestVM.state == ViewState.busy) { + return const Center( + child: CircularProgressIndicator(), + ); + } + return WillPopScope( + onWillPop: () async { + requestVM.clearRequestFilterSelections(); + return true; + }, + child: Column( + children: [ + ListView( + children: [ + 20.height, + // SearchEntityWidget( + // title: LocaleKeys.searchByRequestType.tr(), + // actionWidget: Builder(builder: (context) { + // List requestTypeDrop = []; + // for (var element in requestsVM.myRequestsTypeEnum) { + // requestTypeDrop.add(DropValue(element.id.toInt(), element.enumValueStr, "")); + // } + // return DropdownField( + // (DropValue value) => requestsVM.updateSelectionRequestTypeId(SelectionModel(selectedId: value.id, selectedOption: value.value), shouldCallVehicleTypes: false, isForSearch: true), + // list: requestTypeDrop, + // dropdownValue: requestsVM.requestTypeId.selectedId != -1 ? DropValue(requestsVM.requestTypeId.selectedId, requestsVM.requestTypeId.selectedOption, "") : null, + // hint: LocaleKeys.selectRequestType.tr(), + // errorValue: requestsVM.requestTypeId.errorValue, + // ); + // }), + // historyContent: const [], + // // This is commented out because in the document it is only single value search not with the list value search. May be we can do that in future + // onHistoryItemDeleted: (index) => requestVM.removeRequestTypeSearchHistory(index: index), + // onHistoryItemTapped: (DropValue value) => null, + // ), + // const Divider(thickness: 1.2).paddingOnly(top: 7, bottom: 7), + SearchEntityWidget( + title: LocaleKeys.searchByRequestStatus.tr(), + actionWidget: Builder(builder: (context) { + List requestTypeDrop = []; + for (var element in requestsVM.requestStatusesEnum) { + requestTypeDrop.add(DropValue(element.enumValue.toInt(), element.enumValueStr, "")); + } + return DropdownField( + (DropValue value) => requestsVM.updateRequestStatusId(SelectionModel(selectedId: value.id, selectedOption: value.value), isForSearch: true), + list: requestTypeDrop, + dropdownValue: requestsVM.requestStatusId.selectedId != -1 ? DropValue(requestsVM.requestStatusId.selectedId, requestsVM.requestStatusId.selectedOption, "") : null, + hint: LocaleKeys.selectRequestStatus.tr(), + errorValue: requestsVM.requestStatusId.errorValue, + ); + }), + historyContent: const [], + onHistoryItemDeleted: (index) => requestVM.removeRequestStatusesSearchHistory(index: index), + onHistoryItemTapped: (DropValue value) => null, + ), + const Divider(thickness: 1.2).paddingOnly(top: 7, bottom: 7), + SearchEntityWidget( + title: LocaleKeys.searchByCity.tr(), + actionWidget: Builder(builder: (context) { + List vehicleBrandsDrop = []; + for (var element in requestVM.vehicleCities) { + vehicleBrandsDrop.add(DropValue(element.id?.toInt() ?? 0, element.cityName ?? "", "")); + } + return DropdownField( + (DropValue value) => requestVM.updateSelectionVehicleCityId(SelectionModel(selectedId: value.id, selectedOption: value.value), isForSearch: true), + list: vehicleBrandsDrop, + dropdownValue: requestVM.vehicleCityId.selectedId != -1 ? DropValue(requestVM.vehicleCityId.selectedId, requestVM.vehicleCityId.selectedOption, "") : null, + hint: LocaleKeys.selectCity.tr(), + errorValue: requestVM.vehicleCityId.errorValue, + ); + }), + historyContent: const [], + onHistoryItemDeleted: (index) => requestVM.removeVehicleLocationAdSearchHistory(index: index), + onHistoryItemTapped: (DropValue value) => null, + ), + const Divider(thickness: 1.2).paddingOnly(top: 7, bottom: 7), + SearchEntityWidget( + title: LocaleKeys.searchByBrandName.tr(), + actionWidget: TxtField( + hint: LocaleKeys.brand.tr(), + value: requestsVM.brandForSearch, + onChanged: (e) => requestsVM.updateBrandForSearch(e), + ), + historyContent: const [], + onHistoryItemDeleted: (index) => requestVM.removeVehicleBrandsAdSearchHistory(index: index), + onHistoryItemTapped: (DropValue value) => null, + ), + const Divider(thickness: 1.2).paddingOnly(top: 7, bottom: 7), + SearchEntityWidget( + title: LocaleKeys.searchByVehicleModel.tr(), + actionWidget: TxtField( + hint: LocaleKeys.model.tr(), + value: requestsVM.modelForSearch, + onChanged: (e) => requestsVM.updateModelForSearch(e), + ), + historyContent: const [], + onHistoryItemDeleted: (index) => requestVM.removeVehicleBrandsAdSearchHistory(index: index), + onHistoryItemTapped: (DropValue value) => null, + ), + const Divider(thickness: 1.2).paddingOnly(top: 7, bottom: 7), + SearchEntityWidget( + title: LocaleKeys.searchByVehicleYear.tr(), + actionWidget: Builder( + builder: (context) { + List vehicleBrandsDrop = []; + for (var element in requestVM.vehicleYears) { + vehicleBrandsDrop.add(DropValue(element.id?.toInt() ?? 0, element.modelYear ?? "", "")); + } + return DropdownField( + (DropValue value) => requestVM.updateSelectionVehicleYearId(SelectionModel(selectedId: value.id, selectedOption: value.value), isForSearch: true), + list: vehicleBrandsDrop, + dropdownValue: requestVM.vehicleYearId.selectedId != -1 ? DropValue(requestVM.vehicleYearId.selectedId, requestVM.vehicleYearId.selectedOption, "") : null, + hint: LocaleKeys.selectYear.tr(), + errorValue: requestVM.vehicleYearId.errorValue, + ); + }, + ), + historyContent: const [], + onHistoryItemDeleted: (index) => requestVM.removeVehicleYearAdSearchHistory(index: index), + onHistoryItemTapped: (DropValue value) => null, + ), + const Divider(thickness: 1.2).paddingOnly(top: 7, bottom: 7), + SearchEntityWidget( + title: LocaleKeys.searchByRequestedDate.tr(), + actionWidget: TxtField( + isBackgroundEnabled: true, + isNeedBorder: true, + hint: LocaleKeys.selectDate.tr(), + value: requestVM.requestedDateFilter, + isNeedClickAll: true, + postFixDataColor: MyColors.darkTextColor, + onTap: () async { + final formattedDate = await Utils.pickDateFromDatePicker(context, lastDate: DateTime.now(), firstDate: DateTime(2020)); + requestsVM.updateRequestedDate(formattedDate); + }, + ), + historyContent: const [], + onHistoryItemDeleted: (index) => requestVM.removeVehicleConditionSearchHistory(index: index), + onHistoryItemTapped: (DropValue value) => null, + ), + const Divider(thickness: 1.2).paddingOnly(top: 7, bottom: 7), + SearchEntityWidget( + title: LocaleKeys.searchByCondition.tr(), + actionWidget: Builder( + builder: (context) { + List vehicleOwnerDrop = []; + for (var element in requestVM.vehicleConditionsEnum) { + vehicleOwnerDrop.add(DropValue(element.id.toInt(), element.enumValueStr, "")); + } + return DropdownField( + (DropValue value) => requestVM.updateSelectionVehicleConditionId(SelectionModel(selectedId: value.id, selectedOption: value.value), isForSearch: true), + list: vehicleOwnerDrop, + dropdownValue: requestVM.vehicleConditionId.selectedId != -1 ? DropValue(requestVM.vehicleConditionId.selectedId, requestVM.vehicleConditionId.selectedOption, "") : null, + hint: LocaleKeys.selectCondition.tr(), + errorValue: requestVM.vehicleConditionId.errorValue, + ); + }, + ), + historyContent: const [], + onHistoryItemDeleted: (index) => requestVM.removeVehicleConditionSearchHistory(index: index), + onHistoryItemTapped: (DropValue value) => null, + ), + ], + ).expand(), + Container( + color: MyColors.white, + child: Column( + children: [ + 5.height, + Row( + children: [ + Expanded( + child: ShowFillButton( + maxHeight: 55, + title: LocaleKeys.search.tr(), + onPressed: () async { + bool status = await requestVM.getRequestsBasedOnFilters(); + if (status) { + Navigator.pop(context); + } + }, + backgroundColor: MyColors.darkPrimaryColor, + txtColor: MyColors.white, + fontSize: 18, + ), + ) + ], + ), + 8.height, + InkWell( + onTap: () { + requestsVM.clearRequestsFilters(); + }, + child: LocaleKeys.clearFilters.tr().toText( + fontSize: 14, + isBold: true, + color: MyColors.darkPrimaryColor, + ), + ), + 10.height, + ], + ), + ), + ], + ).horPaddingMain(), + ); + }, + ), + ); + } +} diff --git a/lib/views/requests/review_request_offer.dart b/lib/views/requests/review_request_offer.dart index 28d4f7d..4d37502 100644 --- a/lib/views/requests/review_request_offer.dart +++ b/lib/views/requests/review_request_offer.dart @@ -1,5 +1,4 @@ import 'package:easy_localization/easy_localization.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/classes/consts.dart'; @@ -11,6 +10,7 @@ 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/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/requests_view_model.dart'; import 'package:mc_common_app/views/advertisement/ad_creation_steps/ad_review_containers.dart'; import 'package:mc_common_app/widgets/button/show_fill_button.dart'; @@ -64,7 +64,7 @@ class ReviewRequestOffer extends StatelessWidget { } Widget buildLocationInformation(BuildContext context) { - // final requestVM = context.read(); + final requestVM = context.read(); return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -79,7 +79,7 @@ class ReviewRequestOffer extends StatelessWidget { Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - SingleDetailWidget(text: "${"Will get from API"} }", type: LocaleKeys.location.tr()), + SingleDetailWidget(text: requestVM.currentSelectedRequest!.address ?? "", type: LocaleKeys.location.tr()), 16.height, SingleDetailWidget(text: "N/A", type: "${LocaleKeys.email.tr()} / ${LocaleKeys.additionalAddressDetails.tr()}"), ], @@ -163,6 +163,12 @@ class ReviewRequestOffer extends StatelessWidget { isRemoveBackButton: false, isDrawerEnabled: false, onBackButtonTapped: () => Navigator.pop(context), + actions: [ + IconButton( + onPressed: () => Utils.showHelpBottomSheet(context), + icon: const Icon(Icons.help_outline_outlined).paddingOnly(right: 21), + ), + ], ), body: Column( crossAxisAlignment: CrossAxisAlignment.start, diff --git a/lib/views/requests/widget/request_item.dart b/lib/views/requests/widget/request_item.dart index d2ccdce..5c88a12 100644 --- a/lib/views/requests/widget/request_item.dart +++ b/lib/views/requests/widget/request_item.dart @@ -45,7 +45,9 @@ class RequestItem extends StatelessWidget { 6.height, "${request.brand} ${request.model}".toText(fontSize: 16, letterSpacing: -0.64), showItem("${LocaleKeys.model.tr()}:", "${request.year}"), - showItem("${LocaleKeys.customerName.tr()}:", request.customerName), + if (request.customerName.isNotEmpty) ...[ + showItem("${LocaleKeys.customerName.tr()}:", request.customerName), + ], ], ), ), @@ -103,7 +105,7 @@ class RequestItem extends StatelessWidget { ).toContainer(isShadowEnabled: true).onPress(() async { RequestsVM requestsVM = context.read(); requestsVM.updateCurrentSelectedRequest(request); - if (request.requestStatus == RequestStatusEnum.pending || request.requestStatus == RequestStatusEnum.cancelled) { + if (request.requestStatus == RequestStatusEnum.pending || request.requestStatus == RequestStatusEnum.cancelled || request.requestStatus == RequestStatusEnum.expired) { return; } if (appType == AppType.provider) { diff --git a/lib/views/user/complete_profile_page.dart b/lib/views/user/complete_profile_page.dart index ffa7189..6d34181 100644 --- a/lib/views/user/complete_profile_page.dart +++ b/lib/views/user/complete_profile_page.dart @@ -1,3 +1,4 @@ +import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; @@ -112,6 +113,8 @@ class _CompleteProfilePageState extends State { ), 50.height, Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, children: [ Consumer(builder: (BuildContext context, UserVM userVM, Widget? child) { return Checkbox( @@ -122,21 +125,40 @@ class _CompleteProfilePageState extends State { }, ); }), + Expanded( - child: Column( - children: [ - LocaleKeys.termsOfService.tr().toText(fontSize: 12), - LocaleKeys.terms.tr().toText(fontSize: 12, color: MyColors.darkPrimaryColor), - ], - ), - ), - Theme( - data: ThemeData(unselectedWidgetColor: Colors.transparent), - child: Checkbox( - value: false, - onChanged: (_) {}, + child: Text.rich( + TextSpan( + children: [ + TextSpan( + text: LocaleKeys.termsOfService.tr(), + style: const TextStyle(fontSize: 12, fontWeight: MyFonts.Medium), + ), + TextSpan( + text: " ${LocaleKeys.terms.tr()}", + style: const TextStyle( + decoration: TextDecoration.underline, + fontSize: 12, + color: MyColors.darkPrimaryColor, + fontWeight: MyFonts.Bold, + )) + ], + ), ), ) + // Column( + // children: [ + // LocaleKeys.termsOfService.tr().toText(fontSize: 12), + // LocaleKeys.terms.tr().toText(fontSize: 12, color: MyColors.darkPrimaryColor), + // ], + // ), + // Theme( + // data: ThemeData(unselectedWidgetColor: Colors.transparent), + // child: Checkbox( + // value: false, + // onChanged: (_) {}, + // ), + // ) ], ), 16.height, diff --git a/lib/views/user/register_page.dart b/lib/views/user/register_page.dart index bfbf74f..31c2e05 100644 --- a/lib/views/user/register_page.dart +++ b/lib/views/user/register_page.dart @@ -26,11 +26,13 @@ class _RegisterPageState extends State { TextEditingController emailController = TextEditingController(); + DropValue? selectedDrop; + @override Widget build(BuildContext context) { final UserVM userVM = context.read(); return Scaffold( - appBar: CustomAppBar( isRemoveBackButton: true, title: ""), + appBar: CustomAppBar(isRemoveBackButton: true, title: ""), body: Container( width: double.infinity, height: double.infinity, @@ -41,13 +43,16 @@ class _RegisterPageState extends State { child: Column( children: [ 12.height, - LocaleKeys.signUp.tr().toText(fontSize: 20, letterSpacing: -1.44,), + LocaleKeys.signUp.tr().toText( + fontSize: 20, + letterSpacing: -1.44, + ), 20.height, LocaleKeys.enterPhoneNumber.tr().toText( color: MyColors.lightTextColor, textAlign: TextAlign.center, fontSize: 14, - height: 23 / 24, + height: 23 / 24, letterSpacing: -0.48, ), 30.height, @@ -57,12 +62,8 @@ class _RegisterPageState extends State { if (snapshot.hasData) { List dropList = []; snapshot.data?.data?.forEach((element) { - dropList.add(DropValue( - element.id ?? 0, - EasyLocalization.of(context)?.currentLocale?.countryCode == "SA" - ? "${element.countryNameN ?? ""} ${element.countryCode ?? ""}" - : "${element.countryName ?? ""} ${element.countryCode ?? ""}", - element.countryCode ?? "")); + dropList.add(DropValue(element.id ?? 0, + EasyLocalization.of(context)?.currentLocale?.countryCode == "SA" ? "${element.countryNameN ?? ""} ${element.countryCode ?? ""}" : "${element.countryName ?? ""} ${element.countryCode ?? ""}", element.countryCode ?? "")); }); return Column( children: [ @@ -70,12 +71,15 @@ class _RegisterPageState extends State { color: MyColors.lightTextColor, textAlign: TextAlign.center, fontSize: 14, - height: 23 / 24, + height: 23 / 24, letterSpacing: -0.48, ), 10.height, DropdownField( + dropdownValue: selectedDrop, (DropValue value) { + selectedDrop = value; + setState(() { countryCode = value.subValue; countryId = value.id; @@ -96,7 +100,7 @@ class _RegisterPageState extends State { color: MyColors.lightTextColor, textAlign: TextAlign.center, fontSize: 14, - height: 23 / 24, + height: 23 / 24, letterSpacing: -0.48, ), 10.height, diff --git a/lib/views/user/register_provider_page.dart b/lib/views/user/register_provider_page.dart index eb59608..e6805c0 100644 --- a/lib/views/user/register_provider_page.dart +++ b/lib/views/user/register_provider_page.dart @@ -1,3 +1,5 @@ +import 'dart:developer'; + import 'package:mc_common_app/config/dependency_injection.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; @@ -76,6 +78,8 @@ class _RegisterPageState extends State { fontSize: 20, letterSpacing: -1.44, ), + 20.height, + LocaleKeys.enterPhoneNumber.tr().toText( color: MyColors.lightTextColor, textAlign: TextAlign.center, diff --git a/lib/widgets/button/show_fill_button.dart b/lib/widgets/button/show_fill_button.dart index 06d5f2b..54dc7db 100644 --- a/lib/widgets/button/show_fill_button.dart +++ b/lib/widgets/button/show_fill_button.dart @@ -28,8 +28,8 @@ class ShowFillButton extends StatelessWidget { this.isDisabled = false, this.radius = 0, this.maxWidth = 88, - this.maxHeight = 45, - this.fontSize = 15, + this.maxHeight = 55, + this.fontSize = 18, this.horizontalPadding = 16, this.isFlatButton = false, this.isBold = false, @@ -44,25 +44,25 @@ class ShowFillButton extends StatelessWidget { Widget build(BuildContext context) { return isFlatButton ? Container( - height: maxHeight, - padding: const EdgeInsets.only( - left: 20, - right: 20, - ), - child: showButton(), - ) + height: maxHeight, + padding: const EdgeInsets.only( + left: 20, + right: 20, + ), + child: showButton(), + ) : Padding( - padding: margin ?? const EdgeInsets.all(0.0), - child: ConstrainedBox( - constraints: BoxConstraints( - minHeight: maxHeight, - minWidth: maxWidth, - maxHeight: maxHeight, - maxWidth: maxWidth, - ), - child: showButton(), - ), - ); + padding: margin ?? const EdgeInsets.all(0.0), + child: ConstrainedBox( + constraints: BoxConstraints( + minHeight: maxHeight, + minWidth: maxWidth, + maxHeight: maxHeight, + maxWidth: maxWidth, + ), + child: showButton(), + ), + ); } Widget showButton() { @@ -71,10 +71,10 @@ class ShowFillButton extends StatelessWidget { color: isDisabled ? MyColors.grey98Color.withOpacity(0.3) : (isFlatButton - ? null - : isFilled - ? backgroundColor - : null), + ? null + : isFilled + ? backgroundColor + : null), margin: EdgeInsets.symmetric(horizontal: horizontalMargin, vertical: verticalMargin), child: MaterialButton( onPressed: onPressed, @@ -84,25 +84,25 @@ class ShowFillButton extends StatelessWidget { ), child: iconWidget != null ? Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - iconWidget!, - title.toText( - fontSize: fontSize, - isBold: isBold, - fontWeight: MyFonts.Medium, - color: isDisabled ? MyColors.lightTextColor : txtColor, - maxLines: 1, - ), - ], - ) + mainAxisAlignment: MainAxisAlignment.center, + children: [ + iconWidget!, + title.toText( + fontSize: fontSize, + isBold: isBold, + fontWeight: MyFonts.Medium, + color: isDisabled ? MyColors.lightTextColor : txtColor, + maxLines: 1, + ), + ], + ) : title.toText( - fontSize: fontSize, - isBold: isBold, - fontWeight: MyFonts.Medium, - color: isDisabled ? MyColors.lightTextColor : txtColor, - maxLines: 1, - ), + fontSize: fontSize, + isBold: isBold, + fontWeight: MyFonts.Medium, + color: isDisabled ? MyColors.lightTextColor : txtColor, + maxLines: 1, + ), ), ); } diff --git a/lib/widgets/common_widgets/custom_add_button_widget.dart b/lib/widgets/common_widgets/custom_add_button_widget.dart index 5cb5b5a..9486fd9 100644 --- a/lib/widgets/common_widgets/custom_add_button_widget.dart +++ b/lib/widgets/common_widgets/custom_add_button_widget.dart @@ -25,7 +25,6 @@ class CustomAddButton extends StatelessWidget { const SizedBox(width: 10), text.toText( fontSize: 15, - isBold: true, color: MyColors.lightTextColor, ), ], diff --git a/lib/widgets/common_widgets/custom_rectangle_chip.dart b/lib/widgets/common_widgets/custom_rectangle_chip.dart index 509e664..4b112f3 100644 --- a/lib/widgets/common_widgets/custom_rectangle_chip.dart +++ b/lib/widgets/common_widgets/custom_rectangle_chip.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/theme/colors.dart'; @@ -32,7 +33,7 @@ class CustomRectangleChip extends StatelessWidget { height: height, child: Row( children: [ - text.toText(fontSize: 15, color: MyColors.darkTextColor), + text.toText(fontSize: 15, color: MyColors.darkTextColor, fontWeight: MyFonts.Medium), 8.width, Container( height: 15, diff --git a/lib/widgets/dropdown/dropdow_field.dart b/lib/widgets/dropdown/dropdow_field.dart index 3b2f55a..d0e40c7 100644 --- a/lib/widgets/dropdown/dropdow_field.dart +++ b/lib/widgets/dropdown/dropdow_field.dart @@ -68,8 +68,11 @@ class _DropdownFieldState extends State { iconEnabledColor: borderColor, iconDisabledColor: borderColor, isExpanded: true, - style: TextStyle(color: borderColor, fontSize: 15, ), - hint: (widget.hint ?? "").toText(color: borderColor, fontSize: 15,), + style: const TextStyle( + color: borderColor, + fontSize: 15, + ), + hint: (widget.hint ?? "").toText(color: borderColor, fontSize: 15, fontWeight: MyFonts.Medium), underline: Container(height: 0), onChanged: (DropValue? newValue) { setState(() { diff --git a/lib/widgets/extensions/extensions_widget.dart b/lib/widgets/extensions/extensions_widget.dart index eed7a60..7a42867 100644 --- a/lib/widgets/extensions/extensions_widget.dart +++ b/lib/widgets/extensions/extensions_widget.dart @@ -351,7 +351,7 @@ extension BuildSVG on String? { return SizedBox( height: height, width: width, - child: const Icon(Icons.error_outline_rounded), + child: SvgPicture.asset(MyAssets.providersIcon, color: MyColors.darkPrimaryColor).paddingAll(15), ); } diff --git a/lib/widgets/txt_field.dart b/lib/widgets/txt_field.dart index 11d4539..6ee781a 100644 --- a/lib/widgets/txt_field.dart +++ b/lib/widgets/txt_field.dart @@ -127,8 +127,8 @@ class TxtField extends StatelessWidget { ) : postfixWidget, prefixIcon: prefixData != null ? Icon(prefixData, color: borderColor) : preFixWidget, - labelStyle: TextStyle(color: borderColor, fontSize: 15, fontWeight: MyFonts.Medium), - hintStyle: TextStyle(color: borderColor, fontSize: 15, fontWeight: MyFonts.Medium), + labelStyle: const TextStyle(color: borderColor, fontSize: 15, fontWeight: MyFonts.Medium), + hintStyle: const TextStyle(color: borderColor, fontSize: 15, fontWeight: MyFonts.Medium), hintText: hint ?? "", contentPadding: prefixData == null ? EdgeInsets.only(