diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 17041ca..51434df 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -742,5 +742,9 @@ "paymentType": "نوع الدفع", "searchByCreatedDate": "البحث حسب تاريخ الإنشاء", "dealCompleted": "تم إتمام الصفقة", - "theDealNotCompleted": "لم تكتمل الصفقة" + "theDealNotCompleted": "لم تكتمل الصفقة", + "cancelRequest": "أريد إلغاء الطلب.", + "highPrice": "سعر مرتفع", + "offerNotMatched": "العرض لم يتطابق مع الطلب.", + "offerRejected": "تم رفض العرض." } \ No newline at end of file diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 12adf0c..3e7d6d4 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -740,5 +740,10 @@ "paymentType": "Payment Type", "searchByCreatedDate": "Search By Created Date", "dealCompleted": "The Deal Completed", - "theDealNotCompleted": "The Deal Not Completed" + "theDealNotCompleted": "The Deal Not Completed", + "cancelRequest": "I want to cancel the request.", + "highPrice": "High Price", + "offerNotMatched": "The offer did not match the request.", + "offerRejected": "Offer has been Rejected." + } \ No newline at end of file diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index d98bfba..b3152cc 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -758,7 +758,11 @@ class CodegenLoader extends AssetLoader{ "paymentType": "نوع الدفع", "searchByCreatedDate": "البحث حسب تاريخ الإنشاء", "dealCompleted": "تم إتمام الصفقة", - "theDealNotCompleted": "لم تكتمل الصفقة" + "theDealNotCompleted": "لم تكتمل الصفقة", + "cancelRequest": "أريد إلغاء الطلب.", + "highPrice": "سعر مرتفع", + "offerNotMatched": "العرض لم يتطابق مع الطلب.", + "offerRejected": "تم رفض العرض." }; static const Map en_US = { "firstTimeLogIn": "First Time Log In", @@ -1502,7 +1506,11 @@ static const Map en_US = { "paymentType": "Payment Type", "searchByCreatedDate": "Search By Created Date", "dealCompleted": "The Deal Completed", - "theDealNotCompleted": "The Deal Not Completed" + "theDealNotCompleted": "The Deal Not Completed", + "cancelRequest": "I want to cancel the request.", + "highPrice": "High Price", + "offerNotMatched": "The offer did not match the request.", + "offerRejected": "Offer has been Rejected." }; static const Map> mapLocales = {"ar_SA": ar_SA, "en_US": en_US}; } diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index b866df3..0813115 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -722,5 +722,9 @@ abstract class LocaleKeys { static const searchByCreatedDate = 'searchByCreatedDate'; static const dealCompleted = 'dealCompleted'; static const theDealNotCompleted = 'theDealNotCompleted'; + static const cancelRequest = 'cancelRequest'; + static const highPrice = 'highPrice'; + static const offerNotMatched = 'offerNotMatched'; + static const offerRejected = 'offerRejected'; } diff --git a/lib/view_models/chat_view_model.dart b/lib/view_models/chat_view_model.dart index f7631b6..0a9495d 100644 --- a/lib/view_models/chat_view_model.dart +++ b/lib/view_models/chat_view_model.dart @@ -4,6 +4,7 @@ import 'dart:convert'; import 'dart:developer'; import 'dart:io'; +import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/cupertino.dart'; import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/classes/consts.dart'; @@ -23,7 +24,6 @@ import 'package:mc_common_app/view_models/base_view_model.dart'; import 'package:mc_common_app/view_models/requests_view_model.dart'; import 'package:provider/provider.dart'; import 'package:signalr_core/signalr_core.dart'; -import 'package:easy_localization/easy_localization.dart'; class ChatVM extends BaseVM { final ChatRepo chatRepo; @@ -94,11 +94,13 @@ class ChatVM extends BaseVM { element.isSelected = false; } dealOptionsModelList[index].isSelected = true; + notifyListeners(); } - List indexesForCancelSpecialCarOffer = [0, 1, 6, 7]; - List indexesForCancelSparePartOffer = [2, 7]; - List indexesForRejectOffer = [3, 4, 5, 7]; + List indexesForCancelSpecialCarOffer = [0, 1, 6, 10]; + List indexesForCancelSparePartOffer = [2, 10]; + List indexesForRejectOffer = [3, 4, 5, 10]; + List indexesForDealNotCompleted = [7, 4, 8, 9, 10]; List offerRejectModelList = [ OfferRequestCommentModel( @@ -139,6 +141,21 @@ class ChatVM extends BaseVM { OfferRequestCommentModel( index: 7, isSelected: false, + title: LocaleKeys.cancelRequest.tr(), + ), + OfferRequestCommentModel( + index: 8, + isSelected: false, + title: LocaleKeys.offerNotMatched.tr(), + ), + OfferRequestCommentModel( + index: 9, + isSelected: false, + title: LocaleKeys.testTheService.tr(), + ), + OfferRequestCommentModel( + index: 10, + isSelected: false, title: LocaleKeys.otherVar.tr(), ), ]; diff --git a/lib/view_models/requests_view_model.dart b/lib/view_models/requests_view_model.dart index d752a7e..8eb08ab 100644 --- a/lib/view_models/requests_view_model.dart +++ b/lib/view_models/requests_view_model.dart @@ -3,6 +3,7 @@ import 'dart:convert'; import 'dart:developer'; import 'dart:io'; + import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/cupertino.dart'; import 'package:mc_common_app/classes/app_state.dart'; diff --git a/lib/views/chat/chat_view.dart b/lib/views/chat/chat_view.dart index 2799868..97435cc 100644 --- a/lib/views/chat/chat_view.dart +++ b/lib/views/chat/chat_view.dart @@ -1,10 +1,6 @@ -import 'dart:developer'; - -import 'package:flutter/cupertino.dart'; +import 'package:easy_localization/easy_localization.dart' as lcl; import 'package:flutter/material.dart'; -import 'package:flutter/widgets.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/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; @@ -21,14 +17,11 @@ import 'package:mc_common_app/views/advertisement/components/picked_images_conta import 'package:mc_common_app/views/chat/widgets/chat_bottom_sheets.dart'; import 'package:mc_common_app/views/chat/widgets/chat_message_widget.dart'; import 'package:mc_common_app/views/requests/request_bottomsheets.dart'; -import 'package:mc_common_app/views/setting_options/widgets/custom_setting_options_tile.dart'; import 'package:mc_common_app/widgets/button/show_fill_button.dart'; import 'package:mc_common_app/widgets/common_widgets/app_bar.dart'; -import 'package:mc_common_app/widgets/common_widgets/info_bottom_sheet.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/txt_field.dart'; import 'package:provider/provider.dart'; -import 'package:easy_localization/easy_localization.dart' as lcl; class ChatView extends StatefulWidget { final ChatViewArguments chatViewArguments; diff --git a/lib/views/chat/widgets/chat_bottom_sheets.dart b/lib/views/chat/widgets/chat_bottom_sheets.dart index 2c9bc16..c89c2d1 100644 --- a/lib/views/chat/widgets/chat_bottom_sheets.dart +++ b/lib/views/chat/widgets/chat_bottom_sheets.dart @@ -9,7 +9,6 @@ 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'; import 'package:mc_common_app/utils/navigator.dart'; -import 'package:mc_common_app/view_models/base_view_model.dart'; import 'package:mc_common_app/view_models/chat_view_model.dart'; import 'package:mc_common_app/view_models/dashboard_view_model_customer.dart'; import 'package:mc_common_app/view_models/requests_view_model.dart'; @@ -53,7 +52,7 @@ void dealCompletedConfirmationBottomSheet({required BuildContext mainContext, re if (status) { chatVM.updateAcknowledgePaymentToMowaterStatus(false); mainContext.read().onNavbarTapped(4); - navigateReplaceWithName(mainContext, AppRoutes.dashboard); + navigateReplaceWithNameUntilRoute(mainContext, AppRoutes.dashboard); } }, ), diff --git a/lib/views/chat/widgets/chat_message_widget.dart b/lib/views/chat/widgets/chat_message_widget.dart index d9bd137..5f3ffa2 100644 --- a/lib/views/chat/widgets/chat_message_widget.dart +++ b/lib/views/chat/widgets/chat_message_widget.dart @@ -1,6 +1,5 @@ -import 'dart:developer'; - import 'package:cached_network_image/cached_network_image.dart'; +import 'package:easy_localization/easy_localization.dart' as lcl; import 'package:flutter/material.dart'; import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/classes/consts.dart'; @@ -18,6 +17,7 @@ import 'package:mc_common_app/utils/utils.dart'; import 'package:mc_common_app/view_models/ad_view_model.dart'; import 'package:mc_common_app/view_models/chat_view_model.dart'; import 'package:mc_common_app/view_models/requests_view_model.dart'; +import 'package:mc_common_app/views/chat/widgets/chat_bottom_sheets.dart'; import 'package:mc_common_app/views/requests/request_bottomsheets.dart'; import 'package:mc_common_app/widgets/button/show_fill_button.dart'; import 'package:mc_common_app/widgets/checkbox_with_title_desc.dart'; @@ -25,7 +25,6 @@ import 'package:mc_common_app/widgets/common_widgets/info_bottom_sheet.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/txt_field.dart'; import 'package:provider/provider.dart'; -import 'package:easy_localization/easy_localization.dart' as lcl; class ChatMessageCustomWidget extends StatefulWidget { final ChatMessageModel chatMessageModel; @@ -48,7 +47,7 @@ class ChatMessageCustomWidget extends StatefulWidget { } class _ChatMessageCustomWidgetState extends State { - Future buildDealBottomSheetForSpecialCar({required ChatMessageModel chatMessageModel, required RequestOfferStatusEnum requestOfferStatusEnum}) { + Future buildDealNotCompletedBottomSheetOptions({required ChatMessageModel chatMessageModel}) { return showModalBottomSheet( context: context, isScrollControlled: true, @@ -62,53 +61,57 @@ class _ChatMessageCustomWidgetState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - 12.height, - ListView( - children: [ - CheckBoxWithTitleDescription( - isSelected: chatVM.dealOptionsModelList[0].isSelected!, - title: '${chatVM.dealOptionsModelList[0].title}', - description: '', - onSelection: (bool value) { - chatVM.updateIsSelectedInDealOptionsModelList(0, value); - }, - ), - CheckBoxWithTitleDescription( - isSelected: chatVM.dealOptionsModelList[1].isSelected ?? false, - title: '${chatVM.dealOptionsModelList[1].title}', - description: '', - onSelection: (bool value) { - chatVM.updateIsSelectedInDealOptionsModelList(1, value); - }, - ), - ], - ), - if (chatVM.dealOptionsModelList[1].isSelected!) ...[ - 12.height, - TxtField( - maxLines: 5, - value: chatVM.rejectOfferDescription, - errorValue: chatVM.rejectOfferDescriptionError, - keyboardType: TextInputType.text, - hint: LocaleKeys.description.tr(), - onChanged: (v) => chatVM.updateRejectOfferDescription(v), - ), - ], - ], + 12.height, + ListView.separated( + shrinkWrap: true, + itemCount: chatVM.offerRejectModelList.length, + separatorBuilder: (BuildContext context, int index) { + bool indexContains = chatVM.indexesForDealNotCompleted.indexWhere((i) => i == index) != -1; + if ((!indexContains)) { + return const SizedBox(); + } + + return const Divider(thickness: 0.5); + }, + itemBuilder: (BuildContext context, int index) { + bool indexContains = chatVM.indexesForDealNotCompleted.indexWhere((i) => i == index) != -1; + + if (!indexContains) { + return const SizedBox(); + } + + OfferRequestCommentModel offerRequestCommentModel = chatVM.offerRejectModelList[index]; + return CircleCheckBoxWithTitle( + isChecked: offerRequestCommentModel.isSelected ?? false, + title: '${offerRequestCommentModel.title}', + onSelected: () { + chatVM.updateSelectionInOfferRejectModelList(index); + }, + selectedColor: MyColors.darkPrimaryColor, + ); + }, ), + if (chatVM.offerRejectModelList.last.isSelected ?? false) ...[ + // comparing if the "other" is selected + 12.height, + TxtField( + maxLines: 5, + value: chatVM.rejectOfferDescription, + errorValue: chatVM.rejectOfferDescriptionError, + keyboardType: TextInputType.text, + hint: LocaleKeys.description.tr(), + onChanged: (v) => chatVM.updateRejectOfferDescription(v), + ), + ], 25.height, ShowFillButton( title: LocaleKeys.submit.tr(), onPressed: () async { String comments = ""; - if (chatVM.selectedOfferRequestCommentModel.index == chatVM.offerRejectModelList.length - 1) //Other - { + if (chatVM.offerRejectModelList.last.isSelected ?? false) { comments = chatVM.rejectOfferDescription; } else { - comments = chatVM.selectedOfferRequestCommentModel.title ?? ""; + comments = chatVM.offerRejectModelList.firstWhere((element) => element.isSelected!).title ?? ""; } if (!chatVM.isRejectOfferButtonValidated()) { return; @@ -125,13 +128,13 @@ class _ChatMessageCustomWidgetState extends State { serviceItemName: chatMessageModel.reqOffer!.serviceItemName ?? "", manufacturedOn: chatMessageModel.reqOffer!.manufacturedOn ?? "", manufacturedById: chatMessageModel.reqOffer!.manufacturedById ?? 0, - requestOfferStatusEnum: requestOfferStatusEnum, + requestOfferStatusEnum: RequestOfferStatusEnum.rejected, context: context, ); if (status) { final requestVM = context.read(); - chatMessageModel.reqOffer!.requestOfferStatusEnum = requestOfferStatusEnum; + chatMessageModel.reqOffer!.requestOfferStatusEnum = RequestOfferStatusEnum.rejected; int index = chatVM.serviceProviderOffersList .indexWhere((element) => (element.providerId == requestVM.currentSelectedOffer!.providerId) && (element.requestId == requestVM.currentSelectedOffer!.requestId)); @@ -139,9 +142,8 @@ class _ChatMessageCustomWidgetState extends State { chatVM.serviceProviderOffersList[index].requestOfferStatusEnum = chatMessageModel.reqOffer!.requestOfferStatusEnum; } setState(() {}); - // Navigator.pop(context); chatVM.updateRejectOfferDescription(''); - Utils.showToast("Offer ${requestOfferStatusEnum == RequestOfferStatusEnum.rejected ? "Rejected" : "Cancelled"}"); + Utils.showToast(LocaleKeys.offerRejected.tr()); // navigateReplaceWithName(context, AppRoutes.dashboard); } }, @@ -156,6 +158,68 @@ class _ChatMessageCustomWidgetState extends State { ); } + Future buildDealBottomSheetOptionsForSpecialCar({required ChatMessageModel chatMessageModel, required RequestOfferStatusEnum requestOfferStatusEnum}) { + return showModalBottomSheet( + context: context, + isScrollControlled: true, + enableDrag: true, + builder: (BuildContext context) { + return Consumer(builder: (BuildContext context, ChatVM chatVM, Widget? child) { + return InfoBottomSheet( + title: LocaleKeys.pleaseSpecify.tr().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, + CheckBoxWithTitleDescription( + isSelected: chatVM.dealOptionsModelList[0].isSelected!, + title: '${chatVM.dealOptionsModelList[0].title}', + description: '', + onSelection: (bool value) { + chatVM.updateIsSelectedInDealOptionsModelList(0, value); + }, + ), + CheckBoxWithTitleDescription( + isSelected: chatVM.dealOptionsModelList[1].isSelected ?? false, + title: '${chatVM.dealOptionsModelList[1].title}', + description: '', + onSelection: (bool value) { + chatVM.updateIsSelectedInDealOptionsModelList(1, value); + }, + ), + ], + ), + 25.height, + ShowFillButton( + title: LocaleKeys.continu.tr(), + onPressed: () async { + if (chatVM.dealOptionsModelList[0].isSelected ?? false) { + final requestVM = context.read(); + return dealCompletedConfirmationBottomSheet( + mainContext: context, + requestStatusEnum: RequestStatusEnum.completed, + requestId: requestVM.currentSelectedRequest!.id, + ); + } else { + buildDealNotCompletedBottomSheetOptions(chatMessageModel: chatMessageModel); + } + }, + maxWidth: double.infinity, + ), + 19.height, + ], + ), + )); + }); + }, + ); + } + Future buildRejectOrCancelOfferBottomSheet({required ChatMessageModel chatMessageModel, required RequestOfferStatusEnum requestOfferStatusEnum}) { return showModalBottomSheet( context: context, @@ -434,7 +498,11 @@ class _ChatMessageCustomWidgetState extends State { borderColor: MyColors.greenColor, isFilled: false, onPressed: () { - offerAcceptConfirmationBottomSheet(chatMessageModel: chatMessageModel); + if (widget.requestsTypeEnum == RequestsTypeEnum.specialCarRequest) { + buildDealBottomSheetOptionsForSpecialCar(chatMessageModel: chatMessageModel, requestOfferStatusEnum: requestOfferStatusEnum); + } else { + offerAcceptConfirmationBottomSheet(chatMessageModel: chatMessageModel); + } }, backgroundColor: MyColors.white, txtColor: MyColors.greenColor, diff --git a/lib/widgets/checkbox_with_title_desc.dart b/lib/widgets/checkbox_with_title_desc.dart index 73a9a2a..595c461 100644 --- a/lib/widgets/checkbox_with_title_desc.dart +++ b/lib/widgets/checkbox_with_title_desc.dart @@ -21,31 +21,41 @@ class CheckBoxWithTitleDescription extends StatelessWidget { @override Widget build(BuildContext context) { - return SizedBox( - width: double.infinity, - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Checkbox( - value: isSelected, - activeColor: isDisabled ? MyColors.lightIconColor : MyColors.darkPrimaryColor, - onChanged: (bool? v) { - if (isDisabled) return; - onSelection(v ?? false); + return GestureDetector( + onTap: isDisabled + ? null + : () { + onSelection(!isSelected); }, - ), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - title.toText(fontSize: 14, isBold: true), - description.toText(fontSize: 12, color: MyColors.lightTextColor), - ], + child: SizedBox( + width: double.infinity, + child: Row( + crossAxisAlignment: description.isNotEmpty ? CrossAxisAlignment.start : CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Checkbox( + value: isSelected, + activeColor: isDisabled ? MyColors.lightIconColor : MyColors.darkPrimaryColor, + onChanged: isDisabled + ? null + : (bool? v) { + onSelection(v ?? false); + }, ), - ), - ], + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + title.toText(fontSize: 14, isBold: true), + if (description.isNotEmpty) ...[ + description.toText(fontSize: 12, color: MyColors.lightTextColor), + ] + ], + ), + ), + ], + ), ), ); }