12 feb,2025

aamir_dev
Faiz Hashmi 9 months ago
parent 021618fa6b
commit 59875f5198

@ -805,5 +805,8 @@
"enterEndPrice": "أدخل سعر النهاية", "enterEndPrice": "أدخل سعر النهاية",
"searchByVehicleType": "البحث حسب نوع المركبة", "searchByVehicleType": "البحث حسب نوع المركبة",
"selectVehicleType": "اختر نوع المركبة", "selectVehicleType": "اختر نوع المركبة",
"specialRequestsChats": "دردشات الطلبات الخاصة" "specialRequestsChats": "دردشات الطلبات الخاصة",
"selectDeliveryOption": "اختر خيار التوصيل",
"deliveryOptions": "خيارات التوصيل",
"selfPickup": "الالتقاط الذاتي"
} }

@ -803,5 +803,8 @@
"enterEndPrice": "Enter end price", "enterEndPrice": "Enter end price",
"searchByVehicleType": "Search by vehicle type", "searchByVehicleType": "Search by vehicle type",
"selectVehicleType": "Select vehicle type", "selectVehicleType": "Select vehicle type",
"specialRequestsChats": "Special Requests Chats" "specialRequestsChats": "Special Requests Chats",
"selectDeliveryOption": "Select Delivery Option",
"deliveryOptions": "Delivery Options",
"selfPickup": "Self Pickup"
} }

@ -182,6 +182,8 @@ class ApiConsts {
//Shipping //Shipping
static String shippingRequestStatusUpdate = "${baseUrlServices}api/RequestManagement/ShippingRequestStatus_Update"; static String shippingRequestStatusUpdate = "${baseUrlServices}api/RequestManagement/ShippingRequestStatus_Update";
static String shippingRequestStatusGet = "${baseUrlServices}api/RequestManagement/ShippingRequestStatus_Get"; static String shippingRequestStatusGet = "${baseUrlServices}api/RequestManagement/ShippingRequestStatus_Get";
static String selfPickupRequestStatusGet = "${baseUrlServices}api/RequestManagement/SelfPickUpRequestStatus_Get";
static String selfPickupRequestStatusUpdate = "${baseUrlServices}api/RequestManagement/SelfPickUpRequestStatus_Update";
//Chat //Chat
static String chatHubUrl = "$baseUrlServices/McHub"; static String chatHubUrl = "$baseUrlServices/McHub";
@ -190,6 +192,7 @@ class ApiConsts {
static String getChatMessagesForRequests = "${baseUrlServices}api/RequestManagement/ReqOfferChat_Get"; static String getChatMessagesForRequests = "${baseUrlServices}api/RequestManagement/ReqOfferChat_Get";
static String getChatMessagesForAds = "${baseUrlServices}api/Advertisement/AdsChat_Get"; static String getChatMessagesForAds = "${baseUrlServices}api/Advertisement/AdsChat_Get";
static String getChatBuyersForAds = "${baseUrlServices}api/Advertisement/AdsChatBuyer_Get"; static String getChatBuyersForAds = "${baseUrlServices}api/Advertisement/AdsChatBuyer_Get";
static String reqChatUnreadGet = "${baseUrlServices}api/RequestManagement/Req_ChatUnread_Get";
//Settings Options //Settings Options
static String getAllFAQs = "${baseUrlServices}api/Common/FAQ_Get"; static String getAllFAQs = "${baseUrlServices}api/Common/FAQ_Get";
@ -226,6 +229,7 @@ class GlobalConsts {
static String welcomeVideoUrl = "welcomeVideoUrl"; static String welcomeVideoUrl = "welcomeVideoUrl";
static String doNotShowWelcomeVideo = "doNotShowWelcomeVideo"; static String doNotShowWelcomeVideo = "doNotShowWelcomeVideo";
static String demandAmountError = "Amount Cannot be Empty"; static String demandAmountError = "Amount Cannot be Empty";
static String deliveryOptionSelectionError = "At least one delivery option should be selected.";
static String reservationCancelError = "Cancellation Reason Cannot be Empty"; static String reservationCancelError = "Cancellation Reason Cannot be Empty";
static String descriptionError = "Description should be more than 5 letters."; static String descriptionError = "Description should be more than 5 letters.";
static String acceptingThisOffer = "I am accepting this offer."; static String acceptingThisOffer = "I am accepting this offer.";
@ -420,42 +424,44 @@ class SignalrConsts {
} }
class GuestConsts { class GuestConsts {
UserInfo userInfo = UserInfo.fromJson({ UserInfo userInfo = UserInfo.fromJson(
"id": -1, {
"userID": null, "id": -1,
"firstName": "Guest", "userID": null,
"lastName": "User", "firstName": "Guest",
"companyName": null, "lastName": "User",
"accountStatus": "2", "companyName": null,
"activityStatus": "Offline", "accountStatus": "2",
"accountStatusText": null, "activityStatus": "Offline",
"subscriptionDate": null, "accountStatusText": null,
"mobileNo": "966123456789", "subscriptionDate": null,
"email": "mowatter@gmail.com", "mobileNo": "966123456789",
"userImageUrl": "https://ms.hmg.com/api/ProfileImage?imageName=User_Default.png", "email": "mowatter@gmail.com",
"roleID": 4, "userImageUrl": "https://ms.hmg.com/api/ProfileImage?imageName=User_Default.png",
"roleName": "Customer", "roleID": 4,
"isEmailVerified": false, "roleName": "Customer",
"serviceProviderBranch": [], "isEmailVerified": false,
"isVerified": true, "serviceProviderBranch": [],
"userRoles": [], "isVerified": true,
"isProviderDealership": false, "userRoles": [],
"isProviderIndividual": false, "isProviderDealership": false,
"isProvider": false, "isProviderIndividual": false,
"providerID": null, "isProvider": false,
"isCustomer": true, "providerID": null,
"customerID": 25, "isCustomer": true,
"countryID": 1, "customerID": 25,
"countryName": "Saudi Arabia", "countryID": 1,
"cityID": 1, "countryName": "Saudi Arabia",
"cityName": "Riyadh", "cityID": 1,
"dealershipUserID": null, "cityName": "Riyadh",
"serviceProviderBranchID": null, "dealershipUserID": null,
"createdOn": "2024-12-24T09:20:47.6733333", "serviceProviderBranchID": null,
"genderID": 1, "createdOn": "2024-12-24T09:20:47.6733333",
"genderName": "Male", "genderID": 1,
"serviceProviderPayment": [], "genderName": "Male",
"deviceType": "1", "serviceProviderPayment": [],
"deviceToken": null, "deviceType": "1",
}); "deviceToken": null,
},
);
} }

@ -975,7 +975,7 @@ extension ShippingStatusEnumExt on int {
return ShippingRequestStatusEnum.inTransit; return ShippingRequestStatusEnum.inTransit;
} else if (this == 3) { } else if (this == 3) {
return ShippingRequestStatusEnum.outForDelivery; return ShippingRequestStatusEnum.outForDelivery;
} else if (this == 4) { } else if (this == 4) {
return ShippingRequestStatusEnum.delivered; return ShippingRequestStatusEnum.delivered;
} }
return ShippingRequestStatusEnum.pending; return ShippingRequestStatusEnum.pending;
@ -1003,6 +1003,83 @@ extension ShippingStatusEnumToInt on ShippingRequestStatusEnum {
} }
} }
extension SelfPickupStatusEnumExt on int {
SelfPickupRequestStatusEnum toSelfPickupStatusEnum() {
if (this == -1) {
return SelfPickupRequestStatusEnum.allRequests;
} else if (this == 0) {
return SelfPickupRequestStatusEnum.allRequests;
} else if (this == 1) {
return SelfPickupRequestStatusEnum.preparingToCollect;
} else if (this == 2) {
return SelfPickupRequestStatusEnum.readyToCollect;
} else if (this == 3) {
return SelfPickupRequestStatusEnum.collected;
}
return SelfPickupRequestStatusEnum.allRequests;
}
}
extension SelfPickupStatusEnumToInt on SelfPickupRequestStatusEnum {
int getIdFromSelfPickupStatusEnum() {
switch (this) {
case SelfPickupRequestStatusEnum.allRequests:
return 0;
case SelfPickupRequestStatusEnum.preparingToCollect:
return 1;
case SelfPickupRequestStatusEnum.readyToCollect:
return 2;
case SelfPickupRequestStatusEnum.collected:
return 3;
default:
return -1;
}
}
}
extension RequestDeliveryOptionEnumExt on int {
RequestDeliveryOptionEnum toRequestDeliveryOptionEnum() {
if (this == 1) {
return RequestDeliveryOptionEnum.delivery;
} else if (this == 2) {
return RequestDeliveryOptionEnum.selfPickup;
} else if (this == 3) {
return RequestDeliveryOptionEnum.both;
}
return RequestDeliveryOptionEnum.none;
}
}
extension RequestDeliveryOptionEnumToIntExt on RequestDeliveryOptionEnum {
int getIdRequestDeliveryOptionEnum() {
switch (this) {
case RequestDeliveryOptionEnum.delivery:
return 1;
case RequestDeliveryOptionEnum.selfPickup:
return 2;
case RequestDeliveryOptionEnum.both:
return 3;
default:
return 0;
}
}
}
extension RequestDeliveryOptionEnumTosTRINGExt on RequestDeliveryOptionEnum {
String getStringFromRequestDeliveryOptionEnum() {
switch (this) {
case RequestDeliveryOptionEnum.delivery:
return "Delivery";
case RequestDeliveryOptionEnum.selfPickup:
return "Self Pickup";
case RequestDeliveryOptionEnum.both:
return "Delivery, Self Pickup";
default:
return "Self Pickup";
}
}
}
extension CapitalizeFirstLetter on String { extension CapitalizeFirstLetter on String {
String capitalizeFirstLetter() { String capitalizeFirstLetter() {
if (isEmpty) { if (isEmpty) {

@ -821,7 +821,10 @@ class CodegenLoader extends AssetLoader{
"enterEndPrice": "أدخل سعر النهاية", "enterEndPrice": "أدخل سعر النهاية",
"searchByVehicleType": "البحث حسب نوع المركبة", "searchByVehicleType": "البحث حسب نوع المركبة",
"selectVehicleType": "اختر نوع المركبة", "selectVehicleType": "اختر نوع المركبة",
"specialRequestsChats": "دردشات الطلبات الخاصة" "specialRequestsChats": "دردشات الطلبات الخاصة",
"selectDeliveryOption": "اختر خيار التوصيل",
"deliveryOptions": "خيارات التوصيل",
"selfPickup": "الالتقاط الذاتي"
}; };
static const Map<String,dynamic> en_US = { static const Map<String,dynamic> en_US = {
"firstTimeLogIn": "First Time Log In", "firstTimeLogIn": "First Time Log In",
@ -1628,7 +1631,10 @@ static const Map<String,dynamic> en_US = {
"enterEndPrice": "Enter end price", "enterEndPrice": "Enter end price",
"searchByVehicleType": "Search by vehicle type", "searchByVehicleType": "Search by vehicle type",
"selectVehicleType": "Select vehicle type", "selectVehicleType": "Select vehicle type",
"specialRequestsChats": "Special Requests Chats" "specialRequestsChats": "Special Requests Chats",
"selectDeliveryOption": "Select Delivery Option",
"deliveryOptions": "Delivery Options",
"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};
} }

@ -785,5 +785,8 @@ abstract class LocaleKeys {
static const searchByVehicleType = 'searchByVehicleType'; static const searchByVehicleType = 'searchByVehicleType';
static const selectVehicleType = 'selectVehicleType'; static const selectVehicleType = 'selectVehicleType';
static const specialRequestsChats = 'specialRequestsChats'; static const specialRequestsChats = 'specialRequestsChats';
static const selectDeliveryOption = 'selectDeliveryOption';
static const deliveryOptions = 'deliveryOptions';
static const selfPickup = 'selfPickup';
} }

@ -84,6 +84,7 @@ class ReqOffer {
String? manufacturedOn; String? manufacturedOn;
double? price; double? price;
bool? isDeliveryAvailable; bool? isDeliveryAvailable;
RequestDeliveryOptionEnum? requestDeliveryOption;
RequestsTypeEnum? requestsTypeEnum; RequestsTypeEnum? requestsTypeEnum;
RequestOfferStatusEnum? requestOfferStatusEnum; RequestOfferStatusEnum? requestOfferStatusEnum;
List<MessageImageModel>? reqOfferImages; List<MessageImageModel>? reqOfferImages;
@ -100,6 +101,7 @@ class ReqOffer {
this.manufacturedOn, this.manufacturedOn,
this.price, this.price,
this.isDeliveryAvailable, this.isDeliveryAvailable,
this.requestDeliveryOption,
this.requestOfferStatusEnum, this.requestOfferStatusEnum,
this.requestsTypeEnum, this.requestsTypeEnum,
this.reqOfferImages, this.reqOfferImages,
@ -117,6 +119,7 @@ class ReqOffer {
manufacturedOn = json['offeredItemCreatedOn'] ?? json["createdOn"]; manufacturedOn = json['offeredItemCreatedOn'] ?? json["createdOn"];
price = json['price']; price = json['price'];
isDeliveryAvailable = json['isDeliveryAvailable']; isDeliveryAvailable = json['isDeliveryAvailable'];
requestDeliveryOption = ((json['offerDeliveryOption'] ?? 0) as int).toRequestDeliveryOptionEnum();
requestOfferStatusEnum = ((json['offerStatus']) as int).toRequestOfferStatusEnum(); requestOfferStatusEnum = ((json['offerStatus']) as int).toRequestOfferStatusEnum();
requestsTypeEnum = RequestsTypeEnum.serviceRequest; requestsTypeEnum = RequestsTypeEnum.serviceRequest;
// if (isForReqOfferImagesURLs) { // if (isForReqOfferImagesURLs) {

@ -0,0 +1,45 @@
class OffersUnreadChatModel {
final int reqTotal;
final List<OffersUnreadChatDataModel> reqChatUnread;
OffersUnreadChatModel({
required this.reqTotal,
required this.reqChatUnread,
});
factory OffersUnreadChatModel.fromJson(Map<String, dynamic> json) {
return OffersUnreadChatModel(
reqTotal: json['reqTotal'],
reqChatUnread: (json['reqChatUnread'] as List).map((e) => OffersUnreadChatDataModel.fromJson(e)).toList(),
);
}
}
class OffersUnreadChatDataModel {
final String senderUserID;
final int unreadMessagesCount;
final int requestId;
final String lastChatTime;
final String lastChatText;
final String customerName;
OffersUnreadChatDataModel({
required this.senderUserID,
required this.unreadMessagesCount,
required this.requestId,
required this.lastChatTime,
required this.lastChatText,
required this.customerName,
});
factory OffersUnreadChatDataModel.fromJson(Map<String, dynamic> json) {
return OffersUnreadChatDataModel(
senderUserID: json['senderUserID'],
unreadMessagesCount: json['unreadMessagesCount'],
requestId: json['requestId'] ?? 0,
lastChatTime: json['lastChatTime'],
lastChatText: json['lastChatText'],
customerName: json['customerName'],
);
}
}

@ -66,6 +66,7 @@ class ServiceProvidersOffers {
RequestOfferStatusEnum? requestOfferStatusEnum; RequestOfferStatusEnum? requestOfferStatusEnum;
int? offerCount; int? offerCount;
int? requestId; int? requestId;
String? providerAddress;
List<ChatMessageModel>? chatMessages; List<ChatMessageModel>? chatMessages;
ServiceProvidersOffers({ ServiceProvidersOffers({
@ -80,6 +81,7 @@ class ServiceProvidersOffers {
this.providerUserId, this.providerUserId,
this.createdOn, this.createdOn,
this.requestOfferStatusEnum, this.requestOfferStatusEnum,
this.providerAddress,
}); });
ServiceProvidersOffers.fromJson(Map<String, dynamic> json, int? reqId) { ServiceProvidersOffers.fromJson(Map<String, dynamic> json, int? reqId) {
@ -93,6 +95,7 @@ class ServiceProvidersOffers {
requestId = reqId; requestId = reqId;
createdOn = json['createdOn']; createdOn = json['createdOn'];
requestOfferStatusEnum = ((json['offerStatusLast']) as int).toRequestOfferStatusEnum(); requestOfferStatusEnum = ((json['offerStatusLast']) as int).toRequestOfferStatusEnum();
providerAddress = "Will be in API in case of self pickup";
chatMessages = []; chatMessages = [];
} }

@ -6,6 +6,7 @@ import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/dependency_injection.dart'; import 'package:mc_common_app/config/dependency_injection.dart';
import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/general_models/generic_resp_model.dart'; import 'package:mc_common_app/models/general_models/generic_resp_model.dart';
import 'package:mc_common_app/models/requests_models/offers_unread_chat_model.dart';
import 'package:mc_common_app/models/requests_models/provider_offers_model.dart'; import 'package:mc_common_app/models/requests_models/provider_offers_model.dart';
import 'package:mc_common_app/models/requests_models/providers_offers_chat_model.dart'; import 'package:mc_common_app/models/requests_models/providers_offers_chat_model.dart';
import 'package:mc_common_app/models/requests_models/request_model.dart'; import 'package:mc_common_app/models/requests_models/request_model.dart';
@ -30,6 +31,8 @@ abstract class RequestRepo {
Future<List<ProviderOffersChatsModel>> getOffersChatByProvider({int requestId = 0, required int serviceProviderId}); Future<List<ProviderOffersChatsModel>> getOffersChatByProvider({int requestId = 0, required int serviceProviderId});
Future<OffersUnreadChatModel> getOffersChatsUnreadList({required String userId});
Future<ProviderOffersModel> getOffersFromProvidersByRequest({required int requestId}); Future<ProviderOffersModel> getOffersFromProvidersByRequest({required int requestId});
Future<List<RequestModel>> getRequests({required int providerOrCustomerID}); Future<List<RequestModel>> getRequests({required int providerOrCustomerID});
@ -61,6 +64,7 @@ abstract class RequestRepo {
required int offerId, required int offerId,
required String offerPrice, required String offerPrice,
required bool isDeliveryAvailable, required bool isDeliveryAvailable,
required int offerDeliveryOption,
required String serviceItemName, required String serviceItemName,
required String manufacturedByName, required String manufacturedByName,
required String manufacturedOn, required String manufacturedOn,
@ -293,6 +297,22 @@ class RequestRepoImp implements RequestRepo {
return offersList; return offersList;
} }
@override
Future<OffersUnreadChatModel> getOffersChatsUnreadList({required String userId}) async {
var queryParameters = {
"ReceiverUserID": userId.toString(),
};
GenericRespModel genericRespModel = await apiClient.getJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.reqChatUnreadGet,
queryParameters: queryParameters,
token: appState.getUser.data!.accessToken,
);
OffersUnreadChatModel offersUnreadChatModel = OffersUnreadChatModel.fromJson(genericRespModel.data);
return offersUnreadChatModel;
}
@override @override
Future<ProviderOffersModel> getOffersFromProvidersByRequest({required int requestId}) async { Future<ProviderOffersModel> getOffersFromProvidersByRequest({required int requestId}) async {
final customerId = appState.getUser.data!.userInfo!.customerId; final customerId = appState.getUser.data!.userInfo!.customerId;
@ -353,6 +373,7 @@ class RequestRepoImp implements RequestRepo {
required int offerId, required int offerId,
required String offerPrice, required String offerPrice,
required bool isDeliveryAvailable, required bool isDeliveryAvailable,
required int offerDeliveryOption,
required String serviceItemName, required String serviceItemName,
required String manufacturedByName, required String manufacturedByName,
required String manufacturedOn, required String manufacturedOn,
@ -372,7 +393,8 @@ class RequestRepoImp implements RequestRepo {
"offeredItemCreatedByName": manufacturedByName.toString(), "offeredItemCreatedByName": manufacturedByName.toString(),
"offeredItemCreatedOn": manufacturedOn.toString(), "offeredItemCreatedOn": manufacturedOn.toString(),
"reqOfferImages": requestImages, "reqOfferImages": requestImages,
"isDeliveryAvailable": isDeliveryAvailable "isDeliveryAvailable": isDeliveryAvailable,
"offerDeliveryOption": offerDeliveryOption
}; };
GenericRespModel genericRespModel = await apiClient.postJsonForObject( GenericRespModel genericRespModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json), (json) => GenericRespModel.fromJson(json),

@ -14,9 +14,13 @@ import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/utils.dart'; import 'package:mc_common_app/utils/utils.dart';
abstract class ShippingRepo { abstract class ShippingRepo {
Future<List<ShippingRequestModel>> getSelfPickupRequestListByStatus({SelfPickupRequestStatusEnum? selfPickupRequestStatus, int? requestId});
Future<List<ShippingRequestModel>> getShippingRequestListByStatus({ShippingRequestStatusEnum? shippingStatusEnum, int? requestId}); Future<List<ShippingRequestModel>> getShippingRequestListByStatus({ShippingRequestStatusEnum? shippingStatusEnum, int? requestId});
Future<GenericRespModel> updateShippingRequestStatus({required ShippingRequestStatusEnum shippingStatusEnum, required int shippingRequestId, String? comment}); Future<GenericRespModel> updateShippingRequestStatus({required ShippingRequestStatusEnum shippingStatusEnum, required int shippingRequestId, String? comment});
Future<GenericRespModel> updateSelfPickupRequestStatus({required SelfPickupRequestStatusEnum selfPickupStatusEnum, required int shippingRequestId, String? comment});
} }
class ShippingRepoImp extends ShippingRepo { class ShippingRepoImp extends ShippingRepo {
@ -48,6 +52,31 @@ class ShippingRepoImp extends ShippingRepo {
return list; return list;
} }
@override
Future<List<ShippingRequestModel>> getSelfPickupRequestListByStatus({SelfPickupRequestStatusEnum? selfPickupRequestStatus, int? requestId}) async {
String token = appState.getUser.data!.accessToken ?? "";
Map queryParameters = {
"requestID": "${requestId ?? 0}",
"selfPickUpStatus": "${selfPickupRequestStatus != null ? selfPickupRequestStatus.getIdFromSelfPickupStatusEnum() : -1}", // -1 to get all requests
};
GenericRespModel genericRespModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.selfPickupRequestStatusGet,
queryParameters,
token: token,
);
if (genericRespModel.messageStatus != 1 || genericRespModel.data == null) {
Utils.showToast(genericRespModel.message ?? LocaleKeys.somethingWrong.tr());
return [];
}
List<ShippingRequestModel> list = List.generate(genericRespModel.data.length, (index) => ShippingRequestModel.fromJson(genericRespModel.data[index]));
return list;
}
@override @override
Future<GenericRespModel> updateShippingRequestStatus({required ShippingRequestStatusEnum shippingStatusEnum, required int shippingRequestId, String? comment}) async { Future<GenericRespModel> updateShippingRequestStatus({required ShippingRequestStatusEnum shippingStatusEnum, required int shippingRequestId, String? comment}) async {
String token = appState.getUser.data!.accessToken ?? ""; String token = appState.getUser.data!.accessToken ?? "";
@ -70,4 +99,27 @@ class ShippingRepoImp extends ShippingRepo {
return genericRespModel; return genericRespModel;
} }
@override
Future<GenericRespModel> updateSelfPickupRequestStatus({required SelfPickupRequestStatusEnum selfPickupStatusEnum, required int shippingRequestId, String? comment}) async {
String token = appState.getUser.data!.accessToken ?? "";
Map<String, String> queryParameters = {
"id": "$shippingRequestId",
"selfPickUpStatus": "${selfPickupStatusEnum.getIdFromSelfPickupStatusEnum()}",
"comment": comment ?? "",
};
GenericRespModel genericRespModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.selfPickupRequestStatusUpdate,
queryParameters,
token: token,
);
if (genericRespModel.messageStatus != 1 || genericRespModel.data == null) {
Utils.showToast(genericRespModel.message ?? LocaleKeys.somethingWrong.tr());
}
return genericRespModel;
}
} }

@ -19,6 +19,8 @@ class AppEnums {
static const int conditionEnumId = -1; // to get the Condition Filter Enums static const int conditionEnumId = -1; // to get the Condition Filter Enums
static const int serviceDeliveryTypeEnumId = 24; // to get the serviceDeliveryType static const int serviceDeliveryTypeEnumId = 24; // to get the serviceDeliveryType
static const int shippingStatusEnumId = 30; // to get the Shipping Filter Enums static const int shippingStatusEnumId = 30; // to get the Shipping Filter Enums
static const int selfPickupStatusEnumId = 33; // to get the SelfPickup Status Enums
static const int deliveryOptionEnumId = 32; // to get the SelfPickup Status Enums
} }
enum DashboardRouteEnum { enum DashboardRouteEnum {
@ -223,10 +225,9 @@ enum SubscriptionActionTypeEnum {
ads, ads,
users, users,
branches, branches,
subscription subscription,
} }
enum ShippingRequestStatusEnum { enum ShippingRequestStatusEnum {
allRequests, allRequests,
pending, pending,
@ -236,10 +237,22 @@ enum ShippingRequestStatusEnum {
delivered, delivered,
} }
enum SelfPickupRequestStatusEnum {
allRequests,
preparingToCollect,
readyToCollect,
collected,
}
enum RequestDeliveryOptionEnum {
none,
delivery,
selfPickup,
both,
}
enum InviteTypeEnum { enum InviteTypeEnum {
whatsapp, whatsapp,
sms, sms,
email, email,
} }

@ -362,6 +362,7 @@ class ChatVM extends BaseVM {
required int requestId, required int requestId,
required String offerPrice, required String offerPrice,
required bool isDeliveryAvailable, required bool isDeliveryAvailable,
required RequestDeliveryOptionEnum offerDeliveryOption,
required String serviceItemName, required String serviceItemName,
required String manufacturedByName, required String manufacturedByName,
required String manufacturedOn, required String manufacturedOn,
@ -385,10 +386,11 @@ class ChatVM extends BaseVM {
"RequestID": requestId, "RequestID": requestId,
"Price": double.parse(offerPrice), "Price": double.parse(offerPrice),
"IsDeliveryAvailable": isDeliveryAvailable, "IsDeliveryAvailable": isDeliveryAvailable,
"OfferDeliveryOption": offerDeliveryOption.getIdRequestDeliveryOptionEnum(),
"ServiceItem": serviceItemName, "ServiceItem": serviceItemName,
"ReqOfferImages": offerImages, "ReqOfferImages": offerImages,
"OfferedItemCreatedByName": manufacturedByName, "OfferedItemCreatedByName": manufacturedByName,
"OfferedItemCreatedOn": manufacturedOn, // TODO: This should be in String on Server, Right now it is in DateTime // "OfferedItemCreatedOn": manufacturedOn, // TODO: This should be in String on Server, Right now it is in DateTime
"ServiceProviderID": providerId, "ServiceProviderID": providerId,
"OfferStatus": RequestOfferStatusEnum.offer.getIdFromRequestOfferStatusEnum(), "OfferStatus": RequestOfferStatusEnum.offer.getIdFromRequestOfferStatusEnum(),
"Comment": message, "Comment": message,
@ -651,6 +653,8 @@ class ChatVM extends BaseVM {
required int serviceProviderID, required int serviceProviderID,
required int requestOfferID, required int requestOfferID,
required String offerPrice, required String offerPrice,
required bool isDeliveryAvailable,
required RequestDeliveryOptionEnum offerDeliveryOption,
required String serviceItemName, required String serviceItemName,
required String manufacturedByName, required String manufacturedByName,
required String manufacturedOn, required String manufacturedOn,
@ -675,6 +679,9 @@ class ChatVM extends BaseVM {
"Price": double.parse(offerPrice), "Price": double.parse(offerPrice),
"ServiceItem": serviceItemName, "ServiceItem": serviceItemName,
"OfferedItemCreatedByName": manufacturedByName, "OfferedItemCreatedByName": manufacturedByName,
"IsDeliveryAvailable": isDeliveryAvailable,
"OfferDeliveryOption": offerDeliveryOption.getIdRequestDeliveryOptionEnum(),
// We have commented this because Backend Team is using their server time for this. It was the time offer created by
// "OfferedItemCreatedOn": manufacturedOn, // "OfferedItemCreatedOn": manufacturedOn,
"ServiceProviderID": serviceProviderID, "ServiceProviderID": serviceProviderID,
"OfferStatus": requestOfferStatusEnum.getIdFromRequestOfferStatusEnum(), "OfferStatus": requestOfferStatusEnum.getIdFromRequestOfferStatusEnum(),

@ -68,6 +68,7 @@ class DashboardVmCustomer extends BaseVM {
await appointmentsVM.populateAppointmentsFilterList(); await appointmentsVM.populateAppointmentsFilterList();
await adVM.populateAdsFilterList(); await adVM.populateAdsFilterList();
await requestsVM.populateDataForRequestsFilter(); await requestsVM.populateDataForRequestsFilter();
await requestsVM.populateDeliveryOptionEnums();
await appointmentsVM.applyFilterOnAppointmentsVMForCustomers(appointmentStatusEnum: AppointmentStatusEnum.allAppointments, shouldPopulateUpcoming: true); await appointmentsVM.applyFilterOnAppointmentsVMForCustomers(appointmentStatusEnum: AppointmentStatusEnum.allAppointments, shouldPopulateUpcoming: true);
await appointmentsVM.applyFilterOnBranches(index: 0); // to get all branches! await appointmentsVM.applyFilterOnBranches(index: 0); // to get all branches!
await appointmentsVM.getMyRecentBranches(); // to get my recent branches await appointmentsVM.getMyRecentBranches(); // to get my recent branches

@ -79,20 +79,23 @@ class DashboardVMProvider extends BaseVM {
final serviceVM = context.read<ServiceVM>(); final serviceVM = context.read<ServiceVM>();
final adVM = context.read<AdVM>(); final adVM = context.read<AdVM>();
final subscriptionsVM = context.read<SubscriptionsVM>(); final subscriptionsVM = context.read<SubscriptionsVM>();
requestsVM.populateDataForRequestsFilter(); await requestsVM.populateDataForRequestsFilter();
appointmentVM.populateAppointmentsFilterList(); await requestsVM.populateDeliveryOptionEnums();
shippingManagementVM.populateShippingRequestFilterList(); await appointmentVM.populateAppointmentsFilterList();
await adVM.populateAdsFilterList();
await serviceVM.populateBranchServiceFilters(); await serviceVM.populateBranchServiceFilters();
await serviceVM.getBranchAndServices(); await serviceVM.getBranchAndServices();
await requestsVM.getRequests();
await subscriptionsVM.getSubscriptionBySP(AppState().getUser.data?.userInfo?.providerId.toString() ?? "", true);
if (dashboardRouteEnum != DashboardRouteEnum.fromAdsPayment && dashboardRouteEnum != DashboardRouteEnum.fromAdsSubmit) { if (dashboardRouteEnum != DashboardRouteEnum.fromAdsPayment && dashboardRouteEnum != DashboardRouteEnum.fromAdsSubmit) {
await adVM.getMyAds(); await adVM.getMyAds();
await adVM.getExploreAds(); await adVM.getExploreAds();
} }
await shippingManagementVM.populateShippingRequestFilterList();
await shippingManagementVM.populateSelfPickupRequestFilterList();
await appointmentVM.applyFilterOnAppointmentsVMForProviders(appointmentStatusEnum: AppointmentStatusEnum.allAppointments, shouldPopulateUpcoming: true); await appointmentVM.applyFilterOnAppointmentsVMForProviders(appointmentStatusEnum: AppointmentStatusEnum.allAppointments, shouldPopulateUpcoming: true);
adVM.populateAdsFilterList();
await requestsVM.getRequests();
await subscriptionsVM.getSubscriptionBySP(AppState().getUser.data?.userInfo?.providerId.toString() ?? "", true);
await adVM.getVehicleTypes(); await adVM.getVehicleTypes();
await adVM.getVehicleAdsDuration(); await adVM.getVehicleAdsDuration();
await chatVM.buildHubConnection(context); await chatVM.buildHubConnection(context);

@ -217,7 +217,7 @@ class PaymentVM extends ChangeNotifier {
context.read<DashboardVmCustomer>().onNavbarTapped(1); context.read<DashboardVmCustomer>().onNavbarTapped(1);
} }
navigateReplaceWithNameUntilRoute(context, AppRoutes.dashboard); navigateReplaceWithNameUntilRoute(context, AppRoutes.dashboard);
} }
Future<void> onVisaCardSelected(BuildContext context, PaymentTypes paymentType) async { Future<void> onVisaCardSelected(BuildContext context, PaymentTypes paymentType) async {
currentPaymentType = paymentType; currentPaymentType = paymentType;

@ -18,6 +18,7 @@ import 'package:mc_common_app/models/general_models/enums_model.dart';
import 'package:mc_common_app/models/general_models/generic_resp_model.dart'; import 'package:mc_common_app/models/general_models/generic_resp_model.dart';
import 'package:mc_common_app/models/general_models/widgets_models.dart'; import 'package:mc_common_app/models/general_models/widgets_models.dart';
import 'package:mc_common_app/models/requests_models/offers_model.dart'; import 'package:mc_common_app/models/requests_models/offers_model.dart';
import 'package:mc_common_app/models/requests_models/offers_unread_chat_model.dart';
import 'package:mc_common_app/models/requests_models/provider_offers_model.dart'; import 'package:mc_common_app/models/requests_models/provider_offers_model.dart';
import 'package:mc_common_app/models/requests_models/providers_offers_chat_model.dart'; import 'package:mc_common_app/models/requests_models/providers_offers_chat_model.dart';
import 'package:mc_common_app/models/requests_models/request_model.dart'; import 'package:mc_common_app/models/requests_models/request_model.dart';
@ -843,12 +844,12 @@ class RequestsVM extends BaseVM {
return isValid; return isValid;
} }
List<ProviderOffersChatsModel> providerOffersChatsList = []; Future<void> getOffersChatByProvider({required int providerId, required BuildContext context}) async {
List<ProviderOffersChatsModel> providerOffersChatsList = [];
Future<void> getProviderOffersChatsList({required int serviceProviderId, required BuildContext context}) async {
try { try {
Utils.showLoading(context); Utils.showLoading(context);
List<ProviderOffersChatsModel> respModel = await requestRepo.getOffersChatByProvider(serviceProviderId: serviceProviderId); List<ProviderOffersChatsModel> respModel = await requestRepo.getOffersChatByProvider(serviceProviderId: providerId);
Utils.hideLoading(context); Utils.hideLoading(context);
providerOffersChatsList.clear(); providerOffersChatsList.clear();
providerOffersChatsList = respModel; providerOffersChatsList = respModel;
@ -860,7 +861,26 @@ class RequestsVM extends BaseVM {
} }
} }
OffersUnreadChatModel? offersUnreadChatModel;
Future<void> getOffersChatsUnreadList({required String userId, required BuildContext context}) async {
try {
Utils.showLoading(context);
OffersUnreadChatModel respModel = await requestRepo.getOffersChatsUnreadList(userId: userId);
Utils.hideLoading(context);
offersUnreadChatModel = respModel;
log("offersUnreadChatModel: ${offersUnreadChatModel!.reqChatUnread.length}");
notifyListeners();
} catch (e) {
logger.e(e.toString());
Utils.showToast(e.toString());
Utils.hideLoading(context);
return;
}
}
String offerPriceError = ""; String offerPriceError = "";
String offerDescriptionError = ""; String offerDescriptionError = "";
String offerPrice = ""; String offerPrice = "";
@ -907,6 +927,39 @@ class RequestsVM extends BaseVM {
} }
} }
String deliveryOptionSelectionError = "";
List<EnumsModel> myDeliveryOptionsEnum = [];
List<FilterListModel> myDeliveryOptionsFilterOptions = [];
Future<void> populateDeliveryOptionEnums() async {
if (myDeliveryOptionsFilterOptions.isNotEmpty) return;
try {
notifyListeners();
myDeliveryOptionsEnum = await commonRepo.getEnumTypeValues(enumTypeID: AppEnums.deliveryOptionEnumId);
for (int i = 0; i < myDeliveryOptionsEnum.length; i++) {
myDeliveryOptionsFilterOptions.add(FilterListModel(title: myDeliveryOptionsEnum[i].enumValueStr, isSelected: false, id: myDeliveryOptionsEnum[i].enumValue));
}
notifyListeners();
} catch (e) {
logger.e(e.toString());
}
}
Future<void> applyFilterOnDeliveryOption({required RequestDeliveryOptionEnum requestDeliveryOptionEnum}) async {
if (myDeliveryOptionsFilterOptions.isEmpty) return;
for (var value in myDeliveryOptionsFilterOptions) {
value.isSelected = false;
}
if (requestDeliveryOptionEnum != RequestDeliveryOptionEnum.none) {
myDeliveryOptionsFilterOptions[requestDeliveryOptionEnum.getIdRequestDeliveryOptionEnum() - 1].isSelected = true; // -1 to match with the index
}
notifyListeners();
}
List<OfferRequestCommentModel> providerDeliveryActionsList = [ List<OfferRequestCommentModel> providerDeliveryActionsList = [
OfferRequestCommentModel( OfferRequestCommentModel(
index: 0, index: 0,
@ -974,19 +1027,40 @@ class RequestsVM extends BaseVM {
} else { } else {
offerDescriptionError = ""; offerDescriptionError = "";
} }
if (currentSelectedRequest != null && currentSelectedRequest!.requestType == RequestsTypeEnum.serviceRequest.getIdFromRequestTypeEnum()) {
int index = myDeliveryOptionsFilterOptions.indexWhere((option) => option.isSelected);
if (index == -1) {
deliveryOptionSelectionError = GlobalConsts.deliveryOptionSelectionError;
log("indexindex: ${index}");
isValidated = false;
}
notifyListeners();
} else {
deliveryOptionSelectionError = "";
}
notifyListeners(); notifyListeners();
log("isValidatedisValidated: ${isValidated}");
return isValidated; return isValidated;
} }
void resetSendOfferBottomSheet() { void resetSendOfferBottomSheet() {
offerPrice = ""; offerPrice = "";
offerPriceError = "";
offerDescription = ""; offerDescription = "";
offerDescriptionError = ""; offerDescriptionError = "";
deliveryOptionSelectionError = "";
serviceItem = ""; serviceItem = "";
serviceItemCreatedOn = ""; serviceItemCreatedOn = "";
itemManufacturer = ""; itemManufacturer = "";
isDeliveryAvailableStatus = false; isDeliveryAvailableStatus = false;
if (myDeliveryOptionsFilterOptions.isNotEmpty) {
myDeliveryOptionsFilterOptions.forEach((option) => option.isSelected = false);
}
pickedVehicleImages.clear(); pickedVehicleImages.clear();
notifyListeners(); notifyListeners();
} }
@ -1055,6 +1129,7 @@ class RequestsVM extends BaseVM {
required int offerId, required int offerId,
required String offerPrice, required String offerPrice,
required bool isDeliveryAvailable, required bool isDeliveryAvailable,
required RequestDeliveryOptionEnum offerDeliveryOption,
required String serviceItemName, required String serviceItemName,
required String manufacturedByName, required String manufacturedByName,
required String manufacturedOn, required String manufacturedOn,
@ -1077,6 +1152,7 @@ class RequestsVM extends BaseVM {
offerId: offerId, offerId: offerId,
offerPrice: offerPrice, offerPrice: offerPrice,
isDeliveryAvailable: isDeliveryAvailable, isDeliveryAvailable: isDeliveryAvailable,
offerDeliveryOption: offerDeliveryOption.getIdRequestDeliveryOptionEnum(),
serviceItemName: serviceItemName, serviceItemName: serviceItemName,
manufacturedByName: manufacturedByName, manufacturedByName: manufacturedByName,
manufacturedOn: manufacturedOn, manufacturedOn: manufacturedOn,
@ -1120,6 +1196,7 @@ class RequestsVM extends BaseVM {
required String manufacturedOn, required String manufacturedOn,
required RequestModel requestModel, required RequestModel requestModel,
required bool isDeliveryAvailable, required bool isDeliveryAvailable,
required RequestDeliveryOptionEnum offerDeliveryOption,
required int requestIndex, required int requestIndex,
required bool isFromChatScreen, required bool isFromChatScreen,
required int? offerId, required int? offerId,
@ -1139,6 +1216,7 @@ class RequestsVM extends BaseVM {
requestId: requestId, requestId: requestId,
offerPrice: offerPrice, offerPrice: offerPrice,
isDeliveryAvailable: isDeliveryAvailable, isDeliveryAvailable: isDeliveryAvailable,
offerDeliveryOption: offerDeliveryOption,
manufacturedByName: manufacturedByName, manufacturedByName: manufacturedByName,
manufacturedOn: manufacturedOn, manufacturedOn: manufacturedOn,
serviceItemName: serviceItemName, serviceItemName: serviceItemName,
@ -1173,6 +1251,7 @@ class RequestsVM extends BaseVM {
requestID: requestModel.id, requestID: requestModel.id,
price: double.parse(offerPrice), price: double.parse(offerPrice),
isDeliveryAvailable: isDeliveryAvailable, isDeliveryAvailable: isDeliveryAvailable,
requestDeliveryOption: offerDeliveryOption,
manufacturedByName: manufacturedByName, manufacturedByName: manufacturedByName,
manufacturedOn: manufacturedOn, manufacturedOn: manufacturedOn,
serviceItemName: serviceItemName, serviceItemName: serviceItemName,
@ -1182,6 +1261,7 @@ class RequestsVM extends BaseVM {
reqOfferImages: images, reqOfferImages: images,
), ),
); );
context.read<ChatVM>().onNewMessageReceivedForRequestOffer(messages: [chatMessageModel], requestsVM: this, isMyOwnOffer: true); context.read<ChatVM>().onNewMessageReceivedForRequestOffer(messages: [chatMessageModel], requestsVM: this, isMyOwnOffer: true);
if (!isFromChatScreen) { if (!isFromChatScreen) {

@ -21,8 +21,11 @@ class ShippingManagementVM extends BaseVM {
List<ShippingRequestModel> shippingRequestsList = []; List<ShippingRequestModel> shippingRequestsList = [];
List<EnumsModel> shippingStatusEnums = []; List<EnumsModel> selfPickupStatusEnums = [];
List<FilterListModel> selfPickupRequestsFilterOptions = [];
List<FilterListModel> selfPickupRequestsStatusesList = [];
List<EnumsModel> shippingStatusEnums = [];
List<FilterListModel> shippingRequestFilterOptions = []; List<FilterListModel> shippingRequestFilterOptions = [];
List<FilterListModel> shippingRequestStatusesList = []; List<FilterListModel> shippingRequestStatusesList = [];
@ -32,15 +35,41 @@ class ShippingManagementVM extends BaseVM {
requestStatusComments = value; requestStatusComments = value;
} }
bool isSelfPickupTapped = false;
void updateIsSelfPickupTapped(var value) {
isSelfPickupTapped = value;
notifyListeners();
}
resetFilters() { resetFilters() {
if (shippingRequestFilterOptions.isEmpty) return; if (shippingRequestFilterOptions.isEmpty) return;
for (var value in shippingRequestFilterOptions) { for (var value in shippingRequestFilterOptions) {
value.isSelected = false; value.isSelected = false;
} }
shippingRequestFilterOptions[0].isSelected = true; shippingRequestFilterOptions[0].isSelected = true;
if (selfPickupRequestsFilterOptions.isEmpty) return;
for (var value in selfPickupRequestsFilterOptions) {
value.isSelected = false;
}
selfPickupRequestsFilterOptions[0].isSelected = true;
requestStatusComments = ""; requestStatusComments = "";
} }
Future<void> populateSelfPickupRequestFilterList() async {
selfPickupStatusEnums = await commonRepo.getEnumTypeValues(enumTypeID: AppEnums.selfPickupStatusEnumId);
selfPickupRequestsFilterOptions.clear();
selfPickupRequestsStatusesList.clear();
for (int i = 0; i < selfPickupStatusEnums.length; i++) {
selfPickupRequestsFilterOptions.add(FilterListModel(title: selfPickupStatusEnums[i].enumValueStrDes, isSelected: false, id: selfPickupStatusEnums[i].enumValue));
selfPickupRequestsStatusesList.add(FilterListModel(title: selfPickupStatusEnums[i].enumValueStrDes, isSelected: false, id: selfPickupStatusEnums[i].enumValue));
}
selfPickupRequestsFilterOptions.insert(0, FilterListModel(title: Utils.getNameByShippingRequestStatusEnum(ShippingRequestStatusEnum.allRequests), isSelected: true, id: -1));
notifyListeners();
}
Future<void> populateShippingRequestFilterList() async { Future<void> populateShippingRequestFilterList() async {
// if (shippingRequestFilterOptions.isNotEmpty && shippingRequestStatusesList.isNotEmpty) return; // if (shippingRequestFilterOptions.isNotEmpty && shippingRequestStatusesList.isNotEmpty) return;
@ -78,6 +107,22 @@ class ShippingManagementVM extends BaseVM {
notifyListeners(); notifyListeners();
} }
Future<void> applyFiltersOnSelfPickupRequests({required SelfPickupRequestStatusEnum selfPickupRequestStatusEnum}) async {
for (var value in selfPickupRequestsFilterOptions) {
value.isSelected = false;
}
if (selfPickupRequestStatusEnum == SelfPickupRequestStatusEnum.allRequests) {
selfPickupRequestsFilterOptions[0].isSelected = true;
await getSelfPickupRequestsListByFilters();
notifyListeners();
return;
}
int index = selfPickupRequestsFilterOptions.indexWhere((element) => element.id == selfPickupRequestStatusEnum.getIdFromSelfPickupStatusEnum());
selfPickupRequestsFilterOptions[index].isSelected = true; // +1 to match with the index 0 index has all requests
await getSelfPickupRequestsListByFilters(selfPickupStatusEnum: selfPickupRequestStatusEnum);
notifyListeners();
}
void updateSelectionInShippingRequestStatuses(int index) { void updateSelectionInShippingRequestStatuses(int index) {
for (var value in shippingRequestStatusesList) { for (var value in shippingRequestStatusesList) {
value.isSelected = false; value.isSelected = false;
@ -99,6 +144,19 @@ class ShippingManagementVM extends BaseVM {
} }
} }
Future<void> getSelfPickupRequestsListByFilters({SelfPickupRequestStatusEnum? selfPickupStatusEnum}) async {
setState(ViewState.busy);
try {
shippingRequestsList = await shippingRepo.getSelfPickupRequestListByStatus(selfPickupRequestStatus: selfPickupStatusEnum);
setState(ViewState.idle);
notifyListeners();
} catch (e) {
logger.i(e.toString());
Utils.showToast(e.toString());
setState(ViewState.idle);
}
}
Future<bool> onUpdateShippingStatusTapped({required BuildContext context, required ShippingRequestStatusEnum shippingStatusEnum, required int shippingRequestId}) async { Future<bool> onUpdateShippingStatusTapped({required BuildContext context, required ShippingRequestStatusEnum shippingStatusEnum, required int shippingRequestId}) async {
Utils.showLoading(context); Utils.showLoading(context);
try { try {

@ -370,7 +370,32 @@ class _AdsDetailViewState extends State<AdsDetailView> {
], ],
), ),
], ],
).paddingOnly(top: 5, bottom: 2).toWhiteContainer(width: double.infinity, allPading: 12); ).paddingOnly(top: 2, bottom: 2).toWhiteContainer(width: double.infinity, allPading: 12);
}
Widget buildSpecialServicesContainer() {
if (widget.adDetails.specialservice == null || widget.adDetails.specialservice!.isEmpty) {
return const SizedBox();
}
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.specialServices.tr().toText(fontSize: 16),
3.height,
Column(
children: List.generate(
widget.adDetails.specialservice!.length,
(index) => Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(child: ("${widget.adDetails.specialservice![index].name}").toText(fontSize: 14, color: MyColors.lightTextColor)),
("${widget.adDetails.specialservice![index].price} ${LocaleKeys.sar.tr()} ").toText(fontSize: 14, color: MyColors.lightTextColor),
],
)),
),
],
).paddingOnly(bottom: 2).toWhiteContainer(width: double.infinity, allPading: 12);
} }
@override @override
@ -395,8 +420,12 @@ class _AdsDetailViewState extends State<AdsDetailView> {
width: 42, width: 42,
); );
} else if ((widget.adDetails.adPostStatus != AdPostStatus.pendingForPost)) { } else if ((widget.adDetails.adPostStatus != AdPostStatus.pendingForPost)) {
actionWidget = actionWidget = IconButton(
IconButton(icon: const Icon(Icons.chat_outlined, color: Colors.black), onPressed: () => adVM.onMessagesButtonPressed(context: context, adDetailsModel: widget.adDetails)).toContainer( icon: const Icon(Icons.chat_outlined, color: Colors.black),
onPressed: () => adVM.onMessagesButtonPressed(
context: context,
adDetailsModel: widget.adDetails,
)).toContainer(
margin: const EdgeInsets.fromLTRB(0, 8, 21, 8), margin: const EdgeInsets.fromLTRB(0, 8, 21, 8),
paddingAll: 0, paddingAll: 0,
borderRadius: 100, borderRadius: 100,
@ -434,6 +463,10 @@ class _AdsDetailViewState extends State<AdsDetailView> {
buildPersonalInformationCard(context: context), buildPersonalInformationCard(context: context),
], ],
if (widget.adDetails.isMyAd ?? false) ...[ if (widget.adDetails.isMyAd ?? false) ...[
if (widget.adDetails.specialservice != null && widget.adDetails.specialservice!.isNotEmpty) ...[
12.height,
buildSpecialServicesContainer(),
],
12.height, 12.height,
buildAdStartEndDates(), buildAdStartEndDates(),
], ],

@ -2,6 +2,7 @@ import 'dart:developer';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.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/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart';
@ -12,6 +13,7 @@ import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart'; import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/view_models/subscriptions_view_model.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart'; import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -167,6 +169,7 @@ class AdDurationSelectionSheet extends StatelessWidget {
if (adVM.isFetchingLists) { if (adVM.isFetchingLists) {
return; return;
} else { } else {
final subscriptionsVM = context.read<SubscriptionsVM>();
if (isFromExtendAd && !isUpdateAdSelected) { if (isFromExtendAd && !isUpdateAdSelected) {
List<bool> statuses = List<bool> statuses =
await adVM.createAdExtensionOrder(context, adId: adsID, adsDurationId: adVM.vehicleAdDurationId.selectedId); // [0] Means API response [1] means isPaymentRequired await adVM.createAdExtensionOrder(context, adId: adsID, adsDurationId: adVM.vehicleAdDurationId.selectedId); // [0] Means API response [1] means isPaymentRequired
@ -176,6 +179,7 @@ class AdDurationSelectionSheet extends StatelessWidget {
pop(context); pop(context);
pop(context); pop(context);
pop(context); pop(context);
await subscriptionsVM.getSubscriptionBySP(AppState().getUser.data?.userInfo?.providerId.toString() ?? "", true);
adVM.applyFilterOnMyAds(adPostStatusEnum: AdPostStatus.active); adVM.applyFilterOnMyAds(adPostStatusEnum: AdPostStatus.active);
} }
} else { } else {

@ -11,6 +11,7 @@ import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/utils/utils.dart'; import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/chat_view_model.dart'; import 'package:mc_common_app/view_models/chat_view_model.dart';
import 'package:mc_common_app/view_models/dashboard_view_model_provider.dart';
import 'package:mc_common_app/view_models/payment_view_model.dart'; import 'package:mc_common_app/view_models/payment_view_model.dart';
import 'package:mc_common_app/view_models/requests_view_model.dart'; import 'package:mc_common_app/view_models/requests_view_model.dart';
import 'package:mc_common_app/views/advertisement/ads_buyer_chats_view.dart'; import 'package:mc_common_app/views/advertisement/ads_buyer_chats_view.dart';
@ -175,30 +176,30 @@ class _ChatViewState extends State<ChatView> {
child: chatMessages.isEmpty child: chatMessages.isEmpty
? Center(child: LocaleKeys.noChatMessage.tr().toText(fontSize: 16, color: MyColors.lightTextColor, textAlign: TextAlign.center)).paddingAll(22) ? Center(child: LocaleKeys.noChatMessage.tr().toText(fontSize: 16, color: MyColors.lightTextColor, textAlign: TextAlign.center)).paddingAll(22)
: ListView.separated( : ListView.separated(
controller: chatVM.scrollController, controller: chatVM.scrollController,
itemCount: chatMessages.length, itemCount: chatMessages.length,
separatorBuilder: (BuildContext context, int index) => 20.height, separatorBuilder: (BuildContext context, int index) => 20.height,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
ChatMessageModel chatMessageModel = chatMessages[index]; ChatMessageModel chatMessageModel = chatMessages[index];
return ChatMessageCustomWidget( return ChatMessageCustomWidget(
chatMessageModel: chatMessageModel, chatMessageModel: chatMessageModel,
requestModel: chatTypeEnum == ChatTypeEnum.requestOffer ? chatViewArgumentsForRequest!.requestModel! : null, requestModel: chatTypeEnum == ChatTypeEnum.requestOffer ? chatViewArgumentsForRequest!.requestModel! : null,
requestStatusEnum: requestVM.currentSelectedRequest?.requestStatus, requestStatusEnum: requestVM.currentSelectedRequest?.requestStatus,
chatTypeEnum: chatTypeEnum, chatTypeEnum: chatTypeEnum,
requestsTypeEnum: chatTypeEnum == ChatTypeEnum.requestOffer ? chatViewArgumentsForRequest!.requestModel!.requestType.toRequestTypeEnum() : RequestsTypeEnum.specialCarRequest, requestsTypeEnum: chatTypeEnum == ChatTypeEnum.requestOffer ? chatViewArgumentsForRequest!.requestModel!.requestType.toRequestTypeEnum() : RequestsTypeEnum.specialCarRequest,
); );
}, },
).horPaddingMain(), ).horPaddingMain(),
), ),
10.height, 10.height,
Row( Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
if (chatTypeEnum == ChatTypeEnum.requestOffer && if (
AppState().currentAppType == AppType.customer && chatTypeEnum == ChatTypeEnum.requestOffer &&
requestVM.currentSelectedRequest!.requestType.toRequestTypeEnum() == RequestsTypeEnum.serviceRequest && requestVM.currentSelectedRequest!.requestType.toRequestTypeEnum() == RequestsTypeEnum.serviceRequest &&
requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.inProgress && requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.inProgress &&
requestVM.currentSelectedOffer!.requestOfferStatusEnum == RequestOfferStatusEnum.accepted && requestVM.currentSelectedOffer!.requestOfferStatusEnum == RequestOfferStatusEnum.accepted ) ...[
AppState().currentAppType == AppType.customer) ...[
Expanded( Expanded(
child: ShowFillButton( child: ShowFillButton(
maxWidth: double.infinity, maxWidth: double.infinity,
@ -233,88 +234,93 @@ class _ChatViewState extends State<ChatView> {
// ), // ),
// ] // ]
// //
else ...[ else
if (AppState().currentAppType == AppType.provider && ...[
chatTypeEnum == ChatTypeEnum.requestOffer && if (AppState().currentAppType == AppType.provider &&
requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.submitted && chatTypeEnum == ChatTypeEnum.requestOffer &&
chatVM.pickedImagesForMessage.isEmpty) ...[ requestVM.currentSelectedRequest!.requestStatus == RequestStatusEnum.submitted &&
Expanded( chatVM.pickedImagesForMessage.isEmpty) ...[
flex: 1, Expanded(
child: const Icon( flex: 1,
Icons.local_offer_rounded, child: const Icon(
color: MyColors.darkPrimaryColor, Icons.local_offer_rounded,
size: 30, color: MyColors.darkPrimaryColor,
).onPress( size: 30,
() { ).onPress(
requestVM.resetSendOfferBottomSheet(); () {
RequestDetailPageArguments requestDetailArguments = RequestDetailPageArguments( requestVM.resetSendOfferBottomSheet();
requestIndex: chatViewArgumentsForRequest!.requestIndex, RequestDetailPageArguments requestDetailArguments = RequestDetailPageArguments(
requestModel: chatViewArgumentsForRequest!.requestModel!, requestIndex: chatViewArgumentsForRequest!.requestIndex,
); requestModel: chatViewArgumentsForRequest!.requestModel!,
buildSendOfferBottomSheet( );
context: context, context.read<DashboardVMProvider>().checkUserSubscription(SubscriptionActionTypeEnum.subscription, context, callback: () {
requestDetailPageArguments: requestDetailArguments, buildSendOfferBottomSheet(
isFromChatScreen: true, context: context,
offerId: null, // null means creating new offer requestDetailPageArguments: requestDetailArguments,
); isFromChatScreen: true,
}, offerId: null, // null means creating new offer
);
});
},
),
), ),
), ],
], if (chatVM.pickedImagesForMessage.isNotEmpty) ...[
if (chatVM.pickedImagesForMessage.isNotEmpty) ...[ Expanded(
Expanded( flex: 8,
flex: 8, child: PickedFilesContainer(
child: PickedFilesContainer( pickedFiles: chatVM.pickedImagesForMessage,
pickedFiles: chatVM.pickedImagesForMessage, onCrossPressedPrimary: chatVM.removeImageFromList,
onCrossPressedPrimary: chatVM.removeImageFromList, onAddFilePressed: () => chatVM.pickMultipleImages(),
onAddFilePressed: () => chatVM.pickMultipleImages(), ),
), ),
), ] else
] else if (chatTypeEnum == ChatTypeEnum.requestOffer) ...[ if (chatTypeEnum == ChatTypeEnum.requestOffer) ...[
Expanded(
flex: 1,
child: const Icon(
Icons.photo_library_rounded,
color: MyColors.darkPrimaryColor,
size: 30,
).onPress(() => chatVM.pickMultipleImages()),
),
],
if (chatVM.pickedImagesForMessage.isEmpty) ...[
Expanded(
flex: 8,
child: TxtField(
isNeedLabelOnTop: false,
value: chatVM.chatMessageText,
hint: LocaleKeys.typeMessageHere.tr(),
keyboardType: TextInputType.text,
isNeedBorder: false,
onChanged: (v) => chatVM.updateChatMessageText(v),
),
),
],
Expanded( Expanded(
flex: 1, flex: 1,
child: const Icon( child: const Icon(Icons.send_rounded, color: MyColors.darkPrimaryColor, size: 30).onPress(
Icons.photo_library_rounded, () async {
color: MyColors.darkPrimaryColor, ChatMessageTypeEnum chatMessageTypeEnum = ChatMessageTypeEnum.freeText;
size: 30,
).onPress(() => chatVM.pickMultipleImages()),
),
],
if (chatVM.pickedImagesForMessage.isEmpty) ...[
Expanded(
flex: 8,
child: TxtField(
value: chatVM.chatMessageText,
hint: LocaleKeys.typeMessageHere.tr(),
keyboardType: TextInputType.text,
isNeedBorder: false,
onChanged: (v) => chatVM.updateChatMessageText(v),
),
),
],
Expanded(
flex: 1,
child: const Icon(Icons.send_rounded, color: MyColors.darkPrimaryColor, size: 30).onPress(
() async {
ChatMessageTypeEnum chatMessageTypeEnum = ChatMessageTypeEnum.freeText;
if (chatVM.pickedImagesForMessage.isNotEmpty) { if (chatVM.pickedImagesForMessage.isNotEmpty) {
chatMessageTypeEnum = ChatMessageTypeEnum.image; chatMessageTypeEnum = ChatMessageTypeEnum.image;
} }
final status = await onMessageSend(chatMessageType: chatMessageTypeEnum); final status = await onMessageSend(chatMessageType: chatMessageTypeEnum);
if (status) { if (status) {
chatVM.scrollChatDown(); chatVM.scrollChatDown();
if (chatMessageTypeEnum == ChatMessageTypeEnum.freeText) { if (chatMessageTypeEnum == ChatMessageTypeEnum.freeText) {
chatVM.clearChatMessageText(); chatVM.clearChatMessageText();
} else if (chatMessageTypeEnum == ChatMessageTypeEnum.image) { } else if (chatMessageTypeEnum == ChatMessageTypeEnum.image) {
chatVM.clearPickedImagesForMessage(); chatVM.clearPickedImagesForMessage();
}
} }
} },
}, ),
), ),
), ],
],
], ],
).toContainer(isShadowEnabled: true) ).toContainer(isShadowEnabled: true)
], ],

@ -128,6 +128,8 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
serviceProviderID: chatMessageModel.serviceProviderID ?? 0, serviceProviderID: chatMessageModel.serviceProviderID ?? 0,
requestOfferID: chatMessageModel.reqOffer!.id ?? -1, requestOfferID: chatMessageModel.reqOffer!.id ?? -1,
offerPrice: chatMessageModel.reqOffer!.price.toString(), offerPrice: chatMessageModel.reqOffer!.price.toString(),
isDeliveryAvailable: chatMessageModel.reqOffer!.isDeliveryAvailable ?? false,
offerDeliveryOption: chatMessageModel.reqOffer!.requestDeliveryOption ?? RequestDeliveryOptionEnum.selfPickup,
serviceItemName: chatMessageModel.reqOffer!.serviceItemName ?? "", serviceItemName: chatMessageModel.reqOffer!.serviceItemName ?? "",
manufacturedOn: chatMessageModel.reqOffer!.manufacturedOn ?? "", manufacturedOn: chatMessageModel.reqOffer!.manufacturedOn ?? "",
manufacturedByName: chatMessageModel.reqOffer!.manufacturedByName ?? "", manufacturedByName: chatMessageModel.reqOffer!.manufacturedByName ?? "",
@ -227,6 +229,8 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
serviceProviderID: chatMessageModel.serviceProviderID ?? 0, serviceProviderID: chatMessageModel.serviceProviderID ?? 0,
requestOfferID: chatMessageModel.reqOffer!.id ?? -1, requestOfferID: chatMessageModel.reqOffer!.id ?? -1,
offerPrice: chatMessageModel.reqOffer!.price.toString(), offerPrice: chatMessageModel.reqOffer!.price.toString(),
isDeliveryAvailable: chatMessageModel.reqOffer!.isDeliveryAvailable ?? false,
offerDeliveryOption: chatMessageModel.reqOffer!.requestDeliveryOption ?? RequestDeliveryOptionEnum.selfPickup,
serviceItemName: chatMessageModel.reqOffer!.serviceItemName ?? "", serviceItemName: chatMessageModel.reqOffer!.serviceItemName ?? "",
manufacturedOn: chatMessageModel.reqOffer!.manufacturedOn ?? "", manufacturedOn: chatMessageModel.reqOffer!.manufacturedOn ?? "",
manufacturedByName: chatMessageModel.reqOffer!.manufacturedByName ?? "", manufacturedByName: chatMessageModel.reqOffer!.manufacturedByName ?? "",
@ -374,6 +378,8 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
serviceProviderID: chatMessageModel.serviceProviderID ?? 0, serviceProviderID: chatMessageModel.serviceProviderID ?? 0,
requestOfferID: chatMessageModel.reqOffer!.id ?? -1, requestOfferID: chatMessageModel.reqOffer!.id ?? -1,
offerPrice: chatMessageModel.reqOffer!.price.toString(), offerPrice: chatMessageModel.reqOffer!.price.toString(),
isDeliveryAvailable: chatMessageModel.reqOffer!.isDeliveryAvailable ?? false,
offerDeliveryOption: chatMessageModel.reqOffer!.requestDeliveryOption ?? RequestDeliveryOptionEnum.selfPickup,
serviceItemName: chatMessageModel.reqOffer!.serviceItemName ?? "", serviceItemName: chatMessageModel.reqOffer!.serviceItemName ?? "",
manufacturedOn: chatMessageModel.reqOffer!.manufacturedOn ?? "", manufacturedOn: chatMessageModel.reqOffer!.manufacturedOn ?? "",
manufacturedByName: chatMessageModel.reqOffer!.manufacturedByName ?? "", manufacturedByName: chatMessageModel.reqOffer!.manufacturedByName ?? "",
@ -428,6 +434,8 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
serviceProviderID: chatMessageModel.serviceProviderID ?? 0, serviceProviderID: chatMessageModel.serviceProviderID ?? 0,
requestOfferID: chatMessageModel.reqOffer!.id ?? -1, requestOfferID: chatMessageModel.reqOffer!.id ?? -1,
offerPrice: chatMessageModel.reqOffer!.price.toString(), offerPrice: chatMessageModel.reqOffer!.price.toString(),
isDeliveryAvailable: chatMessageModel.reqOffer!.isDeliveryAvailable ?? false,
offerDeliveryOption: chatMessageModel.reqOffer!.requestDeliveryOption ?? RequestDeliveryOptionEnum.selfPickup,
serviceItemName: chatMessageModel.reqOffer!.serviceItemName ?? "", serviceItemName: chatMessageModel.reqOffer!.serviceItemName ?? "",
manufacturedOn: chatMessageModel.reqOffer!.manufacturedOn ?? "", manufacturedOn: chatMessageModel.reqOffer!.manufacturedOn ?? "",
manufacturedByName: chatMessageModel.reqOffer!.manufacturedByName ?? "", manufacturedByName: chatMessageModel.reqOffer!.manufacturedByName ?? "",
@ -500,6 +508,7 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
Widget buildOfferDetailsInChatMessage({required RequestStatusEnum requestStatusEnum, required ChatMessageModel chatMessageModel, required BuildContext context}) { Widget buildOfferDetailsInChatMessage({required RequestStatusEnum requestStatusEnum, required ChatMessageModel chatMessageModel, required BuildContext context}) {
final requestOfferStatusEnum = chatMessageModel.reqOffer!.requestOfferStatusEnum ?? RequestOfferStatusEnum.offer; final requestOfferStatusEnum = chatMessageModel.reqOffer!.requestOfferStatusEnum ?? RequestOfferStatusEnum.offer;
if (requestStatusEnum != RequestStatusEnum.submitted && requestOfferStatusEnum != RequestOfferStatusEnum.accepted) { if (requestStatusEnum != RequestStatusEnum.submitted && requestOfferStatusEnum != RequestOfferStatusEnum.accepted) {
return Column( return Column(
children: [ children: [
@ -744,6 +753,7 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
requestVM.updateOfferDescription((widget.chatMessageModel.chatText ?? "").toString()); requestVM.updateOfferDescription((widget.chatMessageModel.chatText ?? "").toString());
requestVM.updateIsDeliveryAvailableStatus((offer.isDeliveryAvailable ?? false)); requestVM.updateIsDeliveryAvailableStatus((offer.isDeliveryAvailable ?? false));
requestVM.applyFilterOnDeliveryOption(requestDeliveryOptionEnum: offer.requestDeliveryOption ?? RequestDeliveryOptionEnum.none);
if (offer.reqOfferImages != null && offer.reqOfferImages!.isNotEmpty) { if (offer.reqOfferImages != null && offer.reqOfferImages!.isNotEmpty) {
for (var element in offer.reqOfferImages!) { for (var element in offer.reqOfferImages!) {
if (element.imageUrl != null || element.imageStr != null) { if (element.imageUrl != null || element.imageStr != null) {
@ -886,6 +896,27 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
); );
} }
Widget buildDeliveryOptionsWidget({required RequestDeliveryOptionEnum deliveryOptionId}) {
Widget finalWidget = const SizedBox();
String finalText = "";
if (deliveryOptionId == RequestDeliveryOptionEnum.none) {
finalText = RequestDeliveryOptionEnum.selfPickup.getStringFromRequestDeliveryOptionEnum();
} else {
finalText = deliveryOptionId.getStringFromRequestDeliveryOptionEnum();
}
finalWidget = Directionality(
textDirection: TextDirection.ltr,
child: "${LocaleKeys.deliveryOptions.tr()} : $finalText".toText(
fontSize: 10,
color: (widget.chatMessageModel.isMyMessage ?? false) ? MyColors.white : MyColors.lightTextColor,
fontWeight: MyFonts.Medium,
),
);
return finalWidget;
}
Widget messageWidgetBasedOnType({required ChatMessageTypeEnum? chatMessageTypeEnum}) { Widget messageWidgetBasedOnType({required ChatMessageTypeEnum? chatMessageTypeEnum}) {
Widget messageTypeWidget = const SizedBox(); Widget messageTypeWidget = const SizedBox();
if (chatMessageTypeEnum == null) { if (chatMessageTypeEnum == null) {
@ -908,14 +939,7 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
buildFreeTextDetailsInMessage(chatMessageTypeEnum: chatMessageTypeEnum), buildFreeTextDetailsInMessage(chatMessageTypeEnum: chatMessageTypeEnum),
if (widget.requestsTypeEnum == RequestsTypeEnum.serviceRequest) ...[ if (widget.requestsTypeEnum == RequestsTypeEnum.serviceRequest) ...[
2.height, 2.height,
Directionality( buildDeliveryOptionsWidget(deliveryOptionId: widget.chatMessageModel.reqOffer!.requestDeliveryOption ?? RequestDeliveryOptionEnum.none),
textDirection: TextDirection.ltr,
child: "${LocaleKeys.deliveryAvailable.tr()} : ${(widget.chatMessageModel.reqOffer!.isDeliveryAvailable ?? false) ? LocaleKeys.yes.tr() : LocaleKeys.no.tr()}".toText(
fontSize: 10,
color: (widget.chatMessageModel.isMyMessage ?? false) ? MyColors.white : MyColors.lightTextColor,
fontWeight: MyFonts.Medium,
),
),
], ],
if (widget.chatMessageModel.reqOffer!.reqOfferImages != null && widget.chatMessageModel.reqOffer!.reqOfferImages!.isNotEmpty) ...[ if (widget.chatMessageModel.reqOffer!.reqOfferImages != null && widget.chatMessageModel.reqOffer!.reqOfferImages!.isNotEmpty) ...[
5.height, 5.height,

@ -8,6 +8,7 @@ import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/models/requests_models/offers_model.dart'; import 'package:mc_common_app/models/requests_models/offers_model.dart';
import 'package:mc_common_app/models/requests_models/offers_unread_chat_model.dart';
import 'package:mc_common_app/models/requests_models/provider_offers_model.dart'; import 'package:mc_common_app/models/requests_models/provider_offers_model.dart';
import 'package:mc_common_app/models/requests_models/providers_offers_chat_model.dart'; import 'package:mc_common_app/models/requests_models/providers_offers_chat_model.dart';
import 'package:mc_common_app/models/requests_models/request_model.dart'; import 'package:mc_common_app/models/requests_models/request_model.dart';
@ -39,7 +40,7 @@ class _ProvidersChatListPageState extends State<ProvidersChatListPage> {
_onRefresh() async { _onRefresh() async {
scheduleMicrotask(() async { scheduleMicrotask(() async {
RequestsVM requestsVM = context.read<RequestsVM>(); RequestsVM requestsVM = context.read<RequestsVM>();
await requestsVM.getProviderOffersChatsList(serviceProviderId: AppState().getUser.data!.userInfo!.providerId ?? 0, context: context); await requestsVM.getOffersChatsUnreadList(userId: AppState().getUser.data!.userInfo!.userId ?? "", context: context);
}); });
} }
@ -110,7 +111,7 @@ class _ProvidersChatListPageState extends State<ProvidersChatListPage> {
}, },
child: requestsVM.state == ViewState.busy child: requestsVM.state == ViewState.busy
? const Center(child: CircularProgressIndicator()) ? const Center(child: CircularProgressIndicator())
: requestsVM.providerOffersChatsList.isEmpty : requestsVM.offersUnreadChatModel == null || requestsVM.offersUnreadChatModel!.reqChatUnread.isEmpty
? Center( ? Center(
child: LocaleKeys.noOffersShow.tr().toText( child: LocaleKeys.noOffersShow.tr().toText(
fontSize: 16, fontSize: 16,
@ -118,58 +119,66 @@ class _ProvidersChatListPageState extends State<ProvidersChatListPage> {
), ),
) )
: ListView.separated( : ListView.separated(
itemCount: requestsVM.providerOffersChatsList.length, itemCount: requestsVM.offersUnreadChatModel!.reqChatUnread.length,
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
itemBuilder: (context, index) { itemBuilder: (context, index) {
ProviderOffersChatsModel providerOffersChatsModel = requestsVM.providerOffersChatsList[index]; OffersUnreadChatDataModel offersUnreadChatDataModel = requestsVM.offersUnreadChatModel!.reqChatUnread[index];
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Utils.statusContainerChip( // Utils.statusContainerChip(
text: Utils.getNameByRequestOfferStatusEnum(providerOffersChatsModel.requestOfferStatusEnum!), // text: Utils.getNameByRequestOfferStatusEnum(providerOffersChatsModel.requestOfferStatusEnum!),
chipColor: Utils.getChipColorByRequestOfferStatusEnum(providerOffersChatsModel.requestOfferStatusEnum!), // chipColor: Utils.getChipColorByRequestOfferStatusEnum(providerOffersChatsModel.requestOfferStatusEnum!),
), // ),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
(providerOffersChatsModel.customerName ?? "").toText( (offersUnreadChatDataModel.customerName).toText(
fontSize: 16, fontSize: 16,
isBold: true, isBold: true,
), ),
if (providerOffersChatsModel.createdOn != null && providerOffersChatsModel.createdOn!.isNotEmpty) ...[ if (offersUnreadChatDataModel.unreadMessagesCount > 0) ...[
DateTime.parse(providerOffersChatsModel.createdOn!).getTimeAgo().toText(color: MyColors.lightTextColor, fontSize: 14), Center(
child: "${offersUnreadChatDataModel.unreadMessagesCount}".toText(
color: Colors.white,
isBold: true,
fontSize: 10,
),
).toContainer(
backgroundColor: MyColors.cancelledColor,
borderRadius: 100,
paddingAll: 1,
width: 22,
height: 22,
),
], ],
// if (providerOffersChatsModel. != null && offersModel.offerCount! > 0) ...[
// Center(
// child: "${providerOffersChatsModel.offerCount}".toText(
// color: Colors.white,
// isBold: true,
// fontSize: 10,
// ),
// ).toContainer(
// backgroundColor: MyColors.cancelledColor,
// borderRadius: 100,
// paddingAll: 1,
// width: 22,
// height: 22,
// ),
// ],
], ],
), ),
4.height, 4.height,
Row( Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Expanded( Expanded(
child: "${providerOffersChatsModel.comment}".toText(color: MyColors.lightTextColor, fontSize: 14), child: offersUnreadChatDataModel.lastChatText.toText(color: MyColors.lightTextColor, fontSize: 14),
), ),
const Icon(Icons.arrow_forward, color: MyColors.darkIconColor, size: 18), 4.height,
if (offersUnreadChatDataModel.lastChatTime.isNotEmpty) ...[
DateTime.parse(offersUnreadChatDataModel.lastChatTime).getTimeAgo().toText(color: MyColors.lightTextColor, fontSize: 12),
],
],
),
4.height,
const Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Icon(Icons.arrow_forward, color: MyColors.darkIconColor, size: 18),
], ],
), ),
], ],
).onPress(() async => await onChatTapped(context: context, requestID: providerOffersChatsModel.requestID ?? 0)).toContainer(isShadowEnabled: true); ).onPress(() async => await onChatTapped(context: context, requestID: offersUnreadChatDataModel.requestId ?? 0)).toContainer(isShadowEnabled: true);
}, },
separatorBuilder: (context, index) => 16.height, separatorBuilder: (context, index) => 16.height,
), ),

@ -19,6 +19,7 @@ import 'package:mc_common_app/views/advertisement/ad_creation_steps/ad_creation_
import 'package:mc_common_app/views/advertisement/components/picked_images_container_widget.dart'; import 'package:mc_common_app/views/advertisement/components/picked_images_container_widget.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart'; import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/checkbox_with_title_desc.dart'; import 'package:mc_common_app/widgets/checkbox_with_title_desc.dart';
import 'package:mc_common_app/widgets/common_widgets/filters_list.dart';
import 'package:mc_common_app/widgets/common_widgets/info_bottom_sheet.dart'; import 'package:mc_common_app/widgets/common_widgets/info_bottom_sheet.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:mc_common_app/widgets/txt_field.dart'; import 'package:mc_common_app/widgets/txt_field.dart';
@ -96,7 +97,7 @@ Future buildSendOfferBottomSheet({
], ],
12.height, 12.height,
TxtField( TxtField(
maxLines: 5, maxLines: 3,
value: requestsVM.offerDescription, value: requestsVM.offerDescription,
errorValue: requestsVM.offerDescriptionError, errorValue: requestsVM.offerDescriptionError,
keyboardType: TextInputType.text, keyboardType: TextInputType.text,
@ -105,32 +106,49 @@ Future buildSendOfferBottomSheet({
), ),
12.height, 12.height,
if (requestDetail.requestType == RequestsTypeEnum.serviceRequest.getIdFromRequestTypeEnum()) ...[ if (requestDetail.requestType == RequestsTypeEnum.serviceRequest.getIdFromRequestTypeEnum()) ...[
LocaleKeys.deliveryAvailable.tr().toText(fontSize: 16), LocaleKeys.selectDeliveryOption.tr().toText(fontSize: 16),
8.height, 10.height,
Container( // Container(
width: 50, // width: 50,
height: 30, // height: 30,
decoration: BoxDecoration( // decoration: BoxDecoration(
color: requestsVM.isDeliveryAvailableStatus ? MyColors.darkPrimaryColor : MyColors.white, // color: requestsVM.isDeliveryAvailableStatus ? MyColors.darkPrimaryColor : MyColors.white,
borderRadius: BorderRadius.circular(25.0), // borderRadius: BorderRadius.circular(25.0),
border: Border.all(color: MyColors.black, width: 1), // border: Border.all(color: MyColors.black, width: 1),
), // ),
child: Transform.scale( // child: Transform.scale(
scale: 0.8, // scale: 0.8,
child: CupertinoSwitch( // child: CupertinoSwitch(
activeColor: MyColors.darkPrimaryColor, // activeTrackColor: MyColors.darkPrimaryColor,
trackColor: MyColors.white, // inactiveTrackColor: MyColors.white,
thumbColor: MyColors.grey98Color, // thumbColor: MyColors.grey98Color,
value: requestsVM.isDeliveryAvailableStatus, // value: requestsVM.isDeliveryAvailableStatus,
onChanged: (value) { // onChanged: (value) {
requestsVM.updateIsDeliveryAvailableStatus(value); // requestsVM.updateIsDeliveryAvailableStatus(value);
}, // },
), // ),
// ),
// ),
FiltersList(
filterList: requestsVM.myDeliveryOptionsFilterOptions,
onFilterTapped: (index, selectedFilterId) {
requestsVM.applyFilterOnDeliveryOption(requestDeliveryOptionEnum: selectedFilterId.toRequestDeliveryOptionEnum());
},
needLeftPadding: false,
).paddingOnly(bottom: 21),
if (requestsVM.deliveryOptionSelectionError.isNotEmpty) ...[
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
requestsVM.deliveryOptionSelectionError.toText(),
],
), ),
), ]
], ],
12.height,
if (requestsVM.pickedVehicleImages.isEmpty) ...[ if (requestsVM.pickedVehicleImages.isEmpty) ...[
5.height,
DottedRectContainer( DottedRectContainer(
onTap: () => context.read<RequestsVM>().pickMultipleImages(), onTap: () => context.read<RequestsVM>().pickMultipleImages(),
text: LocaleKeys.attachImage.tr(), text: LocaleKeys.attachImage.tr(),
@ -139,7 +157,7 @@ Future buildSendOfferBottomSheet({
), ),
], ],
if (requestsVM.pickedVehicleImages.isNotEmpty) ...[ if (requestsVM.pickedVehicleImages.isNotEmpty) ...[
16.height, // 14.height,
PickedFilesContainer( PickedFilesContainer(
pickedFiles: requestsVM.pickedVehicleImages, pickedFiles: requestsVM.pickedVehicleImages,
onCrossPressedPrimary: requestsVM.removeImageFromList, onCrossPressedPrimary: requestsVM.removeImageFromList,
@ -159,6 +177,12 @@ Future buildSendOfferBottomSheet({
"${AppState().getUser.data!.userInfo!.firstName} ${AppState().getUser.data!.userInfo!.lastName}", "${AppState().getUser.data!.userInfo!.firstName} ${AppState().getUser.data!.userInfo!.lastName}",
); );
requestsVM.updateServiceItemCreatedOn(DateHelper.formatAsYearMonthDay(DateTime.now())); requestsVM.updateServiceItemCreatedOn(DateHelper.formatAsYearMonthDay(DateTime.now()));
RequestDeliveryOptionEnum requestDeliveryOptionEnum = RequestDeliveryOptionEnum.none;
int index = requestsVM.myDeliveryOptionsFilterOptions.indexWhere((option) => option.isSelected);
if (index != -1) {
requestDeliveryOptionEnum = requestsVM.myDeliveryOptionsFilterOptions[index].id.toRequestDeliveryOptionEnum();
}
if (offerId == null) { if (offerId == null) {
requestsVM.onSendOfferPressed( requestsVM.onSendOfferPressed(
context: context, context: context,
@ -169,6 +193,7 @@ Future buildSendOfferBottomSheet({
offerPrice: requestsVM.offerPrice, offerPrice: requestsVM.offerPrice,
requestModel: requestDetail, requestModel: requestDetail,
isDeliveryAvailable: requestsVM.isDeliveryAvailableStatus, isDeliveryAvailable: requestsVM.isDeliveryAvailableStatus,
offerDeliveryOption: requestDeliveryOptionEnum,
requestIndex: requestDetailPageArguments.requestIndex, requestIndex: requestDetailPageArguments.requestIndex,
isFromChatScreen: isFromChatScreen, isFromChatScreen: isFromChatScreen,
manufacturedByName: requestsVM.itemManufacturer, manufacturedByName: requestsVM.itemManufacturer,
@ -182,6 +207,7 @@ Future buildSendOfferBottomSheet({
offerId: offerId, offerId: offerId,
offerPrice: requestsVM.offerPrice, offerPrice: requestsVM.offerPrice,
isDeliveryAvailable: requestsVM.isDeliveryAvailableStatus, isDeliveryAvailable: requestsVM.isDeliveryAvailableStatus,
offerDeliveryOption: requestDeliveryOptionEnum,
serviceItemName: requestsVM.serviceItem, serviceItemName: requestsVM.serviceItem,
manufacturedByName: requestsVM.itemManufacturer, manufacturedByName: requestsVM.itemManufacturer,
manufacturedOn: requestsVM.serviceItemCreatedOn, manufacturedOn: requestsVM.serviceItemCreatedOn,

@ -26,6 +26,107 @@ class RequestDetailPage extends StatelessWidget {
const RequestDetailPage({super.key, required this.requestDetailPageArguments}); const RequestDetailPage({super.key, required this.requestDetailPageArguments});
Widget buildRequestDetailsContainer(BuildContext context) {
final requestDetail = requestDetailPageArguments.requestModel;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
requestDetail.vehicleTypeName.toText(fontSize: 16, letterSpacing: -0.64),
showItem("${LocaleKeys.brand.tr()}: ", requestDetail.brand),
showItem("${LocaleKeys.model.tr()}: ", requestDetail.model),
showItem("${LocaleKeys.year.tr()}: ", "${requestDetail.year}"),
],
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.start,
children: [
"${requestDetail.city ?? ""} ${requestDetail.countryName}".toText(
color: MyColors.lightTextColor,
),
if (requestDetail.createdOn != null) ...[
DateTime.parse(requestDetail.createdOn!).getTimeAgo().toText(
color: MyColors.lightTextColor,
),
],
],
),
],
),
if (requestDetail.customerName.isNotEmpty) ...[
showItem("${LocaleKeys.customerName.tr()}: ", requestDetail.customerName),
],
showItem("${LocaleKeys.description.tr()}: ", requestDetail.description),
16.height,
if (AppState().currentAppType == AppType.provider &&
(requestDetailPageArguments.requestModel.requestStatus == RequestStatusEnum.inProgress || requestDetailPageArguments.requestModel.requestStatus == RequestStatusEnum.submitted)) ...[
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
("${LocaleKeys.reportComplaint.tr()}?").toText(fontSize: 14, color: MyColors.darkTextColor),
],
).onPress(
() {
int customerID = requestDetailPageArguments.requestModel.customerId;
int complainType = 2;
String customerName = requestDetailPageArguments.requestModel.customerName;
context.read<AppointmentsVM>().buildComplaintBottomSheet(
customerID: customerID,
customerName: customerName,
complainType: complainType,
context: context,
);
},
),
],
// showItem("${LocaleKeys.priceRange.tr()}:", ""),
// Row(
// children: [
// Expanded(
// child: Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// crossAxisAlignment: CrossAxisAlignment.end,
// children: [
// Row(
// crossAxisAlignment: CrossAxisAlignment.end,
// children: [
// "${requestDetail.price.toInt()}".toText(fontSize: 19, isBold: true, letterSpacing: -1.16),
// 2.width,
// LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, fontSize: 10, letterSpacing: -0.4),
// ],
// ),
// Row(
// children: [
// Utils.statusContainerChip(
// text: (requestDetail.requestStatusName),
// chipColor: MyColors.grey98Color.withOpacity(0.1),
// textColor: MyColors.lightTextColor,
// ),
// ],
// ),
// ],
// ),
// ),
// // const Icon(Icons.arrow_forward)
// ],
// ),
],
);
}
Widget buildRequestDetailActionFooter({ Widget buildRequestDetailActionFooter({
required int requestId, required int requestId,
required RequestStatusEnum requestStatus, required RequestStatusEnum requestStatus,
@ -209,107 +310,6 @@ class RequestDetailPage extends StatelessWidget {
); );
} }
Widget buildRequestDetailsContainer(BuildContext context) {
final requestDetail = requestDetailPageArguments.requestModel;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
requestDetail.vehicleTypeName.toText(fontSize: 16, letterSpacing: -0.64),
showItem("${LocaleKeys.brand.tr()}: ", requestDetail.brand),
showItem("${LocaleKeys.model.tr()}: ", requestDetail.model),
showItem("${LocaleKeys.year.tr()}: ", "${requestDetail.year}"),
],
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.start,
children: [
"${requestDetail.city ?? ""} ${requestDetail.countryName}".toText(
color: MyColors.lightTextColor,
),
if (requestDetail.createdOn != null) ...[
DateTime.parse(requestDetail.createdOn!).getTimeAgo().toText(
color: MyColors.lightTextColor,
),
],
],
),
],
),
if (requestDetail.customerName.isNotEmpty) ...[
showItem("${LocaleKeys.customerName.tr()}: ", requestDetail.customerName),
],
showItem("${LocaleKeys.description.tr()}: ", requestDetail.description),
16.height,
if (AppState().currentAppType == AppType.provider &&
(requestDetailPageArguments.requestModel.requestStatus == RequestStatusEnum.inProgress || requestDetailPageArguments.requestModel.requestStatus == RequestStatusEnum.submitted)) ...[
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
("${LocaleKeys.reportComplaint.tr()}?").toText(fontSize: 14, color: MyColors.darkTextColor),
],
).onPress(
() {
int customerID = requestDetailPageArguments.requestModel.customerId;
int complainType = 2;
String customerName = requestDetailPageArguments.requestModel.customerName;
context.read<AppointmentsVM>().buildComplaintBottomSheet(
customerID: customerID,
customerName: customerName,
complainType: complainType,
context: context,
);
},
),
],
// showItem("${LocaleKeys.priceRange.tr()}:", ""),
// Row(
// children: [
// Expanded(
// child: Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// crossAxisAlignment: CrossAxisAlignment.end,
// children: [
// Row(
// crossAxisAlignment: CrossAxisAlignment.end,
// children: [
// "${requestDetail.price.toInt()}".toText(fontSize: 19, isBold: true, letterSpacing: -1.16),
// 2.width,
// LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, fontSize: 10, letterSpacing: -0.4),
// ],
// ),
// Row(
// children: [
// Utils.statusContainerChip(
// text: (requestDetail.requestStatusName),
// chipColor: MyColors.grey98Color.withOpacity(0.1),
// textColor: MyColors.lightTextColor,
// ),
// ],
// ),
// ],
// ),
// ),
// // const Icon(Icons.arrow_forward)
// ],
// ),
],
);
}
Widget showItem(String title, String value) { Widget showItem(String title, String value) {
return Row( return Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,

@ -90,7 +90,12 @@ class _ReviewRequestOfferState extends State<ReviewRequestOffer> {
Widget buildLocationInformation(BuildContext context) { Widget buildLocationInformation(BuildContext context) {
final requestVM = context.watch<RequestsVM>(); final requestVM = context.watch<RequestsVM>();
String address = "";
if (requestVM.acceptedRequestOffer != null && requestVM.acceptedRequestOffer!.requestDeliveryOption == RequestDeliveryOptionEnum.delivery) {
address = requestVM.currentSelectedRequest!.address;
} else {
address = requestVM.currentSelectedOffer!.providerAddress ?? "";
}
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -107,7 +112,11 @@ class _ReviewRequestOfferState extends State<ReviewRequestOffer> {
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
SingleDetailWidget(text: requestVM.currentSelectedRequest!.address ?? "", type: LocaleKeys.location.tr()), Row(
children: [
SingleDetailWidget(text: address, type: LocaleKeys.location.tr()),
],
),
// 16.height, // 16.height,
// SingleDetailWidget( // SingleDetailWidget(
// text: requestVM.additionalAddressSparePartRequestDelivery.isNotEmpty ? requestVM.additionalAddressSparePartRequestDelivery : "N/A", // text: requestVM.additionalAddressSparePartRequestDelivery.isNotEmpty ? requestVM.additionalAddressSparePartRequestDelivery : "N/A",
@ -161,8 +170,9 @@ class _ReviewRequestOfferState extends State<ReviewRequestOffer> {
// SingleDetailWidget(text: "${requestVM.acceptedRequestOffer!.price.toString()} ${LocaleKeys.sar.tr()}", type: LocaleKeys.offerPrice.tr()), // SingleDetailWidget(text: "${requestVM.acceptedRequestOffer!.price.toString()} ${LocaleKeys.sar.tr()}", type: LocaleKeys.offerPrice.tr()),
16.height, 16.height,
SingleDetailWidget(text: requestVM.acceptedRequestOfferProviderName ?? "", type: LocaleKeys.providerName.tr()), SingleDetailWidget(text: requestVM.acceptedRequestOfferProviderName ?? "", type: LocaleKeys.providerName.tr()),
16.height, 16.height,
SingleDetailWidget(text: requestVM.currentSelectedRequest!.description, type: LocaleKeys.description.tr()), SingleDetailWidget(text: LocaleKeys.online.tr(), type: LocaleKeys.paymentType.tr()),
], ],
), ),
), ),
@ -180,21 +190,18 @@ class _ReviewRequestOfferState extends State<ReviewRequestOffer> {
SingleDetailWidget(text: manufacturedOnFormattedDate, type: LocaleKeys.manufacturedOn.tr()), SingleDetailWidget(text: manufacturedOnFormattedDate, type: LocaleKeys.manufacturedOn.tr()),
], ],
16.height, 16.height,
// SingleDetailWidget(text: "${requestVM.currentSelectedRequest!.price.toString()} ${LocaleKeys.sar.tr()}", type: LocaleKeys.totalPrice.tr()),
SingleDetailWidget(text: "${requestVM.acceptedRequestOffer!.price.toString()} ${LocaleKeys.sar.tr()}", type: LocaleKeys.offerPrice.tr()), SingleDetailWidget(text: "${requestVM.acceptedRequestOffer!.price.toString()} ${LocaleKeys.sar.tr()}", type: LocaleKeys.offerPrice.tr()),
if (requestCreatedOn.isNotEmpty) ...[ if (requestCreatedOn.isNotEmpty) ...[
16.height, 16.height,
SingleDetailWidget(text: requestCreatedOn, type: LocaleKeys.requestCreatedOn.tr()), SingleDetailWidget(text: requestCreatedOn, type: LocaleKeys.requestCreatedOn.tr()),
], ],
16.height,
SingleDetailWidget(text: LocaleKeys.online.tr(), type: LocaleKeys.paymentType.tr()),
], ],
), ),
), ),
], ],
), ),
16.height,
SingleDetailWidget(text: requestVM.currentSelectedRequest!.description, type: LocaleKeys.description.tr()),
], ],
); );
} }

@ -108,7 +108,9 @@ class _SettingOptionsMoreState extends State<SettingOptionsMore> {
onTap: () { onTap: () {
navigateWithName(context, AppRoutes.shippingManagementView); navigateWithName(context, AppRoutes.shippingManagementView);
}, },
), ).toViewOnly(context, onTap: () {
navigateWithName(context, AppRoutes.loginWithPassword, arguments: false);
}),
], ],
CustomSettingOptionsTile( CustomSettingOptionsTile(
leadingWidget: const Icon(Icons.settings, size: 20), leadingWidget: const Icon(Icons.settings, size: 20),

@ -1,7 +1,9 @@
import 'dart:async'; import 'dart:async';
import 'dart:developer'; import 'dart:developer';
import 'package:flutter/material.dart'; 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/classes/consts.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart';
@ -39,7 +41,14 @@ class _ShippingManagementViewState extends State<ShippingManagementView> {
if (shippingViewModel.shippingRequestFilterOptions.isNotEmpty) { if (shippingViewModel.shippingRequestFilterOptions.isNotEmpty) {
await shippingViewModel.populateShippingRequestFilterList(); await shippingViewModel.populateShippingRequestFilterList();
} }
await shippingViewModel.getShippingRequestsListByFilters(); if (shippingViewModel.selfPickupRequestsFilterOptions.isNotEmpty) {
await shippingViewModel.populateSelfPickupRequestFilterList();
}
if (shippingViewModel.isSelfPickupTapped) {
await shippingViewModel.getSelfPickupRequestsListByFilters();
} else {
await shippingViewModel.getShippingRequestsListByFilters();
}
}); });
super.initState(); super.initState();
} }
@ -146,27 +155,78 @@ class _ShippingManagementViewState extends State<ShippingManagementView> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Consumer(builder: (BuildContext context, ShippingManagementVM shippingVm, Widget? child) { return Consumer(builder: (BuildContext context, ShippingManagementVM shippingVm, Widget? child) {
return Scaffold( return Scaffold(
appBar: CustomAppBar(title: LocaleKeys.shippingManagement.tr()), appBar: CustomAppBar(title: LocaleKeys.shippingManagement.tr()),
body: Container( body: Container(
color: MyColors.backgroundColor, color: MyColors.backgroundColor,
width: double.infinity, width: double.infinity,
height: double.infinity, height: double.infinity,
child: Column( child: Column(
children: [ children: [
16.height, 16.height,
Row(
children: [
Expanded(
child: ShowFillButton(
isFilled: !shippingVm.isSelfPickupTapped,
maxHeight: 55,
fontSize: 15,
title: LocaleKeys.delivery.tr(),
txtColor: !shippingVm.isSelfPickupTapped ? MyColors.white : MyColors.darkTextColor,
onPressed: () async {
shippingVm.updateIsSelfPickupTapped(false);
int index = shippingVm.shippingRequestFilterOptions.indexWhere((element) => element.isSelected);
int id = shippingVm.shippingRequestFilterOptions[index].id;
await shippingVm.getShippingRequestsListByFilters(shippingStatusEnum: id.toShippingStatusEnum());
},
),
),
12.width,
Expanded(
child: ShowFillButton(
isFilled: shippingVm.isSelfPickupTapped,
txtColor: shippingVm.isSelfPickupTapped ? MyColors.white : MyColors.darkTextColor,
maxHeight: 55,
fontSize: 15,
title: LocaleKeys.selfPickup.tr(),
onPressed: () async {
shippingVm.updateIsSelfPickupTapped(true);
int index = shippingVm.selfPickupRequestsFilterOptions.indexWhere((element) => element.isSelected);
int id = shippingVm.selfPickupRequestsFilterOptions[index].id;
await shippingVm.getSelfPickupRequestsListByFilters(selfPickupStatusEnum: id.toSelfPickupStatusEnum());
},
),
),
],
).horPaddingMain(),
16.height,
if (shippingVm.isSelfPickupTapped) ...[
FiltersList(
filterList: shippingVm.selfPickupRequestsFilterOptions,
onFilterTapped: (index, selectedFilterId) {
shippingVm.applyFiltersOnSelfPickupRequests(selfPickupRequestStatusEnum: selectedFilterId.toSelfPickupStatusEnum());
},
),
] else ...[
FiltersList( FiltersList(
filterList: shippingVm.shippingRequestFilterOptions, filterList: shippingVm.shippingRequestFilterOptions,
onFilterTapped: (index, selectedFilterId) { onFilterTapped: (index, selectedFilterId) {
shippingVm.applyFiltersOnShippingRequests(shippingRequestStatusEnum: selectedFilterId.toShippingStatusEnum()); shippingVm.applyFiltersOnShippingRequests(shippingRequestStatusEnum: selectedFilterId.toShippingStatusEnum());
}, },
), ),
8.height, ],
Expanded( 8.height,
child: RefreshIndicator( Expanded(
child: RefreshIndicator(
onRefresh: () async { onRefresh: () async {
int index = shippingVm.shippingRequestFilterOptions.indexWhere((element) => element.isSelected); if (shippingVm.isSelfPickupTapped) {
int id = shippingVm.shippingRequestFilterOptions[index].id; int index = shippingVm.selfPickupRequestsFilterOptions.indexWhere((element) => element.isSelected);
await shippingVm.getShippingRequestsListByFilters(shippingStatusEnum: id.toShippingStatusEnum()); int id = shippingVm.selfPickupRequestsFilterOptions[index].id;
await shippingVm.getSelfPickupRequestsListByFilters(selfPickupStatusEnum: id.toSelfPickupStatusEnum());
} else {
int index = shippingVm.shippingRequestFilterOptions.indexWhere((element) => element.isSelected);
int id = shippingVm.shippingRequestFilterOptions[index].id;
await shippingVm.getShippingRequestsListByFilters(shippingStatusEnum: id.toShippingStatusEnum());
}
}, },
child: (shippingVm.state == ViewState.busy) child: (shippingVm.state == ViewState.busy)
? const Center(child: CircularProgressIndicator()) ? const Center(child: CircularProgressIndicator())
@ -220,10 +280,12 @@ class _ShippingManagementViewState extends State<ShippingManagementView> {
}, },
separatorBuilder: (context, index) => 16.height, separatorBuilder: (context, index) => 16.height,
), ),
)), ),
], ),
), ],
)); ),
),
);
}); });
} }
} }

@ -36,6 +36,7 @@ class TxtField extends StatelessWidget {
Widget? preFixWidget; Widget? preFixWidget;
bool numbersOnly; bool numbersOnly;
bool allowOnlyOneDigit; bool allowOnlyOneDigit;
bool isNeedLabelOnTop;
TxtField({ TxtField({
super.key, super.key,
@ -66,6 +67,7 @@ class TxtField extends StatelessWidget {
this.onPostFixPressed, this.onPostFixPressed,
this.numbersOnly = false, this.numbersOnly = false,
this.allowOnlyOneDigit = false, this.allowOnlyOneDigit = false,
this.isNeedLabelOnTop = true,
}); });
TextEditingController controller = TextEditingController(); TextEditingController controller = TextEditingController();
@ -77,7 +79,7 @@ class TxtField extends StatelessWidget {
return Column( return Column(
children: [ children: [
if (hint != null) ...[ if (isNeedLabelOnTop && hint != null) ...[
Row( Row(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
@ -149,7 +151,7 @@ class TxtField extends StatelessWidget {
prefixIcon: prefixData != null ? Icon(prefixData, color: borderColor) : preFixWidget, prefixIcon: prefixData != null ? Icon(prefixData, color: borderColor) : preFixWidget,
labelStyle: const TextStyle(color: borderColor, fontSize: 13, fontWeight: MyFonts.Medium), labelStyle: const TextStyle(color: borderColor, fontSize: 13, fontWeight: MyFonts.Medium),
hintStyle: const TextStyle(color: borderColor, fontSize: 13, fontWeight: MyFonts.Medium), hintStyle: const TextStyle(color: borderColor, fontSize: 13, fontWeight: MyFonts.Medium),
// hintText: hint ?? "", hintText: isNeedLabelOnTop ? null : hint ?? "",
contentPadding: prefixData == null contentPadding: prefixData == null
? EdgeInsets.only( ? EdgeInsets.only(
left: 12, left: 12,

Loading…
Cancel
Save