From da9c03a30f1f48814dc616ad8eb29a9264bb1ee6 Mon Sep 17 00:00:00 2001 From: Faiz Hashmi Date: Wed, 16 Apr 2025 16:43:15 +0300 Subject: [PATCH] 16 April, 2025 --- assets/langs/ar-SA.json | 6 +- assets/langs/en-US.json | 5 +- lib/config/routes.dart | 3 + lib/extensions/string_extensions.dart | 4 +- lib/generated/codegen_loader.g.dart | 10 +- lib/generated/locale_keys.g.dart | 3 + lib/main.dart | 2 - .../advertisment_models/ad_details_model.dart | 4 +- lib/repositories/ads_repo.dart | 36 +-- lib/utils/enums.dart | 1 + lib/utils/utils.dart | 14 +- lib/view_models/ad_view_model.dart | 90 +++++-- lib/view_models/appointments_view_model.dart | 55 ++--- .../dashboard_view_model_provider.dart | 6 +- lib/view_models/requests_view_model.dart | 2 +- .../shipping_management_view_model.dart | 6 + .../components/ads_list_widget.dart | 220 ++++++++++-------- lib/views/advertisement/create_ad_view.dart | 24 ++ .../advertisement/my_draft_ads_view.dart | 68 ++++++ .../advertisement/select_ad_type_view.dart | 3 +- lib/views/common_fragments/ads_fragment.dart | 1 + lib/views/requests/create_request_page.dart | 4 +- .../setting_options/setting_options_more.dart | 13 ++ 23 files changed, 398 insertions(+), 182 deletions(-) create mode 100644 lib/views/advertisement/my_draft_ads_view.dart diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 7108750..63ab985 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -811,6 +811,8 @@ "selfPickup": "الالتقاط الذاتي", "updateYourLocationInfo": "قم بتحديث معلومات موقعك", "initiateSelfPickup": "بدء الاستلام الذاتي", - "selfPickupStatus": "حالة الالتقاط الذاتي" - + "selfPickupStatus": "حالة الالتقاط الذاتي", + "myDraftAds": "مسودتي للإعلانات", + "scheduleDeletedSuccessfully": "تم حذف الجدول بنجاح", + "addValidAddress": "رجى إضافة عنوان صالح" } \ No newline at end of file diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index dcaa43e..299d4c0 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -809,5 +809,8 @@ "selfPickup": "Self Pickup", "updateYourLocationInfo": "Update your location information", "initiateSelfPickup": "Initiate Self Pickup", - "selfPickupStatus": "Self Pickup Status" + "selfPickupStatus": "Self Pickup Status", + "myDraftAds": "My Draft Ads", + "scheduleDeletedSuccessfully": "The schedule has been deleted successfully", + "addValidAddress": "Please add a valid address" } \ No newline at end of file diff --git a/lib/config/routes.dart b/lib/config/routes.dart index 52d39bf..4fca131 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -9,6 +9,7 @@ import 'package:mc_common_app/views/advertisement/ads_buyer_chats_view.dart'; import 'package:mc_common_app/views/advertisement/ads_detail_view/ads_detail_view.dart'; import 'package:mc_common_app/views/advertisement/ads_filter_view.dart'; import 'package:mc_common_app/views/advertisement/create_ad_view.dart'; +import 'package:mc_common_app/views/advertisement/my_draft_ads_view.dart'; import 'package:mc_common_app/views/advertisement/select_ad_type_view.dart'; import 'package:mc_common_app/views/chat/chat_view.dart'; import 'package:mc_common_app/views/payments/payment_methods_view.dart'; @@ -130,6 +131,7 @@ class AppRoutes { static const String createAdView = "/createAdView"; static const String adsFilterView = "/adsFilterView"; static const String adsBuyerChatsListView = "/adsBuyersChatListView"; + static const String myDraftAdsView = "/myDraftAdsView"; // Payments static const String paymentMethodsView = "/paymentMethodsView"; @@ -208,6 +210,7 @@ class AppRoutes { AppRoutes.adsDetailView: (context) => AdsDetailView(adDetails: ModalRoute.of(context)!.settings.arguments as AdDetailsModel), AppRoutes.createAdView: (context) => const CreateAdView(), AppRoutes.adsFilterView: (context) => const AdsFilterView(), + AppRoutes.myDraftAdsView: (context) => const MyDraftAdsView(), AppRoutes.selectAdTypeView: (context) => SelectAdTypeView(arguments: ModalRoute.of(context)!.settings.arguments as List), AppRoutes.chatView: (context) => ChatView(chatViewArguments: ModalRoute.of(context)!.settings.arguments as ChatViewArguments), AppRoutes.adsBuyerChatsListView: (context) => AdsBuyerChatsView(buyersListViewArguments: ModalRoute.of(context)!.settings.arguments as List), diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index 4c44be0..ddfee55 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -1012,7 +1012,7 @@ extension SelfPickupStatusEnumExt on int { if (this == -1) { return SelfPickupRequestStatusEnum.allRequests; } else if (this == 0) { - return SelfPickupRequestStatusEnum.allRequests; + return SelfPickupRequestStatusEnum.pending; } else if (this == 1) { return SelfPickupRequestStatusEnum.preparingToCollect; } else if (this == 2) { @@ -1028,6 +1028,8 @@ extension SelfPickupStatusEnumToInt on SelfPickupRequestStatusEnum { int getIdFromSelfPickupStatusEnum() { switch (this) { case SelfPickupRequestStatusEnum.allRequests: + return -1; + case SelfPickupRequestStatusEnum.pending: return 0; case SelfPickupRequestStatusEnum.preparingToCollect: return 1; diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index ca62ea2..e0571b3 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -827,7 +827,10 @@ class CodegenLoader extends AssetLoader{ "selfPickup": "الالتقاط الذاتي", "updateYourLocationInfo": "قم بتحديث معلومات موقعك", "initiateSelfPickup": "بدء الاستلام الذاتي", - "selfPickupStatus": "حالة الالتقاط الذاتي" + "selfPickupStatus": "حالة الالتقاط الذاتي", + "myDraftAds": "مسودتي للإعلانات", + "scheduleDeletedSuccessfully": "تم حذف الجدول بنجاح", + "addValidAddress": "رجى إضافة عنوان صالح" }; static const Map en_US = { "firstTimeLogIn": "First Time Log In", @@ -1640,7 +1643,10 @@ static const Map en_US = { "selfPickup": "Self Pickup", "updateYourLocationInfo": "Update your location information", "initiateSelfPickup": "Initiate Self Pickup", - "selfPickupStatus": "Self Pickup Status" + "selfPickupStatus": "Self Pickup Status", + "myDraftAds": "My Draft Ads", + "scheduleDeletedSuccessfully": "The schedule has been deleted successfully", + "addValidAddress": "Please add a valid address" }; 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 809e464..cb1efef 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -791,5 +791,8 @@ abstract class LocaleKeys { static const updateYourLocationInfo = 'updateYourLocationInfo'; static const initiateSelfPickup = 'initiateSelfPickup'; static const selfPickupStatus = 'selfPickupStatus'; + static const myDraftAds = 'myDraftAds'; + static const scheduleDeletedSuccessfully = 'scheduleDeletedSuccessfully'; + static const addValidAddress = 'addValidAddress'; } diff --git a/lib/main.dart b/lib/main.dart index 85a9d62..235274f 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -2,7 +2,6 @@ import 'package:logger/logger.dart'; Logger logger = Logger(printer: PrettyPrinter(printEmojis: false, colors: true, printTime: false)); - bool disableThingsForQA = true; // Language Tile in Settings @@ -12,4 +11,3 @@ bool disableThingsForQA = true; // todo terminal command to genertate translation keys // flutter pub run easy_localization:generate --source-dir ./assets/langs -f keys -o locale_keys.g.dart // command to generate languages data from json - diff --git a/lib/models/advertisment_models/ad_details_model.dart b/lib/models/advertisment_models/ad_details_model.dart index 0fa5aa3..06a1cce 100644 --- a/lib/models/advertisment_models/ad_details_model.dart +++ b/lib/models/advertisment_models/ad_details_model.dart @@ -137,7 +137,7 @@ class AdDetailsModel { taxPrice = json['taxPrice']; totalPrice = json['totalPrice']; userID = json['userID']; - vehiclePostingID = json['vehiclePostingID']; + vehiclePostingID = (json['vehiclePostingID'] == null || json['vehiclePostingID'] == 0) ? json['id'] : 0; qrCodePath = json['qrCodePath']; isCustomerAcknowledged = json['isCustomerAcknowledged']; createdByRole = json['createdByRole']; @@ -156,7 +156,7 @@ class AdDetailsModel { adOwnerName = json['vehicle'] != null ? (json['vehicle']['adOwnerName'] ?? "") : ""; adOwnerEmail = json['vehicle'] != null ? (json['vehicle']['adOwnerEmail'] ?? "") : ""; adOwnerDetails = (json['vehicle'] != null && json['vehicle']['aDsUser'] != null) ? (AdOwnerDetails.fromJson(json['vehicle']['aDsUser'])) : null; - adPostStatus = (json['statusID'] as int).toAdPostEnum(); + adPostStatus = ((json['statusID'] ?? 1) as int).toAdPostEnum(); adReserveStatus = AdReserveStatus.defaultStatus; createdByRoleEnum = (json['createdByRole'] as int).toCreatedByRoleEnum(); isMyAd = isMyAds; diff --git a/lib/repositories/ads_repo.dart b/lib/repositories/ads_repo.dart index 5644312..cf55335 100644 --- a/lib/repositories/ads_repo.dart +++ b/lib/repositories/ads_repo.dart @@ -140,7 +140,7 @@ class AdsRepoImp implements AdsRepo { "imageName": element.imageName, "imageUrl": element.imageUrl, "imageStr": element.imageStr, - "vehiclePostingID": element.vehiclePostingID ?? 0, + "vehiclePostingID": isCreateNew ? 0 : element.vehiclePostingID ?? 0, "vehiclePosting": null, }; vehiclePostingImages.add(imageMap); @@ -157,14 +157,14 @@ class AdsRepoImp implements AdsRepo { "comment": element.comment, "vehicleImageBase64": element.vehicleImageBase64, "vehicleDamagePartID": element.vehicleDamagePartID, - "vehiclePostingID": element.vehiclePostingID ?? 0, + "vehiclePostingID": isCreateNew ? 0 : element.vehiclePostingID ?? 0, "isActive": true }; vehiclePostingDamageParts.add(imageMap); }); var postParams = { "ads": { - "id": adsCreationPayloadModel.ads!.id ?? 0, + "id": isCreateNew ? 0 : adsCreationPayloadModel.ads!.id ?? 0, "adsDurationID": adsCreationPayloadModel.ads!.adsDurationID, "startDate": adsCreationPayloadModel.ads!.startDate, "countryId": adsCreationPayloadModel.ads!.countryId, @@ -174,7 +174,7 @@ class AdsRepoImp implements AdsRepo { "isOnWhatsApp": adsCreationPayloadModel.ads!.isOnWhatsApp ?? false, }, "vehiclePosting": { - "id": adsCreationPayloadModel.vehiclePosting!.id ?? 0, + "id": isCreateNew ? 0 : adsCreationPayloadModel.vehiclePosting!.id ?? 0, "userID": adsCreationPayloadModel.vehiclePosting!.userID, "vehicleType": adsCreationPayloadModel.vehiclePosting!.vehicleType, "vehicleModelID": adsCreationPayloadModel.vehiclePosting!.vehicleModelID, @@ -224,21 +224,23 @@ class AdsRepoImp implements AdsRepo { List vehiclePostingImages = []; List vehiclePostingDamageParts = []; - if (stepNo == AdCreationStepsEnum.vehicleDetails) { - adsCreationPayloadModel.vehiclePosting!.vehiclePostingImages?.forEach((element) { - var imageMap = { - "id": element.id ?? 0, - "imageName": element.imageName, - "imageUrl": element.imageUrl, - "imageStr": element.imageStr, - "vehiclePostingDraftID": element.vehiclePostingID ?? 0, - "vehiclePosting": null, - }; - vehiclePostingImages.add(imageMap); - }); + if (adsCreationPayloadModel.vehiclePosting!.vehiclePostingImages != null) { + adsCreationPayloadModel.vehiclePosting!.vehiclePostingImages?.forEach( + (element) { + var imageMap = { + "id": element.id ?? 0, + "imageName": element.imageName, + "imageUrl": element.imageUrl, + "imageStr": element.imageStr, + "vehiclePostingDraftID": element.vehiclePostingID ?? 0, + "vehiclePosting": null, + }; + vehiclePostingImages.add(imageMap); + }, + ); } - if (stepNo == AdCreationStepsEnum.damageParts) { + if (adsCreationPayloadModel.vehiclePosting!.vehiclePostingDamageParts != null) { adsCreationPayloadModel.vehiclePosting!.vehiclePostingDamageParts?.forEach((element) { var imageMap = { "id": element.id ?? 0, diff --git a/lib/utils/enums.dart b/lib/utils/enums.dart index 84f1a64..6806c5a 100644 --- a/lib/utils/enums.dart +++ b/lib/utils/enums.dart @@ -240,6 +240,7 @@ enum ShippingRequestStatusEnum { enum SelfPickupRequestStatusEnum { allRequests, + pending, preparingToCollect, readyToCollect, collected, diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart index 062e875..a019572 100644 --- a/lib/utils/utils.dart +++ b/lib/utils/utils.dart @@ -339,6 +339,9 @@ class Utils { case SelfPickupRequestStatusEnum.allRequests: return "All Requests"; + case SelfPickupRequestStatusEnum.pending: + return "Pending"; + case SelfPickupRequestStatusEnum.preparingToCollect: return "Preparing To Collect"; @@ -377,6 +380,9 @@ class Utils { case SelfPickupRequestStatusEnum.allRequests: return MyColors.submittedColor; + case SelfPickupRequestStatusEnum.pending: + return MyColors.pendingColor; + case SelfPickupRequestStatusEnum.preparingToCollect: return MyColors.submittedColor; @@ -767,12 +773,12 @@ class NoInternetDialog { context: context, builder: (BuildContext context) { return AlertDialog( - title: const Text( - LocaleKeys.connectionProblem, + title: Text( + LocaleKeys.connectionProblem.tr(), textAlign: TextAlign.center, ), - content: const Text( - LocaleKeys.pleaseCheckConnection, + content: Text( + LocaleKeys.pleaseCheckConnection.tr(), textAlign: TextAlign.center, ), actions: [ diff --git a/lib/view_models/ad_view_model.dart b/lib/view_models/ad_view_model.dart index 84b4571..ef2d521 100644 --- a/lib/view_models/ad_view_model.dart +++ b/lib/view_models/ad_view_model.dart @@ -82,6 +82,7 @@ class AdVM extends BaseVM { // Edit Variables Amir bool isExtendAdEditEnabled = false; bool isAdEditEnabled = false; + bool isDraftEditEnabled = false; AdDetailsModel? previousAdDetails; List myDraftAds = []; @@ -347,15 +348,20 @@ class AdVM extends BaseVM { int pageIndexForMyDrafts = 1; Future getMyDraftAds() async { - pageIndexForMyAds = 1; - hasMoreDataForMyAds = true; - setState(ViewState.busy); - myDraftAds = await adsRepo.getMyDraftAds(); - notifyListeners(); - setState(ViewState.idle); + try { + pageIndexForMyAds = 1; + hasMoreDataForMyAds = true; + setState(ViewState.busy); + myDraftAds = await adsRepo.getMyDraftAds(); + notifyListeners(); + setState(ViewState.idle); + } catch (e) { + setState(ViewState.idle); + logger.e(e.toString()); + } } - Future fetchMoreDraftAds({required AdPostStatus adsStatus}) async { + Future fetchMoreDraftAds() async { if (isLoadingMore) return; hasMoreDataForMyDraftsAds = true; isLoadingMore = true; @@ -1214,6 +1220,8 @@ class AdVM extends BaseVM { void onBackButtonPressed(BuildContext context) { switch (currentProgressStep) { case AdCreationStepsEnum.vehicleDetails: + isAdEditEnabled = false; + isDraftEditEnabled = false; resetValues(); pop(context); break; @@ -1235,12 +1243,25 @@ class AdVM extends BaseVM { Future saveAdVehicleDetailsDraft({required bool isNew, required BuildContext context, required AdCreationStepsEnum stepNoEnum}) async { AppState appState = injector.get(); + log("selectionDurationStartDate: $selectionDurationStartDate"); + log("specialServiceCards: ${specialServiceCards.length}"); + + List adsSelectedServices = []; + + for (var value in specialServiceCards) { + adsSelectedServices.add(value.serviceSelectedId!.selectedId); + } + Utils.showLoading(context); try { Ads ads = Ads( id: !isNew ? previousAdDetails!.id : 0, adsDurationID: vehicleAdDurationId.selectedId == -1 ? 0 : vehicleAdDurationId.selectedId, + startDate: selectionDurationStartDate, countryId: vehicleCountryId.selectedId, + specialServiceIDs: adsSelectedServices, + showContactDetail: isPhoneNumberShown, + isOnWhatsApp: isNumberOnWhatsApp, ); List vehicleImages = []; @@ -1248,6 +1269,22 @@ class AdVM extends BaseVM { vehicleImages.add(await convertFileToVehiclePostingImages(imageModel: image)); } + List vehicleDamageImages = []; + + for (var card in vehicleDamageCards) { + if (card.partImages != null && card.partImages!.isNotEmpty) { + for (var image in card.partImages!) { + VehiclePostingDamageParts stringImage = await convertFileToVehiclePostingDamageParts( + imageModel: image, + damagePartId: card.partSelectedId!.selectedId, + commentParam: card.damagePartDescription ?? "", + ); + + vehicleDamageImages.add(stringImage); + } + } + } + VehiclePosting vehiclePosting = VehiclePosting( id: !isNew ? previousAdDetails!.vehiclePostingID : null, userID: appState.getUser.data!.userInfo!.userId, @@ -1270,6 +1307,9 @@ class AdVM extends BaseVM { warantyYears: int.parse(warrantyDuration), demandAmount: int.parse(vehicleDemandAmount), vehiclePostingImages: vehicleImages, + vehiclePostingDamageParts: vehicleDamageImages, + phoneNo: isPhoneNumberShown ? adPhoneNumberDialCode + adPhoneNumber : null, + whatsAppNo: (isPhoneNumberShown && isNumberOnWhatsApp) ? adPhoneNumberDialCode + adPhoneNumber : null, ); AdsCreationPayloadModel adsCreationPayloadModel = AdsCreationPayloadModel(ads: ads, vehiclePosting: vehiclePosting); @@ -1336,6 +1376,7 @@ class AdVM extends BaseVM { return; } isAdEditEnabled = false; + isDraftEditEnabled = false; isExtendAdEditEnabled = false; Utils.hideLoading(context); currentProgressStep = AdCreationStepsEnum.vehicleDetails; @@ -1693,7 +1734,11 @@ class AdVM extends BaseVM { log("selectionDurationStartDate: $selectionDurationStartDate"); Ads ads = Ads( - id: isAdEditEnabled ? previousAdDetails!.id : null, + id: isDraftEditEnabled + ? null + : isAdEditEnabled + ? previousAdDetails!.id + : null, adsDurationID: vehicleAdDurationId.selectedId == -1 ? 0 : vehicleAdDurationId.selectedId, startDate: selectionDurationStartDate, countryId: vehicleCountryId.selectedId, @@ -1751,7 +1796,11 @@ class AdVM extends BaseVM { AdsCreationPayloadModel adsCreationPayloadModel = AdsCreationPayloadModel(ads: ads, vehiclePosting: vehiclePosting); - GenericRespModel respModel = await adsRepo.createOrUpdateAd(adsCreationPayloadModel: adsCreationPayloadModel, isCreateNew: !isAdEditEnabled, isExtendAdEditEnabled: isExtendAdEditEnabled); + GenericRespModel respModel = await adsRepo.createOrUpdateAd( + adsCreationPayloadModel: adsCreationPayloadModel, + isCreateNew: isDraftEditEnabled ? true : !isAdEditEnabled, + isExtendAdEditEnabled: isExtendAdEditEnabled, + ); Utils.showToast(respModel.message.toString()); @@ -2289,13 +2338,16 @@ class AdVM extends BaseVM { return []; } - void onEditUpdateAdPressed({required BuildContext context, required AdDetailsModel previousDetails, required bool isFromExtendAd}) { + void onEditUpdateAdPressed({required BuildContext context, required AdDetailsModel previousDetails, required bool isFromExtendAd, bool isForDraft = false}) { isAdEditEnabled = true; + isDraftEditEnabled = true; isExtendAdEditEnabled = isFromExtendAd; previousAdDetails = previousDetails; autoFillSelectedVehicleType(); autoFillSelectedVehicleAdsDuration(); - + if (isForDraft) { + autoFillSelectedVehicleAdsDetails(); + } navigateWithName(context, AppRoutes.selectAdTypeView, arguments: [AppState().currentAppType == AppType.provider, isFromExtendAd, previousDetails.id]); } @@ -2324,12 +2376,14 @@ class AdVM extends BaseVM { void autoFillSelectedVehicleType() async { if (vehicleTypes.isEmpty) { await getVehicleTypes(); - return; + // return; } if (vehicleTypes.isNotEmpty) { for (var vehicle in vehicleTypes) { + vehicle.isSelected = false; if (vehicle.id == previousAdDetails!.vehicle?.vehicleType) { vehicle.isSelected = true; + log("Hi: ${vehicle.vehicleTypeName}"); break; } } @@ -2370,6 +2424,9 @@ class AdVM extends BaseVM { } void autoFillSelectedVehicleAdsDetails() async { + if (vehicleBrands.isEmpty) { + await getVehicleBrandsByVehicleTypeId(); + } int index = vehicleBrands.indexWhere((element) => element.id == previousAdDetails!.vehicle!.model!.vehicleBrandID); if (index != -1) { @@ -2403,6 +2460,7 @@ class AdVM extends BaseVM { for (var element in previousAdDetails!.vehicle!.image!) { if (element.imageUrl != null) { ImageModel imageModel = ImageModel(id: element.id, filePath: element.imageUrl, isFromNetwork: true); + log("running"); pickedPostingImages.add(imageModel); } } @@ -2444,12 +2502,16 @@ class AdVM extends BaseVM { address: "", serviceTime: "", ); - addNewSpecialServiceCard(specialServiceCard: specialServiceCard); + int index = ifSpecialServiceAlreadyThere(element.specialServiceID!); + log("Found at : $index"); + if (index == -1) { + addNewSpecialServiceCard(specialServiceCard: specialServiceCard); + } } } // selectionDurationStartDate = DateHelper.formatDateT(previousAdDetails!.startdate ?? ""); - selectionDurationStartDate = ""; + selectionDurationStartDate = ""; // You have to mention this each time isPhoneNumberShown = previousAdDetails!.showContactDetail ?? false; adPhoneNumber = previousAdDetails!.adOwnerDetails!.mobileNo ?? ""; diff --git a/lib/view_models/appointments_view_model.dart b/lib/view_models/appointments_view_model.dart index d194778..b67ca43 100644 --- a/lib/view_models/appointments_view_model.dart +++ b/lib/view_models/appointments_view_model.dart @@ -307,9 +307,7 @@ class AppointmentsVM extends BaseVM { } void removeServiceInCurrentAppointment(int index) { - int serviceId = servicesInCurrentAppointment - .elementAt(index) - .serviceProviderServiceId ?? -1; + int serviceId = servicesInCurrentAppointment.elementAt(index).serviceProviderServiceId ?? -1; allSelectedItemsInAppointments.removeWhere((element) => element.serviceProviderServiceId == serviceId); servicesInCurrentAppointment[index].serviceItems!.clear(); servicesInCurrentAppointment.removeAt(index); @@ -372,13 +370,15 @@ class AppointmentsVM extends BaseVM { if (shouldPopulateUpcoming) { myUpComingAppointments = myFilteredAppointmentsForProvider .where((element) => - (element.appointmentStatusEnum == AppointmentStatusEnum.booked || element.appointmentStatusEnum == AppointmentStatusEnum.confirmed) && - (DateHelper.parseStringToDate(element.appointmentDate!).isAfter(DateTime.now()))) + (element.appointmentStatusEnum == AppointmentStatusEnum.booked || element.appointmentStatusEnum == AppointmentStatusEnum.confirmed) && + (DateHelper.parseStringToDate(element.appointmentDate!).isAfter(DateTime.now()))) .toList(); log("myUpComingAppointments: ${myUpComingAppointments.length}"); } if (isNeedCustomerFilter) { + log("myFilteredAppointmentsForProvider: ${myFilteredAppointmentsForProvider.length}"); + myFilteredAppointmentsForProvider = findAppointmentsBasedOnCustomers(myFilteredAppointmentsForProvider); } notifyListeners(); @@ -400,8 +400,8 @@ class AppointmentsVM extends BaseVM { if (shouldPopulateUpcoming) { myUpComingAppointments = myFilteredAppointmentsForCustomers .where((element) => - (element.appointmentStatusEnum == AppointmentStatusEnum.booked || element.appointmentStatusEnum == AppointmentStatusEnum.confirmed) && - (DateHelper.parseStringToDate(element.appointmentDate!).isAfter(DateTime.now()))) + (element.appointmentStatusEnum == AppointmentStatusEnum.booked || element.appointmentStatusEnum == AppointmentStatusEnum.confirmed) && + (DateHelper.parseStringToDate(element.appointmentDate!).isAfter(DateTime.now()))) .toList(); } @@ -416,19 +416,14 @@ class AppointmentsVM extends BaseVM { List groupedList = uniqueCustomerIDs.map((id) { List list = appointments.where((item) => item.customerID == id).toList(); - list.sort((a, b) => - DateHelper - .parseStringToDate(DateHelper.formatDateT(b.appointmentDate!)) - .millisecondsSinceEpoch - .compareTo(DateHelper - .parseStringToDate(DateHelper.formatDateT(a.appointmentDate!)) - .millisecondsSinceEpoch)); + list.sort((a, b) => DateHelper.parseStringToDate(DateHelper.formatDateT(b.appointmentDate!)) + .millisecondsSinceEpoch + .compareTo(DateHelper.parseStringToDate(DateHelper.formatDateT(a.appointmentDate!)).millisecondsSinceEpoch)); AppointmentListModel model = list.first; model.customerAppointmentList = list; return model; }).toList(); - return groupedList; } @@ -492,6 +487,9 @@ class AppointmentsVM extends BaseVM { } bool isShowMergeButton() { + if (myFilteredAppointmentsForProvider[selectedAppointmentIndex].customerAppointmentList == null) { + return false; + } return myFilteredAppointmentsForProvider[selectedAppointmentIndex].customerAppointmentList!.every((appointment) => appointment.appointmentStatusEnum == AppointmentStatusEnum.confirmed) && myFilteredAppointmentsForProvider[selectedAppointmentIndex].customerAppointmentList!.length > 1; } @@ -507,7 +505,7 @@ class AppointmentsVM extends BaseVM { void updateCheckBoxInMergeRequest(int currentIndex) { myFilteredAppointmentsForProvider[selectedAppointmentIndex].customerAppointmentList![currentIndex].isSelected = - !(myFilteredAppointmentsForProvider[selectedAppointmentIndex].customerAppointmentList?[currentIndex].isSelected ?? false); + !(myFilteredAppointmentsForProvider[selectedAppointmentIndex].customerAppointmentList?[currentIndex].isSelected ?? false); int count = countSelected(myFilteredAppointmentsForProvider[selectedAppointmentIndex].customerAppointmentList ?? []); if (count > 1) { @@ -519,10 +517,7 @@ class AppointmentsVM extends BaseVM { } int countSelected(List appointments) { - return appointments - .where((appointment) => appointment.isSelected == true) - .toList() - .length; + return appointments.where((appointment) => appointment.isSelected == true).toList().length; } updateSelectedAppointmentDate({required int dateIndex, required int scheduleIndex}) { @@ -698,14 +693,13 @@ 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} ${LocaleKeys.sar.tr()}".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} ${LocaleKeys.sar.tr()}".toText(fontSize: 12, isBold: true), + ], + ), ), ), Row( @@ -924,10 +918,7 @@ class AppointmentsVM extends BaseVM { return InfoBottomSheet( title: LocaleKeys.reportComplaint.tr().toText(fontSize: 28, isBold: true, letterSpacing: -1.44), description: Padding( - padding: EdgeInsets.only(bottom: MediaQuery - .of(context) - .viewInsets - .bottom), + padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ diff --git a/lib/view_models/dashboard_view_model_provider.dart b/lib/view_models/dashboard_view_model_provider.dart index eeeed56..fbb112e 100644 --- a/lib/view_models/dashboard_view_model_provider.dart +++ b/lib/view_models/dashboard_view_model_provider.dart @@ -94,7 +94,11 @@ class DashboardVMProvider extends BaseVM { } await shippingManagementVM.populateShippingRequestFilterList(); await shippingManagementVM.populateSelfPickupRequestFilterList(); - await appointmentVM.applyFilterOnAppointmentsVMForProviders(appointmentStatusEnum: AppointmentStatusEnum.allAppointments, shouldPopulateUpcoming: true); + await appointmentVM.applyFilterOnAppointmentsVMForProviders( + appointmentStatusEnum: AppointmentStatusEnum.allAppointments, + isNeedCustomerFilter: true, + shouldPopulateUpcoming: true, + ); await adVM.getVehicleTypes(); await adVM.getVehicleAdsDuration(); diff --git a/lib/view_models/requests_view_model.dart b/lib/view_models/requests_view_model.dart index b0fd9ea..85e8b6f 100644 --- a/lib/view_models/requests_view_model.dart +++ b/lib/view_models/requests_view_model.dart @@ -861,7 +861,7 @@ class RequestsVM extends BaseVM { Utils.showToast(LocaleKeys.addValidDescription.tr()); isValid = false; } else if (address.isEmpty && requestTypeId.selectedId == 2) { - Utils.showToast(LocaleKeys.addValidDescription.tr()); + Utils.showToast(LocaleKeys.addValidAddress.tr()); isValid = false; } return isValid; diff --git a/lib/view_models/shipping_management_view_model.dart b/lib/view_models/shipping_management_view_model.dart index b2a8fd0..446faa9 100644 --- a/lib/view_models/shipping_management_view_model.dart +++ b/lib/view_models/shipping_management_view_model.dart @@ -66,6 +66,9 @@ class ShippingManagementVM extends BaseVM { selfPickupRequestsStatusesList.add(FilterListModel(title: selfPickupStatusEnums[i].enumValueStrDes, isSelected: false, id: selfPickupStatusEnums[i].enumValue)); } + selfPickupRequestsFilterOptions.sort((FilterListModel a, FilterListModel b) => a.id.compareTo(b.id)); + selfPickupRequestsStatusesList.sort((FilterListModel a, FilterListModel b) => a.id.compareTo(b.id)); + selfPickupRequestsFilterOptions.insert(0, FilterListModel(title: Utils.getNameByShippingRequestStatusEnum(ShippingRequestStatusEnum.allRequests), isSelected: true, id: -1)); notifyListeners(); } @@ -82,6 +85,9 @@ class ShippingManagementVM extends BaseVM { } int index = shippingRequestFilterOptions.indexWhere((element) => element.id == 0); + + shippingRequestFilterOptions.sort((FilterListModel a, FilterListModel b) => a.id.compareTo(b.id)); + shippingRequestStatusesList.sort((FilterListModel a, FilterListModel b) => a.id.compareTo(b.id)); if (index == -1) { log("index: $index"); shippingRequestFilterOptions.insert(0, FilterListModel(title: Utils.getNameByShippingRequestStatusEnum(0.toShippingStatusEnum()), isSelected: false, id: 0)); diff --git a/lib/views/advertisement/components/ads_list_widget.dart b/lib/views/advertisement/components/ads_list_widget.dart index fff3b91..d65de2f 100644 --- a/lib/views/advertisement/components/ads_list_widget.dart +++ b/lib/views/advertisement/components/ads_list_widget.dart @@ -23,6 +23,7 @@ class AdsListWidget extends StatelessWidget { final bool isAdsFragment; final bool shouldShowAdStatus; final bool hasMoreData; + final bool isDraftAds; final Function()? onFetchMoreAds; const AdsListWidget({ @@ -30,6 +31,7 @@ class AdsListWidget extends StatelessWidget { required this.adsList, required this.shouldShowAdStatus, required this.hasMoreData, + required this.isDraftAds, this.onFetchMoreAds, this.scrollPhysics, this.isAdsFragment = false, @@ -47,7 +49,6 @@ class AdsListWidget extends StatelessWidget { } return NotificationListener( onNotification: (ScrollNotification scrollInfo) { - log("hasMoreData: $hasMoreData"); if (scrollInfo.metrics.pixels == scrollInfo.metrics.maxScrollExtent && hasMoreData) { if (onFetchMoreAds != null) { onFetchMoreAds!(); @@ -64,9 +65,20 @@ class AdsListWidget extends StatelessWidget { adDetails: adsList[index], isAdsFragment: isAdsFragment, shouldShowAdStatus: shouldShowAdStatus, - ).onPress(() => navigateWithName(context, AppRoutes.adsDetailView, arguments: adsList[index])).toViewOnly(context, onTap: () { - navigateWithName(context, AppRoutes.loginWithPassword, arguments: false); - }); + ).onPress( + () { + if (isDraftAds) { + context.read().onEditUpdateAdPressed( + context: context, + previousDetails: adsList[index], + isFromExtendAd: false, + isForDraft: true, + ); + } else { + navigateWithName(context, AppRoutes.adsDetailView, arguments: adsList[index]); + } + }, + ).toViewOnly(context, onTap: () => navigateWithName(context, AppRoutes.loginWithPassword, arguments: false)); }, separatorBuilder: (BuildContext context, int index) { return 12.height; @@ -89,110 +101,120 @@ class AdCard extends StatelessWidget { return Stack( alignment: Alignment.center, children: [ - Row( - children: [ - adDetails.vehicle!.image!.first.imageUrl.buildNetworkImage( - width: 80, - height: 80, - fit: BoxFit.cover, + if (adDetails.vehicle == null) ...[ + Expanded( + child: Column( + children: [ + "Zahoor will update the Ad Format".toText(), + ], ), - 12.width, - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - if (isAdsFragment && adDetails.adPostStatus! == AdPostStatus.sold) ...[ - Utils.statusContainerChip(text: adDetails.statuslabel!, chipColor: Utils.getChipColorByAdStatus(adDetails.adPostStatus!)), - ] else if (isAdsFragment && !context.read().isExploreAdsTapped) ...[ - Utils.statusContainerChip(text: adDetails.statuslabel!, chipColor: Utils.getChipColorByAdStatus(adDetails.adPostStatus!)), - ], - (adDetails.vehicle!.vehicleTitle ?? "").toText( - fontSize: 16, - letterSpacing: -0.64, - height: 25 / 16, - ), - Row( - children: [ - ("${LocaleKeys.model.tr()}:").toText( - fontSize: 12, - color: MyColors.lightTextColor, - letterSpacing: -0.48, - height: 18 / 12, - ), - 2.width, - (adDetails.vehicle!.modelyear!.label ?? "").toText( - fontSize: 12, - letterSpacing: -0.48, - height: 18 / 12, - ), - ], - ), - Row( - children: [ - ("${LocaleKeys.mileage.tr()}:").toText( - color: MyColors.lightTextColor, - fontSize: 12, - letterSpacing: -0.48, - height: 18 / 12, - ), - 2.width, - (adDetails.vehicle!.mileage!.mileageEnd ?? "").toText( - fontSize: 12, - letterSpacing: -0.48, - height: 18 / 12, - ), + ), + ] else ...[ + Row( + children: [ + adDetails.vehicle!.image!.first.imageUrl.buildNetworkImage( + width: 80, + height: 80, + fit: BoxFit.cover, + ), + 12.width, + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + if (isAdsFragment && adDetails.adPostStatus! == AdPostStatus.sold && adDetails.statuslabel != null && adDetails.statuslabel!.isNotEmpty) ...[ + Utils.statusContainerChip(text: adDetails.statuslabel ?? "", chipColor: Utils.getChipColorByAdStatus(adDetails.adPostStatus!)), + ] else if (isAdsFragment && !context.read().isExploreAdsTapped && adDetails.statuslabel != null && adDetails.statuslabel!.isNotEmpty) ...[ + Utils.statusContainerChip(text: adDetails.statuslabel ?? "", chipColor: Utils.getChipColorByAdStatus(adDetails.adPostStatus!)), ], - ), - ], + (adDetails.vehicle!.vehicleTitle ?? "").toText( + fontSize: 16, + letterSpacing: -0.64, + height: 25 / 16, + ), + Row( + children: [ + ("${LocaleKeys.model.tr()}:").toText( + fontSize: 12, + color: MyColors.lightTextColor, + letterSpacing: -0.48, + height: 18 / 12, + ), + 2.width, + (adDetails.vehicle!.modelyear!.label ?? "").toText( + fontSize: 12, + letterSpacing: -0.48, + height: 18 / 12, + ), + ], + ), + Row( + children: [ + ("${LocaleKeys.mileage.tr()}:").toText( + color: MyColors.lightTextColor, + fontSize: 12, + letterSpacing: -0.48, + height: 18 / 12, + ), + 2.width, + (adDetails.vehicle!.mileage!.mileageEnd ?? "").toText( + fontSize: 12, + letterSpacing: -0.48, + height: 18 / 12, + ), + ], + ), + ], + ), ), - ), - Column( - crossAxisAlignment: CrossAxisAlignment.end, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - (adDetails.vehicle!.cityName ?? "").toText(color: MyColors.lightTextColor), - adDetails.createdOn != null ? DateTime.parse(adDetails.createdOn!).getTimeAgo().toText(color: MyColors.lightTextColor) : const SizedBox(), - ], - ), - ], - ), - 8.height, - Row( - children: [ - Expanded( - child: Row( - mainAxisAlignment: MainAxisAlignment.start, + Column( crossAxisAlignment: CrossAxisAlignment.end, + mainAxisAlignment: MainAxisAlignment.start, children: [ - (adDetails.vehicle!.demandAmount!.toInt().toString()).toText(fontSize: 19, isBold: true, letterSpacing: -1.16, height: 29 / 19), - 2.width, - LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, fontSize: 10, letterSpacing: -0.4, height: 16 / 10).paddingOnly(bottom: 3), + (adDetails.vehicle!.cityName ?? "").toText(color: MyColors.lightTextColor), + adDetails.createdOn != null ? DateTime.parse(adDetails.createdOn!).getTimeAgo().toText(color: MyColors.lightTextColor) : const SizedBox(), ], ), - ), - SvgPicture.asset( - MyAssets.arrowRight, - height: 9.69, - width: 13, - ), + ], + ), + 8.height, + Row( + children: [ + Expanded( + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + (adDetails.vehicle!.demandAmount!.toInt().toString()).toText(fontSize: 19, isBold: true, letterSpacing: -1.16, height: 29 / 19), + 2.width, + LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, fontSize: 10, letterSpacing: -0.4, height: 16 / 10).paddingOnly(bottom: 3), + ], + ), + ), + SvgPicture.asset( + MyAssets.arrowRight, + height: 9.69, + width: 13, + ), - // const Icon(Icons.arrow_forward) - ], - ), - ], + // const Icon(Icons.arrow_forward) + ], + ), + ], + ), ), - ), - ], - ), + ], + ), + ], if (false) Container( height: 100, diff --git a/lib/views/advertisement/create_ad_view.dart b/lib/views/advertisement/create_ad_view.dart index d8807bd..fca12ae 100644 --- a/lib/views/advertisement/create_ad_view.dart +++ b/lib/views/advertisement/create_ad_view.dart @@ -1,9 +1,13 @@ +import 'dart:developer'; + import 'package:flutter/material.dart'; +import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart'; import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/navigator.dart'; +import 'package:mc_common_app/utils/utils.dart'; import 'package:mc_common_app/view_models/ad_view_model.dart'; import 'package:mc_common_app/views/advertisement/ad_creation_steps/ad_duration_container.dart'; import 'package:mc_common_app/views/advertisement/ad_creation_steps/ad_review_containers.dart'; @@ -94,8 +98,14 @@ class BuildFooterButton extends StatelessWidget { maxHeight: 55, title: LocaleKeys.cancel.tr(), onPressed: () { + adVm.isDraftEditEnabled = false; adVm.resetValues(); pop(context); + if (AppState().currentAppType == AppType.customer) { + pop(context); + } + Utils.showToast('Saved as Draft'); + adVm.getMyDraftAds(); }, backgroundColor: MyColors.greyButtonColor, ), @@ -122,8 +132,15 @@ class BuildFooterButton extends StatelessWidget { maxHeight: 55, title: LocaleKeys.cancel.tr(), onPressed: () { + adVm.isDraftEditEnabled = false; + adVm.resetValues(); pop(context); + if (AppState().currentAppType == AppType.customer) { + pop(context); + } + Utils.showToast('Saved as Draft'); + adVm.getMyDraftAds(); }, backgroundColor: MyColors.greyButtonColor, ), @@ -150,8 +167,15 @@ class BuildFooterButton extends StatelessWidget { maxHeight: 55, title: LocaleKeys.cancel.tr(), onPressed: () { + adVm.isDraftEditEnabled = false; + adVm.resetValues(); pop(context); + if (AppState().currentAppType == AppType.customer) { + pop(context); + } + Utils.showToast('Saved as Draft'); + adVm.getMyDraftAds(); }, backgroundColor: MyColors.greyButtonColor, ), diff --git a/lib/views/advertisement/my_draft_ads_view.dart b/lib/views/advertisement/my_draft_ads_view.dart new file mode 100644 index 0000000..f1c3c31 --- /dev/null +++ b/lib/views/advertisement/my_draft_ads_view.dart @@ -0,0 +1,68 @@ +import 'dart:async'; + +import 'package:mc_common_app/generated/locale_keys.g.dart'; +import 'package:mc_common_app/view_models/ad_view_model.dart'; +import 'package:flutter/material.dart'; +import 'package:mc_common_app/utils/enums.dart'; +import 'package:mc_common_app/views/advertisement/components/ads_list_widget.dart'; +import 'package:mc_common_app/widgets/common_widgets/app_bar.dart'; +import 'package:provider/provider.dart'; +import 'package:easy_localization/easy_localization.dart'; + +class MyDraftAdsView extends StatefulWidget { + const MyDraftAdsView({super.key}); + + @override + State createState() => _MyDraftAdsViewState(); +} + +class _MyDraftAdsViewState extends State { + @override + void initState() { + scheduleMicrotask(() async => context.read().getMyDraftAds()); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Consumer(builder: (BuildContext context, AdVM adVM, Widget? child) { + return Scaffold( + appBar: CustomAppBar(title: LocaleKeys.myDraftAds.tr()), + body: SizedBox( + width: double.infinity, + height: double.infinity, + child: Column( + children: [ + Expanded( + child: RefreshIndicator( + onRefresh: () async { + await adVM.getMyDraftAds(); + }, + child: adVM.state == ViewState.busy + ? const Center(child: CircularProgressIndicator()) + : AdsListWidget( + isAdsFragment: true, + isDraftAds: true, + shouldShowAdStatus: false, + adsList: adVM.myDraftAds, + hasMoreData: adVM.hasMoreDataForMyDraftsAds, + onFetchMoreAds: () async { + await adVM.fetchMoreDraftAds(); + }, + ), + ), + ), + if (adVM.isLoadingMore) ...[ + const Center( + child: Padding( + padding: EdgeInsets.all(8.0), + child: CircularProgressIndicator(), + )) + ] + ], + ), + ), + ); + }); + } +} diff --git a/lib/views/advertisement/select_ad_type_view.dart b/lib/views/advertisement/select_ad_type_view.dart index 06b5602..1597368 100644 --- a/lib/views/advertisement/select_ad_type_view.dart +++ b/lib/views/advertisement/select_ad_type_view.dart @@ -78,7 +78,8 @@ class SelectAdTypeView extends StatelessWidget { onTap: () async { adVM.updateSelectionVehicleTypeId(SelectionModel(selectedId: vehicleTypeModel.id!, selectedOption: vehicleTypeModel.vehicleTypeName ?? "", errorValue: "")); if (adVM.isAdEditEnabled) { - adVM.autoFillSelectedVehicleAdsDetails(); + adVM. + autoFillSelectedVehicleAdsDetails(); } if (AppState().currentAppType == AppType.provider) { if (isFromExtendAd && !adVM.isAdEditEnabled) { diff --git a/lib/views/common_fragments/ads_fragment.dart b/lib/views/common_fragments/ads_fragment.dart index d68c1c5..71329e0 100644 --- a/lib/views/common_fragments/ads_fragment.dart +++ b/lib/views/common_fragments/ads_fragment.dart @@ -150,6 +150,7 @@ class AdsFragment extends StatelessWidget { ? const Center(child: CircularProgressIndicator()) : AdsListWidget( isAdsFragment: true, + isDraftAds: false, shouldShowAdStatus: !adVM.isExploreAdsTapped, adsList: getAdsList(adVM), hasMoreData: adVM.isExploreAdsTapped ? adVM.hasMoreDataForExploreAds : adVM.hasMoreDataForMyAds, diff --git a/lib/views/requests/create_request_page.dart b/lib/views/requests/create_request_page.dart index 00fba07..d298776 100644 --- a/lib/views/requests/create_request_page.dart +++ b/lib/views/requests/create_request_page.dart @@ -234,7 +234,7 @@ class CreateRequestPage extends StatelessWidget { onChanged: (e) => requestsVM.updateAddress(e), ), 8.height, - ] , + ], if (requestsVM.pickedVehicleImages.isEmpty) ...[ DottedRectContainer( onTap: () => context.read().pickMultipleImages(), @@ -285,5 +285,3 @@ class CreateRequestPage extends StatelessWidget { ); } } - - diff --git a/lib/views/setting_options/setting_options_more.dart b/lib/views/setting_options/setting_options_more.dart index c11d98c..37ff91f 100644 --- a/lib/views/setting_options/setting_options_more.dart +++ b/lib/views/setting_options/setting_options_more.dart @@ -112,6 +112,19 @@ class _SettingOptionsMoreState extends State { navigateWithName(context, AppRoutes.loginWithPassword, arguments: false); }), ], + CustomSettingOptionsTile( + leadingWidget: SvgPicture.asset( + MyAssets.icAds, + height: 20, + width: 20, + color: MyColors.darkIconColor, + ), + titleText: LocaleKeys.myDraftAds.tr(), + needBorderBelow: true, + onTap: () { + navigateWithName(context, AppRoutes.myDraftAdsView); + }, + ), CustomSettingOptionsTile( leadingWidget: const Icon(Icons.settings, size: 20), titleText: LocaleKeys.settings.tr(),