From 76fd46c654ae4e4aaf7ed8dde0f2878135fc7a21 Mon Sep 17 00:00:00 2001 From: Faiz Hashmi Date: Thu, 7 Dec 2023 10:02:49 +0300 Subject: [PATCH 1/5] models refinement --- lib/classes/app_state.dart | 2 +- lib/classes/consts.dart | 3 +- lib/config/routes.dart | 3 + lib/extensions/string_extensions.dart | 93 +++++++-- lib/models/account.dart | 44 ---- .../ss_car_check_schedule_model.dart | 4 +- .../ss_photo_schedule_model.dart | 4 +- .../schedule_model.dart | 0 .../service_schedule_model.dart | 2 +- lib/models/chat/cat_message_model.dart | 49 +++++ lib/models/config_model.dart | 12 -- lib/models/content_info_model.dart | 65 ------ lib/models/{ => general}/enums_model.dart | 0 .../{ => general}/generic_resp_model.dart | 0 lib/models/{ => general}/m_response.dart | 0 .../{ => general}/post_params_model.dart | 0 lib/models/{ => general}/widgets_models.dart | 0 lib/models/member_model.dart | 62 ------ lib/models/parent_list.dart | 26 --- .../provider_model.dart | 0 lib/models/response_models.dart | 34 --- lib/models/subscription_model.dart | 125 ----------- lib/models/surah_model.dart | 74 ------- .../account.dart | 44 ++++ .../config_model.dart | 12 ++ .../content_info_model.dart | 65 ++++++ .../member_model.dart | 62 ++++++ .../parent_list.dart | 26 +++ .../provider_category_model.dart | 3 + .../provider_service_model.dart | 2 + .../response_models.dart | 34 +++ .../subscription_model.dart | 125 +++++++++++ .../surah_model.dart | 74 +++++++ lib/repositories/ads_repo.dart | 2 +- lib/repositories/appointment_repo.dart | 8 +- lib/repositories/chat_repo.dart | 66 ++---- lib/repositories/common_repo.dart | 4 +- lib/repositories/payments_repo.dart | 2 +- lib/repositories/provider_repo.dart | 2 +- lib/repositories/request_repo.dart | 2 +- lib/repositories/user_repo.dart | 2 +- lib/utils/enums.dart | 17 ++ lib/view_models/ad_view_model.dart | 8 +- lib/view_models/appointments_view_model.dart | 8 +- lib/view_models/chat_view_model.dart | 59 ++++-- lib/view_models/requests_view_model.dart | 120 +++++++++-- lib/view_models/user_view_model.dart | 2 +- .../ad_duration_container.dart | 2 +- .../vehicle_details_container.dart | 2 +- .../ad_duration_selection_sheet_content.dart | 2 +- lib/views/advertisement/ads_detail_view.dart | 108 +++++++--- lib/views/advertisement/ads_filter_view.dart | 2 +- .../advertisement/bottom_sheet_content.dart | 2 +- .../advertisement/select_ad_type_view.dart | 2 +- .../book_appointment_schedules_view.dart | 3 +- .../appointments/review_appointment_view.dart | 2 +- ...appointment_service_pick_bottom_sheet.dart | 2 +- .../widgets/custom_calender_widget.dart | 2 +- lib/views/chat/chat_view.dart | 195 ++++++++++++++++++ lib/views/requests/create_request_page.dart | 2 +- lib/views/requests/widget/request_item.dart | 12 +- lib/views/user/register_selection_page.dart | 13 ++ .../common_widgets/categories_list.dart | 2 +- lib/widgets/common_widgets/time_slots.dart | 4 +- pubspec.lock | 48 +---- pubspec.yaml | 2 +- 66 files changed, 1107 insertions(+), 651 deletions(-) delete mode 100644 lib/models/account.dart rename lib/models/{ => appointments_models}/schedule_model.dart (100%) rename lib/models/{ => appointments_models}/service_schedule_model.dart (98%) create mode 100644 lib/models/chat/cat_message_model.dart delete mode 100644 lib/models/config_model.dart delete mode 100644 lib/models/content_info_model.dart rename lib/models/{ => general}/enums_model.dart (100%) rename lib/models/{ => general}/generic_resp_model.dart (100%) rename lib/models/{ => general}/m_response.dart (100%) rename lib/models/{ => general}/post_params_model.dart (100%) rename lib/models/{ => general}/widgets_models.dart (100%) delete mode 100644 lib/models/member_model.dart delete mode 100644 lib/models/parent_list.dart rename lib/models/{model => provider_branches_models}/provider_model.dart (100%) delete mode 100644 lib/models/response_models.dart delete mode 100644 lib/models/subscription_model.dart delete mode 100644 lib/models/surah_model.dart create mode 100644 lib/models/verify_usage_before_deleting_these/account.dart create mode 100644 lib/models/verify_usage_before_deleting_these/config_model.dart create mode 100644 lib/models/verify_usage_before_deleting_these/content_info_model.dart create mode 100644 lib/models/verify_usage_before_deleting_these/member_model.dart create mode 100644 lib/models/verify_usage_before_deleting_these/parent_list.dart rename lib/models/{ => verify_usage_before_deleting_these}/provider_category_model.dart (98%) rename lib/models/{ => verify_usage_before_deleting_these}/provider_service_model.dart (99%) create mode 100644 lib/models/verify_usage_before_deleting_these/response_models.dart create mode 100644 lib/models/verify_usage_before_deleting_these/subscription_model.dart create mode 100644 lib/models/verify_usage_before_deleting_these/surah_model.dart create mode 100644 lib/views/chat/chat_view.dart diff --git a/lib/classes/app_state.dart b/lib/classes/app_state.dart index 18dfa20..208654d 100644 --- a/lib/classes/app_state.dart +++ b/lib/classes/app_state.dart @@ -1,5 +1,5 @@ import 'package:google_maps_flutter/google_maps_flutter.dart'; -import 'package:mc_common_app/models/post_params_model.dart'; +import 'package:mc_common_app/models/general/post_params_model.dart'; import 'package:mc_common_app/models/user/user.dart'; import 'package:mc_common_app/utils/enums.dart'; diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index b05708b..d24672d 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -147,7 +147,8 @@ class GlobalConsts { static String fontZoomSize = "font_zoom_size"; static String welcomeVideoUrl = "welcomeVideoUrl"; static String doNotShowWelcomeVideo = "doNotShowWelcomeVideo"; - static String demandAmountError = "Demand Amount Cannot be Empty"; + static String demandAmountError = "Amount Cannot be Empty"; + static String descriptionError = "Description Cannot be Empty"; static String vehicleVinError = "Vehicle VIN Cannot be Empty"; static String vehicleTitleError = "Vehicle Title Cannot be Empty"; static String warrantyError = "Warranty Duration Cannot be Empty"; diff --git a/lib/config/routes.dart b/lib/config/routes.dart index 4a3ad64..e934484 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -71,6 +71,9 @@ class AppRoutes { static const String myRequestsPage = "/myRequestsPage"; static const String createRequestPage = "/createRequestPage"; static const String offersListPage = "/offersListPage"; + static const String requestsDetailPage = "/requestsDetailPage"; + static const String sendOfferPage = "/sendOfferPage"; + //Setting Options static const String settingOptionsFaqs = "/settingOptionsFaqs"; diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index 000ed6a..744d93e 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -235,6 +235,21 @@ extension RequestTypeTypeEnum on int { } } +extension RequestTypeStatusToInt on RequestsTypeEnum { + int getIdFromRequestTypeStatusEnum() { + switch (this) { + case RequestsTypeEnum.specialCarRequest: + return 1; + + case RequestsTypeEnum.serviceRequest: + return 2; + + default: + return 0; + } + } +} + extension AdPostStatusToInt on AdPostStatus { int getIdFromAdPostStatusEnum() { switch (this) { @@ -323,21 +338,6 @@ extension AppointmentStatusToInt on AppointmentStatusEnum { } } -extension RequestTypeStatusToInt on RequestsTypeEnum { - int getIdFromRequestTypeStatusEnum() { - switch (this) { - case RequestsTypeEnum.specialCarRequest: - return 1; - - case RequestsTypeEnum.serviceRequest: - return 2; - - default: - return 0; - } - } -} - extension CreatedByRoleEnumToInt on CreatedByRoleEnum { int getIdFromCreatedByRoleEnum() { switch (this) { @@ -548,3 +548,66 @@ extension FormatMonthByNumber on String { } } } + +extension ChatMessageTypeEnumExt on int { + ChatMessageTypeEnum toChatMessageTypeEnum() { + if (this == 1) { + return ChatMessageTypeEnum.freeText; + } else if (this == 2) { + return ChatMessageTypeEnum.freeText; + } + return ChatMessageTypeEnum.freeText; + } +} + +extension ChatMessageTypeToInt on ChatMessageTypeEnum { + int getIdFromChatMessageTypeEnum() { + switch (this) { + case ChatMessageTypeEnum.freeText: + return 1; + + case ChatMessageTypeEnum.offer: + return 2; + + default: + return 0; + } + } +} + +extension RequestOfferStatusEnumExt on int { + RequestOfferStatusEnum toChatMessageTypeEnum() { + if (this == 1) { + return RequestOfferStatusEnum.offer; + } else if (this == 2) { + return RequestOfferStatusEnum.negotiate; + } else if (this == 3) { + return RequestOfferStatusEnum.accepted; + } else if (this == 4) { + return RequestOfferStatusEnum.rejected; + } else if (this == 5) { + return RequestOfferStatusEnum.cancel; + } + return RequestOfferStatusEnum.cancel; + } +} + +extension RequestOfferStatusEnumToInt on RequestOfferStatusEnum { + int getIdFromRequestOfferStatusEnum() { + switch (this) { + case RequestOfferStatusEnum.offer: + return 1; + case RequestOfferStatusEnum.negotiate: + return 2; + case RequestOfferStatusEnum.accepted: + return 3; + case RequestOfferStatusEnum.rejected: + return 4; + case RequestOfferStatusEnum.cancel: + return 5; + + default: + return 0; + } + } +} diff --git a/lib/models/account.dart b/lib/models/account.dart deleted file mode 100644 index ecafb24..0000000 --- a/lib/models/account.dart +++ /dev/null @@ -1,44 +0,0 @@ -// To parse this JSON data, do -// -// final account = accountFromJson(jsonString); - -import 'dart:convert'; - -import 'package:mc_common_app/models/parent_list.dart'; - - - - -Account accountFromJson(String str) => Account.fromJson(json.decode(str)); - -String accountToJson(Account data) => json.encode(data.toJson()); - -class Account { - Account({ - required this.parentList, - required this.selectedItem, - }); - - List? parentList; - int selectedItem; - - factory Account.fromJson(Map json) => Account( - parentList: json["parentList"] == null - ? null - : List.from( - json["parentList"].map((x) => ParentList.fromJson(x))), - selectedItem: - json["selectedItem"] == null ? null : json["selectedItem"], - ); - - Map toJson() => { - "parentList": parentList == null - ? null - : List.from(parentList!.map((x) => x.toJson())), - "selectedItem": selectedItem == null ? null : selectedItem, - }; - - Map toJsonData() => { - "selectedItem": selectedItem == null ? null : selectedItem, - }; -} diff --git a/lib/models/advertisment_models/ss_car_check_schedule_model.dart b/lib/models/advertisment_models/ss_car_check_schedule_model.dart index 0c0e22d..bd15655 100644 --- a/lib/models/advertisment_models/ss_car_check_schedule_model.dart +++ b/lib/models/advertisment_models/ss_car_check_schedule_model.dart @@ -1,5 +1,5 @@ -import 'package:mc_common_app/models/service_schedule_model.dart'; -import 'package:mc_common_app/models/widgets_models.dart'; +import 'package:mc_common_app/models/appointments_models/service_schedule_model.dart'; +import 'package:mc_common_app/models/general/widgets_models.dart'; class SSCarCheckScheduleModel { int? serviceProviderID; diff --git a/lib/models/advertisment_models/ss_photo_schedule_model.dart b/lib/models/advertisment_models/ss_photo_schedule_model.dart index fdef0fa..048c42b 100644 --- a/lib/models/advertisment_models/ss_photo_schedule_model.dart +++ b/lib/models/advertisment_models/ss_photo_schedule_model.dart @@ -1,6 +1,6 @@ import 'package:mc_common_app/extensions/string_extensions.dart'; -import 'package:mc_common_app/models/service_schedule_model.dart'; -import 'package:mc_common_app/models/widgets_models.dart'; +import 'package:mc_common_app/models/appointments_models/service_schedule_model.dart'; +import 'package:mc_common_app/models/general/widgets_models.dart'; class SSPhotoOfficeScheduleModel { int? photoOfficeID; diff --git a/lib/models/schedule_model.dart b/lib/models/appointments_models/schedule_model.dart similarity index 100% rename from lib/models/schedule_model.dart rename to lib/models/appointments_models/schedule_model.dart diff --git a/lib/models/service_schedule_model.dart b/lib/models/appointments_models/service_schedule_model.dart similarity index 98% rename from lib/models/service_schedule_model.dart rename to lib/models/appointments_models/service_schedule_model.dart index 5df14a7..4e3671a 100644 --- a/lib/models/service_schedule_model.dart +++ b/lib/models/appointments_models/service_schedule_model.dart @@ -1,6 +1,6 @@ import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/models/services/service_model.dart'; -import 'package:mc_common_app/models/widgets_models.dart'; +import 'package:mc_common_app/models/general/widgets_models.dart'; class CustomTimeDateSlotModel { TimeSlotModel? date; diff --git a/lib/models/chat/cat_message_model.dart b/lib/models/chat/cat_message_model.dart new file mode 100644 index 0000000..ca8d778 --- /dev/null +++ b/lib/models/chat/cat_message_model.dart @@ -0,0 +1,49 @@ +class ChatMessageModel { + String? senderUserID; + String? senderName; + int? messageType; + String? message; + RequestOffer? requestOffer; + int? requestID; + int? requestOfferID; + + ChatMessageModel({this.senderUserID, this.senderName, this.messageType, this.message, this.requestOffer, this.requestID, this.requestOfferID}); + + ChatMessageModel.fromJson(Map json) { + senderUserID = json['senderUserID']; + senderName = json['senderName']; + messageType = json['messageType']; + message = json['message']; + if (json['requestOffer'] != null) { + requestOffer = RequestOffer.fromJson(json['requestOffer']); + } else { + requestOffer = null; + } + requestID = json['requestID']; + requestOfferID = json['requestOfferID']; + } +} + +class RequestOffer { + int? id; + int? requestID; + int? serviceProviderID; + int? offerStatus; + String? comment; + int? price; + String? offeredItemCreatedBy; + String? offeredItemCreatedOn; + + RequestOffer({this.id, this.requestID, this.serviceProviderID, this.offerStatus, this.comment, this.price, this.offeredItemCreatedBy, this.offeredItemCreatedOn}); + + RequestOffer.fromJson(Map json) { + id = json['id']; + requestID = json['requestID']; + serviceProviderID = json['serviceProviderID']; + offerStatus = json['offerStatus']; + comment = json['comment']; + price = json['price']; + offeredItemCreatedBy = json['offeredItemCreatedBy']; + offeredItemCreatedOn = json['offeredItemCreatedOn']; + } +} diff --git a/lib/models/config_model.dart b/lib/models/config_model.dart deleted file mode 100644 index 0245ede..0000000 --- a/lib/models/config_model.dart +++ /dev/null @@ -1,12 +0,0 @@ -class ConfigModel { - ConfigModel(this.endpoint, this.organizationName); - - String endpoint; - - String organizationName; - - factory ConfigModel.fromJson(Map json) => - ConfigModel("", ""); - -// Map toJson() => _$ConfigModelToJson(this); -} diff --git a/lib/models/content_info_model.dart b/lib/models/content_info_model.dart deleted file mode 100644 index 4eec746..0000000 --- a/lib/models/content_info_model.dart +++ /dev/null @@ -1,65 +0,0 @@ -class ContentInfoModel { - int? totalItemsCount; - int? statusCode; - String? message; - List? data; - - ContentInfoModel({this.totalItemsCount, this.statusCode, this.message, this.data}); - - ContentInfoModel.fromJson(Map json) { - totalItemsCount = json['totalItemsCount']; - statusCode = json['statusCode']; - message = json['message']; - if (json['data'] != null) { - data = []; - json['data'].forEach((v) { - data?.add(new ContentInfoDataModel.fromJson(v)); - }); - } - } - - Map toJson() { - final Map data = new Map(); - data['totalItemsCount'] = this.totalItemsCount; - data['statusCode'] = this.statusCode; - data['message'] = this.message; - if (this.data != null) { - data['data'] = this.data?.map((v) => v.toJson()).toList(); - } - return data; - } -} - -class ContentInfoDataModel { - int? contentInfoId; - int? contentTypeId; - String? content; - String? contentTypeNameEn; - String? contentTypeNameAr; - String? fileName; - String? exposeFilePath; - - ContentInfoDataModel({this.contentInfoId, this.contentTypeId, this.content, this.contentTypeNameEn, this.contentTypeNameAr, this.fileName, this.exposeFilePath}); - - ContentInfoDataModel.fromJson(Map json) { - contentInfoId = json['contentInfoId']; - contentTypeId = json['contentTypeId']; - content = json['content']; - contentTypeNameEn = json['contentTypeNameEn']; - contentTypeNameAr = json['contentTypeNameAr']; - fileName = json['fileName']; - exposeFilePath = json['exposeFilePath']; - } - - Map toJson() { - final Map data = new Map(); - data['contentInfoId'] = this.contentInfoId; - data['contentTypeId'] = this.contentTypeId; - data['content'] = this.content; - data['contentTypeNameEn'] = this.contentTypeNameEn; - data['contentTypeNameAr'] = this.contentTypeNameAr; - data['fileName'] = this.fileName; - data['exposeFilePath'] = this.exposeFilePath; - return data; - } -} diff --git a/lib/models/enums_model.dart b/lib/models/general/enums_model.dart similarity index 100% rename from lib/models/enums_model.dart rename to lib/models/general/enums_model.dart diff --git a/lib/models/generic_resp_model.dart b/lib/models/general/generic_resp_model.dart similarity index 100% rename from lib/models/generic_resp_model.dart rename to lib/models/general/generic_resp_model.dart diff --git a/lib/models/m_response.dart b/lib/models/general/m_response.dart similarity index 100% rename from lib/models/m_response.dart rename to lib/models/general/m_response.dart diff --git a/lib/models/post_params_model.dart b/lib/models/general/post_params_model.dart similarity index 100% rename from lib/models/post_params_model.dart rename to lib/models/general/post_params_model.dart diff --git a/lib/models/widgets_models.dart b/lib/models/general/widgets_models.dart similarity index 100% rename from lib/models/widgets_models.dart rename to lib/models/general/widgets_models.dart diff --git a/lib/models/member_model.dart b/lib/models/member_model.dart deleted file mode 100644 index d968827..0000000 --- a/lib/models/member_model.dart +++ /dev/null @@ -1,62 +0,0 @@ -class MemberModel { - int? totalItemsCount; - int? statusCode; - String? message; - List? data; - - MemberModel({this.totalItemsCount, this.statusCode, this.message, this.data}); - - MemberModel.fromJson(Map json) { - totalItemsCount = json['totalItemsCount']; - statusCode = json['statusCode']; - message = json['message']; - if (json['data'] != null) { - data = []; - json['data'].forEach((v) { - data?.add(new MemberDataModel.fromJson(v)); - }); - } - } - - Map toJson() { - final Map data = new Map(); - data['totalItemsCount'] = this.totalItemsCount; - data['statusCode'] = this.statusCode; - data['message'] = this.message; - if (this.data != null) { - data['data'] = this.data?.map((v) => v.toJson()).toList(); - } - return data; - } -} - -class MemberDataModel { - int? committeeId; - String? firstName; - String? lastName; - String? description; - String? picture; - int? orderNo; - - MemberDataModel({this.committeeId, this.firstName, this.lastName, this.description, this.picture, this.orderNo}); - - MemberDataModel.fromJson(Map json) { - committeeId = json['committeeId']; - firstName = json['firstName']; - lastName = json['lastName']; - description = json['description']; - picture = json['picture']; - orderNo = json['orderNo']; - } - - Map toJson() { - final Map data = new Map(); - data['committeeId'] = this.committeeId; - data['firstName'] = this.firstName; - data['lastName'] = this.lastName; - data['description'] = this.description; - data['picture'] = this.picture; - data['orderNo'] = this.orderNo; - return data; - } -} diff --git a/lib/models/parent_list.dart b/lib/models/parent_list.dart deleted file mode 100644 index 3f2286f..0000000 --- a/lib/models/parent_list.dart +++ /dev/null @@ -1,26 +0,0 @@ -class ParentList { - ParentList({ - required this.dbId, - required this.text, - required this.path, - required this.isSelected, - }); - - int dbId; - String text; - String path; - bool isSelected; - - factory ParentList.fromJson(Map json) => ParentList( - dbId: json["dbId"] == null ? null : json["dbId"], - text: json["text"] == null ? null : json["text"], - path: json["path"] == null ? null : json["path"], - isSelected: false, - ); - - Map toJson() => { - "dbId": dbId == null ? null : dbId, - "text": text == null ? null : text, - "path": path == null ? null : path, - }; -} diff --git a/lib/models/model/provider_model.dart b/lib/models/provider_branches_models/provider_model.dart similarity index 100% rename from lib/models/model/provider_model.dart rename to lib/models/provider_branches_models/provider_model.dart diff --git a/lib/models/response_models.dart b/lib/models/response_models.dart deleted file mode 100644 index 872893b..0000000 --- a/lib/models/response_models.dart +++ /dev/null @@ -1,34 +0,0 @@ -/// -/// This example was taken from -/// https://flutter.dev/docs/development/data-and-backend/json -/// - -/// This allows the `User` class to access private members in -/// the generated file. The value for this is *.g.dart, where -/// the star denotes the source file name. - -/// An annotation for the code generator to know that this class needs the -/// JSON serialization logic to be generated. - -class BackendResponse { - BackendResponse({required this.id, required this.isOk, required this.result}); - - int id; - bool isOk; - dynamic result; - - /// A necessary factory constructor for creating a new User instance - /// from a map. Pass the map to the generated `_$UserFromJson()` constructor. - /// The constructor is named after the source class, in this case, User. - factory BackendResponse.fromJson(Map json) => - BackendResponse( - id: 1, - isOk: false, - result: null, - ); -// -// /// `toJson` is the convention for a class to declare support for serialization -// /// to JSON. The implementation simply calls the private, generated -// /// helper method `_$UserToJson`. -// Map toJson() => _$BackendResponseToJson(this); -} diff --git a/lib/models/subscription_model.dart b/lib/models/subscription_model.dart deleted file mode 100644 index d192566..0000000 --- a/lib/models/subscription_model.dart +++ /dev/null @@ -1,125 +0,0 @@ -// To parse this JSON data, do -// -// final subscription = subscriptionFromJson(jsonString); - -import 'dart:convert'; - -Subscription subscriptionFromJson(String str) => Subscription.fromJson(json.decode(str)); - -String subscriptionToJson(Subscription data) => json.encode(data.toJson()); - -class SubscriptionModel { - SubscriptionModel({ - this.messageStatus, - this.totalItemsCount, - this.data, - this.message, - }); - - int? messageStatus; - int? totalItemsCount; - List? data; - String? message; - - factory SubscriptionModel.fromJson(Map json) => SubscriptionModel( - messageStatus: json["messageStatus"], - totalItemsCount: json["totalItemsCount"], - data: json["data"] == null ? [] : List.from(json["data"]!.map((x) => Subscription.fromJson(x))), - message: json["message"], - ); - - Map toJson() => { - "messageStatus": messageStatus, - "totalItemsCount": totalItemsCount, - "data": data == null ? [] : List.from(data!.map((x) => x.toJson())), - "message": message, - }; -} - -class Subscription { - Subscription({ - this.id, - this.name, - this.description, - this.durationName, - this.durationDays, - this.price, - this.currency, - this.numberOfBranches, - this.numberOfSubUsers, - this.numberOfAds, - this.countryId, - this.countryName, - this.isSubscribed, - this.subscriptionAppliedId, - this.serviceProviderId, - this.dateStart, - this.dateEnd, - this.isExpired, - this.isActive, - }); - - int? id; - String? name; - String? description; - String? durationName; - int? durationDays; - double? price; - String? currency; - int? numberOfBranches; - int? numberOfSubUsers; - int? numberOfAds; - int? countryId; - String? countryName; - bool? isSubscribed; - int? subscriptionAppliedId; - int? serviceProviderId; - DateTime? dateStart; - DateTime? dateEnd; - bool? isExpired; - bool? isActive; - - factory Subscription.fromJson(Map json) => Subscription( - id: json["id"], - name: json["name"], - description: json["description"], - durationName: json["durationName"], - durationDays: json["durationDays"], - price: json["price"]?.toDouble(), - currency: json["currency"], - numberOfBranches: json["numberOfBranches"], - numberOfSubUsers: json["numberOfSubUsers"], - numberOfAds: json["numberOfAds"], - countryId: json["countryID"], - countryName: json["countryName"]!, - isSubscribed: json["isSubscribed"], - subscriptionAppliedId: json["subscriptionAppliedID"], - serviceProviderId: json["serviceProviderID"], - dateStart: json["dateStart"] == null ? null : DateTime.parse(json["dateStart"]), - dateEnd: json["dateEnd"] == null ? null : DateTime.parse(json["dateEnd"]), - isExpired: json["isExpired"], - isActive: json["isActive"], - ); - - Map toJson() => { - "id": id, - "name": name, - "description": description, - "durationName": durationName, - "durationDays": durationDays, - "price": price, - "currency": currency, - "numberOfBranches": numberOfBranches, - "numberOfSubUsers": numberOfSubUsers, - "numberOfAds": numberOfAds, - "countryID": countryId, - "countryName": countryName, - "isSubscribed": isSubscribed, - "subscriptionAppliedID": subscriptionAppliedId, - "serviceProviderID": serviceProviderId, - "dateStart": dateStart?.toIso8601String(), - "dateEnd": dateEnd?.toIso8601String(), - "isExpired": isExpired, - "isActive": isActive, - }; -} diff --git a/lib/models/surah_model.dart b/lib/models/surah_model.dart deleted file mode 100644 index acc171a..0000000 --- a/lib/models/surah_model.dart +++ /dev/null @@ -1,74 +0,0 @@ -class SurahModel { - int? totalItemsCount; - int? statusCode; - String? message; - List? data; - - SurahModel({this.totalItemsCount, this.statusCode, this.message, this.data}); - - SurahModel.fromJson(Map json) { - totalItemsCount = json['totalItemsCount']; - statusCode = json['statusCode']; - message = json['message']; - if (json['data'] != null) { - data = []; - json['data'].forEach((v) { - data?.add(SurahModelData.fromJson(v)); - }); - } - } - - Map toJson() { - final Map data = new Map(); - data['totalItemsCount'] = totalItemsCount; - data['statusCode'] = statusCode; - data['message'] = message; - if (this.data != null) { - data['data'] = this.data?.map((v) => v.toJson()).toList(); - } - return data; - } -} - -class SurahModelData { - int? id; - int? surahID; - String? nameAR; - String? nameEN; - int? numberOfAyahs; - String? englishNameTranslation; - int? revelationID; - String? revelationType; - int? startPageNo; - int? endPageNo; - - SurahModelData({this.id, this.surahID, this.nameAR, this.nameEN, this.numberOfAyahs, this.englishNameTranslation, this.revelationID, this.revelationType, this.startPageNo, this.endPageNo}); - - SurahModelData.fromJson(Map json) { - id = json['id']; - surahID = json['surahID']; - nameAR = json['nameAR']; - nameEN = json['nameEN']; - numberOfAyahs = json['numberOfAyahs']; - englishNameTranslation = json['englishNameTranslation']; - revelationID = json['revelation_ID']; - revelationType = json['revelationType']; - startPageNo = json['startPageNo']; - endPageNo = json['endPageNo']; - } - - Map toJson() { - final Map data = new Map(); - data['id'] = this.id; - data['surahID'] = this.surahID; - data['nameAR'] = this.nameAR; - data['nameEN'] = this.nameEN; - data['numberOfAyahs'] = this.numberOfAyahs; - data['englishNameTranslation'] = this.englishNameTranslation; - data['revelation_ID'] = this.revelationID; - data['revelationType'] = this.revelationType; - data['startPageNo'] = this.startPageNo; - data['endPageNo'] = this.endPageNo; - return data; - } -} diff --git a/lib/models/verify_usage_before_deleting_these/account.dart b/lib/models/verify_usage_before_deleting_these/account.dart new file mode 100644 index 0000000..32991b3 --- /dev/null +++ b/lib/models/verify_usage_before_deleting_these/account.dart @@ -0,0 +1,44 @@ +// // To parse this JSON data, do +// // +// // final account = accountFromJson(jsonString); +// +// import 'dart:convert'; +// +// import 'package:mc_common_app/models/parent_list.dart'; +// +// +// +// +// Account accountFromJson(String str) => Account.fromJson(json.decode(str)); +// +// String accountToJson(Account data) => json.encode(data.toJson()); +// +// class Account { +// Account({ +// required this.parentList, +// required this.selectedItem, +// }); +// +// List? parentList; +// int selectedItem; +// +// factory Account.fromJson(Map json) => Account( +// parentList: json["parentList"] == null +// ? null +// : List.from( +// json["parentList"].map((x) => ParentList.fromJson(x))), +// selectedItem: +// json["selectedItem"] == null ? null : json["selectedItem"], +// ); +// +// Map toJson() => { +// "parentList": parentList == null +// ? null +// : List.from(parentList!.map((x) => x.toJson())), +// "selectedItem": selectedItem == null ? null : selectedItem, +// }; +// +// Map toJsonData() => { +// "selectedItem": selectedItem == null ? null : selectedItem, +// }; +// } diff --git a/lib/models/verify_usage_before_deleting_these/config_model.dart b/lib/models/verify_usage_before_deleting_these/config_model.dart new file mode 100644 index 0000000..2fc7102 --- /dev/null +++ b/lib/models/verify_usage_before_deleting_these/config_model.dart @@ -0,0 +1,12 @@ +// class ConfigModel { +// ConfigModel(this.endpoint, this.organizationName); +// +// String endpoint; +// +// String organizationName; +// +// factory ConfigModel.fromJson(Map json) => +// ConfigModel("", ""); +// +// // Map toJson() => _$ConfigModelToJson(this); +// } diff --git a/lib/models/verify_usage_before_deleting_these/content_info_model.dart b/lib/models/verify_usage_before_deleting_these/content_info_model.dart new file mode 100644 index 0000000..548a2f4 --- /dev/null +++ b/lib/models/verify_usage_before_deleting_these/content_info_model.dart @@ -0,0 +1,65 @@ +// class ContentInfoModel { +// int? totalItemsCount; +// int? statusCode; +// String? message; +// List? data; +// +// ContentInfoModel({this.totalItemsCount, this.statusCode, this.message, this.data}); +// +// ContentInfoModel.fromJson(Map json) { +// totalItemsCount = json['totalItemsCount']; +// statusCode = json['statusCode']; +// message = json['message']; +// if (json['data'] != null) { +// data = []; +// json['data'].forEach((v) { +// data?.add(new ContentInfoDataModel.fromJson(v)); +// }); +// } +// } +// +// Map toJson() { +// final Map data = new Map(); +// data['totalItemsCount'] = this.totalItemsCount; +// data['statusCode'] = this.statusCode; +// data['message'] = this.message; +// if (this.data != null) { +// data['data'] = this.data?.map((v) => v.toJson()).toList(); +// } +// return data; +// } +// } +// +// class ContentInfoDataModel { +// int? contentInfoId; +// int? contentTypeId; +// String? content; +// String? contentTypeNameEn; +// String? contentTypeNameAr; +// String? fileName; +// String? exposeFilePath; +// +// ContentInfoDataModel({this.contentInfoId, this.contentTypeId, this.content, this.contentTypeNameEn, this.contentTypeNameAr, this.fileName, this.exposeFilePath}); +// +// ContentInfoDataModel.fromJson(Map json) { +// contentInfoId = json['contentInfoId']; +// contentTypeId = json['contentTypeId']; +// content = json['content']; +// contentTypeNameEn = json['contentTypeNameEn']; +// contentTypeNameAr = json['contentTypeNameAr']; +// fileName = json['fileName']; +// exposeFilePath = json['exposeFilePath']; +// } +// +// Map toJson() { +// final Map data = new Map(); +// data['contentInfoId'] = this.contentInfoId; +// data['contentTypeId'] = this.contentTypeId; +// data['content'] = this.content; +// data['contentTypeNameEn'] = this.contentTypeNameEn; +// data['contentTypeNameAr'] = this.contentTypeNameAr; +// data['fileName'] = this.fileName; +// data['exposeFilePath'] = this.exposeFilePath; +// return data; +// } +// } diff --git a/lib/models/verify_usage_before_deleting_these/member_model.dart b/lib/models/verify_usage_before_deleting_these/member_model.dart new file mode 100644 index 0000000..0401282 --- /dev/null +++ b/lib/models/verify_usage_before_deleting_these/member_model.dart @@ -0,0 +1,62 @@ +// class MemberModel { +// int? totalItemsCount; +// int? statusCode; +// String? message; +// List? data; +// +// MemberModel({this.totalItemsCount, this.statusCode, this.message, this.data}); +// +// MemberModel.fromJson(Map json) { +// totalItemsCount = json['totalItemsCount']; +// statusCode = json['statusCode']; +// message = json['message']; +// if (json['data'] != null) { +// data = []; +// json['data'].forEach((v) { +// data?.add(new MemberDataModel.fromJson(v)); +// }); +// } +// } +// +// Map toJson() { +// final Map data = new Map(); +// data['totalItemsCount'] = this.totalItemsCount; +// data['statusCode'] = this.statusCode; +// data['message'] = this.message; +// if (this.data != null) { +// data['data'] = this.data?.map((v) => v.toJson()).toList(); +// } +// return data; +// } +// } +// +// class MemberDataModel { +// int? committeeId; +// String? firstName; +// String? lastName; +// String? description; +// String? picture; +// int? orderNo; +// +// MemberDataModel({this.committeeId, this.firstName, this.lastName, this.description, this.picture, this.orderNo}); +// +// MemberDataModel.fromJson(Map json) { +// committeeId = json['committeeId']; +// firstName = json['firstName']; +// lastName = json['lastName']; +// description = json['description']; +// picture = json['picture']; +// orderNo = json['orderNo']; +// } +// +// Map toJson() { +// final Map data = new Map(); +// data['committeeId'] = this.committeeId; +// data['firstName'] = this.firstName; +// data['lastName'] = this.lastName; +// data['description'] = this.description; +// data['picture'] = this.picture; +// data['orderNo'] = this.orderNo; +// return data; +// } +// } diff --git a/lib/models/verify_usage_before_deleting_these/parent_list.dart b/lib/models/verify_usage_before_deleting_these/parent_list.dart new file mode 100644 index 0000000..26e9a35 --- /dev/null +++ b/lib/models/verify_usage_before_deleting_these/parent_list.dart @@ -0,0 +1,26 @@ +// class ParentList { +// ParentList({ +// required this.dbId, +// required this.text, +// required this.path, +// required this.isSelected, +// }); +// +// int dbId; +// String text; +// String path; +// bool isSelected; +// +// factory ParentList.fromJson(Map json) => ParentList( +// dbId: json["dbId"] == null ? null : json["dbId"], +// text: json["text"] == null ? null : json["text"], +// path: json["path"] == null ? null : json["path"], +// isSelected: false, +// ); +// +// Map toJson() => { +// "dbId": dbId == null ? null : dbId, +// "text": text == null ? null : text, +// "path": path == null ? null : path, +// }; +// } diff --git a/lib/models/provider_category_model.dart b/lib/models/verify_usage_before_deleting_these/provider_category_model.dart similarity index 98% rename from lib/models/provider_category_model.dart rename to lib/models/verify_usage_before_deleting_these/provider_category_model.dart index 18c8dda..37ef197 100644 --- a/lib/models/provider_category_model.dart +++ b/lib/models/verify_usage_before_deleting_these/provider_category_model.dart @@ -30,3 +30,6 @@ // return data; // } // } + +// // test + diff --git a/lib/models/provider_service_model.dart b/lib/models/verify_usage_before_deleting_these/provider_service_model.dart similarity index 99% rename from lib/models/provider_service_model.dart rename to lib/models/verify_usage_before_deleting_these/provider_service_model.dart index 914ce65..830bb2a 100644 --- a/lib/models/provider_service_model.dart +++ b/lib/models/verify_usage_before_deleting_these/provider_service_model.dart @@ -63,3 +63,5 @@ // return 'ProviderServiceModel{id: $id, description: $description, descriptionN: $descriptionN, serviceIconUrl: $serviceIconUrl, serviceImageUrl: $serviceImageUrl, serviceCategoryID: $serviceCategoryID, isActive: $isActive, categoryName: $categoryName, ispartial: $ispartial, appointmentPricePercentage: $appointmentPricePercentage, refundAmountPercentage: $refundAmountPercentage, isSelected: $isSelected}'; // } // } + +// // test \ No newline at end of file diff --git a/lib/models/verify_usage_before_deleting_these/response_models.dart b/lib/models/verify_usage_before_deleting_these/response_models.dart new file mode 100644 index 0000000..6680252 --- /dev/null +++ b/lib/models/verify_usage_before_deleting_these/response_models.dart @@ -0,0 +1,34 @@ +// /// +// /// This example was taken from +// /// https://flutter.dev/docs/development/data-and-backend/json +// /// +// +// /// This allows the `User` class to access private members in +// /// the generated file. The value for this is *.g.dart, where +// /// the star denotes the source file name. +// +// /// An annotation for the code generator to know that this class needs the +// /// JSON serialization logic to be generated. +// +// class BackendResponse { +// BackendResponse({required this.id, required this.isOk, required this.result}); +// +// int id; +// bool isOk; +// dynamic result; +// +// /// A necessary factory constructor for creating a new User instance +// /// from a map. Pass the map to the generated `_$UserFromJson()` constructor. +// /// The constructor is named after the source class, in this case, User. +// factory BackendResponse.fromJson(Map json) => +// BackendResponse( +// id: 1, +// isOk: false, +// result: null, +// ); +// // +// // /// `toJson` is the convention for a class to declare support for serialization +// // /// to JSON. The implementation simply calls the private, generated +// // /// helper method `_$UserToJson`. +// // Map toJson() => _$BackendResponseToJson(this); +// } diff --git a/lib/models/verify_usage_before_deleting_these/subscription_model.dart b/lib/models/verify_usage_before_deleting_these/subscription_model.dart new file mode 100644 index 0000000..c8e781a --- /dev/null +++ b/lib/models/verify_usage_before_deleting_these/subscription_model.dart @@ -0,0 +1,125 @@ +// // To parse this JSON data, do +// // +// // final subscription = subscriptionFromJson(jsonString); +// +// import 'dart:convert'; +// +// Subscription subscriptionFromJson(String str) => Subscription.fromJson(json.decode(str)); +// +// String subscriptionToJson(Subscription data) => json.encode(data.toJson()); +// +// class SubscriptionModel { +// SubscriptionModel({ +// this.messageStatus, +// this.totalItemsCount, +// this.data, +// this.message, +// }); +// +// int? messageStatus; +// int? totalItemsCount; +// List? data; +// String? message; +// +// factory SubscriptionModel.fromJson(Map json) => SubscriptionModel( +// messageStatus: json["messageStatus"], +// totalItemsCount: json["totalItemsCount"], +// data: json["data"] == null ? [] : List.from(json["data"]!.map((x) => Subscription.fromJson(x))), +// message: json["message"], +// ); +// +// Map toJson() => { +// "messageStatus": messageStatus, +// "totalItemsCount": totalItemsCount, +// "data": data == null ? [] : List.from(data!.map((x) => x.toJson())), +// "message": message, +// }; +// } +// +// class Subscription { +// Subscription({ +// this.id, +// this.name, +// this.description, +// this.durationName, +// this.durationDays, +// this.price, +// this.currency, +// this.numberOfBranches, +// this.numberOfSubUsers, +// this.numberOfAds, +// this.countryId, +// this.countryName, +// this.isSubscribed, +// this.subscriptionAppliedId, +// this.serviceProviderId, +// this.dateStart, +// this.dateEnd, +// this.isExpired, +// this.isActive, +// }); +// +// int? id; +// String? name; +// String? description; +// String? durationName; +// int? durationDays; +// double? price; +// String? currency; +// int? numberOfBranches; +// int? numberOfSubUsers; +// int? numberOfAds; +// int? countryId; +// String? countryName; +// bool? isSubscribed; +// int? subscriptionAppliedId; +// int? serviceProviderId; +// DateTime? dateStart; +// DateTime? dateEnd; +// bool? isExpired; +// bool? isActive; +// +// factory Subscription.fromJson(Map json) => Subscription( +// id: json["id"], +// name: json["name"], +// description: json["description"], +// durationName: json["durationName"], +// durationDays: json["durationDays"], +// price: json["price"]?.toDouble(), +// currency: json["currency"], +// numberOfBranches: json["numberOfBranches"], +// numberOfSubUsers: json["numberOfSubUsers"], +// numberOfAds: json["numberOfAds"], +// countryId: json["countryID"], +// countryName: json["countryName"]!, +// isSubscribed: json["isSubscribed"], +// subscriptionAppliedId: json["subscriptionAppliedID"], +// serviceProviderId: json["serviceProviderID"], +// dateStart: json["dateStart"] == null ? null : DateTime.parse(json["dateStart"]), +// dateEnd: json["dateEnd"] == null ? null : DateTime.parse(json["dateEnd"]), +// isExpired: json["isExpired"], +// isActive: json["isActive"], +// ); +// +// Map toJson() => { +// "id": id, +// "name": name, +// "description": description, +// "durationName": durationName, +// "durationDays": durationDays, +// "price": price, +// "currency": currency, +// "numberOfBranches": numberOfBranches, +// "numberOfSubUsers": numberOfSubUsers, +// "numberOfAds": numberOfAds, +// "countryID": countryId, +// "countryName": countryName, +// "isSubscribed": isSubscribed, +// "subscriptionAppliedID": subscriptionAppliedId, +// "serviceProviderID": serviceProviderId, +// "dateStart": dateStart?.toIso8601String(), +// "dateEnd": dateEnd?.toIso8601String(), +// "isExpired": isExpired, +// "isActive": isActive, +// }; +// } diff --git a/lib/models/verify_usage_before_deleting_these/surah_model.dart b/lib/models/verify_usage_before_deleting_these/surah_model.dart new file mode 100644 index 0000000..ef57819 --- /dev/null +++ b/lib/models/verify_usage_before_deleting_these/surah_model.dart @@ -0,0 +1,74 @@ +// class SurahModel { +// int? totalItemsCount; +// int? statusCode; +// String? message; +// List? data; +// +// SurahModel({this.totalItemsCount, this.statusCode, this.message, this.data}); +// +// SurahModel.fromJson(Map json) { +// totalItemsCount = json['totalItemsCount']; +// statusCode = json['statusCode']; +// message = json['message']; +// if (json['data'] != null) { +// data = []; +// json['data'].forEach((v) { +// data?.add(SurahModelData.fromJson(v)); +// }); +// } +// } +// +// Map toJson() { +// final Map data = new Map(); +// data['totalItemsCount'] = totalItemsCount; +// data['statusCode'] = statusCode; +// data['message'] = message; +// if (this.data != null) { +// data['data'] = this.data?.map((v) => v.toJson()).toList(); +// } +// return data; +// } +// } +// +// class SurahModelData { +// int? id; +// int? surahID; +// String? nameAR; +// String? nameEN; +// int? numberOfAyahs; +// String? englishNameTranslation; +// int? revelationID; +// String? revelationType; +// int? startPageNo; +// int? endPageNo; +// +// SurahModelData({this.id, this.surahID, this.nameAR, this.nameEN, this.numberOfAyahs, this.englishNameTranslation, this.revelationID, this.revelationType, this.startPageNo, this.endPageNo}); +// +// SurahModelData.fromJson(Map json) { +// id = json['id']; +// surahID = json['surahID']; +// nameAR = json['nameAR']; +// nameEN = json['nameEN']; +// numberOfAyahs = json['numberOfAyahs']; +// englishNameTranslation = json['englishNameTranslation']; +// revelationID = json['revelation_ID']; +// revelationType = json['revelationType']; +// startPageNo = json['startPageNo']; +// endPageNo = json['endPageNo']; +// } +// +// Map toJson() { +// final Map data = new Map(); +// data['id'] = this.id; +// data['surahID'] = this.surahID; +// data['nameAR'] = this.nameAR; +// data['nameEN'] = this.nameEN; +// data['numberOfAyahs'] = this.numberOfAyahs; +// data['englishNameTranslation'] = this.englishNameTranslation; +// data['revelation_ID'] = this.revelationID; +// data['revelationType'] = this.revelationType; +// data['startPageNo'] = this.startPageNo; +// data['endPageNo'] = this.endPageNo; +// return data; +// } +// } diff --git a/lib/repositories/ads_repo.dart b/lib/repositories/ads_repo.dart index 7f2f8e9..728cfb5 100644 --- a/lib/repositories/ads_repo.dart +++ b/lib/repositories/ads_repo.dart @@ -11,7 +11,7 @@ import 'package:mc_common_app/models/advertisment_models/ads_duration_model.dart import 'package:mc_common_app/models/advertisment_models/reserved_ads_models.dart'; import 'package:mc_common_app/models/advertisment_models/special_service_model.dart'; import 'package:mc_common_app/models/advertisment_models/vehicle_details_models.dart'; -import 'package:mc_common_app/models/generic_resp_model.dart'; +import 'package:mc_common_app/models/general/generic_resp_model.dart'; import 'package:mc_common_app/utils/enums.dart'; abstract class AdsRepo { diff --git a/lib/repositories/appointment_repo.dart b/lib/repositories/appointment_repo.dart index e3f5236..3f53f24 100644 --- a/lib/repositories/appointment_repo.dart +++ b/lib/repositories/appointment_repo.dart @@ -4,11 +4,11 @@ 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/dependencies.dart'; -import 'package:mc_common_app/models/generic_resp_model.dart'; -import 'package:mc_common_app/models/m_response.dart'; +import 'package:mc_common_app/models/general/generic_resp_model.dart'; +import 'package:mc_common_app/models/general/m_response.dart'; import 'package:mc_common_app/models/provider_branches_models/profile/services.dart'; -import 'package:mc_common_app/models/schedule_model.dart'; -import 'package:mc_common_app/models/service_schedule_model.dart'; +import 'package:mc_common_app/models/appointments_models/schedule_model.dart'; +import 'package:mc_common_app/models/appointments_models/service_schedule_model.dart'; import 'package:mc_common_app/utils/enums.dart'; abstract class AppointmentRepo { diff --git a/lib/repositories/chat_repo.dart b/lib/repositories/chat_repo.dart index 2f379cb..337a09d 100644 --- a/lib/repositories/chat_repo.dart +++ b/lib/repositories/chat_repo.dart @@ -1,60 +1,32 @@ +import 'dart:io'; +import 'package:http/io_client.dart'; import 'package:mc_common_app/classes/app_state.dart'; -import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/main.dart'; -import 'package:mc_common_app/utils/utils.dart'; -import 'package:signalr_netcore/http_connection_options.dart'; -import 'package:signalr_netcore/hub_connection.dart'; -import 'package:signalr_netcore/hub_connection_builder.dart'; -import 'package:logging/logging.dart'; +import 'package:signalr_core/signalr_core.dart'; abstract class ChatRepo { - Future buildChatHubConnection(); + Future getHubConnection(); } class ChatRepoImp implements ChatRepo { @override - Future buildChatHubConnection() async { + Future getHubConnection() async { final userId = AppState().getUser.data!.userInfo!.userId ?? ""; - HttpConnectionOptions httpOptions = HttpConnectionOptions(skipNegotiation: false, logMessageContent: true); - HubConnection hubConnection = HubConnectionBuilder() + final hubUrl = "https://ms.hmg.com/McHub?userID=$userId"; + logger.i("Connecting with Hub ($hubUrl)"); + + HubConnection hub; + hub = HubConnectionBuilder() .withUrl( - "${ApiConsts.chatHubUrl}?userID=$userId", - options: httpOptions, - ) - .withAutomaticReconnect( - retryDelays: [2000, 5000, 10000, 20000], - ) - .configureLogging( - Logger("configureLogging"), - ) + hubUrl, + HttpConnectionOptions( + client: IOClient(HttpClient() + ..badCertificateCallback = (x, y, z) => true), + logging: (level, message) { + print(message); + }, + )) .build(); - hubConnection.onclose( - ({Exception? error}) { - logger.i("onClose"); - }, - ); - hubConnection.onreconnecting( - ({Exception? error}) { - logger.i("onReconnecting"); - }, - ); - hubConnection.onreconnected( - ({String? connectionId}) { - logger.i("onReconnected"); - }, - ); - if (hubConnection.state != HubConnectionState.Connected) { - await hubConnection.start(); - logger.i("Started HubConnection"); - - try { - hubConnection.on("ReceiveMessageRequestOffer", (List? arguments) { - Utils.showToast("I received ping : ${arguments.toString()}"); - }); - } catch (e) { - logger.i("Error in OnSendQuestionToParticipant"); - } - } - return hubConnection; + return hub; } } diff --git a/lib/repositories/common_repo.dart b/lib/repositories/common_repo.dart index f4dd9d9..8ede9a0 100644 --- a/lib/repositories/common_repo.dart +++ b/lib/repositories/common_repo.dart @@ -5,13 +5,13 @@ import 'package:mc_common_app/config/dependencies.dart'; import 'package:mc_common_app/models/advertisment_models/ss_car_check_schedule_model.dart'; import 'package:mc_common_app/models/advertisment_models/ss_photo_schedule_model.dart'; import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart'; -import 'package:mc_common_app/models/generic_resp_model.dart'; +import 'package:mc_common_app/models/general/generic_resp_model.dart'; import 'package:mc_common_app/models/user/cities.dart'; import 'package:mc_common_app/models/user/country.dart'; import 'package:mc_common_app/models/user/role.dart'; import '../models/advertisment_models/vehicle_details_models.dart'; -import '../models/enums_model.dart'; +import '../models/general/enums_model.dart'; abstract class CommonRepo { Future getAllCountries(); diff --git a/lib/repositories/payments_repo.dart b/lib/repositories/payments_repo.dart index 5fc6407..d760546 100644 --- a/lib/repositories/payments_repo.dart +++ b/lib/repositories/payments_repo.dart @@ -2,7 +2,7 @@ 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/dependencies.dart'; -import 'package:mc_common_app/models/generic_resp_model.dart'; +import 'package:mc_common_app/models/general/generic_resp_model.dart'; import 'package:mc_common_app/models/payment_models/pay_order_detail_resp_model.dart'; abstract class PaymentsRepo { diff --git a/lib/repositories/provider_repo.dart b/lib/repositories/provider_repo.dart index fee2cc1..2709588 100644 --- a/lib/repositories/provider_repo.dart +++ b/lib/repositories/provider_repo.dart @@ -4,7 +4,7 @@ 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/dependencies.dart'; -import 'package:mc_common_app/models/generic_resp_model.dart'; +import 'package:mc_common_app/models/general/generic_resp_model.dart'; import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart'; import 'package:mc_common_app/models/provider_branches_models/provider_profile_model.dart'; import 'package:mc_common_app/models/services/item_model.dart'; diff --git a/lib/repositories/request_repo.dart b/lib/repositories/request_repo.dart index 2b8de66..8095e4b 100644 --- a/lib/repositories/request_repo.dart +++ b/lib/repositories/request_repo.dart @@ -2,7 +2,7 @@ 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/dependencies.dart'; -import 'package:mc_common_app/models/generic_resp_model.dart'; +import 'package:mc_common_app/models/general/generic_resp_model.dart'; import 'package:mc_common_app/models/requests/offers_model.dart'; import 'package:mc_common_app/models/requests/request_model.dart'; diff --git a/lib/repositories/user_repo.dart b/lib/repositories/user_repo.dart index 1a5b2b1..6d69a24 100644 --- a/lib/repositories/user_repo.dart +++ b/lib/repositories/user_repo.dart @@ -7,7 +7,7 @@ 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/dependencies.dart'; -import 'package:mc_common_app/models/m_response.dart'; +import 'package:mc_common_app/models/general/m_response.dart'; import 'package:mc_common_app/models/user/basic_otp.dart'; import 'package:mc_common_app/models/user/change_email.dart'; import 'package:mc_common_app/models/user/change_mobile.dart'; diff --git a/lib/utils/enums.dart b/lib/utils/enums.dart index 6ef655b..e0a9505 100644 --- a/lib/utils/enums.dart +++ b/lib/utils/enums.dart @@ -155,3 +155,20 @@ enum RequestsTypeEnum { specialCarRequest, serviceRequest, } + +enum ChatMessageTypeEnum { + freeText, + image, + audio, + video, + file, + offer, +} + +enum RequestOfferStatusEnum { + offer, + negotiate, + accepted, + rejected, + cancel, +} diff --git a/lib/view_models/ad_view_model.dart b/lib/view_models/ad_view_model.dart index 2a61780..114b4b5 100644 --- a/lib/view_models/ad_view_model.dart +++ b/lib/view_models/ad_view_model.dart @@ -15,10 +15,10 @@ import 'package:mc_common_app/models/advertisment_models/special_service_model.d import 'package:mc_common_app/models/advertisment_models/ss_car_check_schedule_model.dart'; import 'package:mc_common_app/models/advertisment_models/ss_photo_schedule_model.dart'; import 'package:mc_common_app/models/advertisment_models/vehicle_details_models.dart'; -import 'package:mc_common_app/models/enums_model.dart'; -import 'package:mc_common_app/models/generic_resp_model.dart'; -import 'package:mc_common_app/models/service_schedule_model.dart'; -import 'package:mc_common_app/models/widgets_models.dart'; +import 'package:mc_common_app/models/general/enums_model.dart'; +import 'package:mc_common_app/models/general/generic_resp_model.dart'; +import 'package:mc_common_app/models/appointments_models/service_schedule_model.dart'; +import 'package:mc_common_app/models/general/widgets_models.dart'; import 'package:mc_common_app/repositories/ads_repo.dart'; import 'package:mc_common_app/repositories/common_repo.dart'; import 'package:mc_common_app/services/common_services.dart'; diff --git a/lib/view_models/appointments_view_model.dart b/lib/view_models/appointments_view_model.dart index a09b00e..da26459 100644 --- a/lib/view_models/appointments_view_model.dart +++ b/lib/view_models/appointments_view_model.dart @@ -4,14 +4,14 @@ import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart'; -import 'package:mc_common_app/models/enums_model.dart'; -import 'package:mc_common_app/models/generic_resp_model.dart'; +import 'package:mc_common_app/models/general/enums_model.dart'; +import 'package:mc_common_app/models/general/generic_resp_model.dart'; import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart'; import 'package:mc_common_app/models/provider_branches_models/provider_profile_model.dart'; -import 'package:mc_common_app/models/service_schedule_model.dart'; +import 'package:mc_common_app/models/appointments_models/service_schedule_model.dart'; import 'package:mc_common_app/models/services/item_model.dart'; import 'package:mc_common_app/models/services/service_model.dart'; -import 'package:mc_common_app/models/widgets_models.dart'; +import 'package:mc_common_app/models/general/widgets_models.dart'; import 'package:mc_common_app/repositories/appointment_repo.dart'; import 'package:mc_common_app/repositories/common_repo.dart'; import 'package:mc_common_app/repositories/provider_repo.dart'; diff --git a/lib/view_models/chat_view_model.dart b/lib/view_models/chat_view_model.dart index 5d0c70a..be00103 100644 --- a/lib/view_models/chat_view_model.dart +++ b/lib/view_models/chat_view_model.dart @@ -1,39 +1,68 @@ import 'package:flutter/cupertino.dart'; +import 'package:mc_common_app/classes/app_state.dart'; +import 'package:mc_common_app/extensions/string_extensions.dart'; +import 'package:mc_common_app/main.dart'; import 'package:mc_common_app/repositories/chat_repo.dart'; +import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/utils.dart'; -import 'package:signalr_netcore/hub_connection.dart'; +import 'package:signalr_core/signalr_core.dart'; - class ChatVM extends ChangeNotifier { +class ChatVM extends ChangeNotifier { final ChatRepo chatRepo; ChatVM({required this.chatRepo}); - HubConnection? hubConnection; + late HubConnection hubConnection; Future buildHubConnection() async { - hubConnection = await chatRepo.buildChatHubConnection(); + // if (hubConnection.state != HubConnectionState.Connected) { + try { + hubConnection = await chatRepo.getHubConnection(); + await hubConnection.start(); + hubConnection.on("ReceiveMessageRequestOffer", (List? arguments) { + print("this is the offer: ${arguments.toString()}"); + Utils.showToast("I received ping : ${arguments.toString()}"); + }); + } catch (e) { + logger.i("Error: ${e.toString()}"); + } + notifyListeners(); + // } } - Future onSendMessageForRequestOffer() async { - if (hubConnection == null || hubConnection!.state != HubConnectionState.Connected) { + Future onSendMessageForRequestOffer( + {required String receiverId, required ChatMessageTypeEnum chatMessageType, required String message, required int requestId, required String offerPrice}) async { + if (hubConnection.state != HubConnectionState.connected) { await buildHubConnection(); } - if (hubConnection != null) { - hubConnection!.invoke( + if (hubConnection.state == HubConnectionState.connected) { + final providerId = AppState().getUser.data!.userInfo!.providerId; + print("providerId: $providerId"); + hubConnection.invoke( "SendMessageRequestOffer", args: [ - // { - // "employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER ?? "", - // "employeeName": AppState().memberInformationList!.eMPLOYEENAME ?? "", - // "marathonId": AppState().getMarathonProjectId, - // "prizeId": "8577B2E8-5DD7-43F0-10DD-08DACB0AC064", - // } + { + "ReceiverUserID": receiverId, + "MessageType": chatMessageType.getIdFromChatMessageTypeEnum(), + "Message": message, + "RequestID": requestId, + "RequestOfferID": 0, + "RequestOffer": { + "RequestID": requestId, + "Price": double.parse(offerPrice), + "ServiceProviderID": providerId, + "OfferStatus": RequestOfferStatusEnum.offer.getIdFromRequestOfferStatusEnum(), + "Comment": message, + }, + } ], ).catchError((e) { + logger.i("error in invoking SendMessageRequestOffer: ${e.toString()}"); Utils.showToast(e.toString()); - return null; + return false; }); } + return true; } } diff --git a/lib/view_models/requests_view_model.dart b/lib/view_models/requests_view_model.dart index 8652d5d..c7ac932 100644 --- a/lib/view_models/requests_view_model.dart +++ b/lib/view_models/requests_view_model.dart @@ -2,19 +2,22 @@ import 'dart:convert'; import 'dart:io'; import 'package:flutter/cupertino.dart'; import 'package:mc_common_app/classes/app_state.dart'; +import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/models/advertisment_models/vehicle_details_models.dart'; -import 'package:mc_common_app/models/enums_model.dart'; -import 'package:mc_common_app/models/generic_resp_model.dart'; +import 'package:mc_common_app/models/general/enums_model.dart'; +import 'package:mc_common_app/models/general/generic_resp_model.dart'; import 'package:mc_common_app/models/requests/offers_model.dart'; import 'package:mc_common_app/models/requests/request_model.dart'; -import 'package:mc_common_app/models/widgets_models.dart'; +import 'package:mc_common_app/models/general/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/enums.dart'; import 'package:mc_common_app/utils/utils.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:provider/provider.dart'; class RequestsVM extends BaseVM { final CommonAppServices commonServices; @@ -33,26 +36,46 @@ class RequestsVM extends BaseVM { populateRequestsFilterList() async { requestsTypeFilterOptions.clear(); if (myRequestsTypeEnum.isEmpty) { - myRequestsTypeEnum = await commonRepo.getEnumTypeValues(enumTypeID: 16); //TODO: 13 is to get Requests Filter Enums + myRequestsTypeEnum = await commonRepo.getEnumTypeValues(enumTypeID: 16); //TODO: 16 is to get Requests Filter Enums } for (int i = 0; i < myRequestsTypeEnum.length; i++) { requestsTypeFilterOptions.add(FilterListModel(title: myRequestsTypeEnum[i].enumValueStr, isSelected: false, id: myRequestsTypeEnum[i].enumValue)); } + print("requestsTypeFilterOptions: ${requestsTypeFilterOptions.toString()}"); + notifyListeners(); } - Future getMyRequests({bool isNeedToRebuild = false}) async { + Future getRequests({bool isNeedToRebuild = false, required AppType appType}) async { if (isNeedToRebuild) setState(ViewState.busy); - myRequests = await requestRepo.getRequests( - { - "customerID": AppState().getUser.data!.userInfo!.customerId, - "pageSize": 100, - "pageIndex": 0, - "requestType": 0, - }, - ); + var paramsForGetRequests = {}; + + paramsForGetRequests = { + "pageSize": 100, + "pageIndex": 0, + "requestType": 0, + }; + if (appType == AppType.provider) { + paramsForGetRequests.addEntries([MapEntry("providerID", AppState().getUser.data!.userInfo!.providerId)]); + // paramsForGetRequests = { + // "providerID": AppState().getUser.data!.userInfo!.providerId, + // "pageSize": 100, + // "pageIndex": 0, + // "requestType": 0, + // }; + } else { + paramsForGetRequests.addEntries([MapEntry("customerID", AppState().getUser.data!.userInfo!.customerId)]); + + // paramsForGetRequests = { + // "customerID": AppState().getUser.data!.userInfo!.customerId, + // "pageSize": 100, + // "pageIndex": 0, + // "requestType": 0, + // }; + } + myRequests = await requestRepo.getRequests(paramsForGetRequests); applyFilterOnRequestsVM(requestsTypeEnum: RequestsTypeEnum.specialCarRequest); setState(ViewState.idle); notifyListeners(); @@ -252,7 +275,7 @@ class RequestsVM extends BaseVM { if (respModel.messageStatus == 1) { Utils.showToast("Request Successfully Created"); Navigator.pop(context); - await getMyRequests(); + await getRequests(appType: AppType.customer); } else { Utils.showToast(respModel.message.toString()); } @@ -308,4 +331,73 @@ class RequestsVM extends BaseVM { return []; } } + + String offerPriceError = ""; + String offerDescriptionError = ""; + + String offerPrice = ""; + + void updateOfferPrice(String value) { + offerPrice = value; + if (value.isNotEmpty) { + offerPriceError = ""; + } + } + + String offerDescription = ""; + + void updateOfferDescription(String value) { + offerDescription = value; + if (value.isNotEmpty) { + offerDescriptionError = ""; + } + } + + //SENDING OFFER + bool isSendOfferValidated() { + bool isValidated = true; + if (offerPrice.isEmpty) { + offerPriceError = GlobalConsts.demandAmountError; + isValidated = false; + notifyListeners(); + } else { + offerPriceError = ""; + } + + if (offerDescription.isEmpty) { + offerDescriptionError = GlobalConsts.descriptionError; + isValidated = false; + notifyListeners(); + } else { + offerDescriptionError = ""; + } + notifyListeners(); + + return isValidated; + } + + void resetSendOfferBottomSheet() { + offerPrice = ""; + offerDescription = ""; + offerDescriptionError = ""; + offerDescription = ""; + notifyListeners(); + } + + Future onSendOfferPressed({required BuildContext context, required String receiverId, required String message, required int requestId, required String offerPrice}) async { + if (isSendOfferValidated()) { + bool status = await context.read().onSendMessageForRequestOffer( + receiverId: receiverId, + chatMessageType: ChatMessageTypeEnum.offer, + message: message, + requestId: requestId, + offerPrice: offerPrice, + ); + + if (status) { + // resetSendOfferBottomSheet(); + Navigator.pop(context); + } + } + } } diff --git a/lib/view_models/user_view_model.dart b/lib/view_models/user_view_model.dart index 27d7518..3e2f511 100644 --- a/lib/view_models/user_view_model.dart +++ b/lib/view_models/user_view_model.dart @@ -8,7 +8,7 @@ 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/m_response.dart'; +import 'package:mc_common_app/models/general/m_response.dart'; import 'package:mc_common_app/models/user/basic_otp.dart'; import 'package:mc_common_app/models/user/change_email.dart'; import 'package:mc_common_app/models/user/change_mobile.dart'; diff --git a/lib/views/advertisement/ad_creation_steps/ad_duration_container.dart b/lib/views/advertisement/ad_creation_steps/ad_duration_container.dart index 7cc8db1..0e979cb 100644 --- a/lib/views/advertisement/ad_creation_steps/ad_duration_container.dart +++ b/lib/views/advertisement/ad_creation_steps/ad_duration_container.dart @@ -4,7 +4,7 @@ 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/models/widgets_models.dart'; +import 'package:mc_common_app/models/general/widgets_models.dart'; import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/utils/utils.dart'; import 'package:mc_common_app/view_models/ad_view_model.dart'; 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 17009ec..6405510 100644 --- a/lib/views/advertisement/ad_creation_steps/vehicle_details_container.dart +++ b/lib/views/advertisement/ad_creation_steps/vehicle_details_container.dart @@ -3,7 +3,7 @@ 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/models/widgets_models.dart'; +import 'package:mc_common_app/models/general/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'; diff --git a/lib/views/advertisement/ad_duration_selection_sheet_content.dart b/lib/views/advertisement/ad_duration_selection_sheet_content.dart index 300da1f..47a2524 100644 --- a/lib/views/advertisement/ad_duration_selection_sheet_content.dart +++ b/lib/views/advertisement/ad_duration_selection_sheet_content.dart @@ -3,7 +3,7 @@ import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/models/advertisment_models/ads_duration_model.dart'; -import 'package:mc_common_app/models/widgets_models.dart'; +import 'package:mc_common_app/models/general/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/navigator.dart'; diff --git a/lib/views/advertisement/ads_detail_view.dart b/lib/views/advertisement/ads_detail_view.dart index dbc5c01..1117492 100644 --- a/lib/views/advertisement/ads_detail_view.dart +++ b/lib/views/advertisement/ads_detail_view.dart @@ -9,7 +9,7 @@ import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/models/advertisment_models/ad_details_model.dart'; import 'package:mc_common_app/models/advertisment_models/special_service_model.dart'; -import 'package:mc_common_app/models/widgets_models.dart'; +import 'package:mc_common_app/models/general/widgets_models.dart'; import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/utils/dialogs_and_bottomsheets.dart'; import 'package:mc_common_app/utils/enums.dart'; @@ -27,8 +27,8 @@ import 'package:mc_common_app/widgets/common_widgets/info_bottom_sheet.dart'; import 'package:mc_common_app/widgets/common_widgets/time_slots.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:sizer/sizer.dart'; class AdsDetailView extends StatefulWidget { final AdDetailsModel adDetails; @@ -892,6 +892,79 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget { ); } + Future buildCancelReservationBottomSheet(BuildContext context, {required AdDetailsModel adDetails}) { + return showModalBottomSheet( + context: context, + isScrollControlled: true, + enableDrag: true, + builder: (BuildContext context) { + return InfoBottomSheet( + title: "Cancel Reservation".toText(fontSize: 28, isBold: true, letterSpacing: -1.44), + description: Padding( + padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + 12.height, + TxtField( + maxLines: 5, + value: "", + errorValue: "", + keyboardType: TextInputType.text, + hint: "Reason for cancellation", + onChanged: (v) => () {}, + ), + ], + ), + 25.height, + ShowFillButton( + title: "Submit", + onPressed: () { + Navigator.pop(context); + AdVM adVM = context.read(); + return actionConfirmationBottomSheet( + context: context, + title: "Do you want to cancel the reservation?".toText(fontSize: 28, isBold: true, letterSpacing: -1.44), + subtitle: "Your ad reservation will be cancelled and this ad will be again visible to everyone to buy.", + actionButtonYes: Expanded( + child: ShowFillButton( + maxHeight: 55, + title: "Yes", + fontSize: 15, + onPressed: () { + Navigator.pop(context); + adVM.cancelMyAdReservation(context, adId: adDetails.id!); + }, + ), + ), + actionButtonNo: Expanded( + child: ShowFillButton( + maxHeight: 55, + isFilled: false, + borderColor: MyColors.darkPrimaryColor, + title: "No", + txtColor: MyColors.darkPrimaryColor, + fontSize: 15, + onPressed: () { + Navigator.pop(context); + }, + ), + ), + ); + }, + maxWidth: double.infinity, + ), + 19.height, + ], + ), + )); + }, + ); + } + Widget cancelReservationAction(BuildContext context, {required AdDetailsModel adDetails}) { return Row( children: [ @@ -904,36 +977,7 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget { maxHeight: 55, title: "Cancel Reservation", onPressed: () { - AdVM adVM = context.read(); - return actionConfirmationBottomSheet( - context: context, - title: "Do you want to cancel the reservation?".toText(fontSize: 28, isBold: true, letterSpacing: -1.44), - subtitle: "Your ad reservation will be cancelled and this ad will be again visible to everyone to buy.", - actionButtonYes: Expanded( - child: ShowFillButton( - maxHeight: 55, - title: "Yes", - fontSize: 15, - onPressed: () { - Navigator.pop(context); - adVM.cancelMyAdReservation(context, adId: adDetails.id!); - }, - ), - ), - actionButtonNo: Expanded( - child: ShowFillButton( - maxHeight: 55, - isFilled: false, - borderColor: MyColors.darkPrimaryColor, - title: "No", - txtColor: MyColors.darkPrimaryColor, - fontSize: 15, - onPressed: () { - Navigator.pop(context); - }, - ), - ), - ); + buildCancelReservationBottomSheet(context, adDetails: adDetails); }), ), ], diff --git a/lib/views/advertisement/ads_filter_view.dart b/lib/views/advertisement/ads_filter_view.dart index 5f3eace..51d4d38 100644 --- a/lib/views/advertisement/ads_filter_view.dart +++ b/lib/views/advertisement/ads_filter_view.dart @@ -1,7 +1,7 @@ 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/models/widgets_models.dart'; +import 'package:mc_common_app/models/general/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/widgets/button/show_fill_button.dart'; diff --git a/lib/views/advertisement/bottom_sheet_content.dart b/lib/views/advertisement/bottom_sheet_content.dart index 6a270ba..a91b36a 100644 --- a/lib/views/advertisement/bottom_sheet_content.dart +++ b/lib/views/advertisement/bottom_sheet_content.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/models/advertisment_models/vehicle_details_models.dart'; -import 'package:mc_common_app/models/widgets_models.dart'; +import 'package:mc_common_app/models/general/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/widgets/button/show_fill_button.dart'; diff --git a/lib/views/advertisement/select_ad_type_view.dart b/lib/views/advertisement/select_ad_type_view.dart index 812f6d8..0a8af7d 100644 --- a/lib/views/advertisement/select_ad_type_view.dart +++ b/lib/views/advertisement/select_ad_type_view.dart @@ -4,7 +4,7 @@ import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/models/advertisment_models/vehicle_details_models.dart'; -import 'package:mc_common_app/models/widgets_models.dart'; +import 'package:mc_common_app/models/general/widgets_models.dart'; import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/view_models/ad_view_model.dart'; diff --git a/lib/views/appointments/book_appointment_schedules_view.dart b/lib/views/appointments/book_appointment_schedules_view.dart index 4b27e26..6580be6 100644 --- a/lib/views/appointments/book_appointment_schedules_view.dart +++ b/lib/views/appointments/book_appointment_schedules_view.dart @@ -1,8 +1,7 @@ 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/models/service_schedule_model.dart'; +import 'package:mc_common_app/models/appointments_models/service_schedule_model.dart'; import 'package:mc_common_app/models/services/service_model.dart'; import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/view_models/appointments_view_model.dart'; diff --git a/lib/views/appointments/review_appointment_view.dart b/lib/views/appointments/review_appointment_view.dart index 94c0bca..6f26aa8 100644 --- a/lib/views/appointments/review_appointment_view.dart +++ b/lib/views/appointments/review_appointment_view.dart @@ -5,7 +5,7 @@ import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart'; -import 'package:mc_common_app/models/service_schedule_model.dart'; +import 'package:mc_common_app/models/appointments_models/service_schedule_model.dart'; import 'package:mc_common_app/models/services/item_model.dart'; import 'package:mc_common_app/models/services/service_model.dart'; import 'package:mc_common_app/theme/colors.dart'; diff --git a/lib/views/appointments/widgets/appointment_service_pick_bottom_sheet.dart b/lib/views/appointments/widgets/appointment_service_pick_bottom_sheet.dart index 1c723b2..384b6d9 100644 --- a/lib/views/appointments/widgets/appointment_service_pick_bottom_sheet.dart +++ b/lib/views/appointments/widgets/appointment_service_pick_bottom_sheet.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; -import 'package:mc_common_app/models/widgets_models.dart'; +import 'package:mc_common_app/models/general/widgets_models.dart'; import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/view_models/appointments_view_model.dart'; diff --git a/lib/views/appointments/widgets/custom_calender_widget.dart b/lib/views/appointments/widgets/custom_calender_widget.dart index 3f91f27..fa903d7 100644 --- a/lib/views/appointments/widgets/custom_calender_widget.dart +++ b/lib/views/appointments/widgets/custom_calender_widget.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; -import 'package:mc_common_app/models/service_schedule_model.dart'; +import 'package:mc_common_app/models/appointments_models/service_schedule_model.dart'; import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/view_models/appointments_view_model.dart'; import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart'; diff --git a/lib/views/chat/chat_view.dart b/lib/views/chat/chat_view.dart new file mode 100644 index 0000000..62ff217 --- /dev/null +++ b/lib/views/chat/chat_view.dart @@ -0,0 +1,195 @@ +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'; +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/extensions/extensions_widget.dart'; +import 'package:mc_common_app/widgets/txt_field.dart'; + +class ChatView extends StatelessWidget { + const ChatView({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: const CustomAppBar(title: "Chat"), + body: Column( + children: [ + Expanded( + child: ListView.separated( + itemCount: 15, + separatorBuilder: (BuildContext context, int index) => 20.height, + itemBuilder: (BuildContext context, int index) { + return ChatMessageCustomWidget( + isSent: index.isOdd, + profileUrl: MyAssets.bnCar, + messageText: "Hi, How Are you? I can help you out with the desired request.", + messageTypeEnum: index == 10 + ? (MessageTypeEnum.newOfferRequired) + : index == 12 + ? (MessageTypeEnum.offerProvided) + : (MessageTypeEnum.text), + senderName: "Al Abdullah Cars", + ); + }).horPaddingMain(), + ), + 10.width, + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + flex: 7, + child: TxtField( + // value: adVM.vehicleDemandAmount, + // errorValue: adVM.demandAmountError, + hint: "Type your message here..", + keyboardType: TextInputType.text, + isNeedBorder: false, + onChanged: (v) => null, + ), + ), + Expanded( + flex: 1, + child: const Icon( + Icons.send_rounded, + color: MyColors.darkPrimaryColor, + size: 30, + ).onPress(() {})) + ], + ).toContainer(isShadowEnabled: true), + ], + ), + // body: + ); + } +} + +class ChatMessageCustomWidget extends StatelessWidget { + final String profileUrl; + final String senderName; + final String messageText; + final MessageTypeEnum messageTypeEnum; + final bool isSent; + + const ChatMessageCustomWidget({ + super.key, + required this.profileUrl, + required this.senderName, + required this.messageText, + required this.messageTypeEnum, + required this.isSent, + }); + + @override + Widget build(BuildContext context) { + return Directionality( + textDirection: isSent ? TextDirection.rtl : TextDirection.ltr, + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + flex: 1, + child: Image.asset( + profileUrl, + width: 34, + height: 34, + fit: BoxFit.fill, + ).toCircle(borderRadius: 100), + ), + 10.width, + Expanded( + flex: 10, + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + (isSent ? "You" : senderName).toText(fontSize: 16, isBold: true), + ], + ), + 5.height, + Column( + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: messageText.toText( + color: isSent ? MyColors.white : MyColors.lightTextColor, + fontSize: 12, + // isBold: true, + ), + ), + ], + ), + if (messageTypeEnum == MessageTypeEnum.offerProvided || messageTypeEnum == MessageTypeEnum.newOfferRequired) ...[ + 5.height, + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + "40000".toText(fontSize: 19, isBold: true), + 2.width, + "SAR".toText(color: MyColors.lightTextColor, height: 2.2, fontSize: 10, isBold: true), + ], + ), + 10.height, + if (messageTypeEnum == MessageTypeEnum.newOfferRequired) ...[ + Center( + child: "You asked for the new offer.".toText( + color: MyColors.adPendingStatusColor, + fontSize: 12, + isItalic: true, + ), + ).toContainer(borderRadius: 40, width: double.infinity, backgroundColor: MyColors.adPendingStatusColor.withOpacity(0.16)), + ] else ...[ + Row( + children: [ + Expanded( + child: ShowFillButton( + maxHeight: 27, + title: "Accept", + fontSize: 9, + borderColor: MyColors.greenColor, + isFilled: false, + onPressed: () {}, + backgroundColor: MyColors.white, + txtColor: MyColors.greenColor, + ), + ), + 20.width, + Expanded( + child: ShowFillButton( + maxHeight: 27, + title: "Reject", + borderColor: MyColors.redColor, + isFilled: false, + onPressed: () {}, + backgroundColor: MyColors.white, + txtColor: MyColors.redColor, + fontSize: 9, + ), + ) + ], + ), + ], + ], + ], + ).toContainer( + isShadowEnabled: !isSent, + backgroundColor: isSent ? MyColors.darkIconColor : MyColors.white, + borderRadius: 0, + margin: EdgeInsets.fromLTRB(isSent ? 25 : 0, 0, !isSent ? 25 : 0, 0), + ), + ], + ), + ) + ], + ), + ); + } +} + +enum MessageTypeEnum { text, picture, offerProvided, recording, video, newOfferRequired } diff --git a/lib/views/requests/create_request_page.dart b/lib/views/requests/create_request_page.dart index b24d5e7..cb12e6c 100644 --- a/lib/views/requests/create_request_page.dart +++ b/lib/views/requests/create_request_page.dart @@ -3,7 +3,7 @@ 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/models/widgets_models.dart'; +import 'package:mc_common_app/models/general/widgets_models.dart'; import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/views/advertisement/ad_creation_steps/ad_creation_steps_containers.dart'; import 'package:mc_common_app/views/advertisement/picked_images_container.dart'; diff --git a/lib/views/requests/widget/request_item.dart b/lib/views/requests/widget/request_item.dart index 7844b0a..3c37086 100644 --- a/lib/views/requests/widget/request_item.dart +++ b/lib/views/requests/widget/request_item.dart @@ -1,3 +1,4 @@ +import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/view_models/requests_view_model.dart'; import 'package:flutter/material.dart'; import 'package:mc_common_app/config/routes.dart'; @@ -13,8 +14,9 @@ import 'package:provider/provider.dart'; class RequestItem extends StatelessWidget { final RequestModel request; + final AppType appType; - RequestItem({required this.request}); + const RequestItem({super.key, required this.request, required this.appType}); @override Widget build(BuildContext context) { @@ -100,8 +102,12 @@ class RequestItem extends StatelessWidget { ), ], ).toContainer(isShadowEnabled: true).onPress(() async { - List offers = await context.read().getOffersByRequest(requestId: request.id, context: context); - navigateWithName(context, AppRoutes.offersListPage, arguments: offers); + if (appType == AppType.provider) { + navigateWithName(context, AppRoutes.requestsDetailPage, arguments: request); + } else { + List offers = await context.read().getOffersByRequest(requestId: request.id, context: context); + navigateWithName(context, AppRoutes.offersListPage, arguments: offers); + } }); } diff --git a/lib/views/user/register_selection_page.dart b/lib/views/user/register_selection_page.dart index b819294..0926b8f 100644 --- a/lib/views/user/register_selection_page.dart +++ b/lib/views/user/register_selection_page.dart @@ -12,6 +12,7 @@ import 'package:mc_common_app/widgets/button/show_fill_button.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:sizer/sizer.dart'; import '../../theme/colors.dart'; @@ -82,6 +83,18 @@ class RegisterSelectionPage extends StatelessWidget { ), ), ), + 10.height, + TextButton( + onPressed: () {}, + child: Text( + "${AppState().currentAppType}", + style: const TextStyle( + color: MyColors.darkPrimaryColor, + fontWeight: FontWeight.bold, + decoration: TextDecoration.underline, + ), + ), + ), Utils.mFlex(3), ], ), diff --git a/lib/widgets/common_widgets/categories_list.dart b/lib/widgets/common_widgets/categories_list.dart index 0bc133f..4acf882 100644 --- a/lib/widgets/common_widgets/categories_list.dart +++ b/lib/widgets/common_widgets/categories_list.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; -import 'package:mc_common_app/models/widgets_models.dart'; +import 'package:mc_common_app/models/general/widgets_models.dart'; import 'package:mc_common_app/theme/colors.dart'; class FiltersList extends StatelessWidget { diff --git a/lib/widgets/common_widgets/time_slots.dart b/lib/widgets/common_widgets/time_slots.dart index 2c4099e..f3702cb 100644 --- a/lib/widgets/common_widgets/time_slots.dart +++ b/lib/widgets/common_widgets/time_slots.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; -import 'package:mc_common_app/models/service_schedule_model.dart'; -import 'package:mc_common_app/models/widgets_models.dart'; +import 'package:mc_common_app/models/appointments_models/service_schedule_model.dart'; +import 'package:mc_common_app/models/general/widgets_models.dart'; import 'package:mc_common_app/theme/colors.dart'; class BuildTimeSlots extends StatelessWidget { diff --git a/pubspec.lock b/pubspec.lock index 09c3a03..5aad031 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -613,14 +613,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.2.0" - message_pack_dart: - dependency: transitive - description: - name: message_pack_dart - sha256: "71b9f0ff60e5896e60b337960bb535380d7dba3297b457ac763ccae807385b59" - url: "https://pub.dev" - source: hosted - version: "2.0.1" meta: dependency: transitive description: @@ -789,14 +781,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.6" - pool: - dependency: transitive - description: - name: pool - sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" - url: "https://pub.dev" - source: hosted - version: "1.5.1" provider: dependency: "direct main" description: @@ -877,14 +861,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.1" - shelf: - dependency: transitive - description: - name: shelf - sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 - url: "https://pub.dev" - source: hosted - version: "1.4.1" shimmer: dependency: "direct main" description: @@ -893,14 +869,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.0" - signalr_netcore: + signalr_core: dependency: "direct main" description: - name: signalr_netcore - sha256: "8f84b4b516c03f3a6872f94e9729d1441d5d223a77c81d0a7d7dae5dd0ce1f2f" + name: signalr_core + sha256: dca676372a00c051511591ed0e24521ff7aa4e9320a7fa778a1007f7f522c8c0 url: "https://pub.dev" source: hosted - version: "1.3.6" + version: "1.1.1" simple_gesture_detector: dependency: transitive description: @@ -946,22 +922,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.5.0" - sse: - dependency: transitive - description: - name: sse - sha256: "3ff9088cac3f45aa8b91336f1962e3ea6c81baaba0bbba361c05f8aa7fb59442" - url: "https://pub.dev" - source: hosted - version: "4.1.2" - sse_channel: + sse_client: dependency: transitive description: - name: sse_channel - sha256: ba2b1382b9423c58fa83e1f01a3a40fbaa16a0594aa984870c88bad0b45d4ca4 + name: sse_client + sha256: "71bd826430b41ab20a69d85bf2dfe9f11cfe222938e681ada1aea71fc8adf348" url: "https://pub.dev" source: hosted - version: "0.0.3" + version: "0.1.0" stack_trace: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index d19a6e1..f7f6455 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -39,7 +39,7 @@ dependencies: country_code_picker: ^3.0.0 table_calendar: ^3.0.9 intl: any - signalr_netcore: ^1.3.6 + signalr_core: ^1.1.1 logging: ^1.2.0 From c5cefa2309d884fb1812f979f963b67302941ef0 Mon Sep 17 00:00:00 2001 From: Faiz Hashmi Date: Thu, 7 Dec 2023 11:00:09 +0300 Subject: [PATCH 2/5] models refinement --- lib/api/api_client.dart | 4 +- lib/classes/app_state.dart | 2 +- lib/config/routes.dart | 2 +- .../appointment_list_model.dart | 2 +- .../appointments_models/schedule_model.dart | 2 +- .../service_schedule_model.dart | 2 +- .../cat_message_model.dart | 0 .../branch_detail_model.dart | 2 +- .../profile/categroy.dart | 2 +- .../offers_model.dart | 0 .../request_model.dart | 0 .../item_model.dart | 0 .../service_model.dart | 2 +- .../subscription_model.dart | 125 ++++++++++++++++++ .../{user => user_models}/basic_otp.dart | 0 .../{user => user_models}/branch_user.dart | 0 .../{user => user_models}/change_email.dart | 0 .../{user => user_models}/change_mobile.dart | 0 .../change_password.dart | 0 lib/models/{user => user_models}/cities.dart | 0 .../{user => user_models}/confirm_email.dart | 0 .../{user => user_models}/confirm_mobile.dart | 0 .../confirm_password.dart | 0 lib/models/{user => user_models}/country.dart | 0 .../{user => user_models}/email_verify.dart | 0 .../email_verify_otp.dart | 0 .../forget_password_otp_compare.dart | 0 .../forget_password_otp_request.dart | 0 .../{user => user_models}/image_response.dart | 0 .../{user => user_models}/login_password.dart | 0 .../{user => user_models}/refresh_token.dart | 0 .../{user => user_models}/register_user.dart | 0 lib/models/{user => user_models}/role.dart | 0 lib/models/{user => user_models}/user.dart | 0 .../{user => user_models}/verify_email.dart | 0 .../verify_email_otp.dart | 0 .../subscription_model.dart | 125 ------------------ lib/repositories/common_repo.dart | 6 +- lib/repositories/provider_repo.dart | 2 +- lib/repositories/request_repo.dart | 4 +- lib/repositories/user_repo.dart | 44 +++--- lib/view_models/appointments_view_model.dart | 4 +- .../dashboard_view_model_customer.dart | 2 +- lib/view_models/requests_view_model.dart | 4 +- lib/view_models/user_view_model.dart | 26 ++-- .../appointments/appointment_detail_view.dart | 2 +- .../book_appointment_schedules_view.dart | 2 +- .../book_appointment_services_view.dart | 4 +- .../book_appointments_item_view.dart | 2 +- .../appointments/review_appointment_view.dart | 4 +- lib/views/requests/offer_list_page.dart | 2 +- lib/views/requests/widget/request_item.dart | 4 +- .../requests/widget/request_status_chip.dart | 2 +- lib/views/user/complete_profile_page.dart | 2 +- lib/views/user/forget_password_page.dart | 2 +- lib/views/user/login_with_password_page.dart | 2 +- lib/views/user/register_page.dart | 2 +- lib/views/user/register_provider_page.dart | 4 +- .../common_widgets/provider_details_card.dart | 2 +- 59 files changed, 199 insertions(+), 199 deletions(-) rename lib/models/{chat => chat_models}/cat_message_model.dart (100%) rename lib/models/{requests => requests_models}/offers_model.dart (100%) rename lib/models/{requests => requests_models}/request_model.dart (100%) rename lib/models/{services => services_models}/item_model.dart (100%) rename lib/models/{services => services_models}/service_model.dart (98%) create mode 100644 lib/models/subscriptions_models/subscription_model.dart rename lib/models/{user => user_models}/basic_otp.dart (100%) rename lib/models/{user => user_models}/branch_user.dart (100%) rename lib/models/{user => user_models}/change_email.dart (100%) rename lib/models/{user => user_models}/change_mobile.dart (100%) rename lib/models/{user => user_models}/change_password.dart (100%) rename lib/models/{user => user_models}/cities.dart (100%) rename lib/models/{user => user_models}/confirm_email.dart (100%) rename lib/models/{user => user_models}/confirm_mobile.dart (100%) rename lib/models/{user => user_models}/confirm_password.dart (100%) rename lib/models/{user => user_models}/country.dart (100%) rename lib/models/{user => user_models}/email_verify.dart (100%) rename lib/models/{user => user_models}/email_verify_otp.dart (100%) rename lib/models/{user => user_models}/forget_password_otp_compare.dart (100%) rename lib/models/{user => user_models}/forget_password_otp_request.dart (100%) rename lib/models/{user => user_models}/image_response.dart (100%) rename lib/models/{user => user_models}/login_password.dart (100%) rename lib/models/{user => user_models}/refresh_token.dart (100%) rename lib/models/{user => user_models}/register_user.dart (100%) rename lib/models/{user => user_models}/role.dart (100%) rename lib/models/{user => user_models}/user.dart (100%) rename lib/models/{user => user_models}/verify_email.dart (100%) rename lib/models/{user => user_models}/verify_email_otp.dart (100%) delete mode 100644 lib/models/verify_usage_before_deleting_these/subscription_model.dart diff --git a/lib/api/api_client.dart b/lib/api/api_client.dart index b87e842..8b0d887 100644 --- a/lib/api/api_client.dart +++ b/lib/api/api_client.dart @@ -10,8 +10,8 @@ import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/exceptions/api_exception.dart'; import 'package:mc_common_app/main.dart'; -import 'package:mc_common_app/models/user/refresh_token.dart'; -import 'package:mc_common_app/models/user/user.dart'; +import 'package:mc_common_app/models/user_models/refresh_token.dart'; +import 'package:mc_common_app/models/user_models/user.dart'; import 'package:mc_common_app/utils/shared_prefrence.dart'; typedef FactoryConstructor = U Function(dynamic); diff --git a/lib/classes/app_state.dart b/lib/classes/app_state.dart index 208654d..02ba4b9 100644 --- a/lib/classes/app_state.dart +++ b/lib/classes/app_state.dart @@ -1,6 +1,6 @@ import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:mc_common_app/models/general/post_params_model.dart'; -import 'package:mc_common_app/models/user/user.dart'; +import 'package:mc_common_app/models/user_models/user.dart'; import 'package:mc_common_app/utils/enums.dart'; class AppState { diff --git a/lib/config/routes.dart b/lib/config/routes.dart index e934484..0db2a2c 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -1,4 +1,4 @@ -import 'package:mc_common_app/models/user/register_user.dart'; +import 'package:mc_common_app/models/user_models/register_user.dart'; import 'package:mc_common_app/views/user/change_email_page.dart'; import 'package:mc_common_app/views/user/change_mobile_page.dart'; diff --git a/lib/models/appointments_models/appointment_list_model.dart b/lib/models/appointments_models/appointment_list_model.dart index 091a898..d3da5c0 100644 --- a/lib/models/appointments_models/appointment_list_model.dart +++ b/lib/models/appointments_models/appointment_list_model.dart @@ -1,5 +1,5 @@ import 'package:mc_common_app/extensions/string_extensions.dart'; -import 'package:mc_common_app/models/services/service_model.dart'; +import 'package:mc_common_app/models/services_models/service_model.dart'; import 'package:mc_common_app/utils/enums.dart'; class AppointmentListModel { diff --git a/lib/models/appointments_models/schedule_model.dart b/lib/models/appointments_models/schedule_model.dart index 47c13e6..2f65cd2 100644 --- a/lib/models/appointments_models/schedule_model.dart +++ b/lib/models/appointments_models/schedule_model.dart @@ -4,7 +4,7 @@ import 'dart:convert'; -import 'package:mc_common_app/models/services/service_model.dart'; +import 'package:mc_common_app/models/services_models/service_model.dart'; Schedule scheduleFromJson(String str) => Schedule.fromJson(json.decode(str)); diff --git a/lib/models/appointments_models/service_schedule_model.dart b/lib/models/appointments_models/service_schedule_model.dart index 4e3671a..8a30e93 100644 --- a/lib/models/appointments_models/service_schedule_model.dart +++ b/lib/models/appointments_models/service_schedule_model.dart @@ -1,5 +1,5 @@ import 'package:mc_common_app/extensions/string_extensions.dart'; -import 'package:mc_common_app/models/services/service_model.dart'; +import 'package:mc_common_app/models/services_models/service_model.dart'; import 'package:mc_common_app/models/general/widgets_models.dart'; class CustomTimeDateSlotModel { diff --git a/lib/models/chat/cat_message_model.dart b/lib/models/chat_models/cat_message_model.dart similarity index 100% rename from lib/models/chat/cat_message_model.dart rename to lib/models/chat_models/cat_message_model.dart diff --git a/lib/models/provider_branches_models/branch_detail_model.dart b/lib/models/provider_branches_models/branch_detail_model.dart index 70768c3..6ed2ed9 100644 --- a/lib/models/provider_branches_models/branch_detail_model.dart +++ b/lib/models/provider_branches_models/branch_detail_model.dart @@ -1,6 +1,6 @@ import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/models/provider_branches_models/profile/categroy.dart'; -import 'package:mc_common_app/models/services/service_model.dart'; +import 'package:mc_common_app/models/services_models/service_model.dart'; import 'package:mc_common_app/utils/enums.dart'; class BranchDetailModel { diff --git a/lib/models/provider_branches_models/profile/categroy.dart b/lib/models/provider_branches_models/profile/categroy.dart index 33feaae..cca86fd 100644 --- a/lib/models/provider_branches_models/profile/categroy.dart +++ b/lib/models/provider_branches_models/profile/categroy.dart @@ -6,7 +6,7 @@ import 'dart:convert'; import 'package:equatable/equatable.dart'; import 'package:mc_common_app/models/provider_branches_models/provider_profile_model.dart'; -import 'package:mc_common_app/models/services/service_model.dart'; +import 'package:mc_common_app/models/services_models/service_model.dart'; Category categoryFromJson(String str) => Category.fromJson(json.decode(str)); diff --git a/lib/models/requests/offers_model.dart b/lib/models/requests_models/offers_model.dart similarity index 100% rename from lib/models/requests/offers_model.dart rename to lib/models/requests_models/offers_model.dart diff --git a/lib/models/requests/request_model.dart b/lib/models/requests_models/request_model.dart similarity index 100% rename from lib/models/requests/request_model.dart rename to lib/models/requests_models/request_model.dart diff --git a/lib/models/services/item_model.dart b/lib/models/services_models/item_model.dart similarity index 100% rename from lib/models/services/item_model.dart rename to lib/models/services_models/item_model.dart diff --git a/lib/models/services/service_model.dart b/lib/models/services_models/service_model.dart similarity index 98% rename from lib/models/services/service_model.dart rename to lib/models/services_models/service_model.dart index 2581b63..d158bee 100644 --- a/lib/models/services/service_model.dart +++ b/lib/models/services_models/service_model.dart @@ -1,4 +1,4 @@ -import 'package:mc_common_app/models/services/item_model.dart'; +import 'package:mc_common_app/models/services_models/item_model.dart'; class ServiceModel { final int? serviceProviderServiceId; diff --git a/lib/models/subscriptions_models/subscription_model.dart b/lib/models/subscriptions_models/subscription_model.dart new file mode 100644 index 0000000..d192566 --- /dev/null +++ b/lib/models/subscriptions_models/subscription_model.dart @@ -0,0 +1,125 @@ +// To parse this JSON data, do +// +// final subscription = subscriptionFromJson(jsonString); + +import 'dart:convert'; + +Subscription subscriptionFromJson(String str) => Subscription.fromJson(json.decode(str)); + +String subscriptionToJson(Subscription data) => json.encode(data.toJson()); + +class SubscriptionModel { + SubscriptionModel({ + this.messageStatus, + this.totalItemsCount, + this.data, + this.message, + }); + + int? messageStatus; + int? totalItemsCount; + List? data; + String? message; + + factory SubscriptionModel.fromJson(Map json) => SubscriptionModel( + messageStatus: json["messageStatus"], + totalItemsCount: json["totalItemsCount"], + data: json["data"] == null ? [] : List.from(json["data"]!.map((x) => Subscription.fromJson(x))), + message: json["message"], + ); + + Map toJson() => { + "messageStatus": messageStatus, + "totalItemsCount": totalItemsCount, + "data": data == null ? [] : List.from(data!.map((x) => x.toJson())), + "message": message, + }; +} + +class Subscription { + Subscription({ + this.id, + this.name, + this.description, + this.durationName, + this.durationDays, + this.price, + this.currency, + this.numberOfBranches, + this.numberOfSubUsers, + this.numberOfAds, + this.countryId, + this.countryName, + this.isSubscribed, + this.subscriptionAppliedId, + this.serviceProviderId, + this.dateStart, + this.dateEnd, + this.isExpired, + this.isActive, + }); + + int? id; + String? name; + String? description; + String? durationName; + int? durationDays; + double? price; + String? currency; + int? numberOfBranches; + int? numberOfSubUsers; + int? numberOfAds; + int? countryId; + String? countryName; + bool? isSubscribed; + int? subscriptionAppliedId; + int? serviceProviderId; + DateTime? dateStart; + DateTime? dateEnd; + bool? isExpired; + bool? isActive; + + factory Subscription.fromJson(Map json) => Subscription( + id: json["id"], + name: json["name"], + description: json["description"], + durationName: json["durationName"], + durationDays: json["durationDays"], + price: json["price"]?.toDouble(), + currency: json["currency"], + numberOfBranches: json["numberOfBranches"], + numberOfSubUsers: json["numberOfSubUsers"], + numberOfAds: json["numberOfAds"], + countryId: json["countryID"], + countryName: json["countryName"]!, + isSubscribed: json["isSubscribed"], + subscriptionAppliedId: json["subscriptionAppliedID"], + serviceProviderId: json["serviceProviderID"], + dateStart: json["dateStart"] == null ? null : DateTime.parse(json["dateStart"]), + dateEnd: json["dateEnd"] == null ? null : DateTime.parse(json["dateEnd"]), + isExpired: json["isExpired"], + isActive: json["isActive"], + ); + + Map toJson() => { + "id": id, + "name": name, + "description": description, + "durationName": durationName, + "durationDays": durationDays, + "price": price, + "currency": currency, + "numberOfBranches": numberOfBranches, + "numberOfSubUsers": numberOfSubUsers, + "numberOfAds": numberOfAds, + "countryID": countryId, + "countryName": countryName, + "isSubscribed": isSubscribed, + "subscriptionAppliedID": subscriptionAppliedId, + "serviceProviderID": serviceProviderId, + "dateStart": dateStart?.toIso8601String(), + "dateEnd": dateEnd?.toIso8601String(), + "isExpired": isExpired, + "isActive": isActive, + }; +} diff --git a/lib/models/user/basic_otp.dart b/lib/models/user_models/basic_otp.dart similarity index 100% rename from lib/models/user/basic_otp.dart rename to lib/models/user_models/basic_otp.dart diff --git a/lib/models/user/branch_user.dart b/lib/models/user_models/branch_user.dart similarity index 100% rename from lib/models/user/branch_user.dart rename to lib/models/user_models/branch_user.dart diff --git a/lib/models/user/change_email.dart b/lib/models/user_models/change_email.dart similarity index 100% rename from lib/models/user/change_email.dart rename to lib/models/user_models/change_email.dart diff --git a/lib/models/user/change_mobile.dart b/lib/models/user_models/change_mobile.dart similarity index 100% rename from lib/models/user/change_mobile.dart rename to lib/models/user_models/change_mobile.dart diff --git a/lib/models/user/change_password.dart b/lib/models/user_models/change_password.dart similarity index 100% rename from lib/models/user/change_password.dart rename to lib/models/user_models/change_password.dart diff --git a/lib/models/user/cities.dart b/lib/models/user_models/cities.dart similarity index 100% rename from lib/models/user/cities.dart rename to lib/models/user_models/cities.dart diff --git a/lib/models/user/confirm_email.dart b/lib/models/user_models/confirm_email.dart similarity index 100% rename from lib/models/user/confirm_email.dart rename to lib/models/user_models/confirm_email.dart diff --git a/lib/models/user/confirm_mobile.dart b/lib/models/user_models/confirm_mobile.dart similarity index 100% rename from lib/models/user/confirm_mobile.dart rename to lib/models/user_models/confirm_mobile.dart diff --git a/lib/models/user/confirm_password.dart b/lib/models/user_models/confirm_password.dart similarity index 100% rename from lib/models/user/confirm_password.dart rename to lib/models/user_models/confirm_password.dart diff --git a/lib/models/user/country.dart b/lib/models/user_models/country.dart similarity index 100% rename from lib/models/user/country.dart rename to lib/models/user_models/country.dart diff --git a/lib/models/user/email_verify.dart b/lib/models/user_models/email_verify.dart similarity index 100% rename from lib/models/user/email_verify.dart rename to lib/models/user_models/email_verify.dart diff --git a/lib/models/user/email_verify_otp.dart b/lib/models/user_models/email_verify_otp.dart similarity index 100% rename from lib/models/user/email_verify_otp.dart rename to lib/models/user_models/email_verify_otp.dart diff --git a/lib/models/user/forget_password_otp_compare.dart b/lib/models/user_models/forget_password_otp_compare.dart similarity index 100% rename from lib/models/user/forget_password_otp_compare.dart rename to lib/models/user_models/forget_password_otp_compare.dart diff --git a/lib/models/user/forget_password_otp_request.dart b/lib/models/user_models/forget_password_otp_request.dart similarity index 100% rename from lib/models/user/forget_password_otp_request.dart rename to lib/models/user_models/forget_password_otp_request.dart diff --git a/lib/models/user/image_response.dart b/lib/models/user_models/image_response.dart similarity index 100% rename from lib/models/user/image_response.dart rename to lib/models/user_models/image_response.dart diff --git a/lib/models/user/login_password.dart b/lib/models/user_models/login_password.dart similarity index 100% rename from lib/models/user/login_password.dart rename to lib/models/user_models/login_password.dart diff --git a/lib/models/user/refresh_token.dart b/lib/models/user_models/refresh_token.dart similarity index 100% rename from lib/models/user/refresh_token.dart rename to lib/models/user_models/refresh_token.dart diff --git a/lib/models/user/register_user.dart b/lib/models/user_models/register_user.dart similarity index 100% rename from lib/models/user/register_user.dart rename to lib/models/user_models/register_user.dart diff --git a/lib/models/user/role.dart b/lib/models/user_models/role.dart similarity index 100% rename from lib/models/user/role.dart rename to lib/models/user_models/role.dart diff --git a/lib/models/user/user.dart b/lib/models/user_models/user.dart similarity index 100% rename from lib/models/user/user.dart rename to lib/models/user_models/user.dart diff --git a/lib/models/user/verify_email.dart b/lib/models/user_models/verify_email.dart similarity index 100% rename from lib/models/user/verify_email.dart rename to lib/models/user_models/verify_email.dart diff --git a/lib/models/user/verify_email_otp.dart b/lib/models/user_models/verify_email_otp.dart similarity index 100% rename from lib/models/user/verify_email_otp.dart rename to lib/models/user_models/verify_email_otp.dart diff --git a/lib/models/verify_usage_before_deleting_these/subscription_model.dart b/lib/models/verify_usage_before_deleting_these/subscription_model.dart deleted file mode 100644 index c8e781a..0000000 --- a/lib/models/verify_usage_before_deleting_these/subscription_model.dart +++ /dev/null @@ -1,125 +0,0 @@ -// // To parse this JSON data, do -// // -// // final subscription = subscriptionFromJson(jsonString); -// -// import 'dart:convert'; -// -// Subscription subscriptionFromJson(String str) => Subscription.fromJson(json.decode(str)); -// -// String subscriptionToJson(Subscription data) => json.encode(data.toJson()); -// -// class SubscriptionModel { -// SubscriptionModel({ -// this.messageStatus, -// this.totalItemsCount, -// this.data, -// this.message, -// }); -// -// int? messageStatus; -// int? totalItemsCount; -// List? data; -// String? message; -// -// factory SubscriptionModel.fromJson(Map json) => SubscriptionModel( -// messageStatus: json["messageStatus"], -// totalItemsCount: json["totalItemsCount"], -// data: json["data"] == null ? [] : List.from(json["data"]!.map((x) => Subscription.fromJson(x))), -// message: json["message"], -// ); -// -// Map toJson() => { -// "messageStatus": messageStatus, -// "totalItemsCount": totalItemsCount, -// "data": data == null ? [] : List.from(data!.map((x) => x.toJson())), -// "message": message, -// }; -// } -// -// class Subscription { -// Subscription({ -// this.id, -// this.name, -// this.description, -// this.durationName, -// this.durationDays, -// this.price, -// this.currency, -// this.numberOfBranches, -// this.numberOfSubUsers, -// this.numberOfAds, -// this.countryId, -// this.countryName, -// this.isSubscribed, -// this.subscriptionAppliedId, -// this.serviceProviderId, -// this.dateStart, -// this.dateEnd, -// this.isExpired, -// this.isActive, -// }); -// -// int? id; -// String? name; -// String? description; -// String? durationName; -// int? durationDays; -// double? price; -// String? currency; -// int? numberOfBranches; -// int? numberOfSubUsers; -// int? numberOfAds; -// int? countryId; -// String? countryName; -// bool? isSubscribed; -// int? subscriptionAppliedId; -// int? serviceProviderId; -// DateTime? dateStart; -// DateTime? dateEnd; -// bool? isExpired; -// bool? isActive; -// -// factory Subscription.fromJson(Map json) => Subscription( -// id: json["id"], -// name: json["name"], -// description: json["description"], -// durationName: json["durationName"], -// durationDays: json["durationDays"], -// price: json["price"]?.toDouble(), -// currency: json["currency"], -// numberOfBranches: json["numberOfBranches"], -// numberOfSubUsers: json["numberOfSubUsers"], -// numberOfAds: json["numberOfAds"], -// countryId: json["countryID"], -// countryName: json["countryName"]!, -// isSubscribed: json["isSubscribed"], -// subscriptionAppliedId: json["subscriptionAppliedID"], -// serviceProviderId: json["serviceProviderID"], -// dateStart: json["dateStart"] == null ? null : DateTime.parse(json["dateStart"]), -// dateEnd: json["dateEnd"] == null ? null : DateTime.parse(json["dateEnd"]), -// isExpired: json["isExpired"], -// isActive: json["isActive"], -// ); -// -// Map toJson() => { -// "id": id, -// "name": name, -// "description": description, -// "durationName": durationName, -// "durationDays": durationDays, -// "price": price, -// "currency": currency, -// "numberOfBranches": numberOfBranches, -// "numberOfSubUsers": numberOfSubUsers, -// "numberOfAds": numberOfAds, -// "countryID": countryId, -// "countryName": countryName, -// "isSubscribed": isSubscribed, -// "subscriptionAppliedID": subscriptionAppliedId, -// "serviceProviderID": serviceProviderId, -// "dateStart": dateStart?.toIso8601String(), -// "dateEnd": dateEnd?.toIso8601String(), -// "isExpired": isExpired, -// "isActive": isActive, -// }; -// } diff --git a/lib/repositories/common_repo.dart b/lib/repositories/common_repo.dart index 8ede9a0..26cc5f5 100644 --- a/lib/repositories/common_repo.dart +++ b/lib/repositories/common_repo.dart @@ -6,9 +6,9 @@ import 'package:mc_common_app/models/advertisment_models/ss_car_check_schedule_m import 'package:mc_common_app/models/advertisment_models/ss_photo_schedule_model.dart'; import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart'; import 'package:mc_common_app/models/general/generic_resp_model.dart'; -import 'package:mc_common_app/models/user/cities.dart'; -import 'package:mc_common_app/models/user/country.dart'; -import 'package:mc_common_app/models/user/role.dart'; +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/models/user_models/role.dart'; import '../models/advertisment_models/vehicle_details_models.dart'; import '../models/general/enums_model.dart'; diff --git a/lib/repositories/provider_repo.dart b/lib/repositories/provider_repo.dart index 2709588..36a9a39 100644 --- a/lib/repositories/provider_repo.dart +++ b/lib/repositories/provider_repo.dart @@ -7,7 +7,7 @@ import 'package:mc_common_app/config/dependencies.dart'; import 'package:mc_common_app/models/general/generic_resp_model.dart'; import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart'; import 'package:mc_common_app/models/provider_branches_models/provider_profile_model.dart'; -import 'package:mc_common_app/models/services/item_model.dart'; +import 'package:mc_common_app/models/services_models/item_model.dart'; abstract class ProviderRepo { Future> getAllNearBranchAndServices(); diff --git a/lib/repositories/request_repo.dart b/lib/repositories/request_repo.dart index 8095e4b..ffaa33d 100644 --- a/lib/repositories/request_repo.dart +++ b/lib/repositories/request_repo.dart @@ -3,8 +3,8 @@ import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/config/dependencies.dart'; import 'package:mc_common_app/models/general/generic_resp_model.dart'; -import 'package:mc_common_app/models/requests/offers_model.dart'; -import 'package:mc_common_app/models/requests/request_model.dart'; +import 'package:mc_common_app/models/requests_models/offers_model.dart'; +import 'package:mc_common_app/models/requests_models/request_model.dart'; abstract class RequestRepo { Future createRequest(Map map); diff --git a/lib/repositories/user_repo.dart b/lib/repositories/user_repo.dart index 6d69a24..dba85f4 100644 --- a/lib/repositories/user_repo.dart +++ b/lib/repositories/user_repo.dart @@ -8,22 +8,22 @@ import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/config/dependencies.dart'; import 'package:mc_common_app/models/general/m_response.dart'; -import 'package:mc_common_app/models/user/basic_otp.dart'; -import 'package:mc_common_app/models/user/change_email.dart'; -import 'package:mc_common_app/models/user/change_mobile.dart'; -import 'package:mc_common_app/models/user/cities.dart'; -import 'package:mc_common_app/models/user/confirm_email.dart'; -import 'package:mc_common_app/models/user/confirm_mobile.dart'; -import 'package:mc_common_app/models/user/confirm_password.dart'; -import 'package:mc_common_app/models/user/country.dart'; -import 'package:mc_common_app/models/user/forget_password_otp_compare.dart'; -import 'package:mc_common_app/models/user/image_response.dart'; -import 'package:mc_common_app/models/user/login_password.dart'; -import 'package:mc_common_app/models/user/refresh_token.dart'; -import 'package:mc_common_app/models/user/register_user.dart'; -import 'package:mc_common_app/models/user/role.dart'; -import 'package:mc_common_app/models/user/user.dart'; -import 'package:mc_common_app/models/user/verify_email.dart'; +import 'package:mc_common_app/models/user_models/basic_otp.dart'; +import 'package:mc_common_app/models/user_models/change_email.dart'; +import 'package:mc_common_app/models/user_models/change_mobile.dart'; +import 'package:mc_common_app/models/user_models/cities.dart'; +import 'package:mc_common_app/models/user_models/confirm_email.dart'; +import 'package:mc_common_app/models/user_models/confirm_mobile.dart'; +import 'package:mc_common_app/models/user_models/confirm_password.dart'; +import 'package:mc_common_app/models/user_models/country.dart'; +import 'package:mc_common_app/models/user_models/forget_password_otp_compare.dart'; +import 'package:mc_common_app/models/user_models/image_response.dart'; +import 'package:mc_common_app/models/user_models/login_password.dart'; +import 'package:mc_common_app/models/user_models/refresh_token.dart'; +import 'package:mc_common_app/models/user_models/register_user.dart'; +import 'package:mc_common_app/models/user_models/role.dart'; +import 'package:mc_common_app/models/user_models/user.dart'; +import 'package:mc_common_app/models/user_models/verify_email.dart'; import 'package:mc_common_app/utils/shared_prefrence.dart'; abstract class UserRepo { @@ -81,7 +81,7 @@ class UserRepoImp implements UserRepo { String? t; if (isNeedToPassToken) { t = AppState().getUser.data!.accessToken ?? ""; - debugPrint("token " + t); + debugPrint("token $t"); } return await injector.get().postJsonForObject((json) => BasicOtpRespModel.fromJson(json), ApiConsts.BasicOTP, postParams, token: t); } @@ -96,7 +96,7 @@ class UserRepoImp implements UserRepo { String? t; if (isNeedToPassToken) { t = AppState().getUser.data!.accessToken ?? ""; - debugPrint("token " + t); + debugPrint("token $t"); } return await injector.get().postJsonForObject((json) => RegisterUserRespModel.fromJson(json), ApiConsts.BasicVerify, postParams, token: t); } @@ -112,7 +112,7 @@ class UserRepoImp implements UserRepo { String? t; if (isNeedToPassToken) { t = AppState().getUser.data!.accessToken ?? ""; - debugPrint("token " + t); + debugPrint("token $t"); } return await injector.get().postJsonForObject((json) => RegisterUserRespModel.fromJson(json), ApiConsts.BasicComplete, postParams, token: t); } @@ -212,7 +212,7 @@ class UserRepoImp implements UserRepo { // return await injector.get().postJsonForResponse(ApiConsts.ChangePassword, postParams); String t = AppState().getUser.data!.accessToken ?? ""; - debugPrint("token " + t); + debugPrint("token $t"); return await injector.get().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.ChangePassword, postParams, token: t); } @@ -274,7 +274,7 @@ class UserRepoImp implements UserRepo { // return await injector.get().postJsonForResponse(ApiConsts.ChangePassword, postParams); String t = AppState().getUser.data!.accessToken ?? ""; - debugPrint("token " + t); + debugPrint("token $t"); return await injector.get().postJsonForObject((json) => ImageResponse.fromJson(json), ApiConsts.UpdateUserImage, postParams, token: t); } @@ -284,7 +284,7 @@ class UserRepoImp implements UserRepo { // return await injector.get().postJsonForResponse(ApiConsts.ChangePassword, postParams); String t = AppState().getUser.data!.accessToken ?? ""; - debugPrint("token " + t); + debugPrint("token $t"); return await injector.get().postJsonForObject((json) => ImageResponse.fromJson(json), ApiConsts.UpdateUserImage, postParams, token: t); } diff --git a/lib/view_models/appointments_view_model.dart b/lib/view_models/appointments_view_model.dart index da26459..10c0e4d 100644 --- a/lib/view_models/appointments_view_model.dart +++ b/lib/view_models/appointments_view_model.dart @@ -9,8 +9,8 @@ import 'package:mc_common_app/models/general/generic_resp_model.dart'; import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart'; import 'package:mc_common_app/models/provider_branches_models/provider_profile_model.dart'; import 'package:mc_common_app/models/appointments_models/service_schedule_model.dart'; -import 'package:mc_common_app/models/services/item_model.dart'; -import 'package:mc_common_app/models/services/service_model.dart'; +import 'package:mc_common_app/models/services_models/item_model.dart'; +import 'package:mc_common_app/models/services_models/service_model.dart'; import 'package:mc_common_app/models/general/widgets_models.dart'; import 'package:mc_common_app/repositories/appointment_repo.dart'; import 'package:mc_common_app/repositories/common_repo.dart'; diff --git a/lib/view_models/dashboard_view_model_customer.dart b/lib/view_models/dashboard_view_model_customer.dart index d8ab0d4..513bbe0 100644 --- a/lib/view_models/dashboard_view_model_customer.dart +++ b/lib/view_models/dashboard_view_model_customer.dart @@ -1,7 +1,7 @@ import 'dart:io'; import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart'; -import 'package:mc_common_app/models/user/image_response.dart'; +import 'package:mc_common_app/models/user_models/image_response.dart'; import 'package:mc_common_app/repositories/user_repo.dart'; import 'package:mc_common_app/services/common_services.dart'; import 'package:mc_common_app/utils/utils.dart'; diff --git a/lib/view_models/requests_view_model.dart b/lib/view_models/requests_view_model.dart index c7ac932..44f6f4c 100644 --- a/lib/view_models/requests_view_model.dart +++ b/lib/view_models/requests_view_model.dart @@ -7,8 +7,8 @@ import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/models/advertisment_models/vehicle_details_models.dart'; import 'package:mc_common_app/models/general/enums_model.dart'; import 'package:mc_common_app/models/general/generic_resp_model.dart'; -import 'package:mc_common_app/models/requests/offers_model.dart'; -import 'package:mc_common_app/models/requests/request_model.dart'; +import 'package:mc_common_app/models/requests_models/offers_model.dart'; +import 'package:mc_common_app/models/requests_models/request_model.dart'; import 'package:mc_common_app/models/general/widgets_models.dart'; import 'package:mc_common_app/repositories/common_repo.dart'; import 'package:mc_common_app/repositories/request_repo.dart'; diff --git a/lib/view_models/user_view_model.dart b/lib/view_models/user_view_model.dart index 3e2f511..ac41cd1 100644 --- a/lib/view_models/user_view_model.dart +++ b/lib/view_models/user_view_model.dart @@ -9,19 +9,19 @@ 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/general/m_response.dart'; -import 'package:mc_common_app/models/user/basic_otp.dart'; -import 'package:mc_common_app/models/user/change_email.dart'; -import 'package:mc_common_app/models/user/change_mobile.dart'; -import 'package:mc_common_app/models/user/confirm_email.dart'; -import 'package:mc_common_app/models/user/confirm_mobile.dart'; -import 'package:mc_common_app/models/user/confirm_password.dart'; -import 'package:mc_common_app/models/user/country.dart'; -import 'package:mc_common_app/models/user/forget_password_otp_compare.dart'; -import 'package:mc_common_app/models/user/forget_password_otp_request.dart'; -import 'package:mc_common_app/models/user/login_password.dart'; -import 'package:mc_common_app/models/user/register_user.dart'; -import 'package:mc_common_app/models/user/user.dart'; -import 'package:mc_common_app/models/user/verify_email.dart'; +import 'package:mc_common_app/models/user_models/basic_otp.dart'; +import 'package:mc_common_app/models/user_models/change_email.dart'; +import 'package:mc_common_app/models/user_models/change_mobile.dart'; +import 'package:mc_common_app/models/user_models/confirm_email.dart'; +import 'package:mc_common_app/models/user_models/confirm_mobile.dart'; +import 'package:mc_common_app/models/user_models/confirm_password.dart'; +import 'package:mc_common_app/models/user_models/country.dart'; +import 'package:mc_common_app/models/user_models/forget_password_otp_compare.dart'; +import 'package:mc_common_app/models/user_models/forget_password_otp_request.dart'; +import 'package:mc_common_app/models/user_models/login_password.dart'; +import 'package:mc_common_app/models/user_models/register_user.dart'; +import 'package:mc_common_app/models/user_models/user.dart'; +import 'package:mc_common_app/models/user_models/verify_email.dart'; import 'package:mc_common_app/repositories/user_repo.dart'; import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/navigator.dart'; diff --git a/lib/views/appointments/appointment_detail_view.dart b/lib/views/appointments/appointment_detail_view.dart index 4eca313..6cf7f54 100644 --- a/lib/views/appointments/appointment_detail_view.dart +++ b/lib/views/appointments/appointment_detail_view.dart @@ -3,7 +3,7 @@ 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/models/appointments_models/appointment_list_model.dart'; -import 'package:mc_common_app/models/services/service_model.dart'; +import 'package:mc_common_app/models/services_models/service_model.dart'; import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/utils/dialogs_and_bottomsheets.dart'; import 'package:mc_common_app/utils/enums.dart'; diff --git a/lib/views/appointments/book_appointment_schedules_view.dart b/lib/views/appointments/book_appointment_schedules_view.dart index 6580be6..37738f4 100644 --- a/lib/views/appointments/book_appointment_schedules_view.dart +++ b/lib/views/appointments/book_appointment_schedules_view.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/models/appointments_models/service_schedule_model.dart'; -import 'package:mc_common_app/models/services/service_model.dart'; +import 'package:mc_common_app/models/services_models/service_model.dart'; import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/view_models/appointments_view_model.dart'; import 'package:mc_common_app/views/appointments/widgets/custom_calender_widget.dart'; diff --git a/lib/views/appointments/book_appointment_services_view.dart b/lib/views/appointments/book_appointment_services_view.dart index cadd2e4..ae38cd3 100644 --- a/lib/views/appointments/book_appointment_services_view.dart +++ b/lib/views/appointments/book_appointment_services_view.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; -import 'package:mc_common_app/models/services/item_model.dart'; -import 'package:mc_common_app/models/services/service_model.dart'; +import 'package:mc_common_app/models/services_models/item_model.dart'; +import 'package:mc_common_app/models/services_models/service_model.dart'; import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/view_models/appointments_view_model.dart'; import 'package:mc_common_app/views/advertisement/custom_add_button.dart'; diff --git a/lib/views/appointments/book_appointments_item_view.dart b/lib/views/appointments/book_appointments_item_view.dart index 07a5f37..09f892f 100644 --- a/lib/views/appointments/book_appointments_item_view.dart +++ b/lib/views/appointments/book_appointments_item_view.dart @@ -3,7 +3,7 @@ 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/models/services/item_model.dart'; +import 'package:mc_common_app/models/services_models/item_model.dart'; import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/view_models/appointments_view_model.dart'; diff --git a/lib/views/appointments/review_appointment_view.dart b/lib/views/appointments/review_appointment_view.dart index 6f26aa8..75fbe46 100644 --- a/lib/views/appointments/review_appointment_view.dart +++ b/lib/views/appointments/review_appointment_view.dart @@ -6,8 +6,8 @@ import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart'; import 'package:mc_common_app/models/appointments_models/service_schedule_model.dart'; -import 'package:mc_common_app/models/services/item_model.dart'; -import 'package:mc_common_app/models/services/service_model.dart'; +import 'package:mc_common_app/models/services_models/item_model.dart'; +import 'package:mc_common_app/models/services_models/service_model.dart'; import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/view_models/appointments_view_model.dart'; import 'package:mc_common_app/widgets/button/show_fill_button.dart'; diff --git a/lib/views/requests/offer_list_page.dart b/lib/views/requests/offer_list_page.dart index d97689f..995e863 100644 --- a/lib/views/requests/offer_list_page.dart +++ b/lib/views/requests/offer_list_page.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; -import 'package:mc_common_app/models/requests/offers_model.dart'; +import 'package:mc_common_app/models/requests_models/offers_model.dart'; import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/widgets/common_widgets/app_bar.dart'; diff --git a/lib/views/requests/widget/request_item.dart b/lib/views/requests/widget/request_item.dart index 3c37086..842035a 100644 --- a/lib/views/requests/widget/request_item.dart +++ b/lib/views/requests/widget/request_item.dart @@ -4,8 +4,8 @@ import 'package:flutter/material.dart'; import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; -import 'package:mc_common_app/models/requests/offers_model.dart'; -import 'package:mc_common_app/models/requests/request_model.dart'; +import 'package:mc_common_app/models/requests_models/offers_model.dart'; +import 'package:mc_common_app/models/requests_models/request_model.dart'; import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/utils/utils.dart'; diff --git a/lib/views/requests/widget/request_status_chip.dart b/lib/views/requests/widget/request_status_chip.dart index e93bdbd..3c0b462 100644 --- a/lib/views/requests/widget/request_status_chip.dart +++ b/lib/views/requests/widget/request_status_chip.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; -import 'package:mc_common_app/models/requests/request_model.dart'; +import 'package:mc_common_app/models/requests_models/request_model.dart'; import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; diff --git a/lib/views/user/complete_profile_page.dart b/lib/views/user/complete_profile_page.dart index db5b30d..ffa7189 100644 --- a/lib/views/user/complete_profile_page.dart +++ b/lib/views/user/complete_profile_page.dart @@ -2,7 +2,7 @@ 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'; import 'package:mc_common_app/generated/locale_keys.g.dart'; -import 'package:mc_common_app/models/user/register_user.dart'; +import 'package:mc_common_app/models/user_models/register_user.dart'; import 'package:mc_common_app/view_models/user_view_model.dart'; import 'package:mc_common_app/widgets/common_widgets/app_bar.dart'; import 'package:mc_common_app/widgets/button/show_fill_button.dart'; diff --git a/lib/views/user/forget_password_page.dart b/lib/views/user/forget_password_page.dart index d26bcfd..c4add4b 100644 --- a/lib/views/user/forget_password_page.dart +++ b/lib/views/user/forget_password_page.dart @@ -1,5 +1,5 @@ import 'dart:async'; -import 'package:mc_common_app/models/user/country.dart'; +import 'package:mc_common_app/models/user_models/country.dart'; import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/utils/utils.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; diff --git a/lib/views/user/login_with_password_page.dart b/lib/views/user/login_with_password_page.dart index 8b1dff1..07460f7 100644 --- a/lib/views/user/login_with_password_page.dart +++ b/lib/views/user/login_with_password_page.dart @@ -7,7 +7,7 @@ import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart'; -import 'package:mc_common_app/models/user/country.dart'; +import 'package:mc_common_app/models/user_models/country.dart'; import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/view_models/user_view_model.dart'; diff --git a/lib/views/user/register_page.dart b/lib/views/user/register_page.dart index 25411cf..bfbf74f 100644 --- a/lib/views/user/register_page.dart +++ b/lib/views/user/register_page.dart @@ -1,7 +1,7 @@ import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart'; -import 'package:mc_common_app/models/user/country.dart'; +import 'package:mc_common_app/models/user_models/country.dart'; import 'package:mc_common_app/utils/utils.dart'; import 'package:mc_common_app/view_models/user_view_model.dart'; import 'package:mc_common_app/widgets/common_widgets/app_bar.dart'; diff --git a/lib/views/user/register_provider_page.dart b/lib/views/user/register_provider_page.dart index 4a416fa..121a3f2 100644 --- a/lib/views/user/register_provider_page.dart +++ b/lib/views/user/register_provider_page.dart @@ -2,8 +2,8 @@ import 'package:mc_common_app/config/dependencies.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart'; -import 'package:mc_common_app/models/user/country.dart'; -import 'package:mc_common_app/models/user/role.dart'; +import 'package:mc_common_app/models/user_models/country.dart'; +import 'package:mc_common_app/models/user_models/role.dart'; import 'package:mc_common_app/repositories/user_repo.dart'; import 'package:mc_common_app/utils/utils.dart'; import 'package:mc_common_app/view_models/user_view_model.dart'; diff --git a/lib/widgets/common_widgets/provider_details_card.dart b/lib/widgets/common_widgets/provider_details_card.dart index 169f1c2..f621d3c 100644 --- a/lib/widgets/common_widgets/provider_details_card.dart +++ b/lib/widgets/common_widgets/provider_details_card.dart @@ -4,7 +4,7 @@ import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart'; -import 'package:mc_common_app/models/services/service_model.dart'; +import 'package:mc_common_app/models/services_models/service_model.dart'; import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; From 98b35fbc614ac8b86389ffcb26f6ac79db86cf95 Mon Sep 17 00:00:00 2001 From: Faiz Hashmi Date: Thu, 7 Dec 2023 17:51:04 +0300 Subject: [PATCH 3/5] Chat Module almost finished! --- lib/classes/app_state.dart | 2 +- lib/config/routes.dart | 18 +- lib/extensions/string_extensions.dart | 55 +++- .../ss_car_check_schedule_model.dart | 2 +- .../ss_photo_schedule_model.dart | 2 +- .../service_schedule_model.dart | 2 +- lib/models/chat_models/cat_message_model.dart | 70 ++++- .../enums_model.dart | 0 .../generic_resp_model.dart | 0 .../m_response.dart | 0 .../post_params_model.dart | 0 .../widgets_models.dart | 0 lib/models/requests_models/request_model.dart | 71 ++--- lib/repositories/ads_repo.dart | 2 +- lib/repositories/appointment_repo.dart | 4 +- lib/repositories/common_repo.dart | 6 +- lib/repositories/payments_repo.dart | 2 +- lib/repositories/provider_repo.dart | 2 +- lib/repositories/request_repo.dart | 2 +- lib/repositories/user_repo.dart | 2 +- lib/utils/enums.dart | 6 + lib/view_models/ad_view_model.dart | 6 +- lib/view_models/appointments_view_model.dart | 6 +- lib/view_models/chat_view_model.dart | 74 ++++- lib/view_models/requests_view_model.dart | 24 +- lib/view_models/user_view_model.dart | 2 +- .../ad_duration_container.dart | 2 +- .../vehicle_details_container.dart | 2 +- .../ad_duration_selection_sheet_content.dart | 2 +- lib/views/advertisement/ads_detail_view.dart | 2 +- lib/views/advertisement/ads_filter_view.dart | 2 +- .../advertisement/bottom_sheet_content.dart | 2 +- .../advertisement/select_ad_type_view.dart | 2 +- ...appointment_service_pick_bottom_sheet.dart | 2 +- lib/views/chat/chat_view.dart | 259 +++++++++++------- lib/views/requests/create_request_page.dart | 2 +- lib/views/requests/offer_list_page.dart | 17 +- lib/views/requests/widget/request_item.dart | 9 +- .../common_widgets/categories_list.dart | 2 +- lib/widgets/common_widgets/time_slots.dart | 2 +- 40 files changed, 476 insertions(+), 191 deletions(-) rename lib/models/{general => general_models}/enums_model.dart (100%) rename lib/models/{general => general_models}/generic_resp_model.dart (100%) rename lib/models/{general => general_models}/m_response.dart (100%) rename lib/models/{general => general_models}/post_params_model.dart (100%) rename lib/models/{general => general_models}/widgets_models.dart (100%) diff --git a/lib/classes/app_state.dart b/lib/classes/app_state.dart index 02ba4b9..1379646 100644 --- a/lib/classes/app_state.dart +++ b/lib/classes/app_state.dart @@ -1,5 +1,5 @@ import 'package:google_maps_flutter/google_maps_flutter.dart'; -import 'package:mc_common_app/models/general/post_params_model.dart'; +import 'package:mc_common_app/models/general_models/post_params_model.dart'; import 'package:mc_common_app/models/user_models/user.dart'; import 'package:mc_common_app/utils/enums.dart'; diff --git a/lib/config/routes.dart b/lib/config/routes.dart index 0db2a2c..3da4861 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -1,4 +1,7 @@ +import 'package:mc_common_app/models/requests_models/offers_model.dart'; +import 'package:mc_common_app/models/requests_models/request_model.dart'; import 'package:mc_common_app/models/user_models/register_user.dart'; +import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/views/user/change_email_page.dart'; import 'package:mc_common_app/views/user/change_mobile_page.dart'; @@ -74,7 +77,6 @@ class AppRoutes { static const String requestsDetailPage = "/requestsDetailPage"; static const String sendOfferPage = "/sendOfferPage"; - //Setting Options static const String settingOptionsFaqs = "/settingOptionsFaqs"; static const String settingOptionsLanguages = "/settingOptionsLanguages"; @@ -106,3 +108,17 @@ class AppRoutes { editAccountPage: (context) => const EditAccountPage(), }; } + +class ChatViewArguments { + final RequestModel? requestModel; + final ChatTypeEnum chatTypeEnum; + + ChatViewArguments({required this.chatTypeEnum, this.requestModel}); +} + +class OfferListPageArguments { + final List offersList; + final RequestModel? requestModel; + + OfferListPageArguments({required this.offersList, this.requestModel}); +} diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index 744d93e..d25ffd3 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -550,11 +550,22 @@ extension FormatMonthByNumber on String { } extension ChatMessageTypeEnumExt on int { + //FreeText = 1, + // Image = 2, + // Audio = 3, + // Video = 4, + // Offer = 5 ChatMessageTypeEnum toChatMessageTypeEnum() { if (this == 1) { return ChatMessageTypeEnum.freeText; } else if (this == 2) { - return ChatMessageTypeEnum.freeText; + return ChatMessageTypeEnum.image; + } else if (this == 3) { + return ChatMessageTypeEnum.audio; + } else if (this == 4) { + return ChatMessageTypeEnum.video; + } else if (this == 5) { + return ChatMessageTypeEnum.offer; } return ChatMessageTypeEnum.freeText; } @@ -565,18 +576,23 @@ extension ChatMessageTypeToInt on ChatMessageTypeEnum { switch (this) { case ChatMessageTypeEnum.freeText: return 1; - - case ChatMessageTypeEnum.offer: + case ChatMessageTypeEnum.image: return 2; + case ChatMessageTypeEnum.audio: + return 3; + case ChatMessageTypeEnum.video: + return 4; + case ChatMessageTypeEnum.offer: + return 5; default: - return 0; + return 1; } } } extension RequestOfferStatusEnumExt on int { - RequestOfferStatusEnum toChatMessageTypeEnum() { + RequestOfferStatusEnum toRequestOfferStatusEnum() { if (this == 1) { return RequestOfferStatusEnum.offer; } else if (this == 2) { @@ -611,3 +627,32 @@ extension RequestOfferStatusEnumToInt on RequestOfferStatusEnum { } } } + +extension ChatTypeEnumExt on int { + ChatTypeEnum toChatTypeEnum() { + if (this == 1) { + return ChatTypeEnum.general; + } else if (this == 2) { + return ChatTypeEnum.ads; + } else if (this == 3) { + return ChatTypeEnum.requestOffer; + } + return ChatTypeEnum.general; + } +} + +extension ChatTypeEnumToInt on ChatTypeEnum { + int getIdFromChatTypeEnum() { + switch (this) { + case ChatTypeEnum.general: + return 1; + case ChatTypeEnum.ads: + return 2; + case ChatTypeEnum.requestOffer: + return 3; + + default: + return 1; + } + } +} diff --git a/lib/models/advertisment_models/ss_car_check_schedule_model.dart b/lib/models/advertisment_models/ss_car_check_schedule_model.dart index bd15655..c8de10a 100644 --- a/lib/models/advertisment_models/ss_car_check_schedule_model.dart +++ b/lib/models/advertisment_models/ss_car_check_schedule_model.dart @@ -1,5 +1,5 @@ import 'package:mc_common_app/models/appointments_models/service_schedule_model.dart'; -import 'package:mc_common_app/models/general/widgets_models.dart'; +import 'package:mc_common_app/models/general_models/widgets_models.dart'; class SSCarCheckScheduleModel { int? serviceProviderID; diff --git a/lib/models/advertisment_models/ss_photo_schedule_model.dart b/lib/models/advertisment_models/ss_photo_schedule_model.dart index 048c42b..6aa7f54 100644 --- a/lib/models/advertisment_models/ss_photo_schedule_model.dart +++ b/lib/models/advertisment_models/ss_photo_schedule_model.dart @@ -1,6 +1,6 @@ import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/models/appointments_models/service_schedule_model.dart'; -import 'package:mc_common_app/models/general/widgets_models.dart'; +import 'package:mc_common_app/models/general_models/widgets_models.dart'; class SSPhotoOfficeScheduleModel { int? photoOfficeID; diff --git a/lib/models/appointments_models/service_schedule_model.dart b/lib/models/appointments_models/service_schedule_model.dart index 8a30e93..7d9444f 100644 --- a/lib/models/appointments_models/service_schedule_model.dart +++ b/lib/models/appointments_models/service_schedule_model.dart @@ -1,6 +1,6 @@ import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/models/services_models/service_model.dart'; -import 'package:mc_common_app/models/general/widgets_models.dart'; +import 'package:mc_common_app/models/general_models/widgets_models.dart'; class CustomTimeDateSlotModel { TimeSlotModel? date; diff --git a/lib/models/chat_models/cat_message_model.dart b/lib/models/chat_models/cat_message_model.dart index ca8d778..09e7844 100644 --- a/lib/models/chat_models/cat_message_model.dart +++ b/lib/models/chat_models/cat_message_model.dart @@ -1,26 +1,54 @@ +import 'package:mc_common_app/classes/app_state.dart'; +import 'package:mc_common_app/extensions/string_extensions.dart'; +import 'package:mc_common_app/utils/enums.dart'; + class ChatMessageModel { String? senderUserID; String? senderName; int? messageType; + ChatMessageTypeEnum? messageTypeEnum; String? message; RequestOffer? requestOffer; int? requestID; int? requestOfferID; + bool? isMyMessage; - ChatMessageModel({this.senderUserID, this.senderName, this.messageType, this.message, this.requestOffer, this.requestID, this.requestOfferID}); + ChatMessageModel({ + this.senderUserID, + this.senderName, + this.messageType, + this.message, + this.requestOffer, + this.requestID, + this.requestOfferID, + this.isMyMessage = true, + }); ChatMessageModel.fromJson(Map json) { + final myUserId = AppState().getUser.data!.userInfo!.userId.toString(); senderUserID = json['senderUserID']; senderName = json['senderName']; messageType = json['messageType']; + messageTypeEnum = (json['messageType'] as int).toChatMessageTypeEnum(); message = json['message']; - if (json['requestOffer'] != null) { - requestOffer = RequestOffer.fromJson(json['requestOffer']); - } else { - requestOffer = null; - } + requestOffer = json['requestOffer'] != null ? RequestOffer.fromJson(json['requestOffer']) : null; requestID = json['requestID']; requestOfferID = json['requestOfferID']; + isMyMessage = (json['senderUserId']).toString() == myUserId; + } + + Map toJson() { + final Map data = {}; + data['senderUserID'] = senderUserID; + data['senderName'] = senderName; + data['messageType'] = messageType; + data['message'] = message; + if (requestOffer != null) { + data['requestOffer'] = requestOffer!.toJson(); + } + data['requestID'] = requestID; + data['requestOfferID'] = requestOfferID; + return data; } } @@ -29,21 +57,47 @@ class RequestOffer { int? requestID; int? serviceProviderID; int? offerStatus; + RequestOfferStatusEnum? requestOfferStatusEnum; String? comment; - int? price; + double? price; String? offeredItemCreatedBy; String? offeredItemCreatedOn; - RequestOffer({this.id, this.requestID, this.serviceProviderID, this.offerStatus, this.comment, this.price, this.offeredItemCreatedBy, this.offeredItemCreatedOn}); + RequestOffer({ + this.id, + this.requestID, + this.serviceProviderID, + this.offerStatus, + this.comment, + this.price, + this.offeredItemCreatedBy, + this.offeredItemCreatedOn, + this.requestOfferStatusEnum = RequestOfferStatusEnum.offer, + }); RequestOffer.fromJson(Map json) { id = json['id']; requestID = json['requestID']; serviceProviderID = json['serviceProviderID']; offerStatus = json['offerStatus']; + offerStatus = json['offerStatus']; + requestOfferStatusEnum = ((json['offerStatus']) as int).toRequestOfferStatusEnum(); comment = json['comment']; price = json['price']; offeredItemCreatedBy = json['offeredItemCreatedBy']; offeredItemCreatedOn = json['offeredItemCreatedOn']; } + + Map toJson() { + final Map data = {}; + data['id'] = id; + data['requestID'] = requestID; + data['serviceProviderID'] = serviceProviderID; + data['offerStatus'] = offerStatus; + data['comment'] = comment; + data['price'] = price; + data['offeredItemCreatedBy'] = offeredItemCreatedBy; + data['offeredItemCreatedOn'] = offeredItemCreatedOn; + return data; + } } diff --git a/lib/models/general/enums_model.dart b/lib/models/general_models/enums_model.dart similarity index 100% rename from lib/models/general/enums_model.dart rename to lib/models/general_models/enums_model.dart diff --git a/lib/models/general/generic_resp_model.dart b/lib/models/general_models/generic_resp_model.dart similarity index 100% rename from lib/models/general/generic_resp_model.dart rename to lib/models/general_models/generic_resp_model.dart diff --git a/lib/models/general/m_response.dart b/lib/models/general_models/m_response.dart similarity index 100% rename from lib/models/general/m_response.dart rename to lib/models/general_models/m_response.dart diff --git a/lib/models/general/post_params_model.dart b/lib/models/general_models/post_params_model.dart similarity index 100% rename from lib/models/general/post_params_model.dart rename to lib/models/general_models/post_params_model.dart diff --git a/lib/models/general/widgets_models.dart b/lib/models/general_models/widgets_models.dart similarity index 100% rename from lib/models/general/widgets_models.dart rename to lib/models/general_models/widgets_models.dart diff --git a/lib/models/requests_models/request_model.dart b/lib/models/requests_models/request_model.dart index 1bfa418..5ee653e 100644 --- a/lib/models/requests_models/request_model.dart +++ b/lib/models/requests_models/request_model.dart @@ -10,6 +10,7 @@ class RequestModel { String vehicleTypeName; String countryName; String customerName; + String customerID; dynamic serviceProviders; int offerCount; int id; @@ -43,6 +44,7 @@ class RequestModel { required this.vehicleTypeName, required this.countryName, required this.customerName, + required this.customerID, required this.serviceProviders, required this.offerCount, required this.id, @@ -68,39 +70,42 @@ class RequestModel { required this.modifiedOn, }); - factory RequestModel.fromJson(Map json) => RequestModel( - requestType: json["requestType"], - requestTypeName: json["requestTypeName"], - requestStatusName: json["requestStatusName"], - requestStatus: (json['requestStatus'] as int).toRequestStatusEnum(), - cityName: json["cityName"], - vehicleTypeName: json["vehicleTypeName"], - countryName: json["countryName"], - customerName: json["customerName"], - serviceProviders: json["serviceProviders"], - offerCount: json["offerCount"], - id: json["id"], - customerId: json["customerID"], - customer: json["customer"], - brand: json["brand"], - model: json["model"], - year: json["year"], - isNew: json["isNew"], - description: json["description"], - requestImages: List.from(json["requestImages"].map((x) => x)), - cityId: json["cityID"], - city: json["city"], - price: json["price"], - paymentStatus: json["paymentStatus"], - vehicleTypeId: json["vehicleTypeID"], - countryId: json["countryID"], - requestProviderItem: List.from(json["requestProviderItem"].map((x) => x)), - isActive: json["isActive"], - createdBy: json["createdBy"], - createdOn: DateTime.parse(json["createdOn"]), - modifiedBy: json["modifiedBy"], - modifiedOn: json["modifiedOn"], - ); + factory RequestModel.fromJson(Map json) { + return RequestModel( + requestType: json["requestType"], + requestTypeName: json["requestTypeName"], + requestStatusName: json["requestStatusName"], + requestStatus: (json['requestStatus'] as int).toRequestStatusEnum(), + cityName: json["cityName"], + vehicleTypeName: json["vehicleTypeName"], + countryName: json["countryName"], + customerName: json["customerName"], + customerID: json["customerUserID"], + serviceProviders: json["serviceProviders"], + offerCount: json["offerCount"], + id: json["id"], + customerId: json["customerID"], + customer: json["customer"], + brand: json["brand"], + model: json["model"], + year: json["year"], + isNew: json["isNew"], + description: json["description"], + requestImages: List.from(json["requestImages"].map((x) => x)), + cityId: json["cityID"], + city: json["city"], + price: json["price"], + paymentStatus: json["paymentStatus"], + vehicleTypeId: json["vehicleTypeID"], + countryId: json["countryID"], + requestProviderItem: List.from(json["requestProviderItem"].map((x) => x)), + isActive: json["isActive"], + createdBy: json["createdBy"], + createdOn: DateTime.parse(json["createdOn"]), + modifiedBy: json["modifiedBy"], + modifiedOn: json["modifiedOn"], + ); + } Map toJson() => { "requestType": requestType, diff --git a/lib/repositories/ads_repo.dart b/lib/repositories/ads_repo.dart index 728cfb5..0f419fa 100644 --- a/lib/repositories/ads_repo.dart +++ b/lib/repositories/ads_repo.dart @@ -11,7 +11,7 @@ import 'package:mc_common_app/models/advertisment_models/ads_duration_model.dart import 'package:mc_common_app/models/advertisment_models/reserved_ads_models.dart'; import 'package:mc_common_app/models/advertisment_models/special_service_model.dart'; import 'package:mc_common_app/models/advertisment_models/vehicle_details_models.dart'; -import 'package:mc_common_app/models/general/generic_resp_model.dart'; +import 'package:mc_common_app/models/general_models/generic_resp_model.dart'; import 'package:mc_common_app/utils/enums.dart'; abstract class AdsRepo { diff --git a/lib/repositories/appointment_repo.dart b/lib/repositories/appointment_repo.dart index 3f53f24..9bd8d14 100644 --- a/lib/repositories/appointment_repo.dart +++ b/lib/repositories/appointment_repo.dart @@ -4,8 +4,8 @@ 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/dependencies.dart'; -import 'package:mc_common_app/models/general/generic_resp_model.dart'; -import 'package:mc_common_app/models/general/m_response.dart'; +import 'package:mc_common_app/models/general_models/generic_resp_model.dart'; +import 'package:mc_common_app/models/general_models/m_response.dart'; import 'package:mc_common_app/models/provider_branches_models/profile/services.dart'; import 'package:mc_common_app/models/appointments_models/schedule_model.dart'; import 'package:mc_common_app/models/appointments_models/service_schedule_model.dart'; diff --git a/lib/repositories/common_repo.dart b/lib/repositories/common_repo.dart index 26cc5f5..b9d5209 100644 --- a/lib/repositories/common_repo.dart +++ b/lib/repositories/common_repo.dart @@ -4,14 +4,14 @@ import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/config/dependencies.dart'; import 'package:mc_common_app/models/advertisment_models/ss_car_check_schedule_model.dart'; import 'package:mc_common_app/models/advertisment_models/ss_photo_schedule_model.dart'; +import 'package:mc_common_app/models/advertisment_models/vehicle_details_models.dart'; import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart'; -import 'package:mc_common_app/models/general/generic_resp_model.dart'; +import 'package:mc_common_app/models/general_models/enums_model.dart'; +import 'package:mc_common_app/models/general_models/generic_resp_model.dart'; import 'package:mc_common_app/models/user_models/cities.dart'; import 'package:mc_common_app/models/user_models/country.dart'; import 'package:mc_common_app/models/user_models/role.dart'; -import '../models/advertisment_models/vehicle_details_models.dart'; -import '../models/general/enums_model.dart'; abstract class CommonRepo { Future getAllCountries(); diff --git a/lib/repositories/payments_repo.dart b/lib/repositories/payments_repo.dart index d760546..7f72e8b 100644 --- a/lib/repositories/payments_repo.dart +++ b/lib/repositories/payments_repo.dart @@ -2,7 +2,7 @@ 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/dependencies.dart'; -import 'package:mc_common_app/models/general/generic_resp_model.dart'; +import 'package:mc_common_app/models/general_models/generic_resp_model.dart'; import 'package:mc_common_app/models/payment_models/pay_order_detail_resp_model.dart'; abstract class PaymentsRepo { diff --git a/lib/repositories/provider_repo.dart b/lib/repositories/provider_repo.dart index 36a9a39..b327a17 100644 --- a/lib/repositories/provider_repo.dart +++ b/lib/repositories/provider_repo.dart @@ -4,7 +4,7 @@ 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/dependencies.dart'; -import 'package:mc_common_app/models/general/generic_resp_model.dart'; +import 'package:mc_common_app/models/general_models/generic_resp_model.dart'; import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart'; import 'package:mc_common_app/models/provider_branches_models/provider_profile_model.dart'; import 'package:mc_common_app/models/services_models/item_model.dart'; diff --git a/lib/repositories/request_repo.dart b/lib/repositories/request_repo.dart index ffaa33d..e5b9967 100644 --- a/lib/repositories/request_repo.dart +++ b/lib/repositories/request_repo.dart @@ -2,7 +2,7 @@ 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/dependencies.dart'; -import 'package:mc_common_app/models/general/generic_resp_model.dart'; +import 'package:mc_common_app/models/general_models/generic_resp_model.dart'; import 'package:mc_common_app/models/requests_models/offers_model.dart'; import 'package:mc_common_app/models/requests_models/request_model.dart'; diff --git a/lib/repositories/user_repo.dart b/lib/repositories/user_repo.dart index dba85f4..4e6756e 100644 --- a/lib/repositories/user_repo.dart +++ b/lib/repositories/user_repo.dart @@ -7,7 +7,7 @@ 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/dependencies.dart'; -import 'package:mc_common_app/models/general/m_response.dart'; +import 'package:mc_common_app/models/general_models/m_response.dart'; import 'package:mc_common_app/models/user_models/basic_otp.dart'; import 'package:mc_common_app/models/user_models/change_email.dart'; import 'package:mc_common_app/models/user_models/change_mobile.dart'; diff --git a/lib/utils/enums.dart b/lib/utils/enums.dart index e0a9505..395bb64 100644 --- a/lib/utils/enums.dart +++ b/lib/utils/enums.dart @@ -172,3 +172,9 @@ enum RequestOfferStatusEnum { rejected, cancel, } + +enum ChatTypeEnum { + general, + ads, + requestOffer, +} diff --git a/lib/view_models/ad_view_model.dart b/lib/view_models/ad_view_model.dart index 114b4b5..3120c45 100644 --- a/lib/view_models/ad_view_model.dart +++ b/lib/view_models/ad_view_model.dart @@ -15,10 +15,10 @@ import 'package:mc_common_app/models/advertisment_models/special_service_model.d import 'package:mc_common_app/models/advertisment_models/ss_car_check_schedule_model.dart'; import 'package:mc_common_app/models/advertisment_models/ss_photo_schedule_model.dart'; import 'package:mc_common_app/models/advertisment_models/vehicle_details_models.dart'; -import 'package:mc_common_app/models/general/enums_model.dart'; -import 'package:mc_common_app/models/general/generic_resp_model.dart'; +import 'package:mc_common_app/models/general_models/enums_model.dart'; +import 'package:mc_common_app/models/general_models/generic_resp_model.dart'; import 'package:mc_common_app/models/appointments_models/service_schedule_model.dart'; -import 'package:mc_common_app/models/general/widgets_models.dart'; +import 'package:mc_common_app/models/general_models/widgets_models.dart'; import 'package:mc_common_app/repositories/ads_repo.dart'; import 'package:mc_common_app/repositories/common_repo.dart'; import 'package:mc_common_app/services/common_services.dart'; diff --git a/lib/view_models/appointments_view_model.dart b/lib/view_models/appointments_view_model.dart index 10c0e4d..f55b9d7 100644 --- a/lib/view_models/appointments_view_model.dart +++ b/lib/view_models/appointments_view_model.dart @@ -4,14 +4,14 @@ import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart'; -import 'package:mc_common_app/models/general/enums_model.dart'; -import 'package:mc_common_app/models/general/generic_resp_model.dart'; +import 'package:mc_common_app/models/general_models/enums_model.dart'; +import 'package:mc_common_app/models/general_models/generic_resp_model.dart'; import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart'; import 'package:mc_common_app/models/provider_branches_models/provider_profile_model.dart'; import 'package:mc_common_app/models/appointments_models/service_schedule_model.dart'; import 'package:mc_common_app/models/services_models/item_model.dart'; import 'package:mc_common_app/models/services_models/service_model.dart'; -import 'package:mc_common_app/models/general/widgets_models.dart'; +import 'package:mc_common_app/models/general_models/widgets_models.dart'; import 'package:mc_common_app/repositories/appointment_repo.dart'; import 'package:mc_common_app/repositories/common_repo.dart'; import 'package:mc_common_app/repositories/provider_repo.dart'; diff --git a/lib/view_models/chat_view_model.dart b/lib/view_models/chat_view_model.dart index be00103..f91ce50 100644 --- a/lib/view_models/chat_view_model.dart +++ b/lib/view_models/chat_view_model.dart @@ -1,7 +1,10 @@ +import 'dart:convert'; + import 'package:flutter/cupertino.dart'; import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/main.dart'; +import 'package:mc_common_app/models/chat_models/cat_message_model.dart'; import 'package:mc_common_app/repositories/chat_repo.dart'; import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/utils.dart'; @@ -14,14 +17,34 @@ class ChatVM extends ChangeNotifier { late HubConnection hubConnection; + List chatMessages = []; + + String chatMessageText = ""; + + updateChatMessageText(String value) { + chatMessageText = value; + } + + Future onNewMessageReceived({required List messages}) async { + chatMessages.addAll(messages); + notifyListeners(); + } + Future buildHubConnection() async { // if (hubConnection.state != HubConnectionState.Connected) { try { hubConnection = await chatRepo.getHubConnection(); await hubConnection.start(); hubConnection.on("ReceiveMessageRequestOffer", (List? arguments) { - print("this is the offer: ${arguments.toString()}"); + if (arguments == null || arguments.isEmpty) return; + List chat = []; + for (var message in arguments) { + final chatMessage = ChatMessageModel.fromJson(message as Map); + chat.add(chatMessage); + } + onNewMessageReceived(messages: chat); Utils.showToast("I received ping : ${arguments.toString()}"); + logger.i("I received ping : ${arguments.toString()}"); }); } catch (e) { logger.i("Error: ${e.toString()}"); @@ -31,14 +54,18 @@ class ChatVM extends ChangeNotifier { // } } - Future onSendMessageForRequestOffer( - {required String receiverId, required ChatMessageTypeEnum chatMessageType, required String message, required int requestId, required String offerPrice}) async { + Future onSendMessageForRequestOffer({ + required String receiverId, + required ChatMessageTypeEnum chatMessageType, + required String message, + required int requestId, + required String offerPrice, + }) async { if (hubConnection.state != HubConnectionState.connected) { await buildHubConnection(); } if (hubConnection.state == HubConnectionState.connected) { final providerId = AppState().getUser.data!.userInfo!.providerId; - print("providerId: $providerId"); hubConnection.invoke( "SendMessageRequestOffer", args: [ @@ -65,4 +92,43 @@ class ChatVM extends ChangeNotifier { } return true; } + + Future onTextMessageSend({ + required String receiverId, + required ChatMessageTypeEnum chatMessageType, + required String message, + required int requestId, + required String offerPrice, + }) async { + if (hubConnection.state != HubConnectionState.connected) { + await buildHubConnection(); + } + if (hubConnection.state == HubConnectionState.connected) { + final providerId = AppState().getUser.data!.userInfo!.providerId; + hubConnection.invoke( + "SendMessageRequestOffer", + args: [ + { + "ReceiverUserID": receiverId, + "MessageType": chatMessageType.getIdFromChatMessageTypeEnum(), + "Message": message, + "RequestID": requestId, + // "RequestOfferID": 0, + // "RequestOffer": { + // "RequestID": requestId, + // "Price": double.parse(offerPrice), + // "ServiceProviderID": providerId, + // "OfferStatus": RequestOfferStatusEnum.offer.getIdFromRequestOfferStatusEnum(), + // "Comment": message, + // }, + } + ], + ).catchError((e) { + logger.i("error in invoking SendMessageRequestOffer: ${e.toString()}"); + Utils.showToast(e.toString()); + return false; + }); + } + return true; + } } diff --git a/lib/view_models/requests_view_model.dart b/lib/view_models/requests_view_model.dart index 44f6f4c..d751286 100644 --- a/lib/view_models/requests_view_model.dart +++ b/lib/view_models/requests_view_model.dart @@ -1,19 +1,24 @@ +// ignore_for_file: use_build_context_synchronously + import 'dart:convert'; import 'dart:io'; import 'package:flutter/cupertino.dart'; import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/classes/consts.dart'; +import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/models/advertisment_models/vehicle_details_models.dart'; -import 'package:mc_common_app/models/general/enums_model.dart'; -import 'package:mc_common_app/models/general/generic_resp_model.dart'; +import 'package:mc_common_app/models/chat_models/cat_message_model.dart'; +import 'package:mc_common_app/models/general_models/enums_model.dart'; +import 'package:mc_common_app/models/general_models/generic_resp_model.dart'; import 'package:mc_common_app/models/requests_models/offers_model.dart'; import 'package:mc_common_app/models/requests_models/request_model.dart'; -import 'package:mc_common_app/models/general/widgets_models.dart'; +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/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/base_view_model.dart'; import 'package:mc_common_app/view_models/chat_view_model.dart'; @@ -384,7 +389,14 @@ class RequestsVM extends BaseVM { notifyListeners(); } - Future onSendOfferPressed({required BuildContext context, required String receiverId, required String message, required int requestId, required String offerPrice}) async { + Future onSendOfferPressed({ + required BuildContext context, + required String receiverId, + required String message, + required int requestId, + required String offerPrice, + required RequestModel requestModel, + }) async { if (isSendOfferValidated()) { bool status = await context.read().onSendMessageForRequestOffer( receiverId: receiverId, @@ -397,6 +409,10 @@ class RequestsVM extends BaseVM { if (status) { // resetSendOfferBottomSheet(); Navigator.pop(context); + ChatMessageModel chatMessageModel = ChatMessageModel(isMyMessage: true, message: message, messageType: ChatMessageTypeEnum.freeText, ); + context.read().onNewMessageReceived(messages: messages); + ChatViewArguments chatViewArguments = ChatViewArguments(chatTypeEnum: ChatTypeEnum.requestOffer, requestModel: requestModel); + navigateWithName(context, AppRoutes.chatView, arguments: chatViewArguments); } } } diff --git a/lib/view_models/user_view_model.dart b/lib/view_models/user_view_model.dart index ac41cd1..708bc18 100644 --- a/lib/view_models/user_view_model.dart +++ b/lib/view_models/user_view_model.dart @@ -8,7 +8,7 @@ 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/general/m_response.dart'; +import 'package:mc_common_app/models/general_models/m_response.dart'; import 'package:mc_common_app/models/user_models/basic_otp.dart'; import 'package:mc_common_app/models/user_models/change_email.dart'; import 'package:mc_common_app/models/user_models/change_mobile.dart'; diff --git a/lib/views/advertisement/ad_creation_steps/ad_duration_container.dart b/lib/views/advertisement/ad_creation_steps/ad_duration_container.dart index 0e979cb..139ba00 100644 --- a/lib/views/advertisement/ad_creation_steps/ad_duration_container.dart +++ b/lib/views/advertisement/ad_creation_steps/ad_duration_container.dart @@ -4,7 +4,7 @@ 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/models/general/widgets_models.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/utils.dart'; import 'package:mc_common_app/view_models/ad_view_model.dart'; 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 6405510..8b0b247 100644 --- a/lib/views/advertisement/ad_creation_steps/vehicle_details_container.dart +++ b/lib/views/advertisement/ad_creation_steps/vehicle_details_container.dart @@ -3,7 +3,7 @@ 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/models/general/widgets_models.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/view_models/ad_view_model.dart'; import 'package:mc_common_app/views/advertisement/ad_creation_steps/ad_creation_steps_containers.dart'; diff --git a/lib/views/advertisement/ad_duration_selection_sheet_content.dart b/lib/views/advertisement/ad_duration_selection_sheet_content.dart index 47a2524..c0758f6 100644 --- a/lib/views/advertisement/ad_duration_selection_sheet_content.dart +++ b/lib/views/advertisement/ad_duration_selection_sheet_content.dart @@ -3,7 +3,7 @@ import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/models/advertisment_models/ads_duration_model.dart'; -import 'package:mc_common_app/models/general/widgets_models.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/navigator.dart'; diff --git a/lib/views/advertisement/ads_detail_view.dart b/lib/views/advertisement/ads_detail_view.dart index 1117492..9a955cf 100644 --- a/lib/views/advertisement/ads_detail_view.dart +++ b/lib/views/advertisement/ads_detail_view.dart @@ -9,7 +9,7 @@ import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/models/advertisment_models/ad_details_model.dart'; import 'package:mc_common_app/models/advertisment_models/special_service_model.dart'; -import 'package:mc_common_app/models/general/widgets_models.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/dialogs_and_bottomsheets.dart'; import 'package:mc_common_app/utils/enums.dart'; diff --git a/lib/views/advertisement/ads_filter_view.dart b/lib/views/advertisement/ads_filter_view.dart index 51d4d38..dd1247a 100644 --- a/lib/views/advertisement/ads_filter_view.dart +++ b/lib/views/advertisement/ads_filter_view.dart @@ -1,7 +1,7 @@ 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/models/general/widgets_models.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/view_models/ad_view_model.dart'; import 'package:mc_common_app/widgets/button/show_fill_button.dart'; diff --git a/lib/views/advertisement/bottom_sheet_content.dart b/lib/views/advertisement/bottom_sheet_content.dart index a91b36a..1b7a5b9 100644 --- a/lib/views/advertisement/bottom_sheet_content.dart +++ b/lib/views/advertisement/bottom_sheet_content.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/models/advertisment_models/vehicle_details_models.dart'; -import 'package:mc_common_app/models/general/widgets_models.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/view_models/ad_view_model.dart'; import 'package:mc_common_app/widgets/button/show_fill_button.dart'; diff --git a/lib/views/advertisement/select_ad_type_view.dart b/lib/views/advertisement/select_ad_type_view.dart index 0a8af7d..d8acbf9 100644 --- a/lib/views/advertisement/select_ad_type_view.dart +++ b/lib/views/advertisement/select_ad_type_view.dart @@ -4,7 +4,7 @@ import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/models/advertisment_models/vehicle_details_models.dart'; -import 'package:mc_common_app/models/general/widgets_models.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/view_models/ad_view_model.dart'; diff --git a/lib/views/appointments/widgets/appointment_service_pick_bottom_sheet.dart b/lib/views/appointments/widgets/appointment_service_pick_bottom_sheet.dart index 384b6d9..b086514 100644 --- a/lib/views/appointments/widgets/appointment_service_pick_bottom_sheet.dart +++ b/lib/views/appointments/widgets/appointment_service_pick_bottom_sheet.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; -import 'package:mc_common_app/models/general/widgets_models.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/navigator.dart'; import 'package:mc_common_app/view_models/appointments_view_model.dart'; diff --git a/lib/views/chat/chat_view.dart b/lib/views/chat/chat_view.dart index 62ff217..269371a 100644 --- a/lib/views/chat/chat_view.dart +++ b/lib/views/chat/chat_view.dart @@ -1,66 +1,88 @@ import 'package:flutter/material.dart'; import 'package:mc_common_app/classes/consts.dart'; +import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; +import 'package:mc_common_app/models/chat_models/cat_message_model.dart'; import 'package:mc_common_app/theme/colors.dart'; +import 'package:mc_common_app/utils/enums.dart'; +import 'package:mc_common_app/view_models/chat_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/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/txt_field.dart'; +import 'package:provider/provider.dart'; class ChatView extends StatelessWidget { - const ChatView({super.key}); + final ChatViewArguments chatViewArguments; + + const ChatView({super.key, required this.chatViewArguments}); @override Widget build(BuildContext context) { return Scaffold( appBar: const CustomAppBar(title: "Chat"), - body: Column( - children: [ - Expanded( - child: ListView.separated( - itemCount: 15, - separatorBuilder: (BuildContext context, int index) => 20.height, - itemBuilder: (BuildContext context, int index) { - return ChatMessageCustomWidget( - isSent: index.isOdd, - profileUrl: MyAssets.bnCar, - messageText: "Hi, How Are you? I can help you out with the desired request.", - messageTypeEnum: index == 10 - ? (MessageTypeEnum.newOfferRequired) - : index == 12 - ? (MessageTypeEnum.offerProvided) - : (MessageTypeEnum.text), - senderName: "Al Abdullah Cars", - ); - }).horPaddingMain(), - ), - 10.width, - Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Expanded( - flex: 7, - child: TxtField( - // value: adVM.vehicleDemandAmount, - // errorValue: adVM.demandAmountError, - hint: "Type your message here..", - keyboardType: TextInputType.text, - isNeedBorder: false, - onChanged: (v) => null, + body: Consumer(builder: (BuildContext context, ChatVM chatVM, Widget? child) { + return Column( + children: [ + Expanded( + child: ListView.separated( + itemCount: chatVM.chatMessages.length, + separatorBuilder: (BuildContext context, int index) => 20.height, + itemBuilder: (BuildContext context, int index) { + ChatMessageModel chatMessageModel = chatVM.chatMessages[index]; + return ChatMessageCustomWidget( + isSent: chatMessageModel.isMyMessage ?? false, + profileUrl: MyAssets.bnCar, + messageText: "${chatMessageModel.message}", + messageTypeEnum: chatMessageModel.messageTypeEnum ?? ChatMessageTypeEnum.freeText, + requestOfferStatusEnum: + (chatMessageModel.requestOffer != null ? chatMessageModel.requestOffer!.requestOfferStatusEnum : RequestOfferStatusEnum.offer) ?? RequestOfferStatusEnum.offer, + senderName: "${chatMessageModel.senderName}", + ); + }).horPaddingMain(), + ), + 10.width, + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + flex: 7, + child: TxtField( + value: chatVM.chatMessageText, + hint: "Type your message here..", + keyboardType: TextInputType.text, + isNeedBorder: false, + onChanged: (v) => chatVM.updateChatMessageText(v), + ), ), - ), - Expanded( + Expanded( flex: 1, child: const Icon( Icons.send_rounded, color: MyColors.darkPrimaryColor, size: 30, - ).onPress(() {})) - ], - ).toContainer(isShadowEnabled: true), - ], - ), + ).onPress( + () async { + final status = await chatVM.onTextMessageSend( + receiverId: "7db5e1ae-6de4-47d7-984b-08db2842f899", //Todo: This should be managed somehow!! + message: chatVM.chatMessageText, + requestId: chatViewArguments.chatTypeEnum == ChatTypeEnum.requestOffer ? chatViewArguments.requestModel!.id : 0, + offerPrice: "0.0", + chatMessageType: ChatMessageTypeEnum.freeText, + ); + + if (status) { + chatVM.updateChatMessageText(""); + } + }, + ), + ) + ], + ).toContainer(isShadowEnabled: true), + ], + ); + }), // body: ); } @@ -70,7 +92,8 @@ class ChatMessageCustomWidget extends StatelessWidget { final String profileUrl; final String senderName; final String messageText; - final MessageTypeEnum messageTypeEnum; + final ChatMessageTypeEnum messageTypeEnum; + final RequestOfferStatusEnum requestOfferStatusEnum; final bool isSent; const ChatMessageCustomWidget({ @@ -79,9 +102,107 @@ class ChatMessageCustomWidget extends StatelessWidget { required this.senderName, required this.messageText, required this.messageTypeEnum, + this.requestOfferStatusEnum = RequestOfferStatusEnum.offer, required this.isSent, }); + Widget buildOfferDetailsInChatMessage({required RequestOfferStatusEnum requestOfferStatusEnum}) { + switch (requestOfferStatusEnum) { + case RequestOfferStatusEnum.offer: + return Column( + children: [ + 5.height, + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + "40000".toText(fontSize: 19, isBold: true), + 2.width, + "SAR".toText(color: MyColors.lightTextColor, height: 2.2, fontSize: 10, isBold: true), + ], + ), + 10.height, + Row( + children: [ + Expanded( + child: ShowFillButton( + maxHeight: 27, + title: "Accept", + fontSize: 9, + borderColor: MyColors.greenColor, + isFilled: false, + onPressed: () {}, + backgroundColor: MyColors.white, + txtColor: MyColors.greenColor, + ), + ), + 20.width, + Expanded( + child: ShowFillButton( + maxHeight: 27, + title: "Reject", + borderColor: MyColors.redColor, + isFilled: false, + onPressed: () {}, + backgroundColor: MyColors.white, + txtColor: MyColors.redColor, + fontSize: 9, + ), + ) + ], + ), + ], + ); + case RequestOfferStatusEnum.negotiate: + return Column( + children: [ + Center( + child: "You asked for the new offer.".toText( + color: MyColors.adPendingStatusColor, + fontSize: 12, + isItalic: true, + ), + ).toContainer(borderRadius: 40, width: double.infinity, backgroundColor: MyColors.adPendingStatusColor.withOpacity(0.16)), + ], + ); + case RequestOfferStatusEnum.accepted: + return Column( + children: [ + Center( + child: "You have accepted the offer.".toText( + color: MyColors.adPendingStatusColor, + fontSize: 12, + isItalic: true, + ), + ).toContainer(borderRadius: 40, width: double.infinity, backgroundColor: MyColors.adPendingStatusColor.withOpacity(0.16)), + ], + ); + case RequestOfferStatusEnum.rejected: + return Column( + children: [ + Center( + child: "You have rejected the offer.".toText( + color: MyColors.adPendingStatusColor, + fontSize: 12, + isItalic: true, + ), + ).toContainer(borderRadius: 40, width: double.infinity, backgroundColor: MyColors.adPendingStatusColor.withOpacity(0.16)), + ], + ); + case RequestOfferStatusEnum.cancel: + return Column( + children: [ + Center( + child: "You have cancelled the offer.".toText( + color: MyColors.adPendingStatusColor, + fontSize: 12, + isItalic: true, + ), + ).toContainer(borderRadius: 40, width: double.infinity, backgroundColor: MyColors.adPendingStatusColor.withOpacity(0.16)), + ], + ); + } + } + @override Widget build(BuildContext context) { return Directionality( @@ -125,56 +246,8 @@ class ChatMessageCustomWidget extends StatelessWidget { ), ], ), - if (messageTypeEnum == MessageTypeEnum.offerProvided || messageTypeEnum == MessageTypeEnum.newOfferRequired) ...[ - 5.height, - Row( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - "40000".toText(fontSize: 19, isBold: true), - 2.width, - "SAR".toText(color: MyColors.lightTextColor, height: 2.2, fontSize: 10, isBold: true), - ], - ), - 10.height, - if (messageTypeEnum == MessageTypeEnum.newOfferRequired) ...[ - Center( - child: "You asked for the new offer.".toText( - color: MyColors.adPendingStatusColor, - fontSize: 12, - isItalic: true, - ), - ).toContainer(borderRadius: 40, width: double.infinity, backgroundColor: MyColors.adPendingStatusColor.withOpacity(0.16)), - ] else ...[ - Row( - children: [ - Expanded( - child: ShowFillButton( - maxHeight: 27, - title: "Accept", - fontSize: 9, - borderColor: MyColors.greenColor, - isFilled: false, - onPressed: () {}, - backgroundColor: MyColors.white, - txtColor: MyColors.greenColor, - ), - ), - 20.width, - Expanded( - child: ShowFillButton( - maxHeight: 27, - title: "Reject", - borderColor: MyColors.redColor, - isFilled: false, - onPressed: () {}, - backgroundColor: MyColors.white, - txtColor: MyColors.redColor, - fontSize: 9, - ), - ) - ], - ), - ], + if (messageTypeEnum == ChatMessageTypeEnum.offer) ...[ + buildOfferDetailsInChatMessage(requestOfferStatusEnum: requestOfferStatusEnum), ], ], ).toContainer( @@ -191,5 +264,3 @@ class ChatMessageCustomWidget extends StatelessWidget { ); } } - -enum MessageTypeEnum { text, picture, offerProvided, recording, video, newOfferRequired } diff --git a/lib/views/requests/create_request_page.dart b/lib/views/requests/create_request_page.dart index cb12e6c..43bc84c 100644 --- a/lib/views/requests/create_request_page.dart +++ b/lib/views/requests/create_request_page.dart @@ -3,7 +3,7 @@ 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/models/general/widgets_models.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/views/advertisement/ad_creation_steps/ad_creation_steps_containers.dart'; import 'package:mc_common_app/views/advertisement/picked_images_container.dart'; diff --git a/lib/views/requests/offer_list_page.dart b/lib/views/requests/offer_list_page.dart index 995e863..51f078b 100644 --- a/lib/views/requests/offer_list_page.dart +++ b/lib/views/requests/offer_list_page.dart @@ -4,24 +4,26 @@ import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/models/requests_models/offers_model.dart'; import 'package:mc_common_app/theme/colors.dart'; +import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/widgets/common_widgets/app_bar.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; class OfferListPage extends StatelessWidget { - final List offersList; + final OfferListPageArguments offerListPageArguments; - OfferListPage({required this.offersList}); + const OfferListPage({super.key, required this.offerListPageArguments}); @override Widget build(BuildContext context) { + final List offersList = offerListPageArguments.offersList; return Scaffold( - appBar: CustomAppBar(title: "Offers"), + appBar: const CustomAppBar(title: "Offers"), body: offersList.isEmpty ? Center(child: "No Requests to show.".toText(fontSize: 16, color: MyColors.lightTextColor)) : ListView.separated( itemCount: offersList.length, - padding: EdgeInsets.all(16), + padding: const EdgeInsets.all(16), itemBuilder: (context, index) { OffersModel offersModel = offersList[index]; return Stack( @@ -33,7 +35,7 @@ class OfferListPage extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ - "${offersModel.serviceProvider!.companyName ?? ""}".toText(fontSize: 16, isBold: true), + (offersModel.serviceProvider!.companyName ?? "").toText(fontSize: 16, isBold: true), //Un read offers count @@ -70,14 +72,15 @@ class OfferListPage extends StatelessWidget { ), ], ), - Icon( + const Icon( Icons.arrow_forward, color: MyColors.darkIconColor, size: 18, ), ], ).onPress(() { - navigateWithName(context, AppRoutes.chatView); + ChatViewArguments chatViewArguments = ChatViewArguments(chatTypeEnum: ChatTypeEnum.requestOffer, requestModel: offerListPageArguments.requestModel); + navigateWithName(context, AppRoutes.chatView, arguments: chatViewArguments); }).toContainer(isShadowEnabled: true); }, separatorBuilder: (context, index) => 16.height, diff --git a/lib/views/requests/widget/request_item.dart b/lib/views/requests/widget/request_item.dart index 842035a..b70fed8 100644 --- a/lib/views/requests/widget/request_item.dart +++ b/lib/views/requests/widget/request_item.dart @@ -1,3 +1,5 @@ +// ignore_for_file: use_build_context_synchronously + import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/view_models/requests_view_model.dart'; import 'package:flutter/material.dart'; @@ -34,7 +36,7 @@ class RequestItem extends StatelessWidget { 6.height, "${request.brand} ${request.model}".toText(fontSize: 16, isBold: true), showItem("Model:", "${request.year}"), - showItem("Customer Name:", "${request.customerName}"), + showItem("Customer Name:", request.customerName), ], ), ), @@ -93,7 +95,7 @@ class RequestItem extends StatelessWidget { ), ], ), - Icon( + const Icon( Icons.arrow_forward, color: MyColors.darkIconColor, size: 18, @@ -106,7 +108,8 @@ class RequestItem extends StatelessWidget { navigateWithName(context, AppRoutes.requestsDetailPage, arguments: request); } else { List offers = await context.read().getOffersByRequest(requestId: request.id, context: context); - navigateWithName(context, AppRoutes.offersListPage, arguments: offers); + OfferListPageArguments offerListPageArguments = OfferListPageArguments(offersList: offers, requestModel: request); + navigateWithName(context, AppRoutes.offersListPage, arguments: offerListPageArguments); } }); } diff --git a/lib/widgets/common_widgets/categories_list.dart b/lib/widgets/common_widgets/categories_list.dart index 4acf882..051d3be 100644 --- a/lib/widgets/common_widgets/categories_list.dart +++ b/lib/widgets/common_widgets/categories_list.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; -import 'package:mc_common_app/models/general/widgets_models.dart'; +import 'package:mc_common_app/models/general_models/widgets_models.dart'; import 'package:mc_common_app/theme/colors.dart'; class FiltersList extends StatelessWidget { diff --git a/lib/widgets/common_widgets/time_slots.dart b/lib/widgets/common_widgets/time_slots.dart index f3702cb..2e7bef9 100644 --- a/lib/widgets/common_widgets/time_slots.dart +++ b/lib/widgets/common_widgets/time_slots.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/models/appointments_models/service_schedule_model.dart'; -import 'package:mc_common_app/models/general/widgets_models.dart'; +import 'package:mc_common_app/models/general_models/widgets_models.dart'; import 'package:mc_common_app/theme/colors.dart'; class BuildTimeSlots extends StatelessWidget { From 6245aa9ef41c7edb56b085ba35f4f5bbfda3ac6f Mon Sep 17 00:00:00 2001 From: Faiz Hashmi Date: Sun, 10 Dec 2023 11:59:33 +0300 Subject: [PATCH 4/5] fixed messages bug --- lib/config/routes.dart | 4 ++- lib/view_models/chat_view_model.dart | 31 +++++++++++++++--------- lib/view_models/requests_view_model.dart | 30 +++++++++++++++++------ lib/views/chat/chat_view.dart | 6 ++--- lib/views/requests/offer_list_page.dart | 10 +++++++- 5 files changed, 56 insertions(+), 25 deletions(-) diff --git a/lib/config/routes.dart b/lib/config/routes.dart index 3da4861..fceeb3d 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -112,8 +112,10 @@ class AppRoutes { class ChatViewArguments { final RequestModel? requestModel; final ChatTypeEnum chatTypeEnum; + final String senderId; + final String receiverId; - ChatViewArguments({required this.chatTypeEnum, this.requestModel}); + ChatViewArguments({required this.chatTypeEnum, this.requestModel, required this.senderId, required this.receiverId}); } class OfferListPageArguments { diff --git a/lib/view_models/chat_view_model.dart b/lib/view_models/chat_view_model.dart index f91ce50..49a1dde 100644 --- a/lib/view_models/chat_view_model.dart +++ b/lib/view_models/chat_view_model.dart @@ -1,5 +1,3 @@ -import 'dart:convert'; - import 'package:flutter/cupertino.dart'; import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; @@ -25,6 +23,11 @@ class ChatVM extends ChangeNotifier { chatMessageText = value; } + clearChatMessageText() { + chatMessageText = ""; + notifyListeners(); + } + Future onNewMessageReceived({required List messages}) async { chatMessages.addAll(messages); notifyListeners(); @@ -43,7 +46,6 @@ class ChatVM extends ChangeNotifier { chat.add(chatMessage); } onNewMessageReceived(messages: chat); - Utils.showToast("I received ping : ${arguments.toString()}"); logger.i("I received ping : ${arguments.toString()}"); }); } catch (e) { @@ -100,11 +102,14 @@ class ChatVM extends ChangeNotifier { required int requestId, required String offerPrice, }) async { + if (message.isEmpty) return false; + if (hubConnection.state != HubConnectionState.connected) { await buildHubConnection(); } if (hubConnection.state == HubConnectionState.connected) { - final providerId = AppState().getUser.data!.userInfo!.providerId; + final userId = AppState().getUser.data!.userInfo!.userId.toString(); + final name = AppState().getUser.data!.userInfo!.firstName.toString(); hubConnection.invoke( "SendMessageRequestOffer", args: [ @@ -113,14 +118,6 @@ class ChatVM extends ChangeNotifier { "MessageType": chatMessageType.getIdFromChatMessageTypeEnum(), "Message": message, "RequestID": requestId, - // "RequestOfferID": 0, - // "RequestOffer": { - // "RequestID": requestId, - // "Price": double.parse(offerPrice), - // "ServiceProviderID": providerId, - // "OfferStatus": RequestOfferStatusEnum.offer.getIdFromRequestOfferStatusEnum(), - // "Comment": message, - // }, } ], ).catchError((e) { @@ -128,6 +125,16 @@ class ChatVM extends ChangeNotifier { Utils.showToast(e.toString()); return false; }); + ChatMessageModel chatMessageModel = ChatMessageModel( + messageType: chatMessageType.getIdFromChatMessageTypeEnum(), + message: message, + isMyMessage: true, + requestID: requestId, + senderName: name, + senderUserID: userId, + ); + + onNewMessageReceived(messages: [chatMessageModel]); } return true; } diff --git a/lib/view_models/requests_view_model.dart b/lib/view_models/requests_view_model.dart index d751286..2a8f583 100644 --- a/lib/view_models/requests_view_model.dart +++ b/lib/view_models/requests_view_model.dart @@ -1,6 +1,7 @@ -// ignore_for_file: use_build_context_synchronously +// ignore_for_file: use_build_context_synchronously, avoid_function_literals_in_foreach_calls import 'dart:convert'; +import 'dart:developer'; import 'dart:io'; import 'package:flutter/cupertino.dart'; import 'package:mc_common_app/classes/app_state.dart'; @@ -47,7 +48,7 @@ class RequestsVM extends BaseVM { requestsTypeFilterOptions.add(FilterListModel(title: myRequestsTypeEnum[i].enumValueStr, isSelected: false, id: myRequestsTypeEnum[i].enumValue)); } - print("requestsTypeFilterOptions: ${requestsTypeFilterOptions.toString()}"); + log("requestsTypeFilterOptions: ${requestsTypeFilterOptions.toString()}"); notifyListeners(); } @@ -110,8 +111,8 @@ class RequestsVM extends BaseVM { } void pickMultipleImages() async { - List Images = await commonServices.pickMultipleImages(); - pickedVehicleImages.addAll(Images); + List images = await commonServices.pickMultipleImages(); + pickedVehicleImages.addAll(images); if (pickedVehicleImages.isNotEmpty) vehicleImageError = ""; notifyListeners(); } @@ -286,7 +287,7 @@ class RequestsVM extends BaseVM { } } catch (e, s) { Utils.hideLoading(context); - print(s); + log(s.toString()); } } } @@ -407,11 +408,24 @@ class RequestsVM extends BaseVM { ); if (status) { + final senderName = AppState().getUser.data!.userInfo!.firstName; + final senderId = AppState().getUser.data!.userInfo!.userId; // resetSendOfferBottomSheet(); Navigator.pop(context); - ChatMessageModel chatMessageModel = ChatMessageModel(isMyMessage: true, message: message, messageType: ChatMessageTypeEnum.freeText, ); - context.read().onNewMessageReceived(messages: messages); - ChatViewArguments chatViewArguments = ChatViewArguments(chatTypeEnum: ChatTypeEnum.requestOffer, requestModel: requestModel); + ChatMessageModel chatMessageModel = ChatMessageModel( + isMyMessage: true, + message: message, + messageType: ChatMessageTypeEnum.freeText.getIdFromChatMessageTypeEnum(), + senderName: senderName, + senderUserID: senderId, + ); + context.read().onNewMessageReceived(messages: [chatMessageModel]); + ChatViewArguments chatViewArguments = ChatViewArguments( + chatTypeEnum: ChatTypeEnum.requestOffer, + requestModel: requestModel, + receiverId: requestModel.customerID, + senderId: senderId ?? "", + ); navigateWithName(context, AppRoutes.chatView, arguments: chatViewArguments); } } diff --git a/lib/views/chat/chat_view.dart b/lib/views/chat/chat_view.dart index 269371a..c2281af 100644 --- a/lib/views/chat/chat_view.dart +++ b/lib/views/chat/chat_view.dart @@ -63,9 +63,9 @@ class ChatView extends StatelessWidget { color: MyColors.darkPrimaryColor, size: 30, ).onPress( - () async { + () async { final status = await chatVM.onTextMessageSend( - receiverId: "7db5e1ae-6de4-47d7-984b-08db2842f899", //Todo: This should be managed somehow!! + receiverId: chatViewArguments.receiverId, message: chatVM.chatMessageText, requestId: chatViewArguments.chatTypeEnum == ChatTypeEnum.requestOffer ? chatViewArguments.requestModel!.id : 0, offerPrice: "0.0", @@ -73,7 +73,7 @@ class ChatView extends StatelessWidget { ); if (status) { - chatVM.updateChatMessageText(""); + chatVM.clearChatMessageText(); } }, ), diff --git a/lib/views/requests/offer_list_page.dart b/lib/views/requests/offer_list_page.dart index 51f078b..d3e9eda 100644 --- a/lib/views/requests/offer_list_page.dart +++ b/lib/views/requests/offer_list_page.dart @@ -1,4 +1,7 @@ +import 'dart:developer'; + import 'package:flutter/material.dart'; +import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; @@ -79,7 +82,12 @@ class OfferListPage extends StatelessWidget { ), ], ).onPress(() { - ChatViewArguments chatViewArguments = ChatViewArguments(chatTypeEnum: ChatTypeEnum.requestOffer, requestModel: offerListPageArguments.requestModel); + log("here: ${offersModel.serviceProvider!.providerGUID}"); + ChatViewArguments chatViewArguments = ChatViewArguments( + chatTypeEnum: ChatTypeEnum.requestOffer, + receiverId: "${offersModel.serviceProvider!.providerGUID}", + senderId: AppState().getUser.data!.userInfo!.userId.toString(), + requestModel: offerListPageArguments.requestModel); navigateWithName(context, AppRoutes.chatView, arguments: chatViewArguments); }).toContainer(isShadowEnabled: true); }, From 5999804bc6be38f4b2dcaf3db361ff3e27ce4b92 Mon Sep 17 00:00:00 2001 From: "Mirza.Shafique@cloudsolutions.com.sa" <5093@Shf> Date: Tue, 26 Dec 2023 10:46:45 +0300 Subject: [PATCH 5/5] Book Appointment 1.0 --- lib/classes/consts.dart | 5 + lib/extensions/string_extensions.dart | 114 +++-- .../appointment_list_model.dart | 52 ++- .../appointment_slots.dart | 24 + lib/repositories/appointment_repo.dart | 167 +++++-- lib/repositories/common_repo.dart | 86 ++-- lib/utils/enums.dart | 11 + lib/view_models/appointments_view_model.dart | 415 ++++++++++++++---- .../appointments/appointment_detail_view.dart | 122 +++-- lib/widgets/bottom_sheet.dart | 4 +- .../common_widgets/categories_list.dart | 22 +- pubspec.lock | 54 ++- pubspec.yaml | 1 + 13 files changed, 850 insertions(+), 227 deletions(-) create mode 100644 lib/models/appointments_models/appointment_slots.dart diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index d24672d..b178ed7 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -46,6 +46,7 @@ class ApiConsts { static String Services_Get = "${baseUrlServices}api/ServiceProviders/Services_Get"; static String ServiceProviderService_Create = "${baseUrlServices}api/ServiceProviders/ServiceProviderService_Create"; static String ServiceProviderService_Update = "${baseUrlServices}api/ServiceProviders/ServiceProviderService_Update"; + static String GetProviderServices = "${baseUrlServices}api/ServiceProviders/ServiceProviderService_Get"; static String ServiceProviderService_Get = "${baseUrlServices}api/ServiceProviders/ServiceProviderService_Get"; static String BranchesAndServices = "${baseUrlServices}api/ServiceProviders/ServiceProviderDetail_Get"; @@ -58,6 +59,7 @@ class ApiConsts { static String GetServiceItemAppointmentScheduleSlots = "${baseUrlServices}api/ServiceProviders/ServiceItemAppointmentScheduleSlots_GetByAppointmentType"; static String ServiceProvidersAppointmentCreate = "${baseUrlServices}api/ServiceProviders/ServiceProvidersAppointmentList_Create"; static String ServiceProviderAppointmentRescheduleCancelAppointment = "${baseUrlServices}api/ServiceProviders/ServiceProviderAppointment_RescheduleCancelAppointment"; + static String AddNewServicesInAppointment = "${baseUrlServices}api/ServiceProviders/ServiceProviderAppointment_ServiceItemAdd"; //ServiceProvidersServiceID as params // static String servicesGet = "${baseUrlServices}api/ServiceProviders/Services_Get"; @@ -103,6 +105,9 @@ class ApiConsts { static String adsPhotoOfficeAppointmentScheduleSlotGet = "${baseUrlServices}api/Advertisement/PhotoOfficeAppointmentScheduleSlot_Get"; static String adsPhotoOfficeAppointmentCreate = "${baseUrlServices}api/Advertisement/PhotoOfficeAppointment_Create"; static String adsMCBankAccountAdGet = "${baseUrlServices}api/Advertisement/MCBankAccountAd_Get"; + static String getAppointmentSlots = "${baseUrlServices}api/ServiceProviders/ScheduleSlotsInfo_Get"; + static String updateAppointmentStatus = "${baseUrlServices}api/ServiceProviders/ServiceProvidersAppointmentStatus_Update"; + static String updateAppointmentPaymentStatus = "${baseUrlServices}api/ServiceProviders/ServiceProviderAppointmentServiceItemPaymentStatus_Update"; //Subscription static String getAllSubscriptions = "${baseUrlServices}api/Common/Subscription_Get"; diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index d25ffd3..3431a3f 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -25,7 +25,9 @@ extension EmailValidator on String { style: TextStyle( fontStyle: isItalic ? FontStyle.italic : null, height: height, - decoration: isUnderLine ? TextDecoration.underline : textDecoration ?? TextDecoration.none, + decoration: isUnderLine + ? TextDecoration.underline + : textDecoration ?? TextDecoration.none, fontSize: fontSize ?? 10, fontWeight: isBold ? FontWeight.bold : fontWeight ?? FontWeight.w600, color: color ?? MyColors.darkTextColor, @@ -34,7 +36,9 @@ extension EmailValidator on String { ); bool isValidEmail() { - return RegExp(r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$').hasMatch(this); + return RegExp( + r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$') + .hasMatch(this); } bool isNum() { @@ -206,6 +210,40 @@ extension AdPostEnum on int { } } +extension AppointmentStatusToInt on AppointmentStatusEnum { + int getIdFromAppointmentStatusEnum() { + switch (this) { + case AppointmentStatusEnum.booked: + return 1; + + case AppointmentStatusEnum.confirmed: + return 2; + + case AppointmentStatusEnum.arrived: + return 3; + + case AppointmentStatusEnum.cancelled: + return 4; + + case AppointmentStatusEnum.rescheduled: + return 5; + + case AppointmentStatusEnum.upcoming: + return 6; + + case AppointmentStatusEnum.inProgress: + return 7; + + case AppointmentStatusEnum.completed: + return 8; + + default: + return 0; + } + } +} + +//TODO: Need to verify Enum on upcoming and inprogress with the database extension AppointmentEnum on int { AppointmentStatusEnum toAppointmentStatusEnum() { if (this == 1) { @@ -218,12 +256,60 @@ extension AppointmentEnum on int { return AppointmentStatusEnum.cancelled; } else if (this == 5) { return AppointmentStatusEnum.rescheduled; + } else if (this == 6) { + return AppointmentStatusEnum.upcoming; + } else if (this == 7) { + return AppointmentStatusEnum.inProgress; + } else if (this == 8) { + return AppointmentStatusEnum.completed; } else { return AppointmentStatusEnum.allAppointments; } } } +extension AppointmentPaymentStatusToInt on AppointmentPaymentStatusEnum { + int getIdFromAppointmentPaymentStatusEnum() { + switch (this) { + case AppointmentPaymentStatusEnum.notConfirmed: + return 1; + + case AppointmentPaymentStatusEnum.payNow: + return 2; + + case AppointmentPaymentStatusEnum.paid: + return 3; + + case AppointmentPaymentStatusEnum.payLater: + return 4; + + case AppointmentPaymentStatusEnum.payPartial: + return 5; + + default: + return 1; + } + } +} + +extension AppointmentPaymentEnum on int { + AppointmentPaymentStatusEnum toAppointmentPaymentStatusEnum() { + if (this == 1) { + return AppointmentPaymentStatusEnum.notConfirmed; + } else if (this == 2) { + return AppointmentPaymentStatusEnum.payNow; + } else if (this == 3) { + return AppointmentPaymentStatusEnum.paid; + } else if (this == 4) { + return AppointmentPaymentStatusEnum.payLater; + } else if (this == 5) { + return AppointmentPaymentStatusEnum.payPartial; + } else { + return AppointmentPaymentStatusEnum.notConfirmed; + } + } +} + extension RequestTypeTypeEnum on int { RequestsTypeEnum toRequestTypeStatusEnum() { if (this == 1) { @@ -314,30 +400,6 @@ extension PaymentTypesToInt on PaymentTypes { } } -extension AppointmentStatusToInt on AppointmentStatusEnum { - int getIdFromAppointmentStatusEnum() { - switch (this) { - case AppointmentStatusEnum.booked: - return 1; - - case AppointmentStatusEnum.confirmed: - return 2; - - case AppointmentStatusEnum.arrived: - return 3; - - case AppointmentStatusEnum.cancelled: - return 4; - - case AppointmentStatusEnum.rescheduled: - return 5; - - default: - return 0; - } - } -} - extension CreatedByRoleEnumToInt on CreatedByRoleEnum { int getIdFromCreatedByRoleEnum() { switch (this) { diff --git a/lib/models/appointments_models/appointment_list_model.dart b/lib/models/appointments_models/appointment_list_model.dart index d3da5c0..b19f957 100644 --- a/lib/models/appointments_models/appointment_list_model.dart +++ b/lib/models/appointments_models/appointment_list_model.dart @@ -14,11 +14,20 @@ class AppointmentListModel { int? paymentStatus; String? paymentStatusText; String? customerName; + String? customerMobileNum; + int? appointmentType; String? providerName; String? duration; String? appointmentDate; + String? branchName; + int? branchId; + int? servicePaymentStatus; + double? totalAmount; + double? remainingAmount; AppointmentStatusEnum? appointmentStatusEnum; + AppointmentPaymentStatusEnum? appointmentPaymentStatusEnum; List? appointmentServicesList; + List? customerAppointmentList; AppointmentListModel( {this.id, @@ -32,10 +41,18 @@ class AppointmentListModel { this.paymentStatus, this.paymentStatusText, this.customerName, + this.customerMobileNum, + this.appointmentType, this.providerName, this.duration, + this.branchName, + this.branchId, + this.servicePaymentStatus, + this.totalAmount, + this.remainingAmount, this.appointmentDate, - this.appointmentServicesList}); + this.appointmentServicesList, + this.customerAppointmentList}); @override String toString() { @@ -54,15 +71,26 @@ class AppointmentListModel { paymentStatus = json['paymentStatus']; paymentStatusText = json['paymentStatusText']; customerName = json['customerName']; + customerMobileNum = json['customerMobile']; + appointmentType = json['appointmentType']; providerName = json['providerName']; duration = json['duration']; appointmentDate = json['appointmentDate']; - appointmentStatusEnum = (json['appointmentStatusID'] as int).toAppointmentStatusEnum(); + branchName = json['branchName']; + branchId = json['branchID']; + servicePaymentStatus = json['servicePaymentStatus']; + totalAmount = json['amountTotal']; + remainingAmount = json['amountRem']; + appointmentStatusEnum = + (json['appointmentStatusID'] as int).toAppointmentStatusEnum(); + appointmentPaymentStatusEnum = + (json['servicePaymentStatus'] as int).toAppointmentPaymentStatusEnum(); if (json['serviceList'] != null) { appointmentServicesList = []; json['serviceList'].forEach((v) { - appointmentServicesList!.add(ServiceModel.fromJson(v, isForAppointment: true)); + appointmentServicesList! + .add(ServiceModel.fromJson(v, isForAppointment: true)); }); } } @@ -74,7 +102,11 @@ class ServiceAppointmentItems { String? serviceItemName; String? serviceItemDescription; - ServiceAppointmentItems({this.id, this.serviceItemID, this.serviceItemName, this.serviceItemDescription}); + ServiceAppointmentItems( + {this.id, + this.serviceItemID, + this.serviceItemName, + this.serviceItemDescription}); ServiceAppointmentItems.fromJson(Map json) { id = json['id']; @@ -92,3 +124,15 @@ class ServiceAppointmentItems { return data; } } + +// Data Model Class with 'customerName' and 'customerID' +class CustomerData { + final int customerID; + final String customerName; + final List appointmentList; + + CustomerData( + {required this.customerID, + required this.customerName, + required this.appointmentList}); +} diff --git a/lib/models/appointments_models/appointment_slots.dart b/lib/models/appointments_models/appointment_slots.dart new file mode 100644 index 0000000..828e579 --- /dev/null +++ b/lib/models/appointments_models/appointment_slots.dart @@ -0,0 +1,24 @@ +class AppointmentSlots { + int totalSlots; + int occupiedSlots; + int emptySlots; + + AppointmentSlots({ + required this.totalSlots, + required this.occupiedSlots, + required this.emptySlots, + }); + + factory AppointmentSlots.fromJson(Map json) => + AppointmentSlots( + totalSlots: json["totalSlots"], + occupiedSlots: json["occupiedSlots"], + emptySlots: json["emptySlots"], + ); + + Map toJson() => { + "totalSlots": totalSlots, + "occupiedSlots": occupiedSlots, + "emptySlots": emptySlots, + }; +} diff --git a/lib/repositories/appointment_repo.dart b/lib/repositories/appointment_repo.dart index 9bd8d14..95d1a24 100644 --- a/lib/repositories/appointment_repo.dart +++ b/lib/repositories/appointment_repo.dart @@ -11,7 +11,20 @@ import 'package:mc_common_app/models/appointments_models/schedule_model.dart'; import 'package:mc_common_app/models/appointments_models/service_schedule_model.dart'; import 'package:mc_common_app/utils/enums.dart'; +import '../models/appointments_models/appointment_list_model.dart'; + abstract class AppointmentRepo { + Future> getMyAppointments( + Map map); + + Future updateAppointmentStatus( + Map map); + + Future updateAppointmentPaymentStatus( + Map map); + + Future getAppointmentSlots(Map map); + Future getAllServices(String branchId); Future createSchedule(Map map); @@ -24,14 +37,20 @@ abstract class AppointmentRepo { Future updateServicesInSchedule(Map map); - Future> mergeServiceIntoAvailableSchedules({ + Future> + mergeServiceIntoAvailableSchedules({ required List serviceItemIdsForHome, required List serviceItemIdsForWorkshop, }); - Future createServiceAppointment({required List schedules, required int serviceProviderID}); + Future createServiceAppointment( + {required List schedules, + required int serviceProviderID}); - Future cancelOrRescheduleServiceAppointment({required int serviceAppointmentID, required int serviceSlotID, required int appointmentScheduleAction}); + Future cancelOrRescheduleServiceAppointment( + {required int serviceAppointmentID, + required int serviceSlotID, + required int appointmentScheduleAction}); } class AppointmentRepoImp implements AppointmentRepo { @@ -39,19 +58,25 @@ class AppointmentRepoImp implements AppointmentRepo { Future getAllServices(String branchId) async { Map map = {"ProviderBranchID": branchId}; String t = AppState().getUser.data!.accessToken ?? ""; - return await injector.get().getJsonForObject((json) => Services.fromJson(json), ApiConsts.getServicesOfBranch, token: t, queryParameters: map); + return await injector.get().getJsonForObject( + (json) => Services.fromJson(json), ApiConsts.getServicesOfBranch, + token: t, queryParameters: map); } @override Future createSchedule(Map map) async { String t = AppState().getUser.data!.accessToken ?? ""; - return await injector.get().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.createSchedule, map, token: t); + return await injector.get().postJsonForObject( + (json) => MResponse.fromJson(json), ApiConsts.createSchedule, map, + token: t); } @override Future addServicesInSchedule(Map map) async { String t = AppState().getUser.data!.accessToken ?? ""; - return await injector.get().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.createGroup, map, token: t); + return await injector.get().postJsonForObject( + (json) => MResponse.fromJson(json), ApiConsts.createGroup, map, + token: t); } @override @@ -59,29 +84,36 @@ class AppointmentRepoImp implements AppointmentRepo { Map map = {"ServiceProviderBranchID": branchId}; String t = AppState().getUser.data!.accessToken ?? ""; - GenericRespModel adsGenericModel = await injector.get().getJsonForObject( - (json) => GenericRespModel.fromJson(json), - ApiConsts.getSchedule, - token: t, - queryParameters: map, - ); + GenericRespModel adsGenericModel = + await injector.get().getJsonForObject( + (json) => GenericRespModel.fromJson(json), + ApiConsts.getSchedule, + token: t, + queryParameters: map, + ); - return List.generate(adsGenericModel.data.length, (index) => ScheduleData.fromJson(adsGenericModel.data[index])); + return List.generate(adsGenericModel.data.length, + (index) => ScheduleData.fromJson(adsGenericModel.data[index])); } @override Future updateSchedule(Map map) async { String t = AppState().getUser.data!.accessToken ?? ""; - return await injector.get().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.updateSchedule, map, token: t); + return await injector.get().postJsonForObject( + (json) => MResponse.fromJson(json), ApiConsts.updateSchedule, map, + token: t); } @override Future updateServicesInSchedule(Map map) async { String t = AppState().getUser.data!.accessToken ?? ""; - return await injector.get().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.updateGroup, map, token: t); + return await injector.get().postJsonForObject( + (json) => MResponse.fromJson(json), ApiConsts.updateGroup, map, + token: t); } - Future> mergeServiceIntoAvailableSchedules({ + Future> + mergeServiceIntoAvailableSchedules({ required List serviceItemIdsForHome, required List serviceItemIdsForWorkshop, }) async { @@ -96,21 +128,28 @@ class AppointmentRepoImp implements AppointmentRepo { "ServiceItemIDs": serviceItemIdsForWorkshop, } ]; - GenericRespModel adsGenericModel = await injector.get().postJsonForObject( - (json) => GenericRespModel.fromJson(json), - ApiConsts.GetServiceItemAppointmentScheduleSlots, - queryParameters, - token: t, - ); + GenericRespModel adsGenericModel = + await injector.get().postJsonForObject( + (json) => GenericRespModel.fromJson(json), + ApiConsts.GetServiceItemAppointmentScheduleSlots, + queryParameters, + token: t, + ); if (adsGenericModel.data == null) { return []; } List serviceAppointmentScheduleModel = - List.generate(adsGenericModel.data.length, (index) => ServiceAppointmentScheduleModel.fromJson(adsGenericModel.data[index], isForAppointment: true)); + List.generate( + adsGenericModel.data.length, + (index) => ServiceAppointmentScheduleModel.fromJson( + adsGenericModel.data[index], + isForAppointment: true)); return serviceAppointmentScheduleModel; } - Future createServiceAppointment({required List schedules, required int serviceProviderID}) async { + Future createServiceAppointment( + {required List schedules, + required int serviceProviderID}) async { String t = AppState().getUser.data!.accessToken ?? ""; int customerId = AppState().getUser.data!.userInfo!.customerId ?? 0; @@ -130,18 +169,22 @@ class AppointmentRepoImp implements AppointmentRepo { }); }); - GenericRespModel adsGenericModel = await injector.get().postJsonForObject( - (json) => GenericRespModel.fromJson(json), - ApiConsts.ServiceProvidersAppointmentCreate, - mapList, - token: t, - ); + GenericRespModel adsGenericModel = + await injector.get().postJsonForObject( + (json) => GenericRespModel.fromJson(json), + ApiConsts.ServiceProvidersAppointmentCreate, + mapList, + token: t, + ); return adsGenericModel; } @override - Future cancelOrRescheduleServiceAppointment({required int serviceAppointmentID, required int serviceSlotID, required int appointmentScheduleAction}) async { + Future cancelOrRescheduleServiceAppointment( + {required int serviceAppointmentID, + required int serviceSlotID, + required int appointmentScheduleAction}) async { String t = AppState().getUser.data!.accessToken ?? ""; final payload = { @@ -150,13 +193,63 @@ class AppointmentRepoImp implements AppointmentRepo { "appointmentScheduleAction": appointmentScheduleAction, }; - GenericRespModel adsGenericModel = await injector.get().postJsonForObject( - (json) => GenericRespModel.fromJson(json), - ApiConsts.ServiceProviderAppointmentRescheduleCancelAppointment, - payload, - token: t, - ); + GenericRespModel adsGenericModel = + await injector.get().postJsonForObject( + (json) => GenericRespModel.fromJson(json), + ApiConsts.ServiceProviderAppointmentRescheduleCancelAppointment, + payload, + token: t, + ); return adsGenericModel; } + + @override + Future> getMyAppointments( + Map map) async { + String t = AppState().getUser.data!.accessToken ?? ""; + + GenericRespModel genericRespModel = + await injector.get().getJsonForObject( + token: t, + (json) => GenericRespModel.fromJson(json), + queryParameters: map, + ApiConsts.serviceProvidersAppointmentGet, + ); + List appointmentList = List.generate( + genericRespModel.data.length, + (index) => AppointmentListModel.fromJson(genericRespModel.data[index])); + return appointmentList; + } + + @override + Future getAppointmentSlots(Map map) async { + String t = AppState().getUser.data!.accessToken ?? ""; + + MResponse adsGenericModel = + await injector.get().getJsonForObject( + (json) => MResponse.fromJson(json), + ApiConsts.getAppointmentSlots, + token: t, + queryParameters: map, + ); + + return adsGenericModel; + } + + @override + Future updateAppointmentPaymentStatus(Map map) async { + String t = AppState().getUser.data!.accessToken ?? ""; + return await injector.get().postJsonForObject( + (json) => MResponse.fromJson(json), ApiConsts.updateAppointmentPaymentStatus, map, + token: t); + } + + @override + Future updateAppointmentStatus(Map map) async { + String t = AppState().getUser.data!.accessToken ?? ""; + return await injector.get().postJsonForObject( + (json) => MResponse.fromJson(json), ApiConsts.updateAppointmentStatus, map, + token: t); + } } diff --git a/lib/repositories/common_repo.dart b/lib/repositories/common_repo.dart index b9d5209..0ec703d 100644 --- a/lib/repositories/common_repo.dart +++ b/lib/repositories/common_repo.dart @@ -12,7 +12,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/models/user_models/role.dart'; - abstract class CommonRepo { Future getAllCountries(); @@ -25,9 +24,12 @@ abstract class CommonRepo { Future> getMyAppointments(); - Future getCarCheckServiceScheduleDetails({required double lat, required double long}); + Future getCarCheckServiceScheduleDetails( + {required double lat, required double long}); - Future> getPhotographyServiceScheduleListByOffices({required double lat, required double long}); + Future> + getPhotographyServiceScheduleListByOffices( + {required double lat, required double long}); // Future> getProviderServiceCategories(); @@ -36,9 +38,11 @@ abstract class CommonRepo { Future> getVehicleTypes(); //TODO: Needs to remove common methods from AD's repo and delete all repeated methods. - Future getVehicleDetails({int? vehicleTypeId, int? vehicleBrandId}); + Future getVehicleDetails( + {int? vehicleTypeId, int? vehicleBrandId}); - Future> getEnumTypeValues({int? enumTypeID, String? enumTypeName}); + Future> getEnumTypeValues( + {int? enumTypeID, String? enumTypeName}); } class CommonRepoImp implements CommonRepo { @@ -47,7 +51,8 @@ class CommonRepoImp implements CommonRepo { @override Future getAllCountries() async { - return await apiClient.getJsonForObject((json) => Country.fromJson(json), ApiConsts.GetAllCountry); + return await apiClient.getJsonForObject( + (json) => Country.fromJson(json), ApiConsts.GetAllCountry); } @override @@ -55,18 +60,22 @@ class CommonRepoImp implements CommonRepo { var postParams = { "CountryID": countryId, }; - return await apiClient.getJsonForObject((json) => Cities.fromJson(json), ApiConsts.GetAllCities, queryParameters: postParams); + return await apiClient.getJsonForObject( + (json) => Cities.fromJson(json), ApiConsts.GetAllCities, + queryParameters: postParams); } @override Future getRoles() async { - return await apiClient.getJsonForObject((json) => Role.fromJson(json), ApiConsts.GetProviderRoles); + return await apiClient.getJsonForObject( + (json) => Role.fromJson(json), ApiConsts.GetProviderRoles); } @override Future> getMyAppointments() async { var params = { - "customerID": appState.getUser.data!.userInfo!.customerId.toString() ?? "", + "customerID": + appState.getUser.data!.userInfo!.customerId.toString() ?? "", }; GenericRespModel genericRespModel = await apiClient.getJsonForObject( token: appState.getUser.data!.accessToken, @@ -74,12 +83,15 @@ class CommonRepoImp implements CommonRepo { queryParameters: params, ApiConsts.serviceProvidersAppointmentGet, ); - List appointmentList = List.generate(genericRespModel.data.length, (index) => AppointmentListModel.fromJson(genericRespModel.data[index])); + List appointmentList = List.generate( + genericRespModel.data.length, + (index) => AppointmentListModel.fromJson(genericRespModel.data[index])); return appointmentList; } @override - Future getCarCheckServiceScheduleDetails({required double lat, required double long}) async { + Future getCarCheckServiceScheduleDetails( + {required double lat, required double long}) async { var params = { "Latitude": lat.toString(), "Longitude": long.toString(), @@ -90,12 +102,15 @@ class CommonRepoImp implements CommonRepo { queryParameters: params, ApiConsts.adsCarCheckupSPBranchScheduleSlotGet, ); - SSCarCheckScheduleModel ssCarCheckScheduleModel = SSCarCheckScheduleModel.fromJson(genericRespModel.data[0]); + SSCarCheckScheduleModel ssCarCheckScheduleModel = + SSCarCheckScheduleModel.fromJson(genericRespModel.data[0]); return ssCarCheckScheduleModel; } @override - Future> getPhotographyServiceScheduleListByOffices({required double lat, required double long}) async { + Future> + getPhotographyServiceScheduleListByOffices( + {required double lat, required double long}) async { var params = { "Latitude": lat.toString(), "Longitude": long.toString(), @@ -109,19 +124,28 @@ class CommonRepoImp implements CommonRepo { if (genericRespModel.data == null) { return []; } - List ssPhotoScheduleModel = List.generate(genericRespModel.data.length, (index) => SSPhotoOfficeScheduleModel.fromJson(genericRespModel.data[index])); + List ssPhotoScheduleModel = List.generate( + genericRespModel.data.length, + (index) => + SSPhotoOfficeScheduleModel.fromJson(genericRespModel.data[index])); return ssPhotoScheduleModel ?? []; } @override Future> getVehicleTypes() async { - GenericRespModel adsGenericModel = await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleTypeGet); - List vehicleTypes = List.generate(adsGenericModel.data.length, (index) => VehicleTypeModel.fromJson(adsGenericModel.data[index])); + GenericRespModel adsGenericModel = await apiClient.getJsonForObject( + token: appState.getUser.data!.accessToken, + (json) => GenericRespModel.fromJson(json), + ApiConsts.vehicleTypeGet); + List vehicleTypes = List.generate( + adsGenericModel.data.length, + (index) => VehicleTypeModel.fromJson(adsGenericModel.data[index])); return vehicleTypes; } @override - Future getVehicleDetails({int? vehicleTypeId, int? vehicleBrandId}) async { + Future getVehicleDetails( + {int? vehicleTypeId, int? vehicleBrandId}) async { var postParams = { "vehicleType": vehicleTypeId ?? 0, "isVehicleBrand": "true", @@ -146,24 +170,35 @@ class CommonRepoImp implements CommonRepo { postParams, token: token, ); - VehicleDetailsModel vehicleDetails = VehicleDetailsModel.fromJson(adsGenericModel.data); + VehicleDetailsModel vehicleDetails = + VehicleDetailsModel.fromJson(adsGenericModel.data); return vehicleDetails; } @override - Future> getVehicleCities({required int countryId}) async { + Future> getVehicleCities( + {required int countryId}) async { var postParams = { "CountryID": countryId.toString(), }; - GenericRespModel adsGenericModel = - await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleCityGet, queryParameters: postParams); - List vehicleCities = List.generate(adsGenericModel.data.length, (index) => VehicleCityModel.fromJson(adsGenericModel.data[index])); + GenericRespModel adsGenericModel = await apiClient.getJsonForObject( + token: appState.getUser.data!.accessToken, + (json) => GenericRespModel.fromJson(json), + ApiConsts.vehicleCityGet, + queryParameters: postParams); + List vehicleCities = List.generate( + adsGenericModel.data.length, + (index) => VehicleCityModel.fromJson(adsGenericModel.data[index])); return vehicleCities; } @override - Future> getEnumTypeValues({int? enumTypeID, String? enumTypeName}) async { - var postParams = {"enumTypeID": (enumTypeID ?? 0).toString(), "enumTypeName": enumTypeName ?? ""}; + Future> getEnumTypeValues( + {int? enumTypeID, String? enumTypeName}) async { + var postParams = { + "enumTypeID": (enumTypeID ?? 0).toString(), + "enumTypeName": enumTypeName ?? "" + }; GenericRespModel enumGenericModel = await apiClient.postJsonForObject( (json) => GenericRespModel.fromJson(json), ApiConsts.getEnumTypeValues, @@ -171,7 +206,8 @@ class CommonRepoImp implements CommonRepo { token: appState.getUser.data!.accessToken, ); - List vehicleCities = List.generate(enumGenericModel.data.length, (index) => EnumsModel.fromJson(enumGenericModel.data[index])); + List vehicleCities = List.generate(enumGenericModel.data.length, + (index) => EnumsModel.fromJson(enumGenericModel.data[index])); return vehicleCities; } // diff --git a/lib/utils/enums.dart b/lib/utils/enums.dart index 395bb64..1bf4bd0 100644 --- a/lib/utils/enums.dart +++ b/lib/utils/enums.dart @@ -149,6 +149,17 @@ enum AppointmentStatusEnum { cancelled, rescheduled, allAppointments, + upcoming, + inProgress, + completed, +} + +enum AppointmentPaymentStatusEnum { + notConfirmed, + payNow, + paid, + payLater, + payPartial, } enum RequestsTypeEnum { diff --git a/lib/view_models/appointments_view_model.dart b/lib/view_models/appointments_view_model.dart index f55b9d7..2a9fb1b 100644 --- a/lib/view_models/appointments_view_model.dart +++ b/lib/view_models/appointments_view_model.dart @@ -6,6 +6,7 @@ import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart'; import 'package:mc_common_app/models/general_models/enums_model.dart'; import 'package:mc_common_app/models/general_models/generic_resp_model.dart'; +import 'package:mc_common_app/models/general_models/m_response.dart'; import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart'; import 'package:mc_common_app/models/provider_branches_models/provider_profile_model.dart'; import 'package:mc_common_app/models/appointments_models/service_schedule_model.dart'; @@ -30,20 +31,31 @@ import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:provider/provider.dart'; +import '../models/appointments_models/appointment_slots.dart'; + class AppointmentsVM extends BaseVM { final CommonRepo commonRepo; final CommonAppServices commonServices; final ProviderRepo providerRepo; final AppointmentRepo scheduleRepo; - AppointmentsVM({required this.commonServices, required this.scheduleRepo, required this.providerRepo, required this.commonRepo}); + AppointmentsVM({required this.commonServices, + required this.scheduleRepo, + required this.providerRepo, + required this.commonRepo}); bool isFetchingLists = false; + int selectedBranch = 0; + int selectedAppointmentIndex = 0; + int selectedAppointmentSubIndex = 0; + int selectedAppointmentId = 0; List myAppointments = []; List myUpComingAppointments = []; List myFilteredAppointments = []; List appointmentsFilterOptions = []; + List customersAppointments = []; + List myFilteredAppointments2 = []; // List availableSchedules = []; @@ -56,7 +68,8 @@ class AppointmentsVM extends BaseVM { List serviceAppointmentScheduleList = []; bool ifItemAlreadySelected(int id) { - int indexFound = allSelectedItemsInAppointments.indexWhere((element) => element.id == id); + int indexFound = allSelectedItemsInAppointments + .indexWhere((element) => element.id == id); if (indexFound != -1) { return true; } @@ -65,9 +78,24 @@ class AppointmentsVM extends BaseVM { List allSelectedItemsInAppointments = []; + setupProviderAppointmentFilter() { + appointmentsFilterOptions.clear(); + appointmentsFilterOptions.add( + FilterListModel(id: 0, title: "All Appointments", isSelected: true)); + appointmentsFilterOptions + .add(FilterListModel(id: 6, title: "Upcoming", isSelected: false)); + appointmentsFilterOptions + .add(FilterListModel(id: 3, title: "Arrived", isSelected: false)); + appointmentsFilterOptions + .add(FilterListModel(id: 7, title: "In Progress", isSelected: false)); + appointmentsFilterOptions + .add(FilterListModel(id: 8, title: "Completed", isSelected: false)); + } + Future onItemsSelectedInService() async { if (currentServiceSelection != null) { - int index = servicesInCurrentAppointment.indexWhere((element) => element.serviceId == currentServiceSelection!.serviceId!); + int index = servicesInCurrentAppointment.indexWhere((element) => + element.serviceId == currentServiceSelection!.serviceId!); if (index == -1) { double totalPrice = 0.0; @@ -88,12 +116,14 @@ class AppointmentsVM extends BaseVM { bool isSuccess = false; List appointmentIdsList = []; try { - GenericRespModel genericRespModel = await scheduleRepo.createServiceAppointment( + GenericRespModel genericRespModel = + await scheduleRepo.createServiceAppointment( schedules: serviceAppointmentScheduleList, serviceProviderID: selectedBranchModel!.serviceProviderId ?? 0, ); - if (genericRespModel.messageStatus == 2 || genericRespModel.data == null) { + if (genericRespModel.messageStatus == 2 || + genericRespModel.data == null) { Utils.hideLoading(context); Utils.showToast("${genericRespModel.message.toString()}"); return; @@ -111,13 +141,17 @@ class AppointmentsVM extends BaseVM { } context.read().onNavbarTapped(1); - applyFilterOnAppointmentsVM(appointmentStatusEnum: AppointmentStatusEnum.booked); + applyFilterOnAppointmentsVM( + appointmentStatusEnum: AppointmentStatusEnum.booked); Utils.hideLoading(context); resetAfterBookingAppointment(); if (isSuccess) { if (amountToPayForAppointment > 0) { - context.read().updateAppointmentIdsForPayment(ids: appointmentIdsList); - navigateWithName(context, AppRoutes.paymentMethodsView, arguments: PaymentTypes.appointment); + context + .read() + .updateAppointmentIdsForPayment(ids: appointmentIdsList); + navigateWithName(context, AppRoutes.paymentMethodsView, + arguments: PaymentTypes.appointment); } else { Utils.showToast("Your appointment has been booked successfully!"); getMyAppointments(); @@ -129,28 +163,36 @@ class AppointmentsVM extends BaseVM { } } - Future onConfirmAppointmentPressed({required BuildContext context, required appointmentId}) async { - context.read().updateAppointmentIdsForPayment(ids: [appointmentId]); - navigateWithName(context, AppRoutes.paymentMethodsView, arguments: PaymentTypes.appointment); + Future onConfirmAppointmentPressed( + {required BuildContext context, required appointmentId}) async { + context + .read() + .updateAppointmentIdsForPayment(ids: [appointmentId]); + navigateWithName(context, AppRoutes.paymentMethodsView, + arguments: PaymentTypes.appointment); } - Future onCancelAppointmentPressed({required BuildContext context, required AppointmentListModel appointmentListModel}) async { + Future onCancelAppointmentPressed({required BuildContext context, + required AppointmentListModel appointmentListModel}) async { Utils.showLoading(context); try { - GenericRespModel genericRespModel = await scheduleRepo.cancelOrRescheduleServiceAppointment( + GenericRespModel genericRespModel = + await scheduleRepo.cancelOrRescheduleServiceAppointment( serviceAppointmentID: appointmentListModel.id ?? 0, serviceSlotID: appointmentListModel.serviceSlotID ?? 0, appointmentScheduleAction: 2, // 1 for Reschedule and 2 for Cancel ); - if (genericRespModel.messageStatus == 2 || genericRespModel.data == null) { + if (genericRespModel.messageStatus == 2 || + genericRespModel.data == null) { Utils.hideLoading(context); Utils.showToast("${genericRespModel.message.toString()}"); return; } if (genericRespModel.data == 1) { context.read().onNavbarTapped(1); - applyFilterOnAppointmentsVM(appointmentStatusEnum: AppointmentStatusEnum.cancelled); + applyFilterOnAppointmentsVM( + appointmentStatusEnum: AppointmentStatusEnum.cancelled); Utils.showToast("${genericRespModel.message.toString()}"); await getMyAppointments(); Utils.hideLoading(context); @@ -181,7 +223,8 @@ class AppointmentsVM extends BaseVM { notifyListeners(); } - SelectionModel branchSelectedCategoryId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); + SelectionModel branchSelectedCategoryId = + SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); void updateProviderCategoryId(SelectionModel id) { branchSelectedCategoryId = id; @@ -200,23 +243,30 @@ class AppointmentsVM extends BaseVM { void updateBranchServiceId(SelectionModel id) async { branchSelectedServiceId = id; - currentServiceSelection = branchServices.firstWhere((element) => element.serviceProviderServiceId == id.selectedId); + currentServiceSelection = branchServices.firstWhere( + (element) => element.serviceProviderServiceId == id.selectedId); notifyListeners(); } void removeServiceInCurrentAppointment(int index) { - int serviceId = servicesInCurrentAppointment.elementAt(index).serviceProviderServiceId ?? -1; - allSelectedItemsInAppointments.removeWhere((element) => element.serviceProviderServiceId == serviceId); + int serviceId = servicesInCurrentAppointment + .elementAt(index) + .serviceProviderServiceId ?? + -1; + allSelectedItemsInAppointments.removeWhere( + (element) => element.serviceProviderServiceId == serviceId); servicesInCurrentAppointment.removeAt(index); notifyListeners(); } resetCategorySelectionBottomSheet() { selectedSubServicesCounter = 0; - branchSelectedCategoryId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); + branchSelectedCategoryId = + SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); isHomeTapped = false; - branchSelectedServiceId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); + branchSelectedServiceId = + SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); currentServiceSelection = null; } @@ -231,76 +281,222 @@ class AppointmentsVM extends BaseVM { populateAppointmentsFilterList() async { appointmentsFilterOptions.clear(); - myAppointmentsEnum = await commonRepo.getEnumTypeValues(enumTypeID: 13); //TODO: 13 is to get Appointments Filter Enums + myAppointmentsEnum = await commonRepo.getEnumTypeValues( + enumTypeID: 13); //TODO: 13 is to get Appointments Filter Enums for (int i = 0; i < myAppointmentsEnum.length; i++) { - appointmentsFilterOptions.add(FilterListModel(title: myAppointmentsEnum[i].enumValueStr, isSelected: false, id: myAppointmentsEnum[i].enumValue)); + appointmentsFilterOptions.add(FilterListModel( + title: myAppointmentsEnum[i].enumValueStr, + isSelected: false, + id: myAppointmentsEnum[i].enumValue)); } - appointmentsFilterOptions.insert(0, FilterListModel(title: "All Appointments", isSelected: true, id: 0)); + appointmentsFilterOptions.insert( + 0, FilterListModel(title: "All Appointments", isSelected: true, id: 0)); notifyListeners(); } - applyFilterOnAppointmentsVM({required AppointmentStatusEnum appointmentStatusEnum}) { + applyFilterOnAppointmentsVM( + {required AppointmentStatusEnum appointmentStatusEnum, + bool isNeedCustomerFilter = false}) { if (appointmentsFilterOptions.isEmpty) return; for (var value in appointmentsFilterOptions) { value.isSelected = false; } - appointmentsFilterOptions[appointmentStatusEnum.getIdFromAppointmentStatusEnum()].isSelected = true; + + appointmentsFilterOptions.forEach((element) { + if (element.id == + appointmentStatusEnum.getIdFromAppointmentStatusEnum()) { + element.isSelected = true; + } + }); + // appointmentsFilterOptions[ + // appointmentStatusEnum.getIdFromAppointmentStatusEnum()] + // .isSelected = true; if (appointmentStatusEnum.getIdFromAppointmentStatusEnum() == 0) { myFilteredAppointments = myAppointments; + if (isNeedCustomerFilter) findAppointmentsBasedOnCustomers(); notifyListeners(); return; } - myFilteredAppointments = myAppointments.where((element) => element.appointmentStatusID! == appointmentStatusEnum.getIdFromAppointmentStatusEnum()).toList(); + myFilteredAppointments = myAppointments + .where((element) => + element.appointmentStatusID! == + appointmentStatusEnum.getIdFromAppointmentStatusEnum()) + .toList(); + if (isNeedCustomerFilter) findAppointmentsBasedOnCustomers(); notifyListeners(); } + findAppointmentsBasedOnCustomers() { + // Use a Set to ensure uniqueness of customerIDs + Set uniqueCustomerIDs = Set(); + + // Extract unique customerIDs + for (var item in myFilteredAppointments) { + uniqueCustomerIDs.add(item.customerID ?? 0); + } + + // Create a list of CustomerData instances + myFilteredAppointments2 = uniqueCustomerIDs.map((id) { + List list = myFilteredAppointments + .where((item) => item.customerID == id) + .toList(); + AppointmentListModel model = list.first; + model.customerAppointmentList = list; + return model; + }).toList(); + // customersAppointments = uniqueCustomerIDs.map((id) { + // List list = myFilteredAppointments + // .where((item) => item.customerID == id) + // .toList(); + // var customerItem = + // myFilteredAppointments.firstWhere((item) => item.customerID == id); + // + // return CustomerData( + // customerID: id, + // customerName: customerItem.customerName ?? "", + // appointmentList: list, + // ); + // }).toList(); + } + Future getMyAppointments({bool isNeedToRebuild = false}) async { if (isNeedToRebuild) setState(ViewState.busy); myAppointments = await commonRepo.getMyAppointments(); myFilteredAppointments = myAppointments; - myUpComingAppointments = myAppointments.where((element) => element.appointmentStatusEnum == AppointmentStatusEnum.booked).toList(); + myUpComingAppointments = myAppointments + .where((element) => + element.appointmentStatusEnum == AppointmentStatusEnum.booked) + .toList(); setState(ViewState.idle); // applyFilterOnAppointmentsVM(appointmentStatusEnum: AppointmentStatusEnum.allAppointments); notifyListeners(); } + AppointmentSlots? appointmentSlots; + + Future getAppointmentSlotsInfo({required Map map, + required BuildContext context, + bool isNeedToRebuild = false}) async { + if (isNeedToRebuild) setState(ViewState.busy); + try { + MResponse genericRespModel = await scheduleRepo.getAppointmentSlots(map); + if (genericRespModel.messageStatus == 1) { + appointmentSlots = AppointmentSlots.fromJson(genericRespModel.data); + } else { + Utils.showToast(genericRespModel.message.toString()); + } + } catch (e) { + Utils.showToast(e.toString()); + } + } + + Future getProviderMyAppointments(Map map, + {bool isNeedToRebuild = false}) async { + if (isNeedToRebuild) setState(ViewState.busy); + + myAppointments = await scheduleRepo.getMyAppointments(map); + myFilteredAppointments = myAppointments; + // myUpComingAppointments = myAppointments + // .where((element) => + // element.appointmentStatusEnum == AppointmentStatusEnum.booked) + // .toList(); + setState(ViewState.idle); + applyFilterOnAppointmentsVM( + appointmentStatusEnum: AppointmentStatusEnum.allAppointments, + isNeedCustomerFilter: true); + notifyListeners(); + } + updateSelectedBranch(BranchDetailModel branchDetailModel) { selectedBranchModel = branchDetailModel; getBranchCategories(); notifyListeners(); } - updateSelectedAppointmentDate({required int dateIndex, required int scheduleIndex}) { - for (var element in serviceAppointmentScheduleList[scheduleIndex].customTimeDateSlotList!) { + updateAppointmentStatus(Map map,{bool isNeedToRebuild = false}) async { + if (isNeedToRebuild) setState(ViewState.busy); + try { + MResponse genericRespModel = await scheduleRepo.updateAppointmentStatus(map); + + if (genericRespModel.messageStatus == 1) { + Utils.showToast("appointment status updated"); + } else { + Utils.showToast(genericRespModel.message.toString()); + } + } catch (e) { + Utils.showToast(e.toString()); + } + } + + updateAppointmentPaymentStatus(Map map,{bool isNeedToRebuild = false}) async { + if (isNeedToRebuild) setState(ViewState.busy); + try { + MResponse genericRespModel = await scheduleRepo.updateAppointmentPaymentStatus(map); + + if (genericRespModel.messageStatus == 1) { + Utils.showToast("payment status updated"); + } else { + Utils.showToast(genericRespModel.message.toString()); + } + } catch (e) { + Utils.showToast(e.toString()); + } + } + + updateSelectedAppointmentDate( + {required int dateIndex, required int scheduleIndex}) { + for (var element in serviceAppointmentScheduleList[scheduleIndex] + .customTimeDateSlotList!) { element.date!.isSelected = false; } - serviceAppointmentScheduleList[scheduleIndex].customTimeDateSlotList![dateIndex].date!.isSelected = true; + serviceAppointmentScheduleList[scheduleIndex] + .customTimeDateSlotList![dateIndex] + .date! + .isSelected = true; serviceAppointmentScheduleList[scheduleIndex].selectedDateIndex = dateIndex; final date = TimeSlotModel( - date: serviceAppointmentScheduleList[scheduleIndex].customTimeDateSlotList![dateIndex].date!.date, - slotId: serviceAppointmentScheduleList[scheduleIndex].customTimeDateSlotList![dateIndex].date!.slotId, + date: serviceAppointmentScheduleList[scheduleIndex] + .customTimeDateSlotList![dateIndex] + .date! + .date, + slotId: serviceAppointmentScheduleList[scheduleIndex] + .customTimeDateSlotList![dateIndex] + .date! + .slotId, isSelected: true, slot: "", ); - serviceAppointmentScheduleList[scheduleIndex].selectedCustomTimeDateSlotModel = CustomTimeDateSlotModel(date: date); + serviceAppointmentScheduleList[scheduleIndex] + .selectedCustomTimeDateSlotModel = CustomTimeDateSlotModel(date: date); notifyListeners(); } - updateSelectedAppointmentSlotByDate({required int scheduleIndex, required int slotIndex}) { - for (var element in serviceAppointmentScheduleList[scheduleIndex].customTimeDateSlotList!) { + updateSelectedAppointmentSlotByDate( + {required int scheduleIndex, required int slotIndex}) { + for (var element in serviceAppointmentScheduleList[scheduleIndex] + .customTimeDateSlotList!) { for (var element in element.availableSlots!) { element.isSelected = false; } } - int index = serviceAppointmentScheduleList[scheduleIndex].selectedDateIndex!; - serviceAppointmentScheduleList[scheduleIndex].customTimeDateSlotList![index].availableSlots![slotIndex].isSelected = true; - serviceAppointmentScheduleList[scheduleIndex].selectedCustomTimeDateSlotModel!.availableSlots = serviceAppointmentScheduleList[scheduleIndex].customTimeDateSlotList![index].availableSlots!; + int index = + serviceAppointmentScheduleList[scheduleIndex].selectedDateIndex!; + serviceAppointmentScheduleList[scheduleIndex] + .customTimeDateSlotList![index] + .availableSlots![slotIndex] + .isSelected = true; + serviceAppointmentScheduleList[scheduleIndex] + .selectedCustomTimeDateSlotModel! + .availableSlots = + serviceAppointmentScheduleList[scheduleIndex] + .customTimeDateSlotList![index] + .availableSlots!; notifyListeners(); } @@ -314,7 +510,9 @@ class AppointmentsVM extends BaseVM { int selectedSubServicesCounter = 0; onItemUpdateOrSelected(int index, bool selected, int itemId) { - int serviceIndex = servicesInCurrentAppointment.indexWhere((element) => element.serviceId == currentServiceSelection!.serviceId!); + int serviceIndex = servicesInCurrentAppointment.indexWhere( + (element) => + element.serviceId == currentServiceSelection!.serviceId!); // print("servicesInCurrentAppointment: ${servicesInCurrentAppointment.length}"); // if (serviceIndex == -1) { // return; @@ -329,19 +527,28 @@ class AppointmentsVM extends BaseVM { allSelectedItemsInAppointments.add(serviceItemsFromApi[index]); for (var element in allSelectedItemsInAppointments) { if (!ifItemAlreadySelected(element.id!)) { - servicesInCurrentAppointment[serviceIndex].serviceItems!.add(serviceItemsFromApi[index]); + servicesInCurrentAppointment[serviceIndex] + .serviceItems! + .add(serviceItemsFromApi[index]); servicesInCurrentAppointment[serviceIndex].currentTotalServicePrice = - servicesInCurrentAppointment[serviceIndex].currentTotalServicePrice + double.parse((serviceItemsFromApi[index].price) ?? "0.0"); + servicesInCurrentAppointment[serviceIndex] + .currentTotalServicePrice + + double.parse((serviceItemsFromApi[index].price) ?? "0.0"); } } } if (!selected) { selectedSubServicesCounter = selectedSubServicesCounter - 1; - currentServiceSelection!.serviceItems!.removeWhere((element) => element.id == itemId); - allSelectedItemsInAppointments.removeWhere((element) => element.id == itemId); + currentServiceSelection!.serviceItems! + .removeWhere((element) => element.id == itemId); + 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); + servicesInCurrentAppointment[serviceIndex].currentTotalServicePrice - + double.parse((serviceItemsFromApi[index].price) ?? "0.0"); + servicesInCurrentAppointment[serviceIndex] + .serviceItems! + .removeWhere((element) => element.id == itemId); } notifyListeners(); } @@ -397,7 +604,8 @@ class AppointmentsVM extends BaseVM { String pickHomeLocationError = ""; String selectSubServicesError = ""; - SelectionModel branchSelectedServiceId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); + SelectionModel branchSelectedServiceId = + SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); bool isCategoryAlreadyPresent(int id) { final contain = branchCategories.where((element) => element.id == id); @@ -410,14 +618,16 @@ class AppointmentsVM extends BaseVM { void getBranchCategories() async { for (var value in selectedBranchModel!.branchServices!) { if (!isCategoryAlreadyPresent(value.categoryId!)) { - branchCategories.add(DropValue(value.categoryId!, value.categoryName!, "")); + branchCategories + .add(DropValue(value.categoryId!, value.categoryName!, "")); } } notifyListeners(); } getBranchServices({required int categoryId}) async { - branchSelectedServiceId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); + branchSelectedServiceId = + SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); isHomeTapped = false; pickedHomeLocation = ""; pickHomeLocationError = ""; @@ -430,7 +640,9 @@ class AppointmentsVM extends BaseVM { } List getFilteredBranchServices({required int categoryId}) { - List filteredServices = selectedBranchModel!.branchServices!.where((element) => element.categoryId == categoryId).toList(); + List filteredServices = selectedBranchModel!.branchServices! + .where((element) => element.categoryId == categoryId) + .toList(); return filteredServices; } @@ -472,7 +684,8 @@ class AppointmentsVM extends BaseVM { return totalPrice.toString(); } - void openTheAddServiceBottomSheet(BuildContext context, AppointmentsVM appointmentsVM) { + void openTheAddServiceBottomSheet(BuildContext context, + AppointmentsVM appointmentsVM) { showModalBottomSheet( context: context, isScrollControlled: true, @@ -483,7 +696,8 @@ class AppointmentsVM extends BaseVM { ); } - void priceBreakDownClicked(BuildContext context, ServiceModel selectedService) { + void priceBreakDownClicked(BuildContext context, + ServiceModel selectedService) { showModalBottomSheet( context: context, isScrollControlled: true, @@ -499,19 +713,27 @@ class AppointmentsVM extends BaseVM { Column( children: List.generate( selectedService.serviceItems!.length, - (index) => Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - "${selectedService.serviceItems![index].name}".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), - "${selectedService.serviceItems![index].price} SAR".toText(fontSize: 12, isBold: true), - ], - ), + (index) => + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + "${selectedService.serviceItems![index].name}" + .toText( + fontSize: 12, + color: MyColors.lightTextColor, + isBold: true), + "${selectedService.serviceItems![index] + .price} SAR" + .toText(fontSize: 12, isBold: true), + ], + ), ), ), Row( mainAxisAlignment: MainAxisAlignment.end, children: [ - "${selectedService.currentTotalServicePrice} SAR".toText(fontSize: 16, isBold: true), + "${selectedService.currentTotalServicePrice} SAR" + .toText(fontSize: 16, isBold: true), ], ), if (selectedService.isHomeSelected) ...[ @@ -520,15 +742,20 @@ class AppointmentsVM extends BaseVM { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - "${totalKms}km ".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), - "${selectedService.rangePricePerKm} x $totalKms".toText(fontSize: 12, isBold: true), + "${totalKms}km ".toText( + fontSize: 12, + color: MyColors.lightTextColor, + isBold: true), + "${selectedService.rangePricePerKm} x $totalKms" + .toText(fontSize: 12, isBold: true), ], ), 8.height, Row( mainAxisAlignment: MainAxisAlignment.end, children: [ - "${selectedService.rangePricePerKm ?? 0 * totalKms} SAR".toText(fontSize: 16, isBold: true), + "${selectedService.rangePricePerKm ?? 0 * totalKms} SAR" + .toText(fontSize: 16, isBold: true), ], ), ], @@ -541,11 +768,18 @@ class AppointmentsVM extends BaseVM { crossAxisAlignment: CrossAxisAlignment.end, children: [ (selectedService.isHomeSelected - ? "${(selectedService.currentTotalServicePrice) + (double.parse((selectedService.rangePricePerKm ?? "0.0")) * totalKms)}" - : "${selectedService.currentTotalServicePrice}") + ? "${(selectedService.currentTotalServicePrice) + + (double.parse((selectedService.rangePricePerKm ?? + "0.0")) * totalKms)}" + : "${selectedService.currentTotalServicePrice}") .toText(fontSize: 29, isBold: true), 2.width, - "SAR".toText(color: MyColors.lightTextColor, fontSize: 16, isBold: true).paddingOnly(bottom: 5), + "SAR" + .toText( + color: MyColors.lightTextColor, + fontSize: 16, + isBold: true) + .paddingOnly(bottom: 5), ], ) ], @@ -565,7 +799,8 @@ class AppointmentsVM extends BaseVM { isValidated = false; break; } - if (schedule.selectedCustomTimeDateSlotModel!.date == null || !schedule.selectedCustomTimeDateSlotModel!.date!.isSelected) { + if (schedule.selectedCustomTimeDateSlotModel!.date == null || + !schedule.selectedCustomTimeDateSlotModel!.date!.isSelected) { isValidated = false; break; } else { @@ -573,7 +808,9 @@ class AppointmentsVM extends BaseVM { isValidated = false; break; } else { - TimeSlotModel slot = schedule.selectedCustomTimeDateSlotModel!.availableSlots!.firstWhere((element) => element.isSelected); + TimeSlotModel slot = schedule + .selectedCustomTimeDateSlotModel!.availableSlots! + .firstWhere((element) => element.isSelected); if (slot.date.isNotEmpty) { isValidated = true; break; @@ -582,7 +819,8 @@ class AppointmentsVM extends BaseVM { } } if (!isValidated) { - Utils.showToast("You must select appointment time for each schedule's appointment."); + Utils.showToast( + "You must select appointment time for each schedule's appointment."); return; } navigateWithName(context, AppRoutes.reviewAppointmentView); @@ -601,30 +839,36 @@ class AppointmentsVM extends BaseVM { } } - serviceAppointmentScheduleList = await scheduleRepo.mergeServiceIntoAvailableSchedules( + serviceAppointmentScheduleList = + await scheduleRepo.mergeServiceIntoAvailableSchedules( serviceItemIdsForHome: serviceItemIdsForHome, serviceItemIdsForWorkshop: serviceItemIdsForWorkshop, ); if (serviceAppointmentScheduleList.isEmpty) { Utils.hideLoading(context); - Utils.showToast("There are no available appointments for selected Items."); + Utils.showToast( + "There are no available appointments for selected Items."); return; } totalAmount = 0.0; amountToPayForAppointment = 0.0; for (var schedule in serviceAppointmentScheduleList) { - amountToPayForAppointment = amountToPayForAppointment + (schedule.amountToPay ?? 0.0); + amountToPayForAppointment = + amountToPayForAppointment + (schedule.amountToPay ?? 0.0); totalAmount = totalAmount + (schedule.amountTotal ?? 0.0); } Utils.hideLoading(context); - navigateWithName(context, AppRoutes.bookAppointmenSchedulesView, arguments: ScreenArgumentsForAppointmentDetailPage(routeFlag: 1, appointmentId: 0)); // 1 For Creating an Appointment + navigateWithName(context, AppRoutes.bookAppointmenSchedulesView, + arguments: ScreenArgumentsForAppointmentDetailPage( + routeFlag: 1, appointmentId: 0)); // 1 For Creating an Appointment notifyListeners(); } - Future onRescheduleAppointmentPressed({required BuildContext context, required AppointmentListModel appointmentListModel}) async { + Future onRescheduleAppointmentPressed({required BuildContext context, + required AppointmentListModel appointmentListModel}) async { Utils.showLoading(context); List serviceItemIdsForHome = []; @@ -641,14 +885,16 @@ class AppointmentsVM extends BaseVM { } } - serviceAppointmentScheduleList = await scheduleRepo.mergeServiceIntoAvailableSchedules( + serviceAppointmentScheduleList = + await scheduleRepo.mergeServiceIntoAvailableSchedules( serviceItemIdsForHome: serviceItemIdsForHome, serviceItemIdsForWorkshop: serviceItemIdsForWorkshop, ); if (serviceAppointmentScheduleList.isEmpty) { Utils.hideLoading(context); - Utils.showToast("There are no available appointments for selected Items."); + Utils.showToast( + "There are no available appointments for selected Items."); return; } Utils.hideLoading(context); @@ -656,29 +902,36 @@ class AppointmentsVM extends BaseVM { navigateWithName( context, AppRoutes.bookAppointmenSchedulesView, - arguments: ScreenArgumentsForAppointmentDetailPage(routeFlag: 2, appointmentId: appointmentListModel.id ?? 0), + arguments: ScreenArgumentsForAppointmentDetailPage( + routeFlag: 2, appointmentId: appointmentListModel.id ?? 0), ); // 2 For Rescheduling an Appointment notifyListeners(); } - Future onRescheduleAppointmentConfirmPressed({required BuildContext context, required int appointmentId, required int selectedSlotId}) async { + Future onRescheduleAppointmentConfirmPressed( + {required BuildContext context, + required int appointmentId, + required int selectedSlotId}) async { Utils.showLoading(context); try { - GenericRespModel genericRespModel = await scheduleRepo.cancelOrRescheduleServiceAppointment( + GenericRespModel genericRespModel = + await scheduleRepo.cancelOrRescheduleServiceAppointment( serviceAppointmentID: appointmentId, serviceSlotID: selectedSlotId, appointmentScheduleAction: 1, // 1 for Reschedule and 2 for Cancel ); - if (genericRespModel.messageStatus == 2 || genericRespModel.data == null) { + if (genericRespModel.messageStatus == 2 || + genericRespModel.data == null) { Utils.hideLoading(context); Utils.showToast("${genericRespModel.message.toString()}"); return; } if (genericRespModel.data == 1) { context.read().onNavbarTapped(1); - applyFilterOnAppointmentsVM(appointmentStatusEnum: AppointmentStatusEnum.cancelled); + applyFilterOnAppointmentsVM( + appointmentStatusEnum: AppointmentStatusEnum.cancelled); Utils.showToast("${genericRespModel.message.toString()}"); getMyAppointments(); Utils.hideLoading(context); diff --git a/lib/views/appointments/appointment_detail_view.dart b/lib/views/appointments/appointment_detail_view.dart index 6cf7f54..1d5f297 100644 --- a/lib/views/appointments/appointment_detail_view.dart +++ b/lib/views/appointments/appointment_detail_view.dart @@ -17,9 +17,14 @@ import 'package:provider/provider.dart'; class AppointmentDetailView extends StatelessWidget { final AppointmentListModel appointmentListModel; - AppointmentDetailView({Key? key, required this.appointmentListModel}) : super(key: key); + AppointmentDetailView({Key? key, required this.appointmentListModel}) + : super(key: key); - Widget getBaseActionButtonWidget({required Color color, required String text, Color textColor = MyColors.white, required Function() onPressed}) { + Widget getBaseActionButtonWidget( + {required Color color, + required String text, + Color textColor = MyColors.white, + required Function() onPressed}) { return Expanded( child: ShowFillButton( maxHeight: 55, @@ -32,19 +37,26 @@ class AppointmentDetailView extends StatelessWidget { ); } - Widget buildBottomActionButton({required AppointmentStatusEnum appointmentStatusEnum, required BuildContext context}) { + Widget buildBottomActionButton( + {required AppointmentStatusEnum appointmentStatusEnum, + required BuildContext context}) { switch (appointmentStatusEnum) { case AppointmentStatusEnum.booked: return Align( alignment: Alignment.bottomCenter, child: Row( children: [ - getBaseActionButtonWidget(color: MyColors.redColor, onPressed: () => appointmentCancelConfirmationSheet(context), text: "Cancel"), + getBaseActionButtonWidget( + color: MyColors.redColor, + onPressed: () => appointmentCancelConfirmationSheet(context), + text: "Cancel"), 12.width, getBaseActionButtonWidget( color: MyColors.greenColor, onPressed: () { - context.read().onConfirmAppointmentPressed(context: context, appointmentId: appointmentListModel.id); + context.read().onConfirmAppointmentPressed( + context: context, + appointmentId: appointmentListModel.id); }, text: "Confirm"), ], @@ -55,7 +67,10 @@ class AppointmentDetailView extends StatelessWidget { alignment: Alignment.bottomCenter, child: Row( children: [ - getBaseActionButtonWidget(color: MyColors.redColor, onPressed: () => appointmentCancelConfirmationSheet(context), text: "Cancel"), + getBaseActionButtonWidget( + color: MyColors.redColor, + onPressed: () => appointmentCancelConfirmationSheet(context), + text: "Cancel"), ], ), ); @@ -64,7 +79,11 @@ class AppointmentDetailView extends StatelessWidget { alignment: Alignment.bottomCenter, child: Row( children: [ - getBaseActionButtonWidget(color: MyColors.grey98Color.withOpacity(0.3), textColor: MyColors.lightTextColor, onPressed: () {}, text: "In Progress"), + getBaseActionButtonWidget( + color: MyColors.grey98Color.withOpacity(0.3), + textColor: MyColors.lightTextColor, + onPressed: () {}, + text: "In Progress"), ], ), ); @@ -73,7 +92,11 @@ class AppointmentDetailView extends StatelessWidget { alignment: Alignment.bottomCenter, child: Row( children: [ - getBaseActionButtonWidget(color: MyColors.grey98Color.withOpacity(0.3), textColor: MyColors.lightTextColor, onPressed: () {}, text: "Cancelled"), + getBaseActionButtonWidget( + color: MyColors.grey98Color.withOpacity(0.3), + textColor: MyColors.lightTextColor, + onPressed: () {}, + text: "Cancelled"), ], ), ); @@ -84,17 +107,24 @@ class AppointmentDetailView extends StatelessWidget { alignment: Alignment.bottomCenter, child: Row( children: [ - getBaseActionButtonWidget(color: MyColors.redColor, onPressed: () => appointmentCancelConfirmationSheet(context), text: "Cancel"), + getBaseActionButtonWidget( + color: MyColors.redColor, + onPressed: () => appointmentCancelConfirmationSheet(context), + text: "Cancel"), 12.width, getBaseActionButtonWidget( color: MyColors.greenColor, onPressed: () { - context.read().onConfirmAppointmentPressed(context: context, appointmentId: appointmentListModel.id); + context.read().onConfirmAppointmentPressed( + context: context, + appointmentId: appointmentListModel.id); }, text: "Confirm"), ], ), ); + default: + return SizedBox(); } } @@ -102,8 +132,10 @@ class AppointmentDetailView extends StatelessWidget { final appointmentsVm = context.read(); return actionConfirmationBottomSheet( context: context, - title: "Do you want to cancel this appointment?".toText(fontSize: 28, isBold: true, letterSpacing: -1.44), - subtitle: "Your appointment will be cancelled and you cannot undo this action.", + title: "Do you want to cancel this appointment?" + .toText(fontSize: 28, isBold: true, letterSpacing: -1.44), + subtitle: + "Your appointment will be cancelled and you cannot undo this action.", actionButtonYes: Expanded( child: ShowFillButton( maxHeight: 55, @@ -111,7 +143,8 @@ class AppointmentDetailView extends StatelessWidget { fontSize: 15, onPressed: () { Navigator.pop(context); - appointmentsVm.onCancelAppointmentPressed(context: context, appointmentListModel: appointmentListModel); + appointmentsVm.onCancelAppointmentPressed( + context: context, appointmentListModel: appointmentListModel); }, ), ), @@ -149,7 +182,8 @@ class AppointmentDetailView extends StatelessWidget { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - appointmentListModel.providerName!.toText(fontSize: 16, isBold: true), + appointmentListModel.providerName! + .toText(fontSize: 16, isBold: true), Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ @@ -159,14 +193,23 @@ class AppointmentDetailView extends StatelessWidget { fit: BoxFit.fill, ), 5.width, - "${appointmentListModel.duration ?? ""} ${appointmentListModel.appointmentDate!.toFormattedDateWithoutTime()}".toText(fontSize: 12, isBold: true, color: MyColors.lightTextColor), + "${appointmentListModel.duration ?? ""} ${appointmentListModel.appointmentDate!.toFormattedDateWithoutTime()}" + .toText( + fontSize: 12, + isBold: true, + color: MyColors.lightTextColor), ], ), 13.height, - if (appointmentListModel.appointmentServicesList != null && appointmentListModel.appointmentServicesList!.isNotEmpty) ...[ + if (appointmentListModel.appointmentServicesList != null && + appointmentListModel + .appointmentServicesList!.isNotEmpty) ...[ Column( - children: List.generate(appointmentListModel.appointmentServicesList!.length, (index) { - ServiceModel service = appointmentListModel.appointmentServicesList![index]; + children: List.generate( + appointmentListModel.appointmentServicesList!.length, + (index) { + ServiceModel service = + appointmentListModel.appointmentServicesList![index]; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -178,14 +221,18 @@ class AppointmentDetailView extends StatelessWidget { // fit: BoxFit.fill, // ), // 10.width, - "${index + 1}. ${service.providerServiceDescription}".toText(fontSize: 14, isBold: true), + "${index + 1}. ${service.providerServiceDescription}" + .toText(fontSize: 14, isBold: true), ], ), - if (service.serviceItems != null && service.serviceItems!.isNotEmpty) ...[ + if (service.serviceItems != null && + service.serviceItems!.isNotEmpty) ...[ Column( children: List.generate( service.serviceItems!.length, - (index) => "${service.serviceItems![index].name}".toText( + (index) => + "${service.serviceItems![index].name}" + .toText( textAlign: TextAlign.start, fontSize: 12, color: MyColors.lightTextColor, @@ -197,15 +244,22 @@ class AppointmentDetailView extends StatelessWidget { Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ - ((service.currentTotalServicePrice).toString()).toText(fontSize: 25, isBold: true), + ((service.currentTotalServicePrice).toString()) + .toText(fontSize: 25, isBold: true), 2.width, - "SAR".toText(color: MyColors.lightTextColor, fontSize: 16, isBold: true).paddingOnly(bottom: 5), + "SAR" + .toText( + color: MyColors.lightTextColor, + fontSize: 16, + isBold: true) + .paddingOnly(bottom: 5), Icon( Icons.arrow_drop_down, size: 30, ) ], - ).onPress(() => appointmentsVM.priceBreakDownClicked(context, service)), + ).onPress(() => appointmentsVM.priceBreakDownClicked( + context, service)), ], ); }), @@ -217,16 +271,25 @@ class AppointmentDetailView extends StatelessWidget { CardButtonWithIcon( title: "Reschedule Appointment", onCardTapped: () { - context.read().onRescheduleAppointmentPressed(context: context, appointmentListModel: appointmentListModel); + context + .read() + .onRescheduleAppointmentPressed( + context: context, + appointmentListModel: appointmentListModel); }, icon: MyAssets.scheduleAppointmentIcon.buildSvg(), ), - if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.booked) ...[ + if (appointmentListModel.appointmentStatusEnum == + AppointmentStatusEnum.booked) ...[ 10.width, CardButtonWithIcon( title: "Pay for Appointment", onCardTapped: () { - context.read().onConfirmAppointmentPressed(context: context, appointmentId: appointmentListModel.id); + context + .read() + .onConfirmAppointmentPressed( + context: context, + appointmentId: appointmentListModel.id); }, icon: MyAssets.creditCardIcon.buildSvg(), ), @@ -236,7 +299,10 @@ class AppointmentDetailView extends StatelessWidget { 15.height, ], ).toWhiteContainer(width: double.infinity, allPading: 12), - buildBottomActionButton(appointmentStatusEnum: appointmentListModel.appointmentStatusEnum!, context: context), + buildBottomActionButton( + appointmentStatusEnum: + appointmentListModel.appointmentStatusEnum!, + context: context), ], ), ), diff --git a/lib/widgets/bottom_sheet.dart b/lib/widgets/bottom_sheet.dart index cd920ad..6016334 100644 --- a/lib/widgets/bottom_sheet.dart +++ b/lib/widgets/bottom_sheet.dart @@ -12,8 +12,8 @@ void showMyBottomSheet(BuildContext context, {bool isDismissible = true, require decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( - topRight: Radius.circular(25), - topLeft: Radius.circular(25), + topRight: Radius.circular(0), + topLeft: Radius.circular(0), ), ), clipBehavior: Clip.antiAlias, diff --git a/lib/widgets/common_widgets/categories_list.dart b/lib/widgets/common_widgets/categories_list.dart index 051d3be..94888ca 100644 --- a/lib/widgets/common_widgets/categories_list.dart +++ b/lib/widgets/common_widgets/categories_list.dart @@ -7,8 +7,15 @@ class FiltersList extends StatelessWidget { final List filterList; final Function(int, int) onFilterTapped; final bool needLeftPadding; + EdgeInsets? padding; - const FiltersList({Key? key, required this.filterList, this.needLeftPadding = true, required this.onFilterTapped}) : super(key: key); + FiltersList({ + Key? key, + this.padding, + required this.filterList, + this.needLeftPadding = true, + required this.onFilterTapped, + }) : super(key: key); @override Widget build(BuildContext context) { @@ -16,7 +23,7 @@ class FiltersList extends StatelessWidget { height: 37, width: double.infinity, child: ListView.builder( - padding: EdgeInsets.only(left: needLeftPadding ? 12 : 0), + padding: padding ?? EdgeInsets.only(left: needLeftPadding ? 12 : 0), itemCount: filterList.length, scrollDirection: Axis.horizontal, itemBuilder: (BuildContext context, int index) { @@ -29,15 +36,20 @@ class FiltersList extends StatelessWidget { padding: const EdgeInsets.symmetric(horizontal: 8), margin: const EdgeInsets.symmetric(horizontal: 4), decoration: BoxDecoration( - color: filterList[index].isSelected ? MyColors.darkIconColor : null, + color: filterList[index].isSelected + ? MyColors.darkIconColor + : null, border: Border.all( - color: filterList[index].isSelected ? MyColors.darkIconColor : MyColors.primaryColor, + color: filterList[index].isSelected + ? MyColors.darkIconColor + : MyColors.primaryColor, width: 2, ), ), child: filterList[index].title.toText( fontSize: 12, - color: filterList[index].isSelected ? MyColors.white : null, + color: + filterList[index].isSelected ? MyColors.white : null, ), ), ); diff --git a/pubspec.lock b/pubspec.lock index 5aad031..96e49ba 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -93,10 +93,10 @@ packages: dependency: transitive description: name: collection - sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.1" + version: "1.18.0" country_code_picker: dependency: "direct main" description: @@ -513,10 +513,10 @@ packages: dependency: "direct main" description: name: intl - sha256: a3715e3bc90294e971cb7dc063fbf3cd9ee0ebf8604ffeafabd9e6f16abbdbe6 + sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" url: "https://pub.dev" source: hosted - version: "0.18.0" + version: "0.18.1" js: dependency: transitive description: @@ -601,26 +601,26 @@ packages: dependency: transitive description: name: matcher - sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" + sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" url: "https://pub.dev" source: hosted - version: "0.12.15" + version: "0.12.16" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.5.0" meta: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" mime: dependency: transitive description: @@ -717,6 +717,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.7" + percent_indicator: + dependency: "direct main" + description: + name: percent_indicator + sha256: c37099ad833a883c9d71782321cb65c3a848c21b6939b6185f0ff6640d05814c + url: "https://pub.dev" + source: hosted + version: "4.2.3" permission_handler: dependency: "direct main" description: @@ -902,10 +910,10 @@ packages: dependency: transitive description: name: source_span - sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" sqflite: dependency: transitive description: @@ -934,18 +942,18 @@ packages: dependency: transitive description: name: stack_trace - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.11.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" stream_transform: dependency: transitive description: @@ -990,10 +998,10 @@ packages: dependency: transitive description: name: test_api - sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb + sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" url: "https://pub.dev" source: hosted - version: "0.5.1" + version: "0.6.1" tuple: dependency: transitive description: @@ -1098,6 +1106,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + web: + dependency: transitive + description: + name: web + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 + url: "https://pub.dev" + source: hosted + version: "0.3.0" web_socket_channel: dependency: transitive description: @@ -1131,5 +1147,5 @@ packages: source: hosted version: "6.3.0" sdks: - dart: ">=3.0.0 <4.0.0" + dart: ">=3.2.0-194.0.dev <4.0.0" flutter: ">=3.10.0" diff --git a/pubspec.yaml b/pubspec.yaml index f7f6455..f042568 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -41,6 +41,7 @@ dependencies: intl: any signalr_core: ^1.1.1 logging: ^1.2.0 + percent_indicator: ^4.2.3 # google