Compare commits

..

No commits in common. 'master' and 'aamir_dev' have entirely different histories.

@ -1,63 +0,0 @@
# View-Only Mode: CustomerID Parameter Exclusion
## Summary
Updated all API calls to exclude `customerID` parameter when `AppState().getIsViewOnly` is `true`.
## Files Modified
### 1. **request_repo.dart**
- ✅ `createRequest()` - Excludes customerID in view-only mode
- ✅ `getRequests()` - Excludes customerID for customer app type in view-only mode
- ✅ `getRequestBasedOnFilters()` - Excludes customerID for customer app type in view-only mode
- ✅ `getOffersFromProvidersByRequest()` - Excludes customerID in view-only mode
### 2. **ads_repo.dart**
- ✅ `cancelMyAdReservation()` - Excludes customerID in view-only mode
- ✅ `createReserveAd()` - Excludes customerID in view-only mode
- ✅ `uploadBankReceiptsOnReserveDealDone()` - Excludes customerID in view-only mode
### 3. **appointment_repo.dart**
- ✅ `createAppointmentsMulti()` - Excludes customerID in view-only mode
- ✅ `getMyAppointmentsForCustomersByFilters()` - Excludes customerID in view-only mode
### 4. **branch_repo.dart**
- ✅ `submitBranchRatings()` - Excludes customerID in view-only mode
- ✅ `addProviderToFavourite()` - Excludes customerID in view-only mode
- ✅ `getMyFavoriteProviders()` - Excludes customerID in view-only mode
### 5. **setting_options_repo.dart**
- ✅ `appInvitationCreate()` - Excludes customerID for customer app type in view-only mode
## How It Works
When `AppState().getIsViewOnly` is `true`, the application is in demonstration/view-only mode. In this mode:
1. **API parameters are conditionally added**: Instead of always including `customerID`, we check the view-only flag first
2. **Pattern used**:
```dart
var params = {
"otherParam": value,
};
if (!appState.getIsViewOnly) {
params["customerID"] = customerId;
}
```
3. **App types considered**: The changes properly handle both customer and provider app types
## Testing Recommendations
1. Test in normal mode (getIsViewOnly = false):
- All APIs should include customerID as before
- All existing functionality should work
2. Test in view-only mode (getIsViewOnly = true):
- APIs should NOT include customerID parameter
- Read-only operations should work
- Write operations should be blocked by view-only mode
## Note
The `createComplainFromProvider()` method in `common_repo.dart` was NOT modified because the `customerID` in that API represents the target customer being complained about, not the authenticated user making the request.

@ -413,13 +413,6 @@
"deleteAdConfirmationMessage": "سيتم حذف إعلانك نهائيًا ولا يمكنك التراجع عن هذا الإجراء",
"mileage": "المسافة المقطوعة",
"transmission": "ناقل الحركة",
"odometer": "عداد المسافات",
"accidentFree": "خالية من الحوادث",
"brandNew": "جديدة",
"used": "مستعملة",
"hasYourCarHadAccident": "هل تعرضت سيارتك لأي حادث؟",
"odometerReading": "قراءة عداد المسافات (كم)",
"currentlyInUse": "قيد الاستخدام حاليًا",
"demand": "الطلب",
"adDurationExpired": "انتهت مدة عرض الإعلان الخاص بك",
"bankDetails": "تفاصيل البنك",
@ -727,8 +720,6 @@
"ownerInformation": "معلومات المالك",
"acceptedRequests": "الطلبات المقبولة",
"specialRequestChat": "دردشة الطلب الخاص",
"sparePartRequestChat": "دردشة طلب قطع الغيار",
"specialCarRequestChat": "دردشة طلب السيارة الخاصة",
"companyName": "اسم الشركة",
"noAvailableItems": "لا توجد عناصر متاحة.",
"serviceDeliveryType": "نوع تقديم الخدمة",
@ -817,13 +808,5 @@
"specialRequestsChats": "دردشات الطلبات الخاصة",
"selectDeliveryOption": "اختر خيار التوصيل",
"deliveryOptions": "خيارات التوصيل",
"selfPickup": "الالتقاط الذاتي",
"updateYourLocationInfo": "قم بتحديث معلومات موقعك",
"initiateSelfPickup": "بدء الاستلام الذاتي",
"selfPickupStatus": "حالة الالتقاط الذاتي",
"myDraftAds": "مسودتي للإعلانات",
"scheduleDeletedSuccessfully": "تم حذف الجدول بنجاح",
"addValidAddress": "رجى إضافة عنوان صالح",
"termsPrivacyPolicy": "الشروط وسياسة الخصوصية"
"selfPickup": "الالتقاط الذاتي"
}

@ -414,13 +414,6 @@
"deleteAdConfirmationMessage": "Your ad will be permanently deleted and you cannot undo this action",
"mileage": "Mileage",
"transmission": "Transmission",
"odometer": "Odometer",
"accidentFree": "Accident Free",
"brandNew": "Brand New",
"used": "Used",
"hasYourCarHadAccident": "Has your car had any accident?",
"odometerReading": "Odometer Reading (Km)",
"currentlyInUse": "Currently in Use",
"demand": "Demand",
"adDurationExpired": "Your Ad Duration time is over",
"bankDetails": "Bank Details",
@ -722,8 +715,6 @@
"noItemsToShow": "There are no Items no show.",
"acceptedRequests": "Accepted Requests",
"specialRequestChat": "Special Request Chat",
"sparePartRequestChat": "Spare Part Request Chat",
"specialCarRequestChat": "Special Car Request Chat",
"companyName": "Company Name",
"noAvailableItems": "There are no available items.",
"serviceDeliveryType": "Service Delivery Type",
@ -815,12 +806,5 @@
"specialRequestsChats": "Special Requests Chats",
"selectDeliveryOption": "Select Delivery Option",
"deliveryOptions": "Delivery Options",
"selfPickup": "Self Pickup",
"updateYourLocationInfo": "Update your location information",
"initiateSelfPickup": "Initiate Self Pickup",
"selfPickupStatus": "Self Pickup Status",
"myDraftAds": "My Draft Ads",
"scheduleDeletedSuccessfully": "The schedule has been deleted successfully",
"addValidAddress": "Please add a valid address",
"termsPrivacyPolicy": "Terms & Privacy Policy"
"selfPickup": "Self Pickup"
}

@ -178,8 +178,6 @@ class ApiConsts {
static String updateRequestProvider = "${baseUrlServices}api/RequestManagement/Request_StatusUpdate_Provider";
static String requestOffersSpsGet = "${baseUrlServices}api/RequestManagement/Request_OfferSPs_Get";
static String getServiceRequestsForProvider = "${baseUrlServices}api/RequestManagement/Request_ServiceProvider";
static String requestOfferUpdateDeliveryOptionByCustomer = "${baseUrlServices}api/RequestManagement/RequestOffer_UpdateDeliveryByCustomer";
static String requestUpdateAdditionalAddress = "${baseUrlServices}api/RequestManagement/Request_UpdateAdditionalAddress";
//Shipping

@ -9,7 +9,6 @@ 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';
@ -131,7 +130,6 @@ 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";
@ -210,7 +208,6 @@ 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<dynamic>),
AppRoutes.chatView: (context) => ChatView(chatViewArguments: ModalRoute.of(context)!.settings.arguments as ChatViewArguments),
AppRoutes.adsBuyerChatsListView: (context) => AdsBuyerChatsView(buyersListViewArguments: ModalRoute.of(context)!.settings.arguments as List<BuyersChatForAdsModel>),

@ -182,8 +182,6 @@ extension RequestEnum on int {
return RequestStatusEnum.shipping;
} else if (this == 8) {
return RequestStatusEnum.delivery;
} else if (this == 9) {
return RequestStatusEnum.selfPickup;
} else {
return RequestStatusEnum.pending;
}
@ -209,8 +207,6 @@ extension RequestStatusEnumToInt on RequestStatusEnum {
return 7;
case RequestStatusEnum.delivery:
return 8;
case RequestStatusEnum.selfPickup:
return 9;
case RequestStatusEnum.pending:
return 0;
@ -1012,7 +1008,7 @@ extension SelfPickupStatusEnumExt on int {
if (this == -1) {
return SelfPickupRequestStatusEnum.allRequests;
} else if (this == 0) {
return SelfPickupRequestStatusEnum.pending;
return SelfPickupRequestStatusEnum.allRequests;
} else if (this == 1) {
return SelfPickupRequestStatusEnum.preparingToCollect;
} else if (this == 2) {
@ -1028,8 +1024,6 @@ extension SelfPickupStatusEnumToInt on SelfPickupRequestStatusEnum {
int getIdFromSelfPickupStatusEnum() {
switch (this) {
case SelfPickupRequestStatusEnum.allRequests:
return -1;
case SelfPickupRequestStatusEnum.pending:
return 0;
case SelfPickupRequestStatusEnum.preparingToCollect:
return 1;
@ -1124,36 +1118,3 @@ extension IntToInviteType on int {
}
}
}
extension AdCreationStepsToInt on AdCreationStepsEnum {
int toIntFromStepsEnum() {
switch (this) {
case AdCreationStepsEnum.vehicleDetails:
return 1;
case AdCreationStepsEnum.damageParts:
return 2;
case AdCreationStepsEnum.adDuration:
return 3;
case AdCreationStepsEnum.reviewAd:
return 4;
}
}
}
extension AdCreationStepsFromInt on int {
AdCreationStepsEnum toAdCreationStepsEnumFromInt() {
switch (this) {
case 0:
return AdCreationStepsEnum.vehicleDetails;
case 1:
return AdCreationStepsEnum.vehicleDetails;
case 2:
return AdCreationStepsEnum.damageParts;
case 3:
return AdCreationStepsEnum.adDuration;
case 4:
return AdCreationStepsEnum.reviewAd;
}
return AdCreationStepsEnum.vehicleDetails;
}
}

@ -1,6 +1,6 @@
// DO NOT EDIT. This is code generated via package:easy_localization/generate.dart
// ignore_for_file: prefer_single_quotes, avoid_renaming_method_parameters, constant_identifier_names
// ignore_for_file: prefer_single_quotes, avoid_renaming_method_parameters
import 'dart:ui';
@ -14,7 +14,7 @@ class CodegenLoader extends AssetLoader{
return Future.value(mapLocales[locale.toString()]);
}
static const Map<String,dynamic> _ar_SA = {
static const Map<String,dynamic> ar_SA = {
"firstTimeLogIn": "تسجيل الدخول لأول مره",
"signUp": "التسجيل",
"changeMobile": "تغيير رقم الجوال",
@ -429,13 +429,6 @@ class CodegenLoader extends AssetLoader{
"deleteAdConfirmationMessage": "سيتم حذف إعلانك نهائيًا ولا يمكنك التراجع عن هذا الإجراء",
"mileage": "المسافة المقطوعة",
"transmission": "ناقل الحركة",
"odometer": "عداد المسافات",
"accidentFree": "خالية من الحوادث",
"brandNew": "جديدة",
"used": "مستعملة",
"hasYourCarHadAccident": "هل تعرضت سيارتك لأي حادث؟",
"odometerReading": "قراءة عداد المسافات (كم)",
"currentlyInUse": "قيد الاستخدام حاليًا",
"demand": "الطلب",
"adDurationExpired": "انتهت مدة عرض الإعلان الخاص بك",
"bankDetails": "تفاصيل البنك",
@ -743,8 +736,6 @@ class CodegenLoader extends AssetLoader{
"ownerInformation": "معلومات المالك",
"acceptedRequests": "الطلبات المقبولة",
"specialRequestChat": "دردشة الطلب الخاص",
"sparePartRequestChat": "دردشة طلب قطع الغيار",
"specialCarRequestChat": "دردشة طلب السيارة الخاصة",
"companyName": "اسم الشركة",
"noAvailableItems": "لا توجد عناصر متاحة.",
"serviceDeliveryType": "نوع تقديم الخدمة",
@ -833,16 +824,9 @@ class CodegenLoader extends AssetLoader{
"specialRequestsChats": "دردشات الطلبات الخاصة",
"selectDeliveryOption": "اختر خيار التوصيل",
"deliveryOptions": "خيارات التوصيل",
"selfPickup": "الالتقاط الذاتي",
"updateYourLocationInfo": "قم بتحديث معلومات موقعك",
"initiateSelfPickup": "بدء الاستلام الذاتي",
"selfPickupStatus": "حالة الالتقاط الذاتي",
"myDraftAds": "مسودتي للإعلانات",
"scheduleDeletedSuccessfully": "تم حذف الجدول بنجاح",
"addValidAddress": "رجى إضافة عنوان صالح",
"termsPrivacyPolicy": "الشروط وسياسة الخصوصية"
"selfPickup": "الالتقاط الذاتي"
};
static const Map<String,dynamic> _en_US = {
static const Map<String,dynamic> en_US = {
"firstTimeLogIn": "First Time Log In",
"signUp": "Sign Up",
"changeMobile": "Change Mobile",
@ -1258,13 +1242,6 @@ static const Map<String,dynamic> _en_US = {
"deleteAdConfirmationMessage": "Your ad will be permanently deleted and you cannot undo this action",
"mileage": "Mileage",
"transmission": "Transmission",
"odometer": "Odometer",
"accidentFree": "Accident Free",
"brandNew": "Brand New",
"used": "Used",
"hasYourCarHadAccident": "Has your car had any accident?",
"odometerReading": "Odometer Reading (Km)",
"currentlyInUse": "Currently in Use",
"demand": "Demand",
"adDurationExpired": "Your Ad Duration time is over",
"bankDetails": "Bank Details",
@ -1566,8 +1543,6 @@ static const Map<String,dynamic> _en_US = {
"noItemsToShow": "There are no Items no show.",
"acceptedRequests": "Accepted Requests",
"specialRequestChat": "Special Request Chat",
"sparePartRequestChat": "Spare Part Request Chat",
"specialCarRequestChat": "Special Car Request Chat",
"companyName": "Company Name",
"noAvailableItems": "There are no available items.",
"serviceDeliveryType": "Service Delivery Type",
@ -1659,14 +1634,7 @@ static const Map<String,dynamic> _en_US = {
"specialRequestsChats": "Special Requests Chats",
"selectDeliveryOption": "Select Delivery Option",
"deliveryOptions": "Delivery Options",
"selfPickup": "Self Pickup",
"updateYourLocationInfo": "Update your location information",
"initiateSelfPickup": "Initiate Self Pickup",
"selfPickupStatus": "Self Pickup Status",
"myDraftAds": "My Draft Ads",
"scheduleDeletedSuccessfully": "The schedule has been deleted successfully",
"addValidAddress": "Please add a valid address",
"termsPrivacyPolicy": "Terms & Privacy Policy"
"selfPickup": "Self Pickup"
};
static const Map<String, Map<String,dynamic>> mapLocales = {"ar_SA": _ar_SA, "en_US": _en_US};
static const Map<String, Map<String,dynamic>> mapLocales = {"ar_SA": ar_SA, "en_US": en_US};
}

@ -1,7 +1,5 @@
// DO NOT EDIT. This is code generated via package:easy_localization/generate.dart
// ignore_for_file: constant_identifier_names
abstract class LocaleKeys {
static const firstTimeLogIn = 'firstTimeLogIn';
static const signUp = 'signUp';
@ -394,13 +392,6 @@ abstract class LocaleKeys {
static const deleteAdConfirmationMessage = 'deleteAdConfirmationMessage';
static const mileage = 'mileage';
static const transmission = 'transmission';
static const odometer = 'odometer';
static const accidentFree = 'accidentFree';
static const brandNew = 'brandNew';
static const used = 'used';
static const hasYourCarHadAccident = 'hasYourCarHadAccident';
static const odometerReading = 'odometerReading';
static const currentlyInUse = 'currentlyInUse';
static const demand = 'demand';
static const adDurationExpired = 'adDurationExpired';
static const bankDetails = 'bankDetails';
@ -708,8 +699,6 @@ abstract class LocaleKeys {
static const ownerInformation = 'ownerInformation';
static const acceptedRequests = 'acceptedRequests';
static const specialRequestChat = 'specialRequestChat';
static const sparePartRequestChat = 'sparePartRequestChat';
static const specialCarRequestChat = 'specialCarRequestChat';
static const companyName = 'companyName';
static const noAvailableItems = 'noAvailableItems';
static const serviceDeliveryType = 'serviceDeliveryType';
@ -799,12 +788,5 @@ abstract class LocaleKeys {
static const selectDeliveryOption = 'selectDeliveryOption';
static const deliveryOptions = 'deliveryOptions';
static const selfPickup = 'selfPickup';
static const updateYourLocationInfo = 'updateYourLocationInfo';
static const initiateSelfPickup = 'initiateSelfPickup';
static const selfPickupStatus = 'selfPickupStatus';
static const myDraftAds = 'myDraftAds';
static const scheduleDeletedSuccessfully = 'scheduleDeletedSuccessfully';
static const addValidAddress = 'addValidAddress';
static const termsPrivacyPolicy = 'termsPrivacyPolicy';
}

@ -2,6 +2,7 @@ import 'package:logger/logger.dart';
Logger logger = Logger(printer: PrettyPrinter(printEmojis: false, colors: true, printTime: false));
bool disableThingsForQA = true;
// Language Tile in Settings
@ -11,3 +12,4 @@ 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

@ -32,7 +32,6 @@ class AdDetailsModel {
String? qrCodePath;
bool? isCustomerAcknowledged;
int? createdByRole;
AdCreationStepsEnum? adCreationStepsEnum;
int? totalViews;
String? createdOn;
double? priceExcludingDiscount;
@ -81,7 +80,6 @@ class AdDetailsModel {
this.qrCodePath,
this.isCustomerAcknowledged,
this.createdByRole,
this.adCreationStepsEnum,
this.totalViews,
this.createdOn,
this.priceExcludingDiscount,
@ -137,11 +135,10 @@ class AdDetailsModel {
taxPrice = json['taxPrice'];
totalPrice = json['totalPrice'];
userID = json['userID'];
vehiclePostingID = (json['vehiclePostingID'] == null || json['vehiclePostingID'] == 0) ? json['id'] : 0;
vehiclePostingID = json['vehiclePostingID'];
qrCodePath = json['qrCodePath'];
isCustomerAcknowledged = json['isCustomerAcknowledged'];
createdByRole = json['createdByRole'];
adCreationStepsEnum = json['stepNo'] != null ? (json['stepNo'] as int).toAdCreationStepsEnumFromInt() : AdCreationStepsEnum.vehicleDetails;
totalViews = json['totalViews'];
createdOn = json['createdOn'];
priceExcludingDiscount = json['priceExcludingDiscount'];
@ -156,7 +153,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'] ?? 1) as int).toAdPostEnum();
adPostStatus = (json['statusID'] as int).toAdPostEnum();
adReserveStatus = AdReserveStatus.defaultStatus;
createdByRoleEnum = (json['createdByRole'] as int).toCreatedByRoleEnum();
isMyAd = isMyAds;
@ -190,11 +187,7 @@ class Vehicle {
int? vehicleType;
String? vehicleVIN;
int? countryID;
String? countryName;
String? currency;
int? odometer;
int? isInUsed;
bool? isAccidentFree;
Vehicle(
{this.id,
@ -221,11 +214,7 @@ class Vehicle {
this.vehicleType,
this.vehicleVIN,
this.countryID,
this.countryName,
this.currency,
this.odometer,
this.isInUsed,
this.isAccidentFree});
this.currency});
Vehicle.fromJson(Map<String, dynamic> json) {
id = json['id'];
@ -262,11 +251,7 @@ class Vehicle {
vehicleType = json['vehicleType'];
vehicleVIN = json['vehicleVIN'];
countryID = json['countryID'];
countryName = json['duration'] != null && json['duration']['country'] != null ? json['duration']['country']['label'] : null;
currency = json['currency'];
odometer = json['odometer'];
isInUsed = json['isInUsed'];
isAccidentFree = json['isAccidentFree'];
}
}

@ -124,9 +124,6 @@ class VehiclePosting {
List<VehiclePostingDamageParts>? vehiclePostingDamageParts;
String? phoneNo;
String? whatsAppNo;
int? odometer;
int? isInUsed;
bool? isAccidentFree;
VehiclePosting({
this.id,
@ -154,9 +151,6 @@ class VehiclePosting {
this.whatsAppNo,
this.vehiclePostingImages,
this.vehiclePostingDamageParts,
this.odometer,
this.isInUsed,
this.isAccidentFree,
});
VehiclePosting.fromJson(Map<String, dynamic> json) {
@ -183,9 +177,6 @@ class VehiclePosting {
adStatus = json['adStatus'];
phoneNo = json['phoneNo'];
whatsAppNo = json['whatsAppNo'];
odometer = json['odometer'];
isInUsed = json['isInUsed'];
isAccidentFree = json['isAccidentFree'];
if (json['vehiclePostingImages'] != null) {
vehiclePostingImages = <VehiclePostingImages>[];
json['vehiclePostingImages'].forEach((v) {
@ -202,7 +193,7 @@ class VehiclePosting {
@override
String toString() {
return 'VehiclePosting{id: $id, userID: $userID, vehicleType: $vehicleType, vehicleModelID: $vehicleModelID, vehicleModelYearID: $vehicleModelYearID, vehicleColorID: $vehicleColorID, vehicleCategoryID: $vehicleCategoryID, vehicleConditionID: $vehicleConditionID, vehicleMileageID: $vehicleMileageID, vehicleTransmissionID: $vehicleTransmissionID, vehicleSellerTypeID: $vehicleSellerTypeID, cityID: $cityID, price: $price, vehicleVIN: $vehicleVIN, vehicleDescription: $vehicleDescription, vehicleTitle: $vehicleTitle, vehicleDescriptionN: $vehicleDescriptionN, isFinanceAvailable: $isFinanceAvailable, warantyYears: $warantyYears, demandAmount: $demandAmount, adStatus: $adStatus, vehiclePostingImages: $vehiclePostingImages, vehiclePostingDamageParts: $vehiclePostingDamageParts, phoneNo: $phoneNo, whatsAppNo: $whatsAppNo, odometer: $odometer, isInUsed: $isInUsed, isAccidentFree: $isAccidentFree}';
return 'VehiclePosting{id: $id, userID: $userID, vehicleType: $vehicleType, vehicleModelID: $vehicleModelID, vehicleModelYearID: $vehicleModelYearID, vehicleColorID: $vehicleColorID, vehicleCategoryID: $vehicleCategoryID, vehicleConditionID: $vehicleConditionID, vehicleMileageID: $vehicleMileageID, vehicleTransmissionID: $vehicleTransmissionID, vehicleSellerTypeID: $vehicleSellerTypeID, cityID: $cityID, price: $price, vehicleVIN: $vehicleVIN, vehicleDescription: $vehicleDescription, vehicleTitle: $vehicleTitle, vehicleDescriptionN: $vehicleDescriptionN, isFinanceAvailable: $isFinanceAvailable, warantyYears: $warantyYears, demandAmount: $demandAmount, adStatus: $adStatus, vehiclePostingImages: $vehiclePostingImages, vehiclePostingDamageParts: $vehiclePostingDamageParts, phoneNo: $phoneNo, whatsAppNo: $whatsAppNo}';
}
}

@ -10,22 +10,17 @@ class RequestModel {
RequestStatusEnum requestStatus;
int? shippingStatus;
ShippingRequestStatusEnum? shippingStatusEnum;
SelfPickupRequestStatusEnum? selfPickupRequestStatusEnum;
String cityName;
String vehicleTypeName;
String countryName;
String customerName;
String customerID;
String address;
String additionalAddressDetails;
dynamic serviceProviders;
int offerCount;
int id;
int customerId;
bool isChatted;
bool isOfferAccepted;
RequestDeliveryOptionEnum offerDeliveryOption;
RequestDeliveryOptionEnum selectedDeliveryOptionByCustomer;
String customerUserID;
dynamic customer;
String brand;
@ -55,7 +50,6 @@ class RequestModel {
required this.requestStatus,
required this.shippingStatus,
required this.shippingStatusEnum,
required this.selfPickupRequestStatusEnum,
required this.cityName,
required this.vehicleTypeName,
required this.countryName,
@ -66,13 +60,9 @@ class RequestModel {
required this.id,
required this.customerId,
required this.isChatted,
required this.isOfferAccepted,
required this.offerDeliveryOption,
required this.selectedDeliveryOptionByCustomer,
required this.customerUserID,
required this.customer,
required this.address,
required this.additionalAddressDetails,
required this.brand,
required this.model,
required this.year,
@ -112,22 +102,17 @@ class RequestModel {
requestStatus: (json['requestStatus'] as int).toRequestStatusEnum(),
shippingStatus: json['shippingRequestStatus'],
shippingStatusEnum: json['shippingRequestStatus'] != null ? (json['shippingRequestStatus'] as int).toShippingStatusEnum() : ShippingRequestStatusEnum.pending,
selfPickupRequestStatusEnum: json['selfPickupRequestStatus'] != null ? (json['selfPickupRequestStatus'] as int).toSelfPickupStatusEnum() : SelfPickupRequestStatusEnum.preparingToCollect,
cityName: json["cityName"],
vehicleTypeName: json["vehicleTypeName"],
countryName: json["countryName"],
customerName: json["customerName"] ?? "",
address: json["address"] ?? "",
additionalAddressDetails: json['additionalAddress'] ?? "",
customerID: json["customerUserID"],
serviceProviders: json["serviceProviders"],
offerCount: json["offerCount"],
id: json["id"],
customerId: json["customerID"],
isChatted: json["isChatted"],
isOfferAccepted: json["isOfferAccepted"],
offerDeliveryOption: ((json["offerDeliveryOption"] ?? 0) as int).toRequestDeliveryOptionEnum(),
selectedDeliveryOptionByCustomer: ((json["deliveryOption"] ?? 0) as int).toRequestDeliveryOptionEnum(),
customerUserID: json["customerUserID"],
customer: json["customer"],
brand: json["brand"],

@ -5,10 +5,9 @@ class ShippingRequestModel {
int? id;
int? requestID;
Request? request;
int? pickupOrshippingStatus;
int? shippingStatus;
ShippingRequestStatusEnum? shippingStatusEnum;
SelfPickupRequestStatusEnum? selfPickupRequestStatusEnum;
String? deliveredorCollectedOn;
String? deliveredOn;
String? comment;
String? createdOn;
int? customerID;
@ -20,8 +19,8 @@ class ShippingRequestModel {
this.id,
this.requestID,
this.request,
this.pickupOrshippingStatus,
this.deliveredorCollectedOn,
this.shippingStatus,
this.deliveredOn,
this.comment,
this.createdOn,
this.customerID,
@ -30,15 +29,13 @@ class ShippingRequestModel {
this.vehicleType,
});
ShippingRequestModel.fromJsonShipping(Map<String, dynamic> json, bool isForShipping) {
ShippingRequestModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
requestID = json['requestID'];
request = json['request'] != null ? Request.fromJson(json['request']) : null;
pickupOrshippingStatus = isForShipping ? json['shippingStatus'] : json['selfPickUpStatus'];
shippingStatusEnum = isForShipping ? (json['shippingStatus'] != null ? (json['shippingStatus'] as int).toShippingStatusEnum() : ShippingRequestStatusEnum.initiated) : null;
selfPickupRequestStatusEnum =
isForShipping ? null : (json['selfPickUpStatus'] != null ? (json['selfPickUpStatus'] as int).toSelfPickupStatusEnum() : SelfPickupRequestStatusEnum.preparingToCollect);
deliveredorCollectedOn = isForShipping ? json['deliveredOn'] : json['collectedOn'];
shippingStatus = json['shippingStatus'];
shippingStatusEnum = json['shippingStatus'] != null ? (json['shippingStatus'] as int).toShippingStatusEnum() : ShippingRequestStatusEnum.initiated;
deliveredOn = json['deliveredOn'];
comment = json['comment'];
createdOn = json['createdOn'];
customerID = json['customerID'];

@ -25,8 +25,6 @@ abstract class AdsRepo {
Future<GenericRespModel> createOrUpdateAd({required AdsCreationPayloadModel adsCreationPayloadModel, required bool isCreateNew, required bool isExtendAdEditEnabled});
Future<GenericRespModel> createOrUpdateDraftAd({required AdsCreationPayloadModel adsCreationPayloadModel, required bool isCreateNew, required AdCreationStepsEnum stepNo});
Future<List<AdDetailsModel>> getAllAds({
required bool isMyAds,
AdPostStatus? adPostStatus,
@ -140,7 +138,7 @@ class AdsRepoImp implements AdsRepo {
"imageName": element.imageName,
"imageUrl": element.imageUrl,
"imageStr": element.imageStr,
"vehiclePostingID": isCreateNew ? 0 : element.vehiclePostingID ?? 0,
"vehiclePostingID": element.vehiclePostingID ?? 0,
"vehiclePosting": null,
};
vehiclePostingImages.add(imageMap);
@ -157,14 +155,14 @@ class AdsRepoImp implements AdsRepo {
"comment": element.comment,
"vehicleImageBase64": element.vehicleImageBase64,
"vehicleDamagePartID": element.vehicleDamagePartID,
"vehiclePostingID": isCreateNew ? 0 : element.vehiclePostingID ?? 0,
"vehiclePostingID": element.vehiclePostingID ?? 0,
"isActive": true
};
vehiclePostingDamageParts.add(imageMap);
});
var postParams = {
"ads": {
"id": isCreateNew ? 0 : adsCreationPayloadModel.ads!.id ?? 0,
"id": adsCreationPayloadModel.ads!.id ?? 0,
"adsDurationID": adsCreationPayloadModel.ads!.adsDurationID,
"startDate": adsCreationPayloadModel.ads!.startDate,
"countryId": adsCreationPayloadModel.ads!.countryId,
@ -174,7 +172,7 @@ class AdsRepoImp implements AdsRepo {
"isOnWhatsApp": adsCreationPayloadModel.ads!.isOnWhatsApp ?? false,
},
"vehiclePosting": {
"id": isCreateNew ? 0 : adsCreationPayloadModel.vehiclePosting!.id ?? 0,
"id": adsCreationPayloadModel.vehiclePosting!.id ?? 0,
"userID": adsCreationPayloadModel.vehiclePosting!.userID,
"vehicleType": adsCreationPayloadModel.vehiclePosting!.vehicleType,
"vehicleModelID": adsCreationPayloadModel.vehiclePosting!.vehicleModelID,
@ -199,9 +197,6 @@ class AdsRepoImp implements AdsRepo {
"vehiclePostingDamageParts": vehiclePostingDamageParts,
"mobileNo": adsCreationPayloadModel.vehiclePosting!.phoneNo,
"whatsAppNo": adsCreationPayloadModel.vehiclePosting!.whatsAppNo,
"odometer": adsCreationPayloadModel.vehiclePosting!.odometer,
"isInUsed": adsCreationPayloadModel.vehiclePosting!.isInUsed,
"isAccidentFree": adsCreationPayloadModel.vehiclePosting!.isAccidentFree,
}
};
@ -220,98 +215,6 @@ class AdsRepoImp implements AdsRepo {
return Future.value(adsGenericModel);
}
@override
Future<GenericRespModel> createOrUpdateDraftAd({required AdsCreationPayloadModel adsCreationPayloadModel, required bool isCreateNew, required AdCreationStepsEnum stepNo}) async {
int sellerTypeID = AppState().getUser.data!.userInfo!.roleId ?? 0;
List vehiclePostingImages = [];
List vehiclePostingDamageParts = [];
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 (adsCreationPayloadModel.vehiclePosting!.vehiclePostingDamageParts != null) {
adsCreationPayloadModel.vehiclePosting!.vehiclePostingDamageParts?.forEach((element) {
var imageMap = {
"id": element.id ?? 0,
"comment": element.comment,
"vehicleImageBase64": element.vehicleImageBase64,
"vehicleDamagePartID": element.vehicleDamagePartID,
"vehiclePostingDraftID": element.vehiclePostingID ?? 0,
"isActive": true
};
vehiclePostingDamageParts.add(imageMap);
});
}
var postParams = {
"adsDraft": {
"id": adsCreationPayloadModel.ads!.id ?? 0,
"adsDurationID": adsCreationPayloadModel.ads!.adsDurationID,
"startDate": adsCreationPayloadModel.ads!.startDate,
"countryId": adsCreationPayloadModel.ads!.countryId,
"specialServiceIDs": adsCreationPayloadModel.ads!.specialServiceIDs,
"isMCHandled": false,
"showContactDetail": adsCreationPayloadModel.ads!.showContactDetail ?? false,
"isOnWhatsApp": adsCreationPayloadModel.ads!.isOnWhatsApp ?? false,
},
"vehiclePostingDraft": {
"id": adsCreationPayloadModel.vehiclePosting!.id ?? 0,
"userID": adsCreationPayloadModel.vehiclePosting!.userID,
"vehicleType": adsCreationPayloadModel.vehiclePosting!.vehicleType,
"vehicleModelID": adsCreationPayloadModel.vehiclePosting!.vehicleModelID,
"vehicleModelYearID": adsCreationPayloadModel.vehiclePosting!.vehicleModelYearID,
"vehicleColorID": adsCreationPayloadModel.vehiclePosting!.vehicleColorID,
"vehicleCategoryID": adsCreationPayloadModel.vehiclePosting!.vehicleCategoryID,
"vehicleConditionID": adsCreationPayloadModel.vehiclePosting!.vehicleConditionID,
"vehicleMileageID": adsCreationPayloadModel.vehiclePosting!.vehicleMileageID,
"vehicleTransmissionID": adsCreationPayloadModel.vehiclePosting!.vehicleTransmissionID,
"vehicleSellerTypeID": sellerTypeID,
"cityID": adsCreationPayloadModel.vehiclePosting!.cityID,
"price": adsCreationPayloadModel.vehiclePosting!.price,
"vehicleVIN": adsCreationPayloadModel.vehiclePosting!.vehicleVIN,
"vehicleDescription": adsCreationPayloadModel.vehiclePosting!.vehicleDescription,
"vehicleTitle": adsCreationPayloadModel.vehiclePosting!.vehicleTitle,
"vehicleDescriptionN": adsCreationPayloadModel.vehiclePosting!.vehicleDescription,
"isFinanceAvailable": adsCreationPayloadModel.vehiclePosting!.isFinanceAvailable,
"warantyYears": adsCreationPayloadModel.vehiclePosting!.warantyYears,
"demandAmount": adsCreationPayloadModel.vehiclePosting!.demandAmount,
"vehiclePostingImagesDraft": vehiclePostingImages,
"vehiclePostingDamagePartsDraft": vehiclePostingDamageParts,
"mobileNo": adsCreationPayloadModel.vehiclePosting!.phoneNo,
"whatsAppNo": adsCreationPayloadModel.vehiclePosting!.whatsAppNo,
"odometer": adsCreationPayloadModel.vehiclePosting!.odometer,
"isInUsed": adsCreationPayloadModel.vehiclePosting!.isInUsed,
"isAccidentFree": adsCreationPayloadModel.vehiclePosting!.isAccidentFree,
// "adStatus": 1,
},
"stepNo": stepNo.toIntFromStepsEnum(),
};
String token = appState.getUser.data!.accessToken ?? "";
GenericRespModel adsGenericModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json),
isCreateNew ? ApiConsts.adsSingleStepDraftCreate : ApiConsts.adsSingleStepDraftUpdate,
postParams,
token: token,
);
return Future.value(adsGenericModel);
}
@override
Future<List<AdDetailsModel>> getMyDraftAds({int? page}) async {
var draftAdsParams = {
@ -323,7 +226,7 @@ class AdsRepoImp implements AdsRepo {
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
token: appState.getUser.data!.accessToken,
(json) => GenericRespModel.fromJson(json),
ApiConsts.getMyDraftAds,
ApiConsts.vehicleAdsGet,
queryParameters: draftAdsParams,
);
List<AdDetailsModel> vehicleAdsDetails = List.generate(
@ -591,14 +494,11 @@ class AdsRepoImp implements AdsRepo {
var postParams = {
"adsID": adId,
"customerID": customerID,
"adsReserveStatus": adsReserveStatus,
"comment": reason,
};
if (!AppState().getIsViewOnly) {
postParams["customerID"] = customerID;
}
String token = appState.getUser.data!.accessToken ?? "";
GenericRespModel adsGenericModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json),
@ -616,13 +516,10 @@ class AdsRepoImp implements AdsRepo {
var postParams = {
"adsID": adId,
"customerID": customerID,
"adsReserveStatus": 0,
};
if (!AppState().getIsViewOnly) {
postParams["customerID"] = customerID;
}
String token = appState.getUser.data!.accessToken ?? "";
GenericRespModel adsGenericModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json),
@ -679,14 +576,11 @@ class AdsRepoImp implements AdsRepo {
var postParams = {
"adsID": adId,
"customerID": customerId,
"detailNote": detailNote,
"receiptImages": receiptImages,
};
if (!AppState().getIsViewOnly) {
postParams["customerID"] = customerId;
}
String token = appState.getUser.data!.accessToken ?? "";
GenericRespModel adsGenericModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json),

@ -174,21 +174,16 @@ class AppointmentRepoImp implements AppointmentRepo {
slotId = schedule.selectedCustomTimeDateSlotModel!.availableSlots![index].slotId;
Map<String, dynamic> appointmentMap = {
mapList.add({
"serviceSlotID": slotId,
"serviceProviderID": serviceProviderID,
"customerID": customerId,
"serviceItemID": serviceItemIds,
"amountCustomerLocation": schedule.totalLocationCharges.toString(),
"customerLocLat": (schedule.locationInfoModel!.latitude).toString(),
"customerLocLong": (schedule.locationInfoModel!.longitude).toString(),
"customerLocAddress": (schedule.locationInfoModel!.address).toString(),
};
if (!appState.getIsViewOnly) {
appointmentMap["customerID"] = customerId;
}
mapList.add(appointmentMap);
});
}
log("maplist: ${mapList.toString()}");
@ -283,7 +278,8 @@ class AppointmentRepoImp implements AppointmentRepo {
List<String>? branchIdsList,
AppointmentStatusEnum? appointmentStatusEnum,
}) async {
var params = <String, dynamic>{
var params = {
"customerID": appState.getUser.data!.userInfo!.customerId.toString(),
"ServiceProviderIDs": providerIdsList ?? [],
"ProviderBranchIDs": branchIdsList ?? [],
"ServiceIDs": serviceIdsList ?? [],
@ -291,12 +287,8 @@ class AppointmentRepoImp implements AppointmentRepo {
"CategoryIDs": categoryIdsList ?? [],
};
if (!appState.getIsViewOnly) {
params["customerID"] = appState.getUser.data!.userInfo!.customerId.toString();
}
if (appointmentStatusEnum != null) {
params["AppointmentStatusID"] = appointmentStatusEnum.getIdFromAppointmentStatusEnum().toString();
params.addAll({"AppointmentStatusID": appointmentStatusEnum.getIdFromAppointmentStatusEnum().toString()});
}
GenericRespModel genericRespModel = await apiClient.getJsonForObject(
token: appState.getUser.data!.accessToken,

@ -587,11 +587,7 @@ class BranchRepoImp implements BranchRepo {
@override
Future<GenericRespModel> submitBranchRatings({required int serviceProviderBranchID, required String title, required String review, required double ratingNo}) async {
final customerID = appState.getUser.data!.userInfo!.customerId;
final parameters = {"title": title, "review": review, "ratNo": ratingNo, "serviceProviderBranchID": serviceProviderBranchID};
if (!appState.getIsViewOnly) {
parameters["customerID"] = "$customerID";
}
final parameters = {"title": title, "review": review, "ratNo": ratingNo, "serviceProviderBranchID": serviceProviderBranchID, "customerID": "$customerID"};
GenericRespModel adsGenericModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.createBranchRatings,
@ -606,12 +602,8 @@ class BranchRepoImp implements BranchRepo {
final customerID = appState.getUser.data!.userInfo!.customerId;
final parameters = {
"providerID": providerID.toString(),
"customerID": customerID.toString(),
};
if (!appState.getIsViewOnly) {
parameters["customerID"] = customerID.toString();
}
GenericRespModel adsGenericModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.favouriteServiceProviderCreate,
@ -637,17 +629,13 @@ class BranchRepoImp implements BranchRepo {
Future<List<ProviderProfileModel>> getMyFavoriteProviders() async {
final customerID = appState.getUser.data!.userInfo!.customerId;
var postParams = <String, dynamic>{};
if (!appState.getIsViewOnly) {
postParams["customerID"] = customerID.toString();
}
var postParams = {"customerID": customerID.toString()};
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.favouriteServiceProviderGet,
token: appState.getUser.data!.accessToken,
queryParameters: postParams.isNotEmpty ? postParams : null,
queryParameters: postParams,
);
List<ProviderProfileModel> favProviders = List.generate(adsGenericModel.data.length, (index) => ProviderProfileModel.fromJson(adsGenericModel.data[index]));
return favProviders;

@ -58,8 +58,6 @@ abstract class RequestRepo {
Future<GenericRespModel> updateRequestOfferStatus({required RequestOfferStatusEnum requestOfferStatusEnum, required int requestOfferId, required String comments});
Future<GenericRespModel> updateRequestDeliveryOptionByCustomer({required int requestID, required int requestOfferId, required RequestDeliveryOptionEnum deliveryOptionEnum});
Future<GenericRespModel> updateRequestOfferFromProvider({
required String message,
required int requestId,
@ -73,8 +71,6 @@ abstract class RequestRepo {
required List requestImages,
required RequestOfferStatusEnum requestOfferStatusEnum,
});
Future<GenericRespModel> updateRequestAdditionalAddress({required int requestID, required String additionalAddress});
}
class RequestRepoImp implements RequestRepo {
@ -98,6 +94,7 @@ class RequestRepoImp implements RequestRepo {
required List requestImages,
}) async {
Map<String, dynamic> postParams = {
"customerID": appState.getUser.data!.userInfo!.customerId ?? 0,
"requestType": requestTypeId,
"vehicleTypeID": vehicleTypeId,
"brand": brand,
@ -112,10 +109,6 @@ class RequestRepoImp implements RequestRepo {
"isSpecialServiceNeeded": false,
"requestImages": requestImages,
};
if (!appState.getIsViewOnly) {
postParams["customerID"] = appState.getUser.data!.userInfo!.customerId ?? 0;
}
GenericRespModel enumGenericModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.createRequest,
@ -135,10 +128,8 @@ class RequestRepoImp implements RequestRepo {
if (appState.currentAppType == AppType.provider) {
paramsForGetRequests.addEntries([MapEntry("providerID", providerOrCustomerID)]);
} else {
if (!appState.getIsViewOnly) {
paramsForGetRequests.addEntries([MapEntry("customerID", providerOrCustomerID)]);
}
}
GenericRespModel enumGenericModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.getRequest,
@ -185,9 +176,7 @@ class RequestRepoImp implements RequestRepo {
};
if (appState.currentAppType == AppType.customer) {
if (!appState.getIsViewOnly) {
paramsForGetRequests.addEntries([MapEntry("customerID", appState.getUser.data!.userInfo!.customerId ?? 0)]);
}
} else {
paramsForGetRequests.addEntries([MapEntry("providerID", appState.getUser.data!.userInfo!.providerId.toString())]);
}
@ -221,7 +210,6 @@ class RequestRepoImp implements RequestRepo {
RequestStatusEnum.paid.getIdFromRequestStatusEnum().toString(),
RequestStatusEnum.delivery.getIdFromRequestStatusEnum().toString(),
RequestStatusEnum.shipping.getIdFromRequestStatusEnum().toString(),
RequestStatusEnum.selfPickup.getIdFromRequestStatusEnum().toString(),
];
if (parameters['requestStatus'] != null && parameters['requestStatus'] != "0") {
@ -239,6 +227,7 @@ class RequestRepoImp implements RequestRepo {
parameters.removeWhere((key, value) => key == "doPagination");
parameters.addEntries([MapEntry("ServiceProviderId", appState.getUser.data!.userInfo!.providerId.toString())]);
log("parameters: ${parameters}");
// final parameters = {
// "ServiceProviderId": serviceProviderID.toString(),
// "RequestType": "2", // Only to get the Service Request
@ -268,7 +257,6 @@ class RequestRepoImp implements RequestRepo {
RequestStatusEnum.paid.getIdFromRequestStatusEnum().toString(),
RequestStatusEnum.delivery.getIdFromRequestStatusEnum().toString(),
RequestStatusEnum.shipping.getIdFromRequestStatusEnum().toString(),
RequestStatusEnum.selfPickup.getIdFromRequestStatusEnum().toString(),
];
final parameters = {
"ServiceProviderId": serviceProviderID.toString(),
@ -329,12 +317,9 @@ class RequestRepoImp implements RequestRepo {
Future<ProviderOffersModel> getOffersFromProvidersByRequest({required int requestId}) async {
final customerId = appState.getUser.data!.userInfo!.customerId;
var queryParameters = {
"customerID": customerId.toString(),
"requestID": requestId.toString(),
};
if (!appState.getIsViewOnly) {
queryParameters["customerID"] = customerId.toString();
}
GenericRespModel genericRespModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.requestOffersSpsGet,
@ -364,22 +349,6 @@ class RequestRepoImp implements RequestRepo {
return genericRespModel;
}
@override
Future<GenericRespModel> updateRequestAdditionalAddress({required int requestID, required String additionalAddress}) async {
var queryParameters = {
"requestID": requestID.toString(),
"additionalAddress": additionalAddress.toString(),
};
GenericRespModel genericRespModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.requestUpdateAdditionalAddress,
queryParameters,
token: appState.getUser.data!.accessToken,
);
return genericRespModel;
}
@override
Future<GenericRespModel> updateRequestOfferStatus({required RequestOfferStatusEnum requestOfferStatusEnum, required int requestOfferId, required String comments}) async {
var queryParameters = {
@ -397,23 +366,6 @@ class RequestRepoImp implements RequestRepo {
return genericRespModel;
}
@override
Future<GenericRespModel> updateRequestDeliveryOptionByCustomer({required int requestID, required int requestOfferId, required RequestDeliveryOptionEnum deliveryOptionEnum}) async {
var queryParameters = {
"requestID": requestID.toString(),
"requestOfferId": requestOfferId.toString(),
"deliveryOption": deliveryOptionEnum.getIdRequestDeliveryOptionEnum().toString(),
};
GenericRespModel genericRespModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.requestOfferUpdateDeliveryOptionByCustomer,
queryParameters,
token: appState.getUser.data!.accessToken,
);
return genericRespModel;
}
@override
Future<GenericRespModel> updateRequestOfferFromProvider({
required String message,

@ -166,16 +166,10 @@ class SettingOptionsRepoImp extends SettingOptionsRepo {
};
if (AppState().currentAppType == AppType.customer) {
if (!appState.getIsViewOnly) {
params.addAll({
"customerID": (appState.getUser.data!.userInfo!.customerId ?? "0").toString(),
"channelID": "3",
});
} else {
params.addAll({
"channelID": "3",
});
}
} else {
params.addAll({
"providerID": (appState.getUser.data!.userInfo!.providerId ?? "0").toString(),

@ -47,7 +47,7 @@ class ShippingRepoImp extends ShippingRepo {
return [];
}
List<ShippingRequestModel> list = List.generate(genericRespModel.data.length, (index) => ShippingRequestModel.fromJsonShipping(genericRespModel.data[index], true));
List<ShippingRequestModel> list = List.generate(genericRespModel.data.length, (index) => ShippingRequestModel.fromJson(genericRespModel.data[index]));
return list;
}
@ -72,7 +72,7 @@ class ShippingRepoImp extends ShippingRepo {
return [];
}
List<ShippingRequestModel> list = List.generate(genericRespModel.data.length, (index) => ShippingRequestModel.fromJsonShipping(genericRespModel.data[index], false));
List<ShippingRequestModel> list = List.generate(genericRespModel.data.length, (index) => ShippingRequestModel.fromJson(genericRespModel.data[index]));
return list;
}

@ -59,7 +59,6 @@ class MyColors {
static const Color expiredColor = Colors.grey;
static const Color shippingColor = Colors.purple;
static const Color deliveryColor = Colors.brown;
static const Color selfPickupColor = Colors.orange;
static Decoration gradient = BoxDecoration(
gradient: const LinearGradient(colors: [

@ -81,7 +81,6 @@ enum RequestStatusEnum {
expired,
shipping,
delivery,
selfPickup,
}
enum PaymentMethods {
@ -102,7 +101,7 @@ enum PaymentTypes {
partialAppointment,
}
enum AdCreationStepsEnum {
enum AdCreationSteps {
vehicleDetails,
damageParts,
adDuration,
@ -240,7 +239,6 @@ enum ShippingRequestStatusEnum {
enum SelfPickupRequestStatusEnum {
allRequests,
pending,
preparingToCollect,
readyToCollect,
collected,

@ -4,6 +4,7 @@ import 'dart:typed_data';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart';
@ -16,6 +17,7 @@ import 'package:mc_common_app/widgets/common_widgets/info_bottom_sheet.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:path/path.dart' as p;
import 'package:fluttertoast/fluttertoast.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/exceptions/api_exception.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
@ -25,7 +27,6 @@ import 'package:mc_common_app/widgets/loading_dialog.dart';
import 'package:share_plus/share_plus.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:url_launcher/url_launcher_string.dart';
import 'package:toastification/toastification.dart';
class Utils {
static bool _isLoadingVisible = false;
@ -33,14 +34,8 @@ class Utils {
static bool get isLoading => _isLoadingVisible;
static void showToast(String message) {
toastification.show(
type: ToastificationType.info,
style: ToastificationStyle.minimal,
title: Text(message),
autoCloseDuration: const Duration(seconds: 2),
alignment: Alignment.bottomCenter,
showProgressBar: false,
);
Fluttertoast.showToast(
msg: message, toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.BOTTOM, timeInSecForIosWeb: 2, backgroundColor: Colors.black54, textColor: Colors.white, fontSize: 16.0);
}
static Future<void> openNumberViaCaller({required String phoneNumber}) async {
@ -178,8 +173,8 @@ class Utils {
return base64Encode(imageBytes);
}
static Future delay(int seconds) async {
return await Future.delayed(Duration(seconds: seconds));
static Future delay(int millis) async {
return await Future.delayed(Duration(milliseconds: millis));
}
static inkWellCorner({double? r}) {
@ -279,8 +274,6 @@ class Utils {
return MyColors.shippingColor;
case RequestStatusEnum.delivery:
return MyColors.deliveryColor;
case RequestStatusEnum.selfPickup:
return MyColors.selfPickupColor;
}
}
@ -339,25 +332,6 @@ class Utils {
}
}
static String getNameBySelfPickupRequestStatusEnum(SelfPickupRequestStatusEnum selfPickupRequestStatusEnum) {
switch (selfPickupRequestStatusEnum) {
case SelfPickupRequestStatusEnum.allRequests:
return "All Requests";
case SelfPickupRequestStatusEnum.pending:
return "Pending";
case SelfPickupRequestStatusEnum.preparingToCollect:
return "Preparing To Collect";
case SelfPickupRequestStatusEnum.readyToCollect:
return "Ready To Collect";
case SelfPickupRequestStatusEnum.collected:
return "Collected";
}
}
static Color getChipColorByShippingRequestStatusEnum(ShippingRequestStatusEnum shippingRequestStatusEnum) {
switch (shippingRequestStatusEnum) {
case ShippingRequestStatusEnum.allRequests:
@ -380,25 +354,6 @@ class Utils {
}
}
static Color getChipColorBySelfPickupRequestStatusEnum(SelfPickupRequestStatusEnum selfPickupRequestStatusEnum) {
switch (selfPickupRequestStatusEnum) {
case SelfPickupRequestStatusEnum.allRequests:
return MyColors.submittedColor;
case SelfPickupRequestStatusEnum.pending:
return MyColors.pendingColor;
case SelfPickupRequestStatusEnum.preparingToCollect:
return MyColors.submittedColor;
case SelfPickupRequestStatusEnum.readyToCollect:
return MyColors.shippingColor;
case SelfPickupRequestStatusEnum.collected:
return MyColors.deliveryColor;
}
}
static Color getChipColorByBranchStatus(BranchStatusEnum branchStatusEnum) {
switch (branchStatusEnum) {
case BranchStatusEnum.pending:
@ -778,12 +733,12 @@ class NoInternetDialog {
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text(
LocaleKeys.connectionProblem.tr(),
title: const Text(
LocaleKeys.connectionProblem,
textAlign: TextAlign.center,
),
content: Text(
LocaleKeys.pleaseCheckConnection.tr(),
content: const Text(
LocaleKeys.pleaseCheckConnection,
textAlign: TextAlign.center,
),
actions: [

@ -44,7 +44,7 @@ class AdVM extends BaseVM {
AdVM({required this.commonServices, required this.commonRepo, required this.adsRepo});
AdCreationStepsEnum currentProgressStep = AdCreationStepsEnum.vehicleDetails;
AdCreationSteps currentProgressStep = AdCreationSteps.vehicleDetails;
VehicleDetailsModel? vehicleDetails;
@ -82,7 +82,6 @@ class AdVM extends BaseVM {
// Edit Variables Amir
bool isExtendAdEditEnabled = false;
bool isAdEditEnabled = false;
bool isDraftEditEnabled = false;
AdDetailsModel? previousAdDetails;
List<AdDetailsModel> myDraftAds = [];
@ -348,20 +347,15 @@ class AdVM extends BaseVM {
int pageIndexForMyDrafts = 1;
Future<void> getMyDraftAds() async {
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<void> fetchMoreDraftAds() async {
Future<void> fetchMoreDraftAds({required AdPostStatus adsStatus}) async {
if (isLoadingMore) return;
hasMoreDataForMyDraftsAds = true;
isLoadingMore = true;
@ -729,29 +723,6 @@ class AdVM extends BaseVM {
vehicleDemandAmount = amount;
}
String odometer = "";
void updateOdometer(String value) {
odometer = value;
notifyListeners();
}
int isInUsed = 0;
void updateIsInUsed(int value) {
isInUsed = value;
notifyListeners();
}
bool isAccidentFree = false;
bool isAccidentFreeSet = false;
void updateIsAccidentFree(bool value) {
isAccidentFree = value;
isAccidentFreeSet = true;
notifyListeners();
}
String reservationCancelReason = "";
String reservationCancelError = "";
@ -1242,170 +1213,64 @@ class AdVM extends BaseVM {
void onBackButtonPressed(BuildContext context) {
switch (currentProgressStep) {
case AdCreationStepsEnum.vehicleDetails:
isAdEditEnabled = false;
isDraftEditEnabled = false;
case AdCreationSteps.vehicleDetails:
resetValues();
pop(context);
break;
case AdCreationStepsEnum.damageParts:
currentProgressStep = AdCreationStepsEnum.vehicleDetails;
case AdCreationSteps.damageParts:
currentProgressStep = AdCreationSteps.vehicleDetails;
notifyListeners();
break;
case AdCreationStepsEnum.adDuration:
currentProgressStep = AdCreationStepsEnum.damageParts;
case AdCreationSteps.adDuration:
currentProgressStep = AdCreationSteps.damageParts;
notifyListeners();
break;
case AdCreationStepsEnum.reviewAd:
currentProgressStep = AdCreationStepsEnum.adDuration;
case AdCreationSteps.reviewAd:
currentProgressStep = AdCreationSteps.adDuration;
notifyListeners();
break;
}
}
Future<int> saveAdVehicleDetailsDraft({required bool isNew, required BuildContext context, required AdCreationStepsEnum stepNoEnum}) async {
AppState appState = injector.get<AppState>();
log("selectionDurationStartDate: $selectionDurationStartDate");
log("specialServiceCards: ${specialServiceCards.length}");
List<int> 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<VehiclePostingImages> vehicleImages = [];
for (var image in pickedPostingImages) {
vehicleImages.add(await convertFileToVehiclePostingImages(imageModel: image));
}
List<VehiclePostingDamageParts> 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,
vehicleType: vehicleTypeId.selectedId,
vehicleModelID: vehicleModelId.selectedId,
vehicleModelYearID: vehicleModelYearId.selectedId,
vehicleColorID: vehicleColorId.selectedId,
vehicleCategoryID: vehicleCategoryId.selectedId,
vehicleConditionID: vehicleConditionId.selectedId,
vehicleMileageID: vehicleMileageId.selectedId,
vehicleTransmissionID: vehicleTransmissionId.selectedId,
vehicleSellerTypeID: vehicleSellerTypeId.selectedId == -1 ? 1 : vehicleSellerTypeId.selectedId,
cityID: vehicleCityId.selectedId,
price: int.parse(vehicleDemandAmount),
vehicleVIN: vehicleVin,
vehicleDescription: vehicleDescription,
vehicleTitle: vehicleTitle,
vehicleDescriptionN: vehicleDescription,
isFinanceAvailable: financeAvailableStatus,
warantyYears: int.parse(warrantyDuration),
demandAmount: int.parse(vehicleDemandAmount),
vehiclePostingImages: vehicleImages,
vehiclePostingDamageParts: vehicleDamageImages,
phoneNo: isPhoneNumberShown ? adPhoneNumberDialCode + adPhoneNumber : null,
whatsAppNo: (isPhoneNumberShown && isNumberOnWhatsApp) ? adPhoneNumberDialCode + adPhoneNumber : null,
odometer: odometer.isNotEmpty ? int.tryParse(odometer) : 0,
isInUsed: isInUsed,
isAccidentFree: isAccidentFree,
);
AdsCreationPayloadModel adsCreationPayloadModel = AdsCreationPayloadModel(ads: ads, vehiclePosting: vehiclePosting);
GenericRespModel respModel = await adsRepo.createOrUpdateDraftAd(
adsCreationPayloadModel: adsCreationPayloadModel,
isCreateNew: isNew,
stepNo: stepNoEnum,
);
Utils.hideLoading(context);
return Future.value(respModel.messageStatus == 1 ? respModel.data : -1);
} catch (e) {
Utils.hideLoading(context);
logger.e(e.toString());
return -1;
}
}
Future saveAdDamagePartDetailsDraft() async {}
Future saveAdDurationsDraft() async {}
void updateCurrentStep(BuildContext context) async {
switch (currentProgressStep) {
case AdCreationStepsEnum.vehicleDetails:
case AdCreationSteps.vehicleDetails:
if (isVehicleDetailsValidated()) {
int adID = await saveAdVehicleDetailsDraft(isNew: previousAdDetails == null || previousAdDetails!.id == null, context: context, stepNoEnum: AdCreationStepsEnum.vehicleDetails);
if (previousAdDetails == null || previousAdDetails!.id == null) {
previousAdDetails = AdDetailsModel();
previousAdDetails!.id = adID;
}
currentProgressStep = AdCreationStepsEnum.damageParts;
currentProgressStep = AdCreationSteps.damageParts;
getVehicleDamagePartsList();
notifyListeners();
}
break;
case AdCreationStepsEnum.damageParts:
case AdCreationSteps.damageParts:
if (isDamagePartsValidated()) {
await saveAdVehicleDetailsDraft(isNew: false, context: context, stepNoEnum: AdCreationStepsEnum.damageParts);
currentProgressStep = AdCreationStepsEnum.adDuration;
currentProgressStep = AdCreationSteps.adDuration;
if (vehicleAdsDurations.isEmpty) {
getVehicleAdsDuration();
}
getVehicleAdsSpecialServices(countryId: vehicleCountryId.selectedId, cityId: vehicleCityId.selectedId, specialServiceType: 1);
notifyListeners();
}
break;
case AdCreationStepsEnum.adDuration:
// log("state: ${AppState().getUser.data!.accessToken}");
case AdCreationSteps.adDuration:
if (isAdDurationValidated()) {
await saveAdVehicleDetailsDraft(isNew: false, context: context, stepNoEnum: AdCreationStepsEnum.adDuration);
currentProgressStep = AdCreationStepsEnum.reviewAd;
currentProgressStep = AdCreationSteps.reviewAd;
notifyListeners();
}
break;
case AdCreationStepsEnum.reviewAd:
case AdCreationSteps.reviewAd:
Utils.showLoading(context);
try {
bool status = await createNewAd();
if (!status) {
int status = await createNewAd();
if (status != 1) {
Utils.hideLoading(context);
return;
}
isAdEditEnabled = false;
isDraftEditEnabled = false;
isExtendAdEditEnabled = false;
Utils.hideLoading(context);
currentProgressStep = AdCreationStepsEnum.vehicleDetails;
currentProgressStep = AdCreationSteps.vehicleDetails;
resetValues();
updateIsExploreAds(false);
applyFilterOnMyAds(adPostStatusEnum: AdPostStatus.pendingForReview); //pending for review
@ -1463,7 +1328,7 @@ class AdVM extends BaseVM {
// Added By Aamir
if (pickedPostingImages.length > GlobalConsts.maxFileCount) {
pickedPostingImages = pickedPostingImages.sublist(0, GlobalConsts.maxFileCount);
Utils.showToast(LocaleKeys.maxFileSelection.tr());
Utils.showToast(LocaleKeys.maxFileSelection);
}
if (pickedPostingImages.isNotEmpty) vehicleImageError = "";
@ -1511,7 +1376,7 @@ class AdVM extends BaseVM {
// Added By Aamir
if (vehicleDamageCards[index].partImages!.length > GlobalConsts.maxFileCount) {
vehicleDamageCards[index].partImages = vehicleDamageCards[index].partImages!.sublist(0, GlobalConsts.maxFileCount);
Utils.showToast(LocaleKeys.maxFileSelection.tr());
Utils.showToast(LocaleKeys.maxFileSelection);
}
}
@ -1567,7 +1432,7 @@ class AdVM extends BaseVM {
if (pickedDamageImages.length > GlobalConsts.maxFileCount) {
pickedDamageImages = pickedDamageImages.sublist(0, GlobalConsts.maxFileCount);
Utils.showToast(LocaleKeys.maxFileSelection.tr());
Utils.showToast(LocaleKeys.maxFileSelection);
}
if (pickedDamageImages.isNotEmpty) vehicleDamageImageError = "";
notifyListeners();
@ -1579,7 +1444,7 @@ class AdVM extends BaseVM {
vehicleDamageCards.clear();
specialServiceCards.clear();
vehicleAdsSpecialServices.clear();
currentProgressStep = AdCreationStepsEnum.vehicleDetails;
currentProgressStep = AdCreationSteps.vehicleDetails;
vehicleTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
vehicleModelId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
// vehicleAdDurationId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
@ -1603,10 +1468,6 @@ class AdVM extends BaseVM {
isNumberOnWhatsApp = false;
adPhoneNumberDialCode = "";
adPhoneNumber = "";
odometer = "";
isInUsed = 0;
isAccidentFree = false;
isAccidentFreeSet = false;
clearSpecialServiceCard();
updateFinanceAvailableStatus(false);
notifyListeners();
@ -1743,7 +1604,7 @@ class AdVM extends BaseVM {
}
}
Future<bool> createNewAd() async {
Future<int> createNewAd() async {
AppState appState = injector.get<AppState>();
List<int> adsSelectedServices = [];
@ -1764,11 +1625,7 @@ class AdVM extends BaseVM {
log("selectionDurationStartDate: $selectionDurationStartDate");
Ads ads = Ads(
id: isDraftEditEnabled
? null
: isAdEditEnabled
? previousAdDetails!.id
: null,
id: isAdEditEnabled ? previousAdDetails!.id : null,
adsDurationID: vehicleAdDurationId.selectedId == -1 ? 0 : vehicleAdDurationId.selectedId,
startDate: selectionDurationStartDate,
countryId: vehicleCountryId.selectedId,
@ -1822,22 +1679,15 @@ class AdVM extends BaseVM {
vehiclePostingDamageParts: vehicleDamageImages,
phoneNo: isPhoneNumberShown ? adPhoneNumberDialCode + adPhoneNumber : null,
whatsAppNo: (isPhoneNumberShown && isNumberOnWhatsApp) ? adPhoneNumberDialCode + adPhoneNumber : null,
odometer: odometer.isNotEmpty ? int.tryParse(odometer) : 0,
isInUsed: isInUsed,
isAccidentFree: isAccidentFree,
);
AdsCreationPayloadModel adsCreationPayloadModel = AdsCreationPayloadModel(ads: ads, vehiclePosting: vehiclePosting);
GenericRespModel respModel = await adsRepo.createOrUpdateAd(
adsCreationPayloadModel: adsCreationPayloadModel,
isCreateNew: isDraftEditEnabled ? true : !isAdEditEnabled,
isExtendAdEditEnabled: isExtendAdEditEnabled,
);
GenericRespModel respModel = await adsRepo.createOrUpdateAd(adsCreationPayloadModel: adsCreationPayloadModel, isCreateNew: !isAdEditEnabled, isExtendAdEditEnabled: isExtendAdEditEnabled);
Utils.showToast(respModel.message.toString());
return Future.value(respModel.messageStatus == 1);
return Future.value(respModel.messageStatus);
}
Future<VehiclePostingImages> convertFileToVehiclePostingImages({required ImageModel imageModel}) async {
@ -2371,16 +2221,13 @@ class AdVM extends BaseVM {
return [];
}
void onEditUpdateAdPressed({required BuildContext context, required AdDetailsModel previousDetails, required bool isFromExtendAd, bool isForDraft = false}) {
void onEditUpdateAdPressed({required BuildContext context, required AdDetailsModel previousDetails, required bool isFromExtendAd}) {
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]);
}
@ -2409,14 +2256,12 @@ 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;
}
}
@ -2457,9 +2302,6 @@ 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) {
@ -2488,16 +2330,11 @@ class AdVM extends BaseVM {
vehicleTitle = previousAdDetails!.vehicle!.vehicleTitle.toString();
vehicleDescription = previousAdDetails!.vehicle!.vehicleDescription.toString();
financeAvailableStatus = previousAdDetails!.vehicle!.isFinanceAvailable ?? false;
odometer = previousAdDetails!.vehicle!.odometer != null ? previousAdDetails!.vehicle!.odometer.toString() : "0";
isInUsed = previousAdDetails!.vehicle!.isInUsed ?? 0;
isAccidentFree = previousAdDetails!.vehicle!.isAccidentFree ?? false;
isAccidentFreeSet = true;
pickedPostingImages.clear();
if (previousAdDetails!.vehicle!.image != null && previousAdDetails!.vehicle!.image!.isNotEmpty) {
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);
}
}
@ -2539,16 +2376,12 @@ class AdVM extends BaseVM {
address: "",
serviceTime: "",
);
int index = ifSpecialServiceAlreadyThere(element.specialServiceID!);
log("Found at : $index");
if (index == -1) {
addNewSpecialServiceCard(specialServiceCard: specialServiceCard);
}
}
}
// selectionDurationStartDate = DateHelper.formatDateT(previousAdDetails!.startdate ?? "");
selectionDurationStartDate = ""; // You have to mention this each time
selectionDurationStartDate = "";
isPhoneNumberShown = previousAdDetails!.showContactDetail ?? false;
adPhoneNumber = previousAdDetails!.adOwnerDetails!.mobileNo ?? "";

@ -307,7 +307,9 @@ 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);
@ -377,8 +379,6 @@ class AppointmentsVM extends BaseVM {
}
if (isNeedCustomerFilter) {
log("myFilteredAppointmentsForProvider: ${myFilteredAppointmentsForProvider.length}");
myFilteredAppointmentsForProvider = findAppointmentsBasedOnCustomers(myFilteredAppointmentsForProvider);
}
notifyListeners();
@ -416,14 +416,19 @@ class AppointmentsVM extends BaseVM {
List<AppointmentListModel> groupedList = uniqueCustomerIDs.map((id) {
List<AppointmentListModel> list = appointments.where((item) => item.customerID == id).toList();
list.sort((a, b) => DateHelper.parseStringToDate(DateHelper.formatDateT(b.appointmentDate!))
list.sort((a, b) =>
DateHelper
.parseStringToDate(DateHelper.formatDateT(b.appointmentDate!))
.millisecondsSinceEpoch
.compareTo(DateHelper.parseStringToDate(DateHelper.formatDateT(a.appointmentDate!)).millisecondsSinceEpoch));
.compareTo(DateHelper
.parseStringToDate(DateHelper.formatDateT(a.appointmentDate!))
.millisecondsSinceEpoch));
AppointmentListModel model = list.first;
model.customerAppointmentList = list;
return model;
}).toList();
return groupedList;
}
@ -487,9 +492,6 @@ 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;
}
@ -517,7 +519,10 @@ class AppointmentsVM extends BaseVM {
}
int countSelected(List<AppointmentListModel> 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}) {
@ -693,7 +698,8 @@ class AppointmentsVM extends BaseVM {
Column(
children: List.generate(
selectedService.serviceItems!.length,
(index) => Row(
(index) =>
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"${selectedService.serviceItems![index].name}".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
@ -918,7 +924,10 @@ 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: [

@ -447,7 +447,7 @@ class ChatVM extends BaseVM {
pickedImagesForMessage.addAll(imageModels);
if (pickedImagesForMessage.length > GlobalConsts.maxFileCount) {
pickedImagesForMessage = pickedImagesForMessage.sublist(0, GlobalConsts.maxFileCount);
Utils.showToast(LocaleKeys.maxFileSelection.tr());
Utils.showToast(LocaleKeys.maxFileSelection);
}
notifyListeners();
@ -635,7 +635,7 @@ class ChatVM extends BaseVM {
try {
GenericRespModel genericRespModel = await requestRepo.updateRequestOfferStatus(requestOfferStatusEnum: requestOfferStatusEnum, requestOfferId: reqOfferId, comments: comments);
Utils.showToast(genericRespModel.message.toString());
Utils.hideLoading(context);
Utils.showLoading(context);
return genericRespModel.messageStatus == 1 ? reqOfferId : -1;
} catch (e) {
logger.i(e.toString());

@ -94,11 +94,7 @@ class DashboardVMProvider extends BaseVM {
}
await shippingManagementVM.populateShippingRequestFilterList();
await shippingManagementVM.populateSelfPickupRequestFilterList();
await appointmentVM.applyFilterOnAppointmentsVMForProviders(
appointmentStatusEnum: AppointmentStatusEnum.allAppointments,
isNeedCustomerFilter: true,
shouldPopulateUpcoming: true,
);
await appointmentVM.applyFilterOnAppointmentsVMForProviders(appointmentStatusEnum: AppointmentStatusEnum.allAppointments, shouldPopulateUpcoming: true);
await adVM.getVehicleTypes();
await adVM.getVehicleAdsDuration();

@ -81,12 +81,10 @@ class RequestsVM extends BaseVM {
notifyListeners();
}
void updateAdditionalAddressSparePartRequestDelivery(String value, bool isNotify) {
void updateAdditionalAddressSparePartRequestDelivery(String value) {
additionalAddressSparePartRequestDelivery = value;
if (isNotify) {
notifyListeners();
}
}
RequestDeliveryOptionEnum? selectedDeliveryOptionEnum;
@ -294,7 +292,7 @@ class RequestsVM extends BaseVM {
pickedVehicleImages.addAll(imageModels);
if (pickedVehicleImages.length > GlobalConsts.maxFileCount) {
pickedVehicleImages = pickedVehicleImages.sublist(0, GlobalConsts.maxFileCount);
Utils.showToast(LocaleKeys.maxFileSelection.tr());
Utils.showToast(LocaleKeys.maxFileSelection);
}
if (pickedVehicleImages.isNotEmpty) vehicleImageError = "";
@ -861,7 +859,7 @@ class RequestsVM extends BaseVM {
Utils.showToast(LocaleKeys.addValidDescription.tr());
isValid = false;
} else if (address.isEmpty && requestTypeId.selectedId == 2) {
Utils.showToast(LocaleKeys.addValidAddress.tr());
Utils.showToast(LocaleKeys.addValidDescription.tr());
isValid = false;
}
return isValid;
@ -976,13 +974,7 @@ class RequestsVM extends BaseVM {
void populateRequestDeliveryOptions() {
deliveryOptionsForReviewRequest.clear();
log("acceptedRequestOffer!.requestDeliveryOption: ${acceptedRequestOffer!.requestDeliveryOption}");
if (acceptedRequestOffer != null && acceptedRequestOffer!.requestDeliveryOption == RequestDeliveryOptionEnum.both) {
deliveryOptionsForReviewRequest.addAll(myDeliveryOptionsFilterOptions.where((element) => element.id != RequestDeliveryOptionEnum.both.getIdRequestDeliveryOptionEnum()).toList());
} else {
deliveryOptionsForReviewRequest.addAll(myDeliveryOptionsFilterOptions.where((element) => element.id == acceptedRequestOffer!.requestDeliveryOption!.getIdRequestDeliveryOptionEnum()));
}
notifyListeners();
}
@ -1317,38 +1309,4 @@ class RequestsVM extends BaseVM {
}
}
}
Future<int> onRequestDeliveryOptionTapped({required BuildContext context, required int requestID, required int reqOfferId, required RequestDeliveryOptionEnum deliveryOptionEnum}) async {
Utils.showLoading(context);
try {
GenericRespModel genericRespModel = await requestRepo.updateRequestDeliveryOptionByCustomer(requestID: requestID, requestOfferId: reqOfferId, deliveryOptionEnum: deliveryOptionEnum);
Utils.hideLoading(context);
return genericRespModel.messageStatus == 1 ? reqOfferId : -1;
} catch (e) {
logger.i(e.toString());
Utils.showToast(e.toString());
Utils.hideLoading(context);
return -1;
}
}
Future<bool> updateRequestAdditionalAddress({required BuildContext context, required String additionalAddress, required int requestId, bool needLoading = true}) async {
if (needLoading) {
Utils.showLoading(context);
}
try {
GenericRespModel genericRespModel = await requestRepo.updateRequestAdditionalAddress(requestID: requestId, additionalAddress: additionalAddress);
if (needLoading) {
Utils.hideLoading(context);
}
return genericRespModel.messageStatus == 1;
} catch (e) {
logger.i(e.toString());
Utils.showToast(e.toString());
if (needLoading) {
Utils.hideLoading(context);
}
return false;
}
}
}

@ -142,7 +142,7 @@ class ServiceVM extends BaseVM {
pickedBranchImages.addAll(imageModels);
if (pickedBranchImages.length > GlobalConsts.maxFileCount) {
pickedBranchImages = pickedBranchImages.sublist(0, GlobalConsts.maxFileCount);
Utils.showToast(LocaleKeys.maxFileSelection.tr());
Utils.showToast(LocaleKeys.maxFileSelection);
}
if (pickedBranchImages.isNotEmpty) branchImageError = "";
notifyListeners();
@ -275,7 +275,11 @@ class ServiceVM extends BaseVM {
context,
allowMultiple: false,
);
if (files != null && files.any((element) => element.path.split('.').last.toLowerCase() != 'pdf')) {
if (files != null && files.any((element) =>
element.path
.split('.')
.last
.toLowerCase() != 'pdf')) {
Utils.showToast("Only PDF Files are allowed");
return;
}
@ -837,7 +841,9 @@ class ServiceVM extends BaseVM {
File file = File(imageModel.filePath!);
List<int> imageBytes = await file.readAsBytes();
String image = base64Encode(imageBytes);
String fileName = file.path.split('/').last;
String fileName = file.path
.split('/')
.last;
branchPostingImages = BranchPostingImages(
imageName: fileName,
imageStr: image,

@ -92,14 +92,11 @@ class SettingOptionsVM extends BaseVM {
List<AppInvitationHistoryModel> appInvitationHistoryList = [];
Future<void> getAppInvitationHistoryList(BuildContext context) async {
Utils.showLoading(context);
Future<void> getAppInvitationHistoryList() async {
try {
appInvitationHistoryList = await settingOptionsRepo.getAppInvitationsHistory();
Utils.hideLoading(context);
} catch (e) {
logger.i(e.toString());
Utils.hideLoading(context);
}
}
}

@ -66,9 +66,6 @@ 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();
}
@ -85,9 +82,6 @@ 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));
@ -137,14 +131,6 @@ class ShippingManagementVM extends BaseVM {
notifyListeners();
}
void updateSelectionInSelfPickupRequestStatuses(int index) {
for (var value in selfPickupRequestsStatusesList) {
value.isSelected = false;
}
selfPickupRequestsStatusesList[index].isSelected = true;
notifyListeners();
}
Future<void> getShippingRequestsListByFilters({ShippingRequestStatusEnum? shippingStatusEnum}) async {
setState(ViewState.busy);
try {
@ -186,21 +172,4 @@ class ShippingManagementVM extends BaseVM {
return false;
}
}
Future<bool> onUpdateSelfPickupStatusTapped({required BuildContext context, required SelfPickupRequestStatusEnum selfPickupRequestStatusEnum, required int shippingRequestId}) async {
Utils.showLoading(context);
try {
GenericRespModel? genericRespModel =
await shippingRepo.updateSelfPickupRequestStatus(selfPickupStatusEnum: selfPickupRequestStatusEnum, shippingRequestId: shippingRequestId, comment: requestStatusComments);
Utils.showToast(genericRespModel.message.toString());
Utils.hideLoading(context);
requestStatusComments = "";
return genericRespModel.messageStatus == 1;
} catch (e) {
logger.i(e.toString());
Utils.showToast(e.toString());
Utils.hideLoading(context);
return false;
}
}
}

@ -78,10 +78,6 @@ class VehicleDetailsReview extends StatelessWidget {
16.height,
SingleDetailWidget(text: adVM.vehicleCityId.selectedOption, type: LocaleKeys.vehicleCity.tr()),
16.height,
SingleDetailWidget(text: adVM.isAccidentFree ? LocaleKeys.yes.tr() : LocaleKeys.no.tr(), type: LocaleKeys.accidentFree.tr()),
16.height,
SingleDetailWidget(text: "${adVM.odometer} Km", type: LocaleKeys.odometer.tr()),
16.height,
SingleDetailWidget(text: adVM.vehicleVin, type: LocaleKeys.vehicleVIN.tr()),
16.height,
SingleDetailWidget(text: ("${adVM.warrantyDuration} ${LocaleKeys.years.tr()}"), type: LocaleKeys.warrantyAvailable.tr()),
@ -108,9 +104,7 @@ class VehicleDetailsReview extends StatelessWidget {
16.height,
SingleDetailWidget(text: adVM.vehicleTitle, type: LocaleKeys.vehicleTitle.tr()),
16.height,
SingleDetailWidget(text: adVM.financeAvailableStatus ? LocaleKeys.yes.tr() : LocaleKeys.no.tr(), type: LocaleKeys.financeAvailable.tr()),
16.height,
SingleDetailWidget(text: adVM.isInUsed == 1 ? LocaleKeys.yes.tr() : LocaleKeys.no.tr(), type: LocaleKeys.currentlyInUse.tr()),
SingleDetailWidget(text: adVM.financeAvailableStatus ? "Yes" : "No", type: LocaleKeys.financeAvailable.tr()),
16.height,
],
),

@ -237,28 +237,6 @@ class VehicleDetails extends StatelessWidget {
errorValue: adVM.vehicleCityId.errorValue,
);
}),
8.height,
Builder(builder: (context) {
List<DropValue> accidentFreeDrop = [
DropValue(1, LocaleKeys.yes.tr(), ""),
DropValue(0, LocaleKeys.no.tr(), ""),
];
return DropdownField(
(DropValue value) => adVM.updateIsAccidentFree(value.id == 1),
list: accidentFreeDrop,
dropdownValue: adVM.isAccidentFreeSet ? DropValue(adVM.isAccidentFree ? 1 : 0, adVM.isAccidentFree ? LocaleKeys.yes.tr() : LocaleKeys.no.tr(), "") : null,
hint: LocaleKeys.hasYourCarHadAccident.tr(),
errorValue: "",
);
}),
8.height,
TxtField(
value: adVM.odometer,
keyboardType: TextInputType.number,
numbersOnly: true,
hint: LocaleKeys.odometerReading.tr(),
onChanged: (v) => adVM.updateOdometer(v),
),
],
],
8.height,
@ -304,13 +282,6 @@ class VehicleDetails extends StatelessWidget {
onChanged: (v) => adVM.updateVehicleDescription(v),
),
22.height,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.financeAvailable.tr().toText(fontSize: 16),
8.height,
Container(
@ -334,42 +305,6 @@ class VehicleDetails extends StatelessWidget {
),
),
),
],
),
),
8.width,
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.currentlyInUse.tr().toText(fontSize: 16),
8.height,
Container(
width: 50,
height: 30,
decoration: BoxDecoration(
color: adVM.isInUsed == 1 ? MyColors.darkPrimaryColor : MyColors.white,
borderRadius: BorderRadius.circular(25.0),
border: Border.all(color: MyColors.black, width: 1),
),
child: Transform.scale(
scale: 0.8,
child: CupertinoSwitch(
activeColor: MyColors.darkPrimaryColor,
trackColor: MyColors.white,
thumbColor: MyColors.grey98Color,
value: adVM.isInUsed == 1,
onChanged: (value) {
adVM.updateIsInUsed(value ? 1 : 0);
},
),
),
),
],
),
),
],
),
28.height,
LocaleKeys.vehiclePictures.tr().toText(fontSize: 18, isBold: true),
8.height,

@ -1,5 +1,7 @@
import 'dart:async';
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
@ -104,20 +106,13 @@ class _AdsDetailViewState extends State<AdsDetailView> {
children: [
Row(
children: [
("${LocaleKeys.vehicleModel.tr()}: ").toText(fontSize: 12, color: MyColors.lightTextColor),
"${widget.adDetails.vehicle!.model!.label}".toText(fontSize: 12),
],
),
(widget.adDetails.vehicle!.countryName ?? '').toText(fontSize: 10, color: MyColors.lightTextColor),
("${LocaleKeys.model.tr()}: ").toText(fontSize: 12, color: MyColors.lightTextColor),
"${widget.adDetails.vehicle!.modelyear!.label}".toText(fontSize: 12),
],
),
Row(
children: [
("${LocaleKeys.vehicleModelYear.tr()}: ").toText(fontSize: 12, color: MyColors.lightTextColor),
"${widget.adDetails.vehicle!.modelyear!.label}".toText(fontSize: 12),
"${widget.adDetails.vehicle!.countryID}".toText(fontSize: 10, color: MyColors.lightTextColor),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
@ -136,24 +131,6 @@ class _AdsDetailViewState extends State<AdsDetailView> {
"${widget.adDetails.vehicle!.transmission!.label}".toText(fontSize: 12),
],
),
Row(
children: [
("${LocaleKeys.odometer.tr()}: ").toText(fontSize: 12, color: MyColors.lightTextColor),
"${widget.adDetails.vehicle!.odometer ?? 0} Km".toText(fontSize: 12),
],
),
Row(
children: [
("${LocaleKeys.vehicleCondition.tr()}: ").toText(fontSize: 12, color: MyColors.lightTextColor),
(widget.adDetails.vehicle!.isInUsed == 0 ? LocaleKeys.brandNew.tr() : LocaleKeys.used.tr()).toText(fontSize: 12),
],
),
Row(
children: [
("${LocaleKeys.accidentFree.tr()}: ").toText(fontSize: 12, color: MyColors.lightTextColor),
((widget.adDetails.vehicle!.isAccidentFree ?? false) ? LocaleKeys.yes.tr() : LocaleKeys.no.tr()).toText(fontSize: 12),
],
),
Row(
children: [
("${LocaleKeys.financeAvailable.tr()}: ").toText(fontSize: 12, color: MyColors.lightTextColor),
@ -413,7 +390,7 @@ class _AdsDetailViewState extends State<AdsDetailView> {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(child: ("${widget.adDetails.specialservice![index].name}").toText(fontSize: 14, color: MyColors.lightTextColor)),
("${widget.adDetails.specialservice![index].price} ${widget.adDetails.vehicle!.currency ?? LocaleKeys.sar.tr()} ").toText(fontSize: 14, color: MyColors.lightTextColor),
("${widget.adDetails.specialservice![index].price} ${LocaleKeys.sar.tr()} ").toText(fontSize: 14, color: MyColors.lightTextColor),
],
)),
),

@ -56,7 +56,7 @@ class BuildAdDetailsActionButtonForExploreAds extends StatelessWidget {
children: [
"${adDetailsModel.reservePrice}".toText(fontSize: 19, isBold: true),
2.width,
(adDetailsModel.vehicle!.currency ?? LocaleKeys.sar.tr()).toText(color: MyColors.lightTextColor, fontSize: 10, isBold: true).paddingOnly(bottom: 3),
LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, fontSize: 10, isBold: true).paddingOnly(bottom: 3),
],
)
],
@ -73,7 +73,7 @@ class BuildAdDetailsActionButtonForExploreAds extends StatelessWidget {
children: [
"${adDetailsModel.vehicle!.demandAmount ?? 0.0}".toText(fontSize: 19, isBold: true),
2.width,
(adDetailsModel.vehicle!.currency ?? LocaleKeys.sar.tr()).toText(color: MyColors.lightTextColor, fontSize: 10, isBold: true).paddingOnly(bottom: 3),
LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, fontSize: 10, isBold: true).paddingOnly(bottom: 3),
],
)
],
@ -123,7 +123,7 @@ class BuildAdDetailsActionButtonForExploreAds extends StatelessWidget {
children: [
"${(adDetailsModel.vehicle!.demandAmount ?? 0.0)}".toText(fontSize: 19, isBold: true),
2.width,
(adDetailsModel.vehicle!.currency ?? LocaleKeys.sar.tr()).toText(color: MyColors.lightTextColor, fontSize: 10, isBold: true).paddingOnly(bottom: 3),
LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, fontSize: 10, isBold: true).paddingOnly(bottom: 3),
],
)
],

@ -349,7 +349,6 @@ class _AdsFilterViewState extends State<AdsFilterView> {
title: LocaleKeys.search.tr(),
onPressed: () {
Navigator.pop(context);
adVM.updateIsExploreAds(true);
adVM.getAdsBasedOnFilters(isFromLazyLoad: false, pageIndex: 0);
},
backgroundColor: MyColors.darkPrimaryColor,
@ -361,10 +360,7 @@ class _AdsFilterViewState extends State<AdsFilterView> {
),
8.height,
InkWell(
onTap: () {
adVM.updateIsExploreAds(true);
adVM.clearAdsFilters();
},
onTap: () => adVM.clearAdsFilters(),
child: LocaleKeys.clearFilters.tr().toText(
fontSize: 14,
isBold: true,

@ -36,21 +36,17 @@ class _AdDamagePartPicturesSheetState extends State<AdDamagePartPicturesSheet> {
void populateDamagePartPictures() {
List<dynamic> adDamageReportList = widget.adDamageReportList; // Assuming this is your data source.
Map<int, VehicleDamageCard> groupedDamageCards = {};
Map<String, VehicleDamageCard> groupedDamageCards = {};
for (var element in adDamageReportList) {
int partId = element.vehicleDamagePartID ?? 0;
String partName = element.partName ?? "Unknown";
ImageModel imageModel = ImageModel(id: element.id!, filePath: element.imageUrl!, isFromNetwork: true);
if (groupedDamageCards.containsKey(partId)) {
groupedDamageCards[partId]!.partImages!.add(imageModel);
if (groupedDamageCards.containsKey(partName)) {
groupedDamageCards[partName]!.partImages!.add(imageModel);
} else {
groupedDamageCards[partId] = VehicleDamageCard(
groupedDamageCards[partName] = VehicleDamageCard(
partSelectedId: SelectionModel(
selectedId: partId,
selectedId: element.vehicleDamagePartID!,
selectedOption: partName,
),
damagePartDescription: element.comment ?? "",

@ -23,7 +23,6 @@ class AdsListWidget extends StatelessWidget {
final bool isAdsFragment;
final bool shouldShowAdStatus;
final bool hasMoreData;
final bool isDraftAds;
final Function()? onFetchMoreAds;
const AdsListWidget({
@ -31,7 +30,6 @@ class AdsListWidget extends StatelessWidget {
required this.adsList,
required this.shouldShowAdStatus,
required this.hasMoreData,
required this.isDraftAds,
this.onFetchMoreAds,
this.scrollPhysics,
this.isAdsFragment = false,
@ -39,35 +37,17 @@ class AdsListWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final adVM = context.watch<AdVM>();
if (isAdsFragment && adsList.isEmpty) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(height: 25),
(adVM.adsFiltersCounter > 0 ? "No Ads that matches your search" : LocaleKeys.noAdsShow.tr()).toText(fontSize: 16, color: MyColors.lightTextColor, fontWeight: MyFonts.Medium),
if (adVM.adsFiltersCounter > 0) ...[
const SizedBox(height: 16),
GestureDetector(
onTap: () {
adVM.clearAdsFilters();
},
child: Text(
LocaleKeys.clearFilters.tr(),
style: const TextStyle(
color: MyColors.darkPrimaryColor,
fontSize: 18,
fontWeight: FontWeight.w600,
),
),
),
],
LocaleKeys.noAdsShow.tr().toText(fontSize: 16, color: MyColors.lightTextColor, fontWeight: MyFonts.Medium),
],
);
}
return NotificationListener<ScrollNotification>(
onNotification: (ScrollNotification scrollInfo) {
log("hasMoreData: $hasMoreData");
if (scrollInfo.metrics.pixels == scrollInfo.metrics.maxScrollExtent && hasMoreData) {
if (onFetchMoreAds != null) {
onFetchMoreAds!();
@ -84,20 +64,9 @@ class AdsListWidget extends StatelessWidget {
adDetails: adsList[index],
isAdsFragment: isAdsFragment,
shouldShowAdStatus: shouldShowAdStatus,
).onPress(
() {
if (isDraftAds) {
context.read<AdVM>().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));
).onPress(() => navigateWithName(context, AppRoutes.adsDetailView, arguments: adsList[index])).toViewOnly(context, onTap: () {
navigateWithName(context, AppRoutes.loginWithPassword, arguments: false);
});
},
separatorBuilder: (BuildContext context, int index) {
return 12.height;
@ -120,15 +89,6 @@ class AdCard extends StatelessWidget {
return Stack(
alignment: Alignment.center,
children: [
if (adDetails.vehicle == null) ...[
Expanded(
child: Column(
children: [
"Ad format needs to be updated.".toText(),
],
),
),
] else ...[
Row(
children: [
adDetails.vehicle!.image!.first.imageUrl.buildNetworkImage(
@ -150,10 +110,10 @@ class AdCard extends StatelessWidget {
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<AdVM>().isExploreAdsTapped && adDetails.statuslabel != null && adDetails.statuslabel!.isNotEmpty) ...[
Utils.statusContainerChip(text: adDetails.statuslabel ?? "", chipColor: Utils.getChipColorByAdStatus(adDetails.adPostStatus!)),
if (isAdsFragment && adDetails.adPostStatus! == AdPostStatus.sold) ...[
Utils.statusContainerChip(text: adDetails.statuslabel!, chipColor: Utils.getChipColorByAdStatus(adDetails.adPostStatus!)),
] else if (isAdsFragment && !context.read<AdVM>().isExploreAdsTapped) ...[
Utils.statusContainerChip(text: adDetails.statuslabel!, chipColor: Utils.getChipColorByAdStatus(adDetails.adPostStatus!)),
],
(adDetails.vehicle!.vehicleTitle ?? "").toText(
fontSize: 16,
@ -215,7 +175,7 @@ class AdCard extends StatelessWidget {
children: [
(adDetails.vehicle!.demandAmount!.toInt().toString()).toText(fontSize: 19, isBold: true, letterSpacing: -1.16, height: 29 / 19),
2.width,
(adDetails.vehicle!.currency ?? "").toText(color: MyColors.lightTextColor, fontSize: 10, letterSpacing: -0.4, height: 16 / 10).paddingOnly(bottom: 3),
LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, fontSize: 10, letterSpacing: -0.4, height: 16 / 10).paddingOnly(bottom: 3),
],
),
),
@ -233,7 +193,6 @@ class AdCard extends StatelessWidget {
),
],
),
],
if (false)
Container(
height: 100,

@ -41,19 +41,19 @@ class CreateAdProgressSteps extends StatelessWidget {
);
}
bool isStepCompleted({required AdCreationStepsEnum currentStep}) {
bool isStepCompleted({required AdCreationSteps currentStep}) {
return true;
}
int getProgressStepNumber({required AdCreationStepsEnum currentStep}) {
int getProgressStepNumber({required AdCreationSteps currentStep}) {
switch (currentStep) {
case AdCreationStepsEnum.vehicleDetails:
case AdCreationSteps.vehicleDetails:
return 1;
case AdCreationStepsEnum.damageParts:
case AdCreationSteps.damageParts:
return 2;
case AdCreationStepsEnum.adDuration:
case AdCreationSteps.adDuration:
return 3;
case AdCreationStepsEnum.reviewAd:
case AdCreationSteps.reviewAd:
return 4;
}
}

@ -1,13 +1,9 @@
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';
@ -79,7 +75,7 @@ class BuildFooterButton extends StatelessWidget {
return Consumer(
builder: (BuildContext context, AdVM adVm, Widget? child) {
switch (adVm.currentProgressStep) {
case AdCreationStepsEnum.vehicleDetails:
case AdCreationSteps.vehicleDetails:
return SizedBox(
width: double.infinity,
child: ShowFillButton(
@ -89,7 +85,7 @@ class BuildFooterButton extends StatelessWidget {
},
),
);
case AdCreationStepsEnum.damageParts:
case AdCreationSteps.damageParts:
return Row(
children: [
Expanded(
@ -98,14 +94,8 @@ 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,
),
@ -123,7 +113,7 @@ class BuildFooterButton extends StatelessWidget {
),
],
);
case AdCreationStepsEnum.adDuration:
case AdCreationSteps.adDuration:
return Row(
children: [
Expanded(
@ -132,15 +122,8 @@ 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,
),
@ -158,7 +141,7 @@ class BuildFooterButton extends StatelessWidget {
),
],
);
case AdCreationStepsEnum.reviewAd:
case AdCreationSteps.reviewAd:
return Row(
children: [
Expanded(
@ -167,15 +150,8 @@ 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,
),
@ -208,7 +184,7 @@ class BuildAdStepContainer extends StatelessWidget {
final WidgetBuilder onDamageParts;
final WidgetBuilder onAdDuration;
final WidgetBuilder onReviewAd;
final AdCreationStepsEnum adCreationStepsEnum;
final AdCreationSteps adCreationStepsEnum;
const BuildAdStepContainer({
super.key,
@ -222,16 +198,16 @@ class BuildAdStepContainer extends StatelessWidget {
@override
Widget build(BuildContext context) {
switch (adCreationStepsEnum) {
case AdCreationStepsEnum.vehicleDetails:
case AdCreationSteps.vehicleDetails:
return onVehicleDetails(context);
case AdCreationStepsEnum.damageParts:
case AdCreationSteps.damageParts:
return onDamageParts(context);
case AdCreationStepsEnum.adDuration:
case AdCreationSteps.adDuration:
return onAdDuration(context);
case AdCreationStepsEnum.reviewAd:
case AdCreationSteps.reviewAd:
return onReviewAd(context);
}
}

@ -1,68 +0,0 @@
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<MyDraftAdsView> createState() => _MyDraftAdsViewState();
}
class _MyDraftAdsViewState extends State<MyDraftAdsView> {
@override
void initState() {
scheduleMicrotask(() async => context.read<AdVM>().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(),
))
]
],
),
),
);
});
}
}

@ -78,8 +78,7 @@ 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) {

@ -328,16 +328,7 @@ class AppointmentDetailView extends StatelessWidget {
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
if (service.isHomeSelected) ...[
Builder(builder: (context) {
double totalKms = double.parse(service.servicelocationInfo.distanceToBranch.toStringAsFixed(2));
double pricePerKm = double.parse(service.servicelocationInfo.homeChargesInCurrentService.toStringAsFixed(2));
return ((service.currentTotalServicePrice + (pricePerKm * totalKms)).toStringAsFixed(2))
.toText(fontSize: 19, isBold: true);
}),
] else ...[
((service.currentTotalServicePrice).toString()).toText(fontSize: 19, isBold: true),
],
2.width,
LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, fontSize: 12, isBold: true).paddingOnly(bottom: 5),
const Icon(Icons.arrow_drop_down, size: 25)

@ -106,8 +106,7 @@ class BookAppointmentSchedulesView extends StatelessWidget {
onDateSelected: (int dateIndex) {
appointmentsVM.updateSelectedAppointmentDate(scheduleIndex: scheduleIndex, dateIndex: dateIndex);
},
selectedCustomTimeDateSlotModel: scheduleData.selectedCustomTimeDateSlotModel,
),
selectedCustomTimeDateSlotModel: scheduleData.selectedCustomTimeDateSlotModel),
if (appointmentsVM.serviceAppointmentScheduleList[scheduleIndex].selectedDateIndex != null) ...[
5.height,
Row(

@ -107,12 +107,8 @@ class BookAppointmentServicesView extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.end,
children: [
if (serviceData.isHomeSelected) ...[
Builder(builder: (context) {
double totalKms = double.parse(serviceData.servicelocationInfo.distanceToBranch.toStringAsFixed(2));
double pricePerKm = double.parse(serviceData.servicelocationInfo.homeChargesInCurrentService.toStringAsFixed(2));
return ((serviceData.currentTotalServicePrice + (pricePerKm * totalKms)).toStringAsFixed(2))
.toText(fontSize: 32, isBold: true);
}),
((serviceData.currentTotalServicePrice + (serviceData.servicelocationInfo.distanceToBranch * double.parse(serviceData.rangePricePerKm!))).toStringAsFixed(2))
.toText(fontSize: 32, isBold: true),
] else ...[
((serviceData.currentTotalServicePrice).toString()).toText(fontSize: 32, isBold: true),
],

@ -106,15 +106,7 @@ class _ChatViewState extends State<ChatView> {
final requestVM = context.read<RequestsVM>();
if (chatTypeEnum == ChatTypeEnum.requestOffer &&
requestVM.currentSelectedRequest != null &&
((requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.shipping || requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.delivery) ||
requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.selfPickup)) {
var name = '';
if (requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.shipping || requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.delivery) {
name = Utils.getNameByShippingRequestStatusEnum(requestVM.currentSelectedRequest?.shippingStatusEnum ?? ShippingRequestStatusEnum.pending);
} else {
name = Utils.getNameBySelfPickupRequestStatusEnum(requestVM.currentSelectedRequest?.selfPickupRequestStatusEnum ?? SelfPickupRequestStatusEnum.preparingToCollect);
}
(requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.shipping || requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.delivery)) {
appBarHeadlines = Container(
width: double.infinity,
color: MyColors.darkIconColor,
@ -128,7 +120,8 @@ class _ChatViewState extends State<ChatView> {
child: Row(
children: [
Flexible(
child: "${LocaleKeys.deliveryStatus.tr()} $name".toText(
child: "${LocaleKeys.deliveryStatus.tr()} ${Utils.getNameByShippingRequestStatusEnum(requestVM.currentSelectedRequest?.shippingStatusEnum ?? ShippingRequestStatusEnum.pending)}"
.toText(
fontSize: 12,
color: Colors.white,
decorationColor: MyColors.white,
@ -138,8 +131,7 @@ class _ChatViewState extends State<ChatView> {
),
),
10.width,
if ((requestVM.currentSelectedRequest?.shippingStatusEnum == ShippingRequestStatusEnum.delivered) ||
(requestVM.currentSelectedRequest?.selfPickupRequestStatusEnum == SelfPickupRequestStatusEnum.collected)) ...[
if ((requestVM.currentSelectedRequest?.shippingStatusEnum ?? ShippingRequestStatusEnum.pending) == ShippingRequestStatusEnum.delivered) ...[
Expanded(
flex: 2,
child: "${LocaleKeys.markAsCompleted.tr()} ".toText(isUnderLine: true, fontSize: 12, color: Colors.white, decorationColor: MyColors.white).onPress(() {
@ -203,11 +195,11 @@ class _ChatViewState extends State<ChatView> {
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
if (AppState().currentAppType == AppType.customer &&
chatTypeEnum == ChatTypeEnum.requestOffer &&
if (
AppState().currentAppType == AppType.customer && chatTypeEnum == ChatTypeEnum.requestOffer &&
requestVM.currentSelectedRequest!.requestType.toRequestTypeEnum() == RequestsTypeEnum.serviceRequest &&
requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.inProgress &&
requestVM.currentSelectedOffer!.requestOfferStatusEnum == RequestOfferStatusEnum.accepted) ...[
requestVM.currentSelectedOffer!.requestOfferStatusEnum == RequestOfferStatusEnum.accepted ) ...[
Expanded(
child: ShowFillButton(
maxWidth: double.infinity,
@ -217,7 +209,6 @@ class _ChatViewState extends State<ChatView> {
isBold: false,
onPressed: () {
context.read<PaymentVM>().updateRequestId(id: requestVM.currentSelectedRequest!.id);
requestVM.selectedDeliveryOptionEnum = null;
navigateWithName(context, AppRoutes.reviewRequestOffer, arguments: PaymentTypes.request);
},
),
@ -243,7 +234,8 @@ class _ChatViewState extends State<ChatView> {
// ),
// ]
//
else ...[
else
...[
if (AppState().currentAppType == AppType.provider &&
chatTypeEnum == ChatTypeEnum.requestOffer &&
requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.submitted &&
@ -282,7 +274,8 @@ class _ChatViewState extends State<ChatView> {
onAddFilePressed: () => chatVM.pickMultipleImages(),
),
),
] else if (chatTypeEnum == ChatTypeEnum.requestOffer) ...[
] else
if (chatTypeEnum == ChatTypeEnum.requestOffer) ...[
Expanded(
flex: 1,
child: const Icon(

@ -75,8 +75,6 @@ void dealCompletedConsentBottomSheet({
requestVM.myFilteredRequests[index].requestStatus = requestStatusEnum;
}
chatVM.updateAcknowledgePaymentToMowaterStatus(false);
// Refresh requests list before navigating
await requestVM.getRequestsBasedOnFilters();
mainContext.read<DashboardVmCustomer>().onNavbarTapped(4);
navigateReplaceWithNameUntilRoute(mainContext, AppRoutes.dashboard);
}
@ -95,8 +93,6 @@ void dealCompletedConsentBottomSheet({
requestVM.myFilteredRequests[index].requestStatus = requestStatusEnum;
}
chatVM.updateAcknowledgePaymentToMowaterStatus(false);
// Refresh requests list before navigating
await requestVM.getRequestsBasedOnFilters();
mainContext.read<DashboardVmCustomer>().onNavbarTapped(4);
navigateReplaceWithNameUntilRoute(mainContext, AppRoutes.dashboard);
}

@ -148,8 +148,6 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
}
setState(() {});
chatVM.updateRejectOfferDescription('');
// Refresh requests list
await requestVM.getRequestsBasedOnFilters();
Utils.showToast(LocaleKeys.offerRejected.tr());
// navigateReplaceWithName(context, AppRoutes.dashboard);
}
@ -252,8 +250,6 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
chatVM.serviceProviderOffersList[index].requestOfferStatusEnum = chatMessageModel.reqOffer!.requestOfferStatusEnum;
}
setState(() {});
// Refresh requests list
await requestVM.getRequestsBasedOnFilters();
Utils.showToast(LocaleKeys.offerAccepted.tr());
return true;
} else {
@ -403,8 +399,6 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
setState(() {});
// Navigator.pop(context);
chatVM.updateRejectOfferDescription('');
// Refresh requests list
await requestVM.getRequestsBasedOnFilters();
Utils.showToast("Offer ${requestOfferStatusEnum == RequestOfferStatusEnum.rejected ? "Rejected" : "Cancelled"}");
// navigateReplaceWithName(context, AppRoutes.dashboard);
}
@ -465,8 +459,6 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
}
setState(() {});
// Navigator.pop(context);
// Refresh requests list
await requestVM.getRequestsBasedOnFilters();
Utils.showToast(LocaleKeys.offerAccepted.tr());
// navigateReplaceWithName(context, AppRoutes.dashboard);
}

@ -150,7 +150,6 @@ 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,

@ -1,5 +1,3 @@
import 'dart:developer';
import 'package:flutter/gestures.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart';
@ -178,9 +176,6 @@ class MyRequestsFragment extends StatelessWidget {
onTap: () async {
RequestModel request = requestsVM.myFilteredRequests[index];
requestsVM.updateCurrentSelectedRequest(request);
log("request.requestStatus: ${request.requestStatus}");
if (request.requestStatus == RequestStatusEnum.pending ||
request.requestStatus == RequestStatusEnum.cancelled ||
request.requestStatus == RequestStatusEnum.expired) {

@ -37,8 +37,6 @@ class _PickLocationPageState extends State<PickLocationPage> {
late LatLng currentPosition;
Completer<GoogleMapController> mapController = Completer();
final ValueNotifier<String> _counter = ValueNotifier<String>("");
final ValueNotifier<bool> _isLoadingAddress = ValueNotifier<bool>(false);
String actualAddress = ""; // Store the actual address to return
@override
void initState() {
@ -76,7 +74,7 @@ class _PickLocationPageState extends State<PickLocationPage> {
Expanded(
child: Stack(
children: [
appMap,
if (appMap != null) appMap,
ValueListenableBuilder<String>(
builder: (BuildContext context, String value, Widget? child) {
// This builder will only get called when the _counter
@ -88,42 +86,13 @@ class _PickLocationPageState extends State<PickLocationPage> {
child: Card(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Text(value),
child: Text(value ?? ""),
)),
)
: Container();
},
valueListenable: _counter,
),
ValueListenableBuilder<bool>(
builder: (BuildContext context, bool isLoading, Widget? child) {
return isLoading
? Container(
width: double.infinity,
margin: const EdgeInsets.only(top: 70),
alignment: Alignment.topCenter,
child: const Card(
child: Padding(
padding: EdgeInsets.all(12.0),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(strokeWidth: 2),
),
SizedBox(width: 12),
Text('Loading address...'),
],
),
),
),
)
: const SizedBox.shrink();
},
valueListenable: _isLoadingAddress,
),
const Align(
alignment: Alignment.center,
child: Icon(
@ -139,20 +108,12 @@ class _PickLocationPageState extends State<PickLocationPage> {
width: double.infinity,
child: Padding(
padding: const EdgeInsets.all(12.0),
child: ValueListenableBuilder<bool>(
valueListenable: _isLoadingAddress,
builder: (context, isLoading, child) {
return ShowFillButton(
child: ShowFillButton(
maxHeight: 55,
title: isLoading ? 'Loading Address...' : LocaleKeys.pickAddress.tr(),
isDisabled: isLoading || _counter.value.isEmpty,
title: LocaleKeys.pickAddress.tr(),
onPressed: () {
if (!isLoading && _counter.value.isNotEmpty) {
widget.onPickAddress(latitude, longitude, actualAddress);
widget.onPickAddress(latitude, longitude, _counter.value);
pop(context);
}
},
);
},
),
),
@ -196,33 +157,8 @@ class _PickLocationPageState extends State<PickLocationPage> {
}
updateAddress(double latitude, double longitude) async {
_isLoadingAddress.value = true;
try {
List<Placemark> placemarks = await placemarkFromCoordinates(latitude, longitude).timeout(
const Duration(seconds: 5),
onTimeout: () {
throw TimeoutException('Geocoding request timed out');
},
);
if (placemarks.isNotEmpty) {
final placemark = placemarks.first;
// Restore original format - building address string from individual fields
actualAddress = '${placemark.street}, ${placemark.subLocality}, ${placemark.locality}, ${placemark.postalCode}, ${placemark.country}';
_counter.value = actualAddress;
} else {
actualAddress = "";
_counter.value = "";
}
} catch (e) {
log('Error getting address: $e');
// On error, leave address empty - user can try again by moving the map
actualAddress = "";
_counter.value = "";
} finally {
_isLoadingAddress.value = false;
}
List<Placemark> placemarks = await placemarkFromCoordinates(latitude, longitude);
_counter.value = '${placemarks.first.street}, ${placemarks.first.subLocality}, ${placemarks.first.locality}, ${placemarks.first.postalCode}, ${placemarks.first.country}';
}
setMap() {

@ -20,7 +20,6 @@ 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 CreateRequestPage extends StatelessWidget {
const CreateRequestPage({super.key});
@ -241,7 +240,7 @@ class CreateRequestPage extends StatelessWidget {
text: LocaleKeys.attachImage.tr(),
icon: MyAssets.attachmentIcon.buildSvg(),
extensions: GlobalConsts.allowedFileExtensions,
).paddingOnly(top: 8),
),
],
if (requestsVM.vehicleImageError != "") ...[
10.height,

@ -1,5 +1,3 @@
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';
@ -131,25 +129,19 @@ class RequestDetailPage extends StatelessWidget {
Widget buildRequestDetailActionFooter({
required int requestId,
required RequestDeliveryOptionEnum selectedDeliveryOption,
required RequestStatusEnum requestStatus,
required RequestsTypeEnum requestTypeEnum,
required ShippingRequestStatusEnum shippingRequestStatusEnum,
required SelfPickupRequestStatusEnum selfPickupRequestStatusEnum,
required String statusText,
required BuildContext context,
}) {
switch (requestStatus) {
case RequestStatusEnum.submitted:
String chatButtonText = requestTypeEnum == RequestsTypeEnum.specialCarRequest
? LocaleKeys.specialCarRequestChat.tr()
: LocaleKeys.sparePartRequestChat.tr();
return ShowFillButton(
maxWidth: double.infinity,
margin: const EdgeInsets.all(15),
maxHeight: 55,
title: chatButtonText,
title: LocaleKeys.specialRequestChat.tr(),
isBold: false,
onPressed: () => onViewChatTapped(context),
);
@ -163,23 +155,6 @@ class RequestDetailPage extends StatelessWidget {
case RequestStatusEnum.paid:
if (AppState().currentAppType == AppType.provider) {
if (selectedDeliveryOption == RequestDeliveryOptionEnum.selfPickup) {
return ShowFillButton(
maxWidth: double.infinity,
margin: const EdgeInsets.all(15),
maxHeight: 55,
title: LocaleKeys.initiateSelfPickup.tr(),
isBold: false,
onPressed: () async {
final requestVM = context.read<RequestsVM>();
bool status = await requestVM.onActionRequestTapped(context: context, requestStatusEnum: RequestStatusEnum.selfPickup, requestId: requestId);
if (status) {
await requestVM.getRequests(isNeedToRebuild: true);
pop(context);
}
},
);
}
return ShowFillButton(
maxWidth: double.infinity,
margin: const EdgeInsets.all(15),
@ -235,33 +210,6 @@ class RequestDetailPage extends StatelessWidget {
},
);
}
case RequestStatusEnum.selfPickup:
if (AppState().currentAppType == AppType.customer && selfPickupRequestStatusEnum == SelfPickupRequestStatusEnum.collected) {
return Column(
children: [
Utils.buildStatusContainer("${LocaleKeys.selfPickupStatus.tr()} ${Utils.getNameBySelfPickupRequestStatusEnum(selfPickupRequestStatusEnum).capitalizeFirstLetter()}")
.paddingOnly(left: 8, right: 8),
ShowFillButton(
maxWidth: double.infinity,
margin: const EdgeInsets.all(15),
maxHeight: 55,
title: LocaleKeys.markAsCompleted.tr(),
onPressed: () {
return dealCompletedConsentBottomSheet(
mainContext: context,
requestStatusEnum: RequestStatusEnum.completed,
requestId: requestId,
showAcknowledgement: AppState().currentAppType == AppType.customer,
);
},
)
],
);
} else if (AppState().currentAppType == AppType.provider) {
return Utils.buildStatusContainer(LocaleKeys.shippingManagementInstruction.tr());
} else {
return Utils.buildStatusContainer(statusText);
}
case RequestStatusEnum.completed:
case RequestStatusEnum.cancelled:
case RequestStatusEnum.expired:
@ -353,9 +301,7 @@ class RequestDetailPage extends StatelessWidget {
statusText: "Offer ${requestDetailPageArguments.requestModel.requestStatusName}",
requestTypeEnum: requestDetailPageArguments.requestModel.requestType.toRequestTypeEnum(),
shippingRequestStatusEnum: requestDetailPageArguments.requestModel.shippingStatusEnum ?? ShippingRequestStatusEnum.pending,
selfPickupRequestStatusEnum: requestDetailPageArguments.requestModel.selfPickupRequestStatusEnum ?? SelfPickupRequestStatusEnum.preparingToCollect,
context: context,
selectedDeliveryOption: requestDetailPageArguments.requestModel.selectedDeliveryOptionByCustomer,
),
],
],

@ -37,10 +37,9 @@ class _ReviewRequestOfferState extends State<ReviewRequestOffer> {
@override
void initState() {
final requestVM = context.read<RequestsVM>();
log("requestVM.acceptedRequestOffer!.requestDeliveryOption: ${requestVM.acceptedRequestOffer!.requestDeliveryOption}");
// if (requestVM.acceptedRequestOffer != null && requestVM.acceptedRequestOffer!.requestDeliveryOption == RequestDeliveryOptionEnum.both) {
if (requestVM.acceptedRequestOffer != null && requestVM.acceptedRequestOffer!.requestDeliveryOption == RequestDeliveryOptionEnum.both) {
populateRequestDeliveryOptions();
// }
}
if (requestVM.currentSelectedRequest != null && requestVM.currentSelectedRequest!.address.isEmpty) {
requestVM.addressSparePartRequestDelivery = "";
@ -57,9 +56,7 @@ class _ReviewRequestOfferState extends State<ReviewRequestOffer> {
populateRequestDeliveryOptions() {
scheduleMicrotask(() {
final requestVM = context.read<RequestsVM>();
requestVM.populateRequestDeliveryOptions();
requestVM.updateAdditionalAddressSparePartRequestDelivery(requestVM.currentSelectedRequest!.additionalAddressDetails, false);
});
}
@ -127,28 +124,20 @@ class _ReviewRequestOfferState extends State<ReviewRequestOffer> {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.serviceDeliveryType.tr().toText(fontSize: 18),
LocaleKeys.locationInformation.tr().toText(fontSize: 18),
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// LocaleKeys.serviceDeliveryType.tr().toText(fontSize: 18),
// LocaleKeys.locationInformation.tr().toText(fontSize: 18),
// MyAssets.icEdit.buildSvg().onPress(() => buildLocationInformationEditBottomSheet(context, requestVM)),
// ],
// ),
8.height,
FiltersList(
filterList: requestVM.deliveryOptionsForReviewRequest,
onFilterTapped: (index, selectedFilterId) async {
int response = await requestVM.onRequestDeliveryOptionTapped(
context: context,
requestID: requestVM.currentSelectedRequest!.id,
reqOfferId: requestVM.acceptedRequestOffer!.id ?? 0,
deliveryOptionEnum: selectedFilterId.toRequestDeliveryOptionEnum());
if (response != -1) {
onFilterTapped: (index, selectedFilterId) {
requestVM.updateSelectedDeliveryOptionEnum(selectedFilterId.toRequestDeliveryOptionEnum());
}
},
needLeftPadding: false,
).paddingOnly(bottom: 8),
@ -160,22 +149,7 @@ class _ReviewRequestOfferState extends State<ReviewRequestOffer> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SingleDetailWidget(text: address, type: LocaleKeys.location.tr()),
if (requestVM.selectedDeliveryOptionEnum == RequestDeliveryOptionEnum.delivery) ...[
8.height,
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
("${LocaleKeys.additionalAddressDetails.tr()}:").toText(fontSize: 12, color: MyColors.lightTextColor),
MyAssets.icEdit.buildSvg(height: 15).onPress(() => buildLocationInformationEditBottomSheet(context, requestVM)),
],
),
(requestVM.additionalAddressSparePartRequestDelivery).toText(fontSize: 14, color: MyColors.darkTextColor),
],
),
] else if (requestVM.selectedDeliveryOptionEnum == RequestDeliveryOptionEnum.selfPickup) ...[
if (requestVM.selectedDeliveryOptionEnum == RequestDeliveryOptionEnum.selfPickup) ...[
Row(
children: [
LocaleKeys.openMapLocation.tr().toText(
@ -207,7 +181,7 @@ class _ReviewRequestOfferState extends State<ReviewRequestOffer> {
}
Widget buildServiceInformation(BuildContext context) {
final requestVM = context.watch<RequestsVM>();
final requestVM = context.read<RequestsVM>();
String manufacturedOnFormattedDate = "";
if (requestVM.acceptedRequestOffer!.manufacturedOn != null) {
@ -217,23 +191,6 @@ class _ReviewRequestOfferState extends State<ReviewRequestOffer> {
if (requestVM.currentSelectedRequest!.createdOn != null) {
requestCreatedOn = DateHelper.formatAsDayMonthYear(DateHelper.parseStringToDate(DateHelper.formatDateT(requestVM.currentSelectedRequest!.createdOn.toString() ?? "")));
}
// Get selected delivery type
String selectedDeliveryType = "-";
String deliveryAddress = "";
bool showMapButton = false;
if (requestVM.selectedDeliveryOptionEnum != null) {
selectedDeliveryType = requestVM.selectedDeliveryOptionEnum!.getStringFromRequestDeliveryOptionEnum();
if (requestVM.selectedDeliveryOptionEnum == RequestDeliveryOptionEnum.delivery) {
deliveryAddress = requestVM.currentSelectedRequest!.address;
} else if (requestVM.selectedDeliveryOptionEnum == RequestDeliveryOptionEnum.selfPickup) {
deliveryAddress = requestVM.currentSelectedOffer!.providerAddress ?? "";
showMapButton = true;
}
}
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@ -254,8 +211,6 @@ class _ReviewRequestOfferState extends State<ReviewRequestOffer> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SingleDetailWidget(text: requestVM.currentSelectedRequest!.requestTypeName, type: LocaleKeys.serviceCategory.tr()),
16.height,
SingleDetailWidget(text: requestVM.currentSelectedRequest!.vehicleTypeName, type: LocaleKeys.vehicleType.tr()),
16.height,
SingleDetailWidget(text: '${requestVM.currentSelectedRequest!.model} ${requestVM.currentSelectedRequest!.year}', type: LocaleKeys.model.tr()),
@ -263,8 +218,11 @@ class _ReviewRequestOfferState extends State<ReviewRequestOffer> {
16.height,
SingleDetailWidget(text: (requestVM.acceptedRequestOffer!.manufacturedByName ?? "").toString(), type: LocaleKeys.manufacturedBy.tr()),
],
// 16.height,
// SingleDetailWidget(text: "${requestVM.acceptedRequestOffer!.price.toString()} ${LocaleKeys.sar.tr()}", type: LocaleKeys.offerPrice.tr()),
16.height,
SingleDetailWidget(text: requestVM.acceptedRequestOfferProviderName ?? "", type: LocaleKeys.providerName.tr()),
16.height,
SingleDetailWidget(text: LocaleKeys.online.tr(), type: LocaleKeys.paymentType.tr()),
],
@ -276,8 +234,6 @@ class _ReviewRequestOfferState extends State<ReviewRequestOffer> {
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
SingleDetailWidget(text: selectedDeliveryType, type: LocaleKeys.serviceDeliveryType.tr()),
16.height,
SingleDetailWidget(text: requestVM.currentSelectedRequest!.brand, type: LocaleKeys.vehicleBrand.tr()),
16.height,
SingleDetailWidget(text: requestVM.acceptedRequestOffer!.serviceItemName ?? "", type: LocaleKeys.serviceName.tr()),
@ -298,52 +254,6 @@ class _ReviewRequestOfferState extends State<ReviewRequestOffer> {
),
16.height,
SingleDetailWidget(text: requestVM.currentSelectedRequest!.description, type: LocaleKeys.description.tr()),
if (requestVM.selectedDeliveryOptionEnum != null && deliveryAddress.isNotEmpty) ...[
16.height,
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: SingleDetailWidget(text: deliveryAddress, type: LocaleKeys.location.tr()),
),
if (showMapButton) ...[
8.width,
Row(
children: [
LocaleKeys.openMapLocation.tr().toText(
fontSize: 12,
isBold: true,
color: MyColors.primaryColor,
isUnderLine: true,
),
4.width,
Image.asset(
MyAssets.icRightUpPng,
height: 6,
width: 6,
color: MyColors.primaryColor,
),
],
).onPress(() async {
double latitude, longitude = 0.0;
latitude = double.parse(requestVM.currentSelectedOffer!.providerLatitude ?? "0.0");
longitude = double.parse(requestVM.currentSelectedOffer!.providerLongitude ?? "0.0");
await Utils.openLocationInMaps(latitude: latitude, longitude: longitude);
}),
],
],
),
if (requestVM.selectedDeliveryOptionEnum == RequestDeliveryOptionEnum.delivery && requestVM.additionalAddressSparePartRequestDelivery.isNotEmpty) ...[
8.height,
SingleDetailWidget(text: requestVM.additionalAddressSparePartRequestDelivery, type: LocaleKeys.additionalAddressDetails.tr()),
],
],
),
],
],
);
}
@ -364,33 +274,32 @@ class _ReviewRequestOfferState extends State<ReviewRequestOffer> {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.updateYourLocationInfo.tr().toText(fontSize: 14, fontWeight: MyFonts.Medium),
// 8.height,
// TxtField(
// hint: LocaleKeys.address.tr(),
// isNeedClickAll: false,
// value: requestsVM.addressSparePartRequestDelivery,
// postfixWidget: IconButton(
// icon: const Icon(
// size: 28,
// Icons.add_location_outlined,
// ),
// onPressed: () {
// navigateTo(
// context,
// PickLocationPage(
// onPickAddress: (double latitude, double longitude, String address) {
// requestsVM.updateAddressSparePartRequestDelivery(address);
// setState(() {});
// },
// ),
// );
// }),
// onChanged: (e) => requestsVM.updateAddressSparePartRequestDelivery(e),
// ),
"Update your location information".toText(fontSize: 14, fontWeight: MyFonts.Medium),
8.height,
TxtField(
hint: LocaleKeys.address.tr(),
isNeedClickAll: false,
value: requestsVM.addressSparePartRequestDelivery,
postfixWidget: IconButton(
icon: const Icon(
size: 28,
Icons.add_location_outlined,
),
onPressed: () {
navigateTo(
context,
PickLocationPage(
onPickAddress: (double latitude, double longitude, String address) {
requestsVM.updateAddressSparePartRequestDelivery(address);
setState(() {});
},
),
);
}),
onChanged: (e) => requestsVM.updateAddressSparePartRequestDelivery(e),
),
8.height,
TxtField(
maxLines: 2,
hint: LocaleKeys.additionalAddressDetails.tr(),
isNeedClickAll: false,
value: requestsVM.additionalAddressSparePartRequestDelivery,
@ -403,14 +312,12 @@ class _ReviewRequestOfferState extends State<ReviewRequestOffer> {
Expanded(
child: ShowFillButton(
title: LocaleKeys.submit.tr(),
onPressed: () async {
bool status = await requestsVM.updateRequestAdditionalAddress(context: context, additionalAddress: additionalDetails, requestId: requestsVM.currentSelectedRequest!.id);
if (status) {
requestsVM.updateAdditionalAddressSparePartRequestDelivery(additionalDetails, true);
onPressed: () {
// TODO: Call some api here to update this info for this specific request.
requestsVM.currentSelectedRequest!.address = requestsVM.addressSparePartRequestDelivery;
requestsVM.updateAdditionalAddressSparePartRequestDelivery(additionalDetails);
requestsVM.notifyListeners();
pop(context);
}
},
),
)
@ -474,7 +381,7 @@ class _ReviewRequestOfferState extends State<ReviewRequestOffer> {
onPressed: () {
final requestVM = context.read<RequestsVM>();
// context.read<PaymentVM>().updateRequestId(id: requestVM.currentSelectedRequest!.id);
if (requestVM.selectedDeliveryOptionEnum == null) {
if (requestVM.acceptedRequestOffer!.requestDeliveryOption == RequestDeliveryOptionEnum.both && requestVM.selectedDeliveryOptionEnum == null) {
requestVM.updateSelectedDeliveryOptionEnumError(GlobalConsts.deliveryOptionSelectionError);
} else {
navigateWithName(context, AppRoutes.paymentMethodsView, arguments: PaymentTypes.request);

@ -48,21 +48,10 @@ class RequestItem extends StatelessWidget {
],
6.height,
"${request.brand} ${request.model} | ${request.id}".toText(fontSize: 16, letterSpacing: -0.64),
showItem("${LocaleKeys.year.tr()}:", "${request.year}"),
if (request.customerName.isNotEmpty) ...[
showItem("${LocaleKeys.customerName.tr()}:", request.customerName),
],
if (request.brand.isNotEmpty) ...[
showItem("${LocaleKeys.brand.tr()}:", request.brand),
],
if (request.model.isNotEmpty) ...[
showItem("${LocaleKeys.model.tr()}:", request.model),
],
if (request.year > 0) ...[
showItem("${LocaleKeys.year.tr()}:", "${request.year}"),
],
if (request.vehicleTypeName.isNotEmpty) ...[
showItem("${LocaleKeys.vehicleType.tr()}:", request.vehicleTypeName),
],
showItem("${LocaleKeys.description.tr()}:", request.description),
],
),

@ -55,7 +55,7 @@ class SettingOptionsHelp extends StatelessWidget {
size: 20,
color: MyColors.greyColor,
),
titleText: LocaleKeys.termsPrivacyPolicy.tr(),
titleText: LocaleKeys.termPrivacy.tr(),
needBorderBelow: true,
onTap: () => navigateWithName(context, AppRoutes.settingOptionsTermsAndConditions),
),

@ -128,8 +128,7 @@ class SettingOptionsInviteFriends extends StatelessWidget {
leadingWidget: const Icon(Icons.group, size: 20),
titleText: LocaleKeys.inviteFriends.tr(),
needBorderBelow: true,
onTap: () async {
await context.read<SettingOptionsVM>().getAppInvitationHistoryList(context);
onTap: () {
return buildInviteFriendsBottomSheet(context);
},
),
@ -144,8 +143,9 @@ class SettingOptionsInviteFriends extends StatelessWidget {
leadingWidget: const Icon(Icons.person, size: 20),
titleText: LocaleKeys.account.tr(),
needBorderBelow: false,
onTap: () => navigateWithName(context, AppRoutes.profileView),
),
onTap: () {
navigateWithName(context, AppRoutes.profileView);
}),
],
).toContainer(
width: double.infinity,

@ -112,25 +112,12 @@ class _SettingOptionsMoreState extends State<SettingOptionsMore> {
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(),
needBorderBelow: false,
onTap: () {
// context.read<SettingOptionsVM>().getAppInvitationHistoryList();
context.read<SettingOptionsVM>().getAppInvitationHistoryList();
navigateWithName(context, AppRoutes.settingOptionsInviteFriends);
}),
],

@ -60,7 +60,7 @@ class _SettingOptionsTermsAndConditionsState extends State<SettingOptionsTermsAn
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
title: LocaleKeys.termsPrivacyPolicy.tr(),
title: LocaleKeys.termPrivacy.tr(),
isRemoveBackButton: false,
isDrawerEnabled: false,
onBackButtonTapped: () => Navigator.pop(context),

@ -53,7 +53,7 @@ class _ShippingManagementViewState extends State<ShippingManagementView> {
super.initState();
}
List<FilterListModel> getAvailableStatusesShippingList(List<FilterListModel> list, ShippingRequestStatusEnum shippingRequestStatusEnum) {
List<FilterListModel> getAvailableStatusesList(List<FilterListModel> list, ShippingRequestStatusEnum shippingRequestStatusEnum) {
List<FilterListModel> newList = [];
for (var element in list) {
@ -64,17 +64,6 @@ class _ShippingManagementViewState extends State<ShippingManagementView> {
return newList;
}
List<FilterListModel> getAvailableStatusesPickupList(List<FilterListModel> list, SelfPickupRequestStatusEnum selfPickupRequestStatusEnum) {
List<FilterListModel> newList = [];
for (var element in list) {
if (element.id > selfPickupRequestStatusEnum.getIdFromSelfPickupStatusEnum()) {
newList.add(element);
}
}
return newList;
}
Future buildUpdateShippingStatusBottomSheet({required int shippingRequestId, required ShippingRequestStatusEnum shippingRequestStatusEnum}) {
return showModalBottomSheet(
context: context,
@ -95,7 +84,7 @@ class _ShippingManagementViewState extends State<ShippingManagementView> {
12.height,
ListView.separated(
shrinkWrap: true,
itemCount: getAvailableStatusesShippingList(shippingManagementVM.shippingRequestStatusesList, shippingRequestStatusEnum).length,
itemCount: getAvailableStatusesList(shippingManagementVM.shippingRequestStatusesList, shippingRequestStatusEnum).length,
separatorBuilder: (BuildContext context, int index) {
return const Padding(
padding: EdgeInsets.symmetric(vertical: 3.0),
@ -103,7 +92,7 @@ class _ShippingManagementViewState extends State<ShippingManagementView> {
);
},
itemBuilder: (BuildContext context, int index) {
List<FilterListModel> list = getAvailableStatusesShippingList(shippingManagementVM.shippingRequestStatusesList, shippingRequestStatusEnum);
List<FilterListModel> list = getAvailableStatusesList(shippingManagementVM.shippingRequestStatusesList, shippingRequestStatusEnum);
FilterListModel shippingFilterListModel = list[index];
int id = list[index].id;
return CircleCheckBoxWithTitle(
@ -156,91 +145,6 @@ class _ShippingManagementViewState extends State<ShippingManagementView> {
);
}
Future buildUpdateSelfPickupStatusBottomSheet({required int shippingRequestId, required SelfPickupRequestStatusEnum selfPickupRequestStatusEnum}) {
return showModalBottomSheet(
context: context,
isScrollControlled: true,
enableDrag: true,
builder: (BuildContext context) {
return Consumer(builder: (BuildContext context, ShippingManagementVM shippingManagementVM, 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,
ListView.separated(
shrinkWrap: true,
itemCount: getAvailableStatusesPickupList(shippingManagementVM.selfPickupRequestsStatusesList, selfPickupRequestStatusEnum).length,
separatorBuilder: (BuildContext context, int index) {
return const Padding(
padding: EdgeInsets.symmetric(vertical: 3.0),
child: Divider(thickness: 0.5),
);
},
itemBuilder: (BuildContext context, int index) {
List<FilterListModel> list = getAvailableStatusesPickupList(shippingManagementVM.selfPickupRequestsStatusesList, selfPickupRequestStatusEnum);
FilterListModel shippingFilterListModel = list[index];
int id = list[index].id;
return CircleCheckBoxWithTitle(
isChecked: shippingFilterListModel.isSelected,
title: shippingFilterListModel.title,
onSelected: () {
int i = shippingManagementVM.selfPickupRequestsStatusesList.indexWhere((element) => element.id == id);
if (i == -1) {
return;
}
shippingManagementVM.updateSelectionInSelfPickupRequestStatuses(i);
},
selectedColor: MyColors.darkPrimaryColor,
);
},
),
12.height,
TxtField(
maxLines: 4,
value: shippingManagementVM.requestStatusComments,
errorValue: "",
keyboardType: TextInputType.text,
hint: LocaleKeys.comment.tr(),
onChanged: (v) => shippingManagementVM.updateRequestStatusComments(v),
),
],
),
25.height,
ShowFillButton(
title: LocaleKeys.submit.tr(),
onPressed: () async {
FilterListModel value = shippingManagementVM.selfPickupRequestsStatusesList.firstWhere((element) => element.isSelected);
SelfPickupRequestStatusEnum selfPickupRequestStatusEnum = value.id.toSelfPickupStatusEnum();
bool status = await shippingManagementVM.onUpdateSelfPickupStatusTapped(
selfPickupRequestStatusEnum: selfPickupRequestStatusEnum,
shippingRequestId: shippingRequestId,
context: context,
);
if (status) {
pop(context);
int index = shippingManagementVM.selfPickupRequestsFilterOptions.indexWhere((element) => element.isSelected);
int id = shippingManagementVM.selfPickupRequestsFilterOptions[index].id;
await shippingManagementVM.getSelfPickupRequestsListByFilters(selfPickupStatusEnum: id.toSelfPickupStatusEnum());
}
},
maxWidth: double.infinity,
),
19.height,
],
),
));
});
},
);
}
@override
void dispose() {
shippingViewModel.resetFilters();
@ -336,17 +240,10 @@ class _ShippingManagementViewState extends State<ShippingManagementView> {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (shippingVm.isSelfPickupTapped) ...[
Utils.statusContainerChip(
text: Utils.getNameBySelfPickupRequestStatusEnum(shippingRequest.selfPickupRequestStatusEnum ?? SelfPickupRequestStatusEnum.preparingToCollect),
chipColor: Utils.getChipColorBySelfPickupRequestStatusEnum(shippingRequest.selfPickupRequestStatusEnum ?? SelfPickupRequestStatusEnum.preparingToCollect),
),
] else ...[
Utils.statusContainerChip(
text: Utils.getNameByShippingRequestStatusEnum(shippingRequest.shippingStatusEnum ?? ShippingRequestStatusEnum.initiated),
chipColor: Utils.getChipColorByShippingRequestStatusEnum(shippingRequest.shippingStatusEnum ?? ShippingRequestStatusEnum.initiated),
),
],
("${shippingRequest.request!.brand} ${shippingRequest.request!.model} | ${shippingRequest.requestID.toString()}").toText(fontSize: 16),
(shippingRequest.request!.description ?? "").toText(color: MyColors.lightTextColor, fontSize: 12, fontWeight: MyFonts.Medium),
if (shippingRequest.vehicleType != null && shippingRequest.vehicleType!.isNotEmpty) ...[
@ -368,30 +265,17 @@ class _ShippingManagementViewState extends State<ShippingManagementView> {
],
],
),
if (shippingVm.isSelfPickupTapped) ...[
if (shippingRequest.selfPickupRequestStatusEnum != SelfPickupRequestStatusEnum.collected) ...[
const Icon(Icons.arrow_forward, color: MyColors.darkIconColor, size: 18),
],
] else ...[
if (shippingRequest.shippingStatusEnum != ShippingRequestStatusEnum.delivered) ...[
const Icon(Icons.arrow_forward, color: MyColors.darkIconColor, size: 18),
],
],
],
),
],
).onPress(() {
if (shippingVm.isSelfPickupTapped) {
if (shippingRequest.selfPickupRequestStatusEnum == SelfPickupRequestStatusEnum.collected) {
return;
}
buildUpdateSelfPickupStatusBottomSheet(shippingRequestId: shippingRequest.id!, selfPickupRequestStatusEnum: shippingRequest.selfPickupRequestStatusEnum!);
} else {
if (shippingRequest.shippingStatusEnum == ShippingRequestStatusEnum.delivered) {
return;
}
buildUpdateShippingStatusBottomSheet(shippingRequestId: shippingRequest.id!, shippingRequestStatusEnum: shippingRequest.shippingStatusEnum!);
}
}).toContainer(isShadowEnabled: true);
},
separatorBuilder: (context, index) => 16.height,

@ -19,7 +19,7 @@ class SplashPageState extends State<SplashPage> with WidgetsBindingObserver {
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
// performTimer(context);
performTimer(context);
}
@override
@ -38,14 +38,10 @@ class SplashPageState extends State<SplashPage> with WidgetsBindingObserver {
}
// Timer function to navigate after a delay
// performTimer(BuildContext context) {
// Utils.delay(3).whenComplete(() {
// navigateReplaceWithName(context, AppRoutes.registerSelection);
// });
// }
navigateToNextDeciderPage() {
performTimer(BuildContext context) {
Utils.delay(3).whenComplete(() {
navigateReplaceWithName(context, AppRoutes.registerSelection);
});
}
@override
@ -78,15 +74,10 @@ class SplashPageState extends State<SplashPage> with WidgetsBindingObserver {
// Engine Image
Expanded(
flex: 3,
child: InkWell(
onTap: () {
navigateToNextDeciderPage();
},
child: Image.asset(
MyAssets.icEnginePng,
),
),
),
// Spacer widget again for spacing
Utils.mExp(1),
],

@ -1,6 +1,7 @@
import 'dart:async';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart';
@ -19,7 +20,7 @@ import 'package:mc_common_app/widgets/txt_field.dart';
import 'package:provider/provider.dart';
class AddPhoneNumWidget extends StatefulWidget {
const AddPhoneNumWidget({super.key});
const AddPhoneNumWidget({Key? key}) : super(key: key);
@override
State<AddPhoneNumWidget> createState() => _AddPhoneNumWidgetState();
@ -81,34 +82,11 @@ class _AddPhoneNumWidgetState extends State<AddPhoneNumWidget> {
8.height,
TxtField(
keyboardType: TextInputType.phone,
hint: "Phone without country code ",
hint: "546758594",
value: phoneNum,
isSidePaddingZero: true,
onChanged: (v) {
// Remove country code if user enters it
String cleanedPhone = v.trim();
// If country code is selected and phone starts with it, remove it
if (countryCode.isNotEmpty && cleanedPhone.startsWith(countryCode)) {
cleanedPhone = cleanedPhone.substring(countryCode.length).trim();
}
// Also handle cases where user adds + before country code
if (countryCode.isNotEmpty && cleanedPhone.startsWith('+$countryCode')) {
cleanedPhone = cleanedPhone.substring(countryCode.length + 1).trim();
}
// Handle case where user just types + followed by digits matching country code
if (countryCode.isNotEmpty && cleanedPhone.startsWith('+')) {
String codeWithoutPlus = countryCode.replaceAll('+', '');
if (cleanedPhone.substring(1).startsWith(codeWithoutPlus)) {
cleanedPhone = cleanedPhone.substring(codeWithoutPlus.length + 1).trim();
}
}
setState(() {
phoneNum = cleanedPhone;
});
phoneNum = v;
},
),
16.height,
@ -183,10 +161,10 @@ class CustomBottomPicker extends StatelessWidget {
final void Function(DropValue selectedItem) onItemSelected;
const CustomBottomPicker({
super.key,
Key? key,
required this.items,
required this.onItemSelected,
});
}) : super(key: key);
@override
Widget build(BuildContext context) {

@ -58,7 +58,6 @@ class _DropdownFieldState extends State<DropdownField> {
dropdownValue = widget.dropdownValue;
return Column(
children: [
// Always show hint as label when provided
if (widget.hint != null) ...[
Row(
mainAxisAlignment: MainAxisAlignment.start,
@ -72,41 +71,19 @@ class _DropdownFieldState extends State<DropdownField> {
),
4.height,
],
// Show disabled text field when not selectable
if (!widget.isSelectAble)
Container(
decoration: Utils.containerColorRadiusBorderWidth(
MyColors.greyShadowColor,
0,
MyColors.greyACColor,
2
),
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 14),
width: double.infinity,
child: (dropdownValue?.value ?? "").toText(
color: MyColors.darkTextColor,
fontSize: 15,
fontWeight: MyFonts.Medium,
),
)
else
// Show normal dropdown when selectable
Container(
decoration: widget.showAppointmentPickerVariant
? null
: Utils.containerColorRadiusBorderWidth(
MyColors.white,
0,
MyColors.darkPrimaryColor,
2
),
IgnorePointer(
ignoring: !widget.isSelectAble,
child: Container(
decoration:
widget.showAppointmentPickerVariant ? null : Utils.containerColorRadiusBorderWidth(MyColors.white, 0, widget.isSelectAble ? MyColors.darkPrimaryColor : MyColors.greyACColor, 2),
margin: const EdgeInsets.all(0),
padding: const EdgeInsets.only(left: 8, right: 8),
width: widget.showAppointmentPickerVariant ? 170 : null,
child: DropdownButton<DropValue>(
value: dropdownValue,
icon: const Icon(
icon: Icon(
Icons.keyboard_arrow_down_sharp,
color: !widget.isSelectAble ? Colors.transparent : null,
size: 21,
),
elevation: 16,
@ -118,6 +95,7 @@ class _DropdownFieldState extends State<DropdownField> {
color: borderColor,
fontSize: 15,
),
// hint: (widget.hint ?? "").toText(color: borderColor, fontSize: 15, fontWeight: MyFonts.Medium),
underline: Container(height: 0),
onChanged: (DropValue? newValue) {
setState(() {
@ -131,16 +109,13 @@ class _DropdownFieldState extends State<DropdownField> {
return DropdownMenuItem<DropValue>(
value: value,
enabled: value.isEnabled ?? true,
child: value.value.toText(
fontSize: 15,
color: value.isEnabled == false ? MyColors.darkTextColor : null,
fontWeight: MyFonts.Medium
),
child: value.value.toText(fontSize: 15, color: value.isEnabled == false ? MyColors.darkTextColor : null, fontWeight: MyFonts.Medium),
);
},
).toList(),
),
),
),
if (widget.errorValue != "")
Row(
mainAxisAlignment: MainAxisAlignment.end,

@ -20,6 +20,7 @@ dependencies:
permission_handler: ^11.3.1
flutter_svg: ^2.0.14
sizer: ^3.0.4
fluttertoast: ^8.0.8
shared_preferences: ^2.0.6
file_picker: ^8.0.7
image_picker: ^1.1.2
@ -37,12 +38,11 @@ dependencies:
country_code_picker: ^3.0.0
table_calendar: ^3.0.9
intl: any
signalr_core: ^1.1.2
signalr_core: ^1.1.1
logging: ^1.2.0
percent_indicator: ^4.2.3
change_app_package_name: ^1.3.0
share_plus: any
toastification: ^2.3.0
# Firebase Packages
@ -54,13 +54,14 @@ dependencies:
# google
google_maps_flutter: ^2.1.1
geolocator: ^10.1.1
geocoding: ^4.0.0
geolocator: any
# geocoding: ^2.1.0
geocoding: ^3.0.0
# Auth
local_auth: ^2.2.0
# huawei_fido: ^6.3.0+305
# huawei_fido: ^6.3.0+305
device_info_plus: ^10.1.0

Loading…
Cancel
Save