Minor Fixes

aamir_dev
Faiz Hashmi 1 year ago
parent 0ada291516
commit 4b350dbeb6

@ -785,6 +785,10 @@
"tapToView": "انقر لعرض", "tapToView": "انقر لعرض",
"noServicesAvailableToCopy": "لا توجد خدمات متاحة في هذا الفرع لنسخها.", "noServicesAvailableToCopy": "لا توجد خدمات متاحة في هذا الفرع لنسخها.",
"copySelectedItems": "نسخ العناصر المحددة", "copySelectedItems": "نسخ العناصر المحددة",
"companyNameMandatory": "اسم الشركة إلزامي" "companyNameMandatory": "اسم الشركة إلزامي",
"noOfInvites": "عدد الدعوات",
"noSpecialServicesAvailable": "لا توجد خدمات خاصة متاحة للمنطقة المحددة.",
"customService": "الخدمة المخصصة",
"selectServiceDetails": "اختر تفاصيل الخدمة",
"addServiceDetails": "أضف تفاصيل الخدمة"
} }

@ -783,5 +783,10 @@
"tapToView": "Tap to view", "tapToView": "Tap to view",
"noServicesAvailableToCopy": "There are no services available in this branch to copy.", "noServicesAvailableToCopy": "There are no services available in this branch to copy.",
"copySelectedItems": "Copy Selected Items", "copySelectedItems": "Copy Selected Items",
"companyNameMandatory": "Company Name is mandatory" "companyNameMandatory": "Company Name is mandatory",
"noOfInvites": "No of invites",
"noSpecialServicesAvailable": "There are no special services available for the selected region.",
"customService": "Custom Service",
"selectServiceDetails": "Select service details",
"addServiceDetails": "Add service details"
} }

@ -41,6 +41,7 @@ class ApiConsts {
static String getUserImage = "${baseUrlServices}api/ProfileImage"; static String getUserImage = "${baseUrlServices}api/ProfileImage";
static String userUpdate = "${baseUrlServices}api/User_Update"; static String userUpdate = "${baseUrlServices}api/User_Update";
static String providerComplaintCreate = "${baseUrlServices}api/ServiceProviders/ProviderComplaint_Create"; static String providerComplaintCreate = "${baseUrlServices}api/ServiceProviders/ProviderComplaint_Create";
static String provideContactInfoGet = "${baseUrlServices}api/ServiceProviders/ServiceProviderContact_Get";
//Profile //Profile
static String fetProviderDocument = "${baseUrlServices}api/ServiceProviders/ServiceProviderDocument_Get"; static String fetProviderDocument = "${baseUrlServices}api/ServiceProviders/ServiceProviderDocument_Get";
@ -191,6 +192,7 @@ class ApiConsts {
static String getContactInfo = "${baseUrlServices}api/Master/ContactInfo_Get"; static String getContactInfo = "${baseUrlServices}api/Master/ContactInfo_Get";
static String getAppInfo = "${baseUrlServices}api/Master/AppInfo_Get"; static String getAppInfo = "${baseUrlServices}api/Master/AppInfo_Get";
static String getTermsAndConditions = "${baseUrlServices}api/Master/TermAndCondition_Get"; static String getTermsAndConditions = "${baseUrlServices}api/Master/TermAndCondition_Get";
static String getAppInvitationHistory = "${baseUrlServices}api/Common/AppInvitation_Get";
static List<String> closingUrls = ["PayFortResponse"]; static List<String> closingUrls = ["PayFortResponse"];
} }
@ -234,6 +236,9 @@ class GlobalConsts {
static String homeLocationEmptyError = "Home location cannot be empty"; static String homeLocationEmptyError = "Home location cannot be empty";
static String fillAllFields = "Please fill out all the fields."; static String fillAllFields = "Please fill out all the fields.";
static String requestTypeCannotBeEmpty = "Request type cannot be empty."; static String requestTypeCannotBeEmpty = "Request type cannot be empty.";
static String serviceNameError = "Service name cannot be empty.";
static String priceError = "Price cannot be empty.";
static String taxError = "Tax cannot be empty.";
static String reserveAdPriceInfo = static String reserveAdPriceInfo =
"Some dummy description to explain the following concept. This price will be for 24 hours and if a user cancels the reservations before 24 hours then the amount will be automatically refunded to the buyer."; "Some dummy description to explain the following concept. This price will be for 24 hours and if a user cancels the reservations before 24 hours then the amount will be automatically refunded to the buyer.";
static String appInvitationMessageEn = "🚗 Hey , check out MOWATER to book car services, buy/sell vehicles, and more—join here! [Invite Link]"; static String appInvitationMessageEn = "🚗 Hey , check out MOWATER to book car services, buy/sell vehicles, and more—join here! [Invite Link]";
@ -261,8 +266,8 @@ class GlobalConsts {
static int maxFileCount = 7; static int maxFileCount = 7;
static int maxFileSizeInBytes = 2 * 1024 * 1024; static int maxFileSizeInBytes = 2 * 1024 * 1024;
static String allowedFileExtensions = "jpg,png - 2MB"; static String allowedFileExtensions = "jpg,jpeg,png - 2MB/file";
static String allowedFileExtensionsPDF = "PDF 2MB"; static String allowedFileExtensionsPDF = "PDF 2MB/file";
static int providerDealerRoleTypeId = 6; static int providerDealerRoleTypeId = 6;
static int providerIndividualRoleTypeId = 5; static int providerIndividualRoleTypeId = 5;

@ -736,7 +736,7 @@ class CodegenLoader extends AssetLoader{
"ownerInformation": "معلومات المالك", "ownerInformation": "معلومات المالك",
"acceptedRequests": "الطلبات المقبولة", "acceptedRequests": "الطلبات المقبولة",
"specialRequestChat": "دردشة الطلب الخاص", "specialRequestChat": "دردشة الطلب الخاص",
"companyName": "اسم الشركة *", "companyName": "اسم الشركة",
"noAvailableItems": "لا توجد عناصر متاحة.", "noAvailableItems": "لا توجد عناصر متاحة.",
"serviceDeliveryType": "نوع تقديم الخدمة", "serviceDeliveryType": "نوع تقديم الخدمة",
"noImagesToShow": "لا توجد صور للعرض", "noImagesToShow": "لا توجد صور للعرض",
@ -801,7 +801,12 @@ class CodegenLoader extends AssetLoader{
"tapToView": "انقر لعرض", "tapToView": "انقر لعرض",
"noServicesAvailableToCopy": "لا توجد خدمات متاحة في هذا الفرع لنسخها.", "noServicesAvailableToCopy": "لا توجد خدمات متاحة في هذا الفرع لنسخها.",
"copySelectedItems": "نسخ العناصر المحددة", "copySelectedItems": "نسخ العناصر المحددة",
"companyNameMandatory": "اسم الشركة إلزامي" "companyNameMandatory": "اسم الشركة إلزامي",
"noOfInvites": "عدد الدعوات",
"noSpecialServicesAvailable": "لا توجد خدمات خاصة متاحة للمنطقة المحددة.",
"customService": "الخدمة المخصصة",
"selectServiceDetails": "اختر تفاصيل الخدمة",
"addServiceDetails": "أضف تفاصيل الخدمة"
}; };
static const Map<String,dynamic> en_US = { static const Map<String,dynamic> en_US = {
"firstTimeLogIn": "First Time Log In", "firstTimeLogIn": "First Time Log In",
@ -1519,7 +1524,7 @@ static const Map<String,dynamic> en_US = {
"noItemsToShow": "There are no Items no show.", "noItemsToShow": "There are no Items no show.",
"acceptedRequests": "Accepted Requests", "acceptedRequests": "Accepted Requests",
"specialRequestChat": "Special Request Chat", "specialRequestChat": "Special Request Chat",
"companyName": "Company Name *", "companyName": "Company Name",
"noAvailableItems": "There are no available items.", "noAvailableItems": "There are no available items.",
"serviceDeliveryType": "Service Delivery Type", "serviceDeliveryType": "Service Delivery Type",
"noImagesToShow": "No Images to Show", "noImagesToShow": "No Images to Show",
@ -1588,7 +1593,12 @@ static const Map<String,dynamic> en_US = {
"tapToView": "Tap to view", "tapToView": "Tap to view",
"noServicesAvailableToCopy": "There are no services available in this branch to copy.", "noServicesAvailableToCopy": "There are no services available in this branch to copy.",
"copySelectedItems": "Copy Selected Items", "copySelectedItems": "Copy Selected Items",
"companyNameMandatory": "Company Name is mandatory" "companyNameMandatory": "Company Name is mandatory",
"noOfInvites": "No of invites",
"noSpecialServicesAvailable": "There are no special services available for the selected region.",
"customService": "Custom Service",
"selectServiceDetails": "Select service details",
"addServiceDetails": "Add service details"
}; };
static const Map<String, Map<String,dynamic>> mapLocales = {"ar_SA": ar_SA, "en_US": en_US}; static const Map<String, Map<String,dynamic>> mapLocales = {"ar_SA": ar_SA, "en_US": en_US};
} }

@ -1,6 +1,6 @@
// DO NOT EDIT. This is code generated via package:easy_localization/generate.dart // DO NOT EDIT. This is code generated via package:easy_localization/generate.dart
abstract class LocaleKeys { abstract class LocaleKeys {
static const firstTimeLogIn = 'firstTimeLogIn'; static const firstTimeLogIn = 'firstTimeLogIn';
static const signUp = 'signUp'; static const signUp = 'signUp';
static const changeMobile = 'changeMobile'; static const changeMobile = 'changeMobile';
@ -47,7 +47,7 @@ abstract class LocaleKeys {
static const emailChangedSuccessfully = 'emailChangedSuccessfully'; static const emailChangedSuccessfully = 'emailChangedSuccessfully';
static const passwordIsUpdated = 'passwordIsUpdated'; static const passwordIsUpdated = 'passwordIsUpdated';
static const passwordShouldContains = 'passwordShouldContains'; static const passwordShouldContains = 'passwordShouldContains';
static const successfullyRegistered = ' successfullyRegistered'; static const successfullyRegistered = ' successfullyRegistered';
static const pleaseEnterSamePassword = 'pleaseEnterSamePassword'; static const pleaseEnterSamePassword = 'pleaseEnterSamePassword';
static const firstNameMandatory = 'firstNameMandatory'; static const firstNameMandatory = 'firstNameMandatory';
static const surnameNameMandatory = 'surnameNameMandatory'; static const surnameNameMandatory = 'surnameNameMandatory';
@ -765,5 +765,10 @@ abstract class LocaleKeys {
static const noServicesAvailableToCopy = 'noServicesAvailableToCopy'; static const noServicesAvailableToCopy = 'noServicesAvailableToCopy';
static const copySelectedItems = 'copySelectedItems'; static const copySelectedItems = 'copySelectedItems';
static const companyNameMandatory = 'companyNameMandatory'; static const companyNameMandatory = 'companyNameMandatory';
static const noOfInvites = 'noOfInvites';
static const noSpecialServicesAvailable = 'noSpecialServicesAvailable';
static const customService = 'customService';
static const selectServiceDetails = 'selectServiceDetails';
static const addServiceDetails = 'addServiceDetails';
} }

@ -0,0 +1,47 @@
class ProviderContactInfoModel {
int? id;
int? providerID;
String? name;
int? allDocStatus;
String? companyName;
String? companyDescription;
int? countryID;
String? countryName;
String? userID;
String? memberSince;
String? mobile;
String? whatsApp;
String? email;
ProviderContactInfoModel({
this.id,
this.providerID,
this.name,
this.allDocStatus,
this.companyName,
this.companyDescription,
this.countryID,
this.countryName,
this.userID,
this.memberSince,
this.mobile,
this.whatsApp,
this.email,
});
ProviderContactInfoModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
providerID = json['providerID'];
name = json['name'];
allDocStatus = json['allDocStatus'];
companyName = json['companyName'];
companyDescription = json['companyDescription'];
countryID = json['countryID'];
countryName = json['countryName'];
userID = json['userID'];
memberSince = json['memberSince'];
mobile = json['mobile'];
whatsApp = json['whatsApp'];
email = json['email'];
}
}

@ -4,6 +4,7 @@ class ProviderProfileModel {
ProviderProfileModel({ ProviderProfileModel({
this.id, this.id,
this.companyName, this.companyName,
this.profileImage,
this.name, this.name,
this.countryName, this.countryName,
this.companyDescription, this.companyDescription,
@ -20,6 +21,7 @@ class ProviderProfileModel {
}); });
final int? id; final int? id;
final String? profileImage;
final String? companyName; final String? companyName;
final String? companyDescription; final String? companyDescription;
int? countryID; int? countryID;
@ -38,6 +40,7 @@ class ProviderProfileModel {
factory ProviderProfileModel.fromJson(Map<String, dynamic> json) => ProviderProfileModel( factory ProviderProfileModel.fromJson(Map<String, dynamic> json) => ProviderProfileModel(
id: json["id"], id: json["id"],
companyName: json["companyName"], companyName: json["companyName"],
profileImage: json["profileImage"] ?? "",
name: json["name"], name: json["name"],
countryName: json["countryName"], countryName: json["countryName"],
countryID: json["countryID"], countryID: json["countryID"],

@ -0,0 +1,26 @@
class AppInvitationHistoryModel {
int? id;
int? customerID;
int? channelID;
int? appInvitationEnumID;
int? noOfInvites;
String? comments;
AppInvitationHistoryModel({
this.id,
this.customerID,
this.channelID,
this.appInvitationEnumID,
this.noOfInvites,
this.comments,
});
AppInvitationHistoryModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
customerID = json['customerID'];
channelID = json['channelID'];
appInvitationEnumID = json['appInvitationEnumID'];
noOfInvites = json['noofInvites'];
comments = json['comments'];
}
}

@ -22,17 +22,17 @@ class Role {
String? message; String? message;
factory Role.fromJson(Map<String, dynamic> json) => Role( factory Role.fromJson(Map<String, dynamic> json) => Role(
totalItemsCount: json["totalItemsCount"] == null ? null : json["totalItemsCount"], totalItemsCount: json["totalItemsCount"],
data: json["data"] == null ? null : List<RoleData>.from(json["data"].map((x) => RoleData.fromJson(x))), data: json["data"] == null ? null : List<RoleData>.from(json["data"].map((x) => RoleData.fromJson(x))),
messageStatus: json["messageStatus"] == null ? null : json["messageStatus"], messageStatus: json["messageStatus"],
message: json["message"] == null ? null : json["message"], message: json["message"],
); );
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
"totalItemsCount": totalItemsCount == null ? null : totalItemsCount, "totalItemsCount": totalItemsCount,
"data": data == null ? null : List<dynamic>.from(data!.map((x) => x.toJson())), "data": data == null ? null : List<dynamic>.from(data!.map((x) => x.toJson())),
"messageStatus": messageStatus == null ? null : messageStatus, "messageStatus": messageStatus,
"message": message == null ? null : message, "message": message,
}; };
} }
@ -50,16 +50,16 @@ class RoleData {
bool? isActive; bool? isActive;
factory RoleData.fromJson(Map<String, dynamic> json) => RoleData( factory RoleData.fromJson(Map<String, dynamic> json) => RoleData(
id: json["id"] == null ? null : json["id"], id: json["id"],
roleName: json["roleName"] == null ? null : json["roleName"], roleName: json["roleName"],
roleNameN: json["roleNameN"] == null ? null : json["roleNameN"], roleNameN: json["roleNameN"],
isActive: json["isActive"] == null ? null : json["isActive"], isActive: json["isActive"],
); );
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
"id": id == null ? null : id, "id": id,
"roleName": roleName == null ? null : roleName, "roleName": roleName,
"roleNameN": roleNameN == null ? null : roleNameN, "roleNameN": roleNameN,
"isActive": isActive == null ? null : isActive, "isActive": isActive,
}; };
} }

@ -137,6 +137,9 @@ class AdsRepoImp implements AdsRepo {
}); });
List vehiclePostingDamageParts = []; List vehiclePostingDamageParts = [];
int sellerTypeID = AppState().getUser.data!.userInfo!.roleId ?? 0;
adsCreationPayloadModel.vehiclePosting!.vehiclePostingDamageParts?.forEach((element) { adsCreationPayloadModel.vehiclePosting!.vehiclePostingDamageParts?.forEach((element) {
log("comment: ${element.comment}"); log("comment: ${element.comment}");
var imageMap = { var imageMap = {
@ -169,7 +172,7 @@ class AdsRepoImp implements AdsRepo {
"vehicleConditionID": adsCreationPayloadModel.vehiclePosting!.vehicleConditionID, "vehicleConditionID": adsCreationPayloadModel.vehiclePosting!.vehicleConditionID,
"vehicleMileageID": adsCreationPayloadModel.vehiclePosting!.vehicleMileageID, "vehicleMileageID": adsCreationPayloadModel.vehiclePosting!.vehicleMileageID,
"vehicleTransmissionID": adsCreationPayloadModel.vehiclePosting!.vehicleTransmissionID, "vehicleTransmissionID": adsCreationPayloadModel.vehiclePosting!.vehicleTransmissionID,
"vehicleSellerTypeID": adsCreationPayloadModel.vehiclePosting!.vehicleSellerTypeID, "vehicleSellerTypeID": sellerTypeID,
"cityID": adsCreationPayloadModel.vehiclePosting!.cityID, "cityID": adsCreationPayloadModel.vehiclePosting!.cityID,
"price": adsCreationPayloadModel.vehiclePosting!.price, "price": adsCreationPayloadModel.vehiclePosting!.price,
"vehicleVIN": adsCreationPayloadModel.vehiclePosting!.vehicleVIN, "vehicleVIN": adsCreationPayloadModel.vehiclePosting!.vehicleVIN,
@ -534,7 +537,7 @@ class AdsRepoImp implements AdsRepo {
String token = appState.getUser.data!.accessToken ?? ""; String token = appState.getUser.data!.accessToken ?? "";
GenericRespModel adsGenericModel = await apiClient.postJsonForObject( GenericRespModel adsGenericModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json), (json) => GenericRespModel.fromJson(json),
ApiConsts.adsPhotoOfficeAppointmentCreate, "",
postParams, postParams,
token: token, token: token,
); );

@ -21,6 +21,7 @@ abstract class AppointmentRepo {
List<String>? customerNamesList, List<String>? customerNamesList,
List<String>? customerPhonesList, List<String>? customerPhonesList,
List<String>? deliveryTypeIdsList, List<String>? deliveryTypeIdsList,
AppointmentStatusEnum? appointmentStatusEnum,
String? fromDate, String? fromDate,
String? toDate, String? toDate,
}); });
@ -31,6 +32,7 @@ abstract class AppointmentRepo {
List<String>? serviceIdsList, List<String>? serviceIdsList,
List<String>? itemIdsList, List<String>? itemIdsList,
List<String>? branchIdsList, List<String>? branchIdsList,
AppointmentStatusEnum? appointmentStatusEnum,
}); });
Future<GenericRespModel> updateAppointmentStatus({required int appointmentId, required AppointmentStatusEnum appointmentStatusEnum}); Future<GenericRespModel> updateAppointmentStatus({required int appointmentId, required AppointmentStatusEnum appointmentStatusEnum});
@ -170,7 +172,6 @@ class AppointmentRepoImp implements AppointmentRepo {
index = 0; index = 0;
} }
slotId = schedule.selectedCustomTimeDateSlotModel!.availableSlots![index].slotId; slotId = schedule.selectedCustomTimeDateSlotModel!.availableSlots![index].slotId;
mapList.add({ mapList.add({
@ -237,6 +238,7 @@ class AppointmentRepoImp implements AppointmentRepo {
List<String>? customerNamesList, List<String>? customerNamesList,
List<String>? customerPhonesList, List<String>? customerPhonesList,
List<String>? deliveryTypeIdsList, List<String>? deliveryTypeIdsList,
AppointmentStatusEnum? appointmentStatusEnum,
String? fromDate, String? fromDate,
String? toDate, String? toDate,
}) async { }) async {
@ -254,6 +256,9 @@ class AppointmentRepoImp implements AppointmentRepo {
"DateTo": toDate ?? "", "DateTo": toDate ?? "",
}; };
if (appointmentStatusEnum != null) {
params.addAll({"AppointmentStatusID": appointmentStatusEnum.getIdFromAppointmentStatusEnum().toString()});
}
GenericRespModel genericRespModel = await apiClient.getJsonForObject( GenericRespModel genericRespModel = await apiClient.getJsonForObject(
token: t, token: t,
(json) => GenericRespModel.fromJson(json), (json) => GenericRespModel.fromJson(json),
@ -271,6 +276,7 @@ class AppointmentRepoImp implements AppointmentRepo {
List<String>? serviceIdsList, List<String>? serviceIdsList,
List<String>? itemIdsList, List<String>? itemIdsList,
List<String>? branchIdsList, List<String>? branchIdsList,
AppointmentStatusEnum? appointmentStatusEnum,
}) async { }) async {
var params = { var params = {
"customerID": appState.getUser.data!.userInfo!.customerId.toString(), "customerID": appState.getUser.data!.userInfo!.customerId.toString(),
@ -280,6 +286,10 @@ class AppointmentRepoImp implements AppointmentRepo {
"ServiceItemIDs": itemIdsList ?? [], "ServiceItemIDs": itemIdsList ?? [],
"CategoryIDs": categoryIdsList ?? [], "CategoryIDs": categoryIdsList ?? [],
}; };
if (appointmentStatusEnum != null) {
params.addAll({"AppointmentStatusID": appointmentStatusEnum.getIdFromAppointmentStatusEnum().toString()});
}
GenericRespModel genericRespModel = await apiClient.getJsonForObject( GenericRespModel genericRespModel = await apiClient.getJsonForObject(
token: appState.getUser.data!.accessToken, token: appState.getUser.data!.accessToken,
(json) => GenericRespModel.fromJson(json), (json) => GenericRespModel.fromJson(json),

@ -77,7 +77,7 @@ abstract class BranchRepo {
Future<GenericRespModel> updateCategoryStatus({required int branchId, required int categoryId, required ServiceStatusEnum serviceStatusEnum}); Future<GenericRespModel> updateCategoryStatus({required int branchId, required int categoryId, required ServiceStatusEnum serviceStatusEnum});
Future<List<AppointmentBasicDetailsModel>> getAppointmentsByCategoryOrService({required int branchId, required int serviceId}); Future<List<AppointmentBasicDetailsModel>> getAppointmentsByCategoryOrService({required int branchId, required int categoryId, required int serviceId});
Future<GenericRespModel> getMatchedServices(int oldBranchId, int newBranchId, int categoryId); Future<GenericRespModel> getMatchedServices(int oldBranchId, int newBranchId, int categoryId);
@ -217,7 +217,7 @@ class BranchRepoImp implements BranchRepo {
"documentExt": documents[i].fileExt, "documentExt": documents[i].fileExt,
"documentImage": documents[i].document, "documentImage": documents[i].document,
"isActive": true, "isActive": true,
"dateExpire":documents[i].dateExpire, "dateExpire": documents[i].dateExpire,
}; };
map.add(postParams); map.add(postParams);
} }
@ -348,12 +348,22 @@ class BranchRepoImp implements BranchRepo {
} }
@override @override
Future<List<AppointmentBasicDetailsModel>> getAppointmentsByCategoryOrService({required int branchId, required int serviceId}) async { Future<List<AppointmentBasicDetailsModel>> getAppointmentsByCategoryOrService({required int branchId, required int categoryId, required int serviceId}) async {
var map = { var map = {
"ProviderBranchID": branchId.toString(), "ProviderBranchID": branchId.toString(),
"ServiceProviderServiceID": serviceId.toString(),
}; };
if (serviceId != -1) {
map.addAll({
"ServiceProviderServiceID": serviceId.toString(),
});
}
if (categoryId != -1) {
map.addAll({
"ServiceProviderServiceID": serviceId.toString(),
});
}
String t = AppState().getUser.data!.accessToken ?? ""; String t = AppState().getUser.data!.accessToken ?? "";
GenericRespModel genericRespModel = await apiClient.getJsonForObject( GenericRespModel genericRespModel = await apiClient.getJsonForObject(
(json) => GenericRespModel.fromJson(json), (json) => GenericRespModel.fromJson(json),

@ -8,6 +8,7 @@ import 'package:mc_common_app/models/advertisment_models/vehicle_details_models.
import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart'; import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart';
import 'package:mc_common_app/models/general_models/enums_model.dart'; import 'package:mc_common_app/models/general_models/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/provider_branches_models/provider_contact_info_model.dart';
import 'package:mc_common_app/models/user_models/cities.dart'; import 'package:mc_common_app/models/user_models/cities.dart';
import 'package:mc_common_app/models/user_models/country.dart'; import 'package:mc_common_app/models/user_models/country.dart';
import 'package:mc_common_app/models/user_models/role.dart'; import 'package:mc_common_app/models/user_models/role.dart';
@ -56,6 +57,8 @@ abstract class CommonRepo {
Future<List<EnumsModel>> getEnumTypeValues({int? enumTypeID, String? enumTypeName}); Future<List<EnumsModel>> getEnumTypeValues({int? enumTypeID, String? enumTypeName});
Future<GenericRespModel> createComplainFromProvider({required int customerId, required String comment, required int complainType}); Future<GenericRespModel> createComplainFromProvider({required int customerId, required String comment, required int complainType});
Future<ProviderContactInfoModel> getProvidersContactInfo({required int providerId});
} }
class CommonRepoImp implements CommonRepo { class CommonRepoImp implements CommonRepo {
@ -363,4 +366,19 @@ class CommonRepoImp implements CommonRepo {
); );
return adsGenericModel; return adsGenericModel;
} }
@override
Future<ProviderContactInfoModel> getProvidersContactInfo({required int providerId}) async {
final parameters = {
"ProviderID": providerId.toString(),
};
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
token: appState.getUser.data!.accessToken,
(json) => GenericRespModel.fromJson(json),
ApiConsts.provideContactInfoGet,
queryParameters: parameters,
);
ProviderContactInfoModel contactInfoModel = ProviderContactInfoModel.fromJson(adsGenericModel.data);
return contactInfoModel;
}
} }

@ -6,6 +6,7 @@ import 'package:mc_common_app/config/dependency_injection.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/general_models/generic_resp_model.dart'; import 'package:mc_common_app/models/general_models/generic_resp_model.dart';
import 'package:mc_common_app/models/setting_utils_models/app_info_model.dart'; import 'package:mc_common_app/models/setting_utils_models/app_info_model.dart';
import 'package:mc_common_app/models/setting_utils_models/app_invitation_history_model.dart';
import 'package:mc_common_app/models/setting_utils_models/contact_infos_model.dart'; import 'package:mc_common_app/models/setting_utils_models/contact_infos_model.dart';
import 'package:mc_common_app/models/setting_utils_models/faqs_model.dart'; import 'package:mc_common_app/models/setting_utils_models/faqs_model.dart';
import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/enums.dart';
@ -21,6 +22,8 @@ abstract class SettingOptionsRepo {
Future<List<AppInfoModel>> getTermsAndConditions(); Future<List<AppInfoModel>> getTermsAndConditions();
Future<GenericRespModel> appInvitationCreate({required int channelId, required String message}); Future<GenericRespModel> appInvitationCreate({required int channelId, required String message});
Future<List<AppInvitationHistoryModel>> getAppInvitationsHistory();
} }
class SettingOptionsRepoImp extends SettingOptionsRepo { class SettingOptionsRepoImp extends SettingOptionsRepo {
@ -158,17 +161,19 @@ class SettingOptionsRepoImp extends SettingOptionsRepo {
String token = appState.getUser.data!.accessToken ?? ""; String token = appState.getUser.data!.accessToken ?? "";
final params = { final params = {
"channelID": channelId.toString(), "appInvitationEnumID": channelId.toString(),
"comments": message, "comments": message,
}; };
if (AppState().currentAppType == AppType.customer) { if (AppState().currentAppType == AppType.customer) {
params.addAll({ params.addAll({
"customerID": (appState.getUser.data!.userInfo!.customerId ?? "0").toString(), "customerID": (appState.getUser.data!.userInfo!.customerId ?? "0").toString(),
"channelID": "3",
}); });
} else { } else {
params.addAll({ params.addAll({
"providerID": (appState.getUser.data!.userInfo!.providerId ?? "0").toString(), "providerID": (appState.getUser.data!.userInfo!.providerId ?? "0").toString(),
"channelID": "2",
}); });
} }
@ -180,4 +185,30 @@ class SettingOptionsRepoImp extends SettingOptionsRepo {
); );
return genericRespModel; return genericRespModel;
} }
@override
Future<List<AppInvitationHistoryModel>> getAppInvitationsHistory() async {
final params = {
"CustomerID": (appState.getUser.data!.userInfo!.customerId ?? "0").toString(),
"ChannelID": "3",
};
String token = appState.getUser.data!.accessToken ?? "";
GenericRespModel genericRespModel = await injector.get<ApiClient>().getJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.getAppInvitationHistory,
queryParameters: params,
token: token,
);
if (genericRespModel.messageStatus != 1 || genericRespModel.data == null) {
Utils.showToast(genericRespModel.message ?? LocaleKeys.somethingWrong.tr());
return [];
}
List<AppInvitationHistoryModel> list = List.generate(genericRespModel.data.length, (index) => AppInvitationHistoryModel.fromJson(genericRespModel.data[index]));
return list;
}
} }

@ -379,7 +379,14 @@ class AdVM extends BaseVM {
} }
Future<void> getVehicleAdsSpecialServices({required int cityId, required int countryId, required int specialServiceType}) async { Future<void> getVehicleAdsSpecialServices({required int cityId, required int countryId, required int specialServiceType}) async {
log("cityId: $cityId");
vehicleAdsSpecialServices = await adsRepo.getSpecialServices(specialServiceType: specialServiceType, countryId: countryId, cityId: cityId); vehicleAdsSpecialServices = await adsRepo.getSpecialServices(specialServiceType: specialServiceType, countryId: countryId, cityId: cityId);
vehicleAdsSpecialServices = vehicleAdsSpecialServices.where((ad) {
bool matchesCityInDetails = ad.details?.any((detail) => detail.fromcity == cityId || detail.tocity == cityId) ?? false;
bool matchesCityInOffice = ad.office?.any((office) => office.cityID == cityId) ?? false;
return matchesCityInDetails || matchesCityInOffice;
}).toList();
notifyListeners(); notifyListeners();
} }
@ -1472,12 +1479,11 @@ class AdVM extends BaseVM {
List<SSPhotoOfficeScheduleModel> photoSSSchedulesByOffices = []; List<SSPhotoOfficeScheduleModel> photoSSSchedulesByOffices = [];
SSPhotoOfficeScheduleModel selectedPhotoSSSchedulesByOffice = SSPhotoOfficeScheduleModel(); SSPhotoOfficeScheduleModel selectedPhotoSSSchedulesByOffice = SSPhotoOfficeScheduleModel();
Future<void> getPhotographyServiceScheduleListByOffices({required double latitude, required double longitude, bool isNeedToRebuild = false}) async { Future<void> getPhotographyServiceScheduleListByOffices({required int cityId, required double latitude, required double longitude, bool isNeedToRebuild = false}) async {
if (isNeedToRebuild) setState(ViewState.busy); if (isNeedToRebuild) setState(ViewState.busy);
int cityID = AppState().getUser.data!.userInfo!.cityId ?? 1;
try { try {
photoSSSchedulesByOffices = await commonRepo.getPhotographyServiceScheduleListByOffices(lat: latitude, long: longitude, cityID: cityID); photoSSSchedulesByOffices = await commonRepo.getPhotographyServiceScheduleListByOffices(lat: latitude, long: longitude, cityID: cityId);
if (isNeedToRebuild) setState(ViewState.idle); if (isNeedToRebuild) setState(ViewState.idle);
} catch (e) { } catch (e) {
if (isNeedToRebuild) setState(ViewState.idle); if (isNeedToRebuild) setState(ViewState.idle);
@ -2118,7 +2124,8 @@ class AdVM extends BaseVM {
} }
} }
selectionDurationStartDate = DateHelper.formatDateT(previousAdDetails!.startdate ?? ""); // selectionDurationStartDate = DateHelper.formatDateT(previousAdDetails!.startdate ?? "");
selectionDurationStartDate = "";
isPhoneNumberShown = previousAdDetails!.phoneNo != null; isPhoneNumberShown = previousAdDetails!.phoneNo != null;
if (isPhoneNumberShown) { if (isPhoneNumberShown) {
adPhoneNumber = previousAdDetails!.phoneNo ?? ""; adPhoneNumber = previousAdDetails!.phoneNo ?? "";

@ -20,6 +20,7 @@ import 'package:mc_common_app/models/provider_branches_models/branch_detail_mode
import 'package:mc_common_app/models/provider_branches_models/branch_review_model.dart'; import 'package:mc_common_app/models/provider_branches_models/branch_review_model.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/categroy.dart'; import 'package:mc_common_app/models/provider_branches_models/profile/categroy.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/services.dart'; import 'package:mc_common_app/models/provider_branches_models/profile/services.dart';
import 'package:mc_common_app/models/provider_branches_models/provider_contact_info_model.dart';
import 'package:mc_common_app/models/provider_branches_models/provider_model.dart'; import 'package:mc_common_app/models/provider_branches_models/provider_model.dart';
import 'package:mc_common_app/models/provider_branches_models/provider_profile_model.dart'; import 'package:mc_common_app/models/provider_branches_models/provider_profile_model.dart';
import 'package:mc_common_app/models/services_models/item_model.dart'; import 'package:mc_common_app/models/services_models/item_model.dart';
@ -62,9 +63,9 @@ class AppointmentsVM extends BaseVM {
List<AppointmentListModel> myAppointments = []; List<AppointmentListModel> myAppointments = [];
List<AppointmentListModel> myUpComingAppointments = []; List<AppointmentListModel> myUpComingAppointments = [];
List<AppointmentListModel> myFilteredAppointments = []; List<AppointmentListModel> myFilteredAppointmentsForCustomers = [];
List<FilterListModel> appointmentsFilterOptions = []; List<FilterListModel> appointmentsFilterOptions = [];
List<AppointmentListModel> myFilteredAppointments2 = []; List<AppointmentListModel> myFilteredAppointmentsForProvider = [];
bool isFetchingServices = false; bool isFetchingServices = false;
@ -140,7 +141,7 @@ class AppointmentsVM extends BaseVM {
} }
context.read<DashboardVmCustomer>().onNavbarTapped(1); context.read<DashboardVmCustomer>().onNavbarTapped(1);
applyFilterOnAppointmentsVM(appointmentStatusEnum: AppointmentStatusEnum.booked); applyFilterOnAppointmentsVMForCustomers(appointmentStatusEnum: AppointmentStatusEnum.booked);
Utils.hideLoading(context); Utils.hideLoading(context);
resetAfterBookingAppointment(); resetAfterBookingAppointment();
if (isSuccess) { if (isSuccess) {
@ -149,7 +150,6 @@ class AppointmentsVM extends BaseVM {
navigateWithName(context, AppRoutes.paymentMethodsView, arguments: PaymentTypes.appointment); navigateWithName(context, AppRoutes.paymentMethodsView, arguments: PaymentTypes.appointment);
} else { } else {
Utils.showToast(LocaleKeys.appointmentBookedSuccessfully.tr()); Utils.showToast(LocaleKeys.appointmentBookedSuccessfully.tr());
getMyAppointmentsForCustomer();
navigateReplaceWithNameUntilRoute(context, AppRoutes.dashboard); navigateReplaceWithNameUntilRoute(context, AppRoutes.dashboard);
} }
} }
@ -227,9 +227,8 @@ class AppointmentsVM extends BaseVM {
} }
if (genericRespModel.messageStatus == 1 && AppState().currentAppType == AppType.customer) { if (genericRespModel.messageStatus == 1 && AppState().currentAppType == AppType.customer) {
context.read<DashboardVmCustomer>().onNavbarTapped(1); context.read<DashboardVmCustomer>().onNavbarTapped(1);
applyFilterOnAppointmentsVM(appointmentStatusEnum: AppointmentStatusEnum.cancelled); applyFilterOnAppointmentsVMForCustomers(appointmentStatusEnum: AppointmentStatusEnum.cancelled);
Utils.showToast(genericRespModel.message.toString()); Utils.showToast(genericRespModel.message.toString());
await getMyAppointmentsForCustomer();
Utils.hideLoading(context); Utils.hideLoading(context);
navigateReplaceWithNameUntilRoute(context, AppRoutes.dashboard); navigateReplaceWithNameUntilRoute(context, AppRoutes.dashboard);
} }
@ -353,46 +352,69 @@ class AppointmentsVM extends BaseVM {
notifyListeners(); notifyListeners();
} }
applyFilterOnAppointmentsVM({required AppointmentStatusEnum appointmentStatusEnum, bool isNeedCustomerFilter = false}) { bool isAppointmentLoading = false;
log("appointmentStatusEnum: $appointmentStatusEnum");
// isNeedCustomerFilter IS ONLY FOR THE PROVIDER APP applyFilterOnAppointmentsVMForProviders({int? branchID, required AppointmentStatusEnum appointmentStatusEnum, bool isNeedCustomerFilter = false, bool shouldPopulateUpcoming = false}) async {
if (appointmentsFilterOptions.isEmpty) return; if (appointmentsFilterOptions.isEmpty) return;
for (var value in appointmentsFilterOptions) { for (var value in appointmentsFilterOptions) {
value.isSelected = false; value.isSelected = false;
} }
int index = appointmentsFilterOptions.indexWhere((element) => element.id == appointmentStatusEnum.getIdFromAppointmentStatusEnum());
appointmentsFilterOptions[index].isSelected = true;
for (var element in appointmentsFilterOptions) { isAppointmentLoading = true;
if (element.id == appointmentStatusEnum.getIdFromAppointmentStatusEnum()) { notifyListeners();
element.isSelected = true; myFilteredAppointmentsForProvider = await getAppointmentsBasedOnFiltersForProviders(branchID: branchID ?? selectedBranchIdForAppointments, appointmentStatus: appointmentStatusEnum);
} isAppointmentLoading = false;
if (shouldPopulateUpcoming) {
myUpComingAppointments = myFilteredAppointmentsForProvider
.where((element) =>
(element.appointmentStatusEnum == AppointmentStatusEnum.booked || element.appointmentStatusEnum == AppointmentStatusEnum.confirmed) &&
(DateHelper.parseStringToDate(element.appointmentDate!).isAfter(DateTime.now())))
.toList();
} }
// appointmentsFilterOptions[
// appointmentStatusEnum.getIdFromAppointmentStatusEnum()]
// .isSelected = true;
if (appointmentStatusEnum == AppointmentStatusEnum.allAppointments) { log("myUpComingAppointments: ${myUpComingAppointments.length}");
myFilteredAppointments = myAppointments;
if (isNeedCustomerFilter) findAppointmentsBasedOnCustomers(myFilteredAppointments); if (isNeedCustomerFilter) {
notifyListeners(); myFilteredAppointmentsForProvider = findAppointmentsBasedOnCustomers(myFilteredAppointmentsForProvider);
return; }
notifyListeners();
}
applyFilterOnAppointmentsVMForCustomers({required AppointmentStatusEnum appointmentStatusEnum, bool shouldPopulateUpcoming = false}) async {
log("appointmentsFilterOptions: ${appointmentsFilterOptions.isEmpty}");
if (appointmentsFilterOptions.isEmpty) return;
for (var value in appointmentsFilterOptions) {
value.isSelected = false;
}
int index = appointmentsFilterOptions.indexWhere((element) => element.id == appointmentStatusEnum.getIdFromAppointmentStatusEnum());
appointmentsFilterOptions[index].isSelected = true;
isAppointmentLoading = true;
notifyListeners();
myFilteredAppointmentsForCustomers = await getAppointmentsBasedOnFiltersForCustomer();
isAppointmentLoading = false;
if (shouldPopulateUpcoming) {
myUpComingAppointments = myFilteredAppointmentsForCustomers
.where((element) =>
(element.appointmentStatusEnum == AppointmentStatusEnum.booked || element.appointmentStatusEnum == AppointmentStatusEnum.confirmed) &&
(DateHelper.parseStringToDate(element.appointmentDate!).isAfter(DateTime.now())))
.toList();
} }
myFilteredAppointments = myAppointments.where((element) => element.appointmentStatusID! == appointmentStatusEnum.getIdFromAppointmentStatusEnum()).toList();
if (isNeedCustomerFilter) findAppointmentsBasedOnCustomers(myFilteredAppointments);
notifyListeners(); notifyListeners();
} }
findAppointmentsBasedOnCustomers(List<AppointmentListModel> appointments) { List<AppointmentListModel> findAppointmentsBasedOnCustomers(List<AppointmentListModel> appointments) {
// Use a Set to ensure uniqueness of customerIDs
Set<int> uniqueCustomerIDs = <int>{}; Set<int> uniqueCustomerIDs = <int>{};
// Extract unique customerIDs
for (var item in appointments) { for (var item in appointments) {
uniqueCustomerIDs.add(item.customerID ?? 0); uniqueCustomerIDs.add(item.customerID ?? 0);
} }
// Create a list of CustomerData instances List<AppointmentListModel> groupedList = uniqueCustomerIDs.map((id) {
myFilteredAppointments2 = uniqueCustomerIDs.map((id) {
List<AppointmentListModel> list = appointments.where((item) => item.customerID == id).toList(); List<AppointmentListModel> list = appointments.where((item) => item.customerID == id).toList();
list.sort((a, b) => DateHelper.parseStringToDate(DateHelper.formatDateT(b.appointmentDate!)) list.sort((a, b) => DateHelper.parseStringToDate(DateHelper.formatDateT(b.appointmentDate!))
.millisecondsSinceEpoch .millisecondsSinceEpoch
@ -402,61 +424,16 @@ class AppointmentsVM extends BaseVM {
return model; return model;
}).toList(); }).toList();
// customersAppointments = uniqueCustomerIDs.map((id) { return groupedList;
// List<AppointmentListModel> list = myFilteredAppointments
// .where((item) => item.customerID == id)
// .toList();
// var customerItem =
// myFilteredAppointments.firstWhere((item) => item.customerID == id);
//
// return CustomerData(
// customerID: id,
// customerName: customerItem.customerName ?? "",
// appointmentList: list,
// );
// }).toList();
}
// Future<void> getMyAppointments() async {
// setState(ViewState.busy);
//
// myAppointments =
// await appointmentRepo.getMyAppointmentsForCustomersByFilters();
// myFilteredAppointments = myAppointments;
// myUpComingAppointments = myAppointments
// .where((element) =>
// element.appointmentStatusEnum == AppointmentStatusEnum.booked)
// .toList();
// applyFilterOnAppointmentsVM(
// appointmentStatusEnum: AppointmentStatusEnum.allAppointments);
// if (myUpComingAppointments.isEmpty) {
// isShowEmptyMessage = true;
// }
// setState(ViewState.idle);
// notifyListeners();
// }
Future<void> getMyAppointmentsForCustomer({bool isNeedToRebuild = false}) async {
if (isNeedToRebuild) setState(ViewState.busy);
myAppointments = await appointmentRepo.getMyAppointmentsForCustomersByFilters();
// myFilteredAppointments = myAppointments;
setState(ViewState.idle);
applyFilterOnAppointmentsVM(appointmentStatusEnum: AppointmentStatusEnum.allAppointments);
myUpComingAppointments = myAppointments
.where((element) =>
(element.appointmentStatusEnum == AppointmentStatusEnum.booked || element.appointmentStatusEnum == AppointmentStatusEnum.confirmed) &&
(DateHelper.parseStringToDate(element.appointmentDate!).isAfter(DateTime.now())))
.toList();
notifyListeners();
} }
AppointmentSlots? appointmentSlots; AppointmentSlots? appointmentSlots;
Future<void> getAppointmentSlotsInfo({required int branchID, required BuildContext context, bool isNeedToRebuild = false}) async { bool isSlotsLoading = true;
if (isNeedToRebuild) setState(ViewState.busy);
Future<void> getAppointmentSlotsInfo({required int branchID}) async {
isSlotsLoading = true;
notifyListeners();
try { try {
GenericRespModel genericRespModel = await appointmentRepo.getAppointmentSlots(branchID: branchID, fromDate: selectedDateForAppointments, toDate: selectedDateForAppointments); GenericRespModel genericRespModel = await appointmentRepo.getAppointmentSlots(branchID: branchID, fromDate: selectedDateForAppointments, toDate: selectedDateForAppointments);
if (genericRespModel.messageStatus == 1) { if (genericRespModel.messageStatus == 1) {
@ -464,25 +441,15 @@ class AppointmentsVM extends BaseVM {
} else { } else {
Utils.showToast(genericRespModel.message.toString()); Utils.showToast(genericRespModel.message.toString());
} }
isSlotsLoading = false;
notifyListeners();
} catch (e) { } catch (e) {
isSlotsLoading = false;
notifyListeners();
Utils.showToast(e.toString()); Utils.showToast(e.toString());
} }
} }
Future<void> getMyAppointmentsForProvider({required int branchID}) async {
setState(ViewState.busy);
myAppointments = await appointmentRepo.getMyAppointmentsForProvidersByFilters(branchID: branchID);
myFilteredAppointments = myAppointments;
myUpComingAppointments = myAppointments
.where((element) =>
(element.appointmentStatusEnum == AppointmentStatusEnum.confirmed || element.appointmentStatusEnum == AppointmentStatusEnum.booked) &&
(DateHelper.parseStringToDate(element.appointmentDate!).isAfter(DateTime.now())))
.toList();
notifyListeners();
applyFilterOnAppointmentsVM(appointmentStatusEnum: AppointmentStatusEnum.allAppointments, isNeedCustomerFilter: true);
setState(ViewState.idle);
}
Future<bool> updateAppointmentStatus({required int appointmentId, required AppointmentStatusEnum appointmentStatusEnum, bool isNeedToRebuild = false}) async { Future<bool> updateAppointmentStatus({required int appointmentId, required AppointmentStatusEnum appointmentStatusEnum, bool isNeedToRebuild = false}) async {
if (isNeedToRebuild) setState(ViewState.busy); if (isNeedToRebuild) setState(ViewState.busy);
try { try {
@ -520,8 +487,8 @@ class AppointmentsVM extends BaseVM {
} }
bool isShowMergeButton() { bool isShowMergeButton() {
return myFilteredAppointments2[selectedAppointmentIndex].customerAppointmentList!.every((appointment) => appointment.appointmentStatusEnum == AppointmentStatusEnum.confirmed) && return myFilteredAppointmentsForProvider[selectedAppointmentIndex].customerAppointmentList!.every((appointment) => appointment.appointmentStatusEnum == AppointmentStatusEnum.confirmed) &&
myFilteredAppointments2[selectedAppointmentIndex].customerAppointmentList!.length > 1; myFilteredAppointmentsForProvider[selectedAppointmentIndex].customerAppointmentList!.length > 1;
} }
Future<GenericRespModel> createMergeAppointment(Map<String, dynamic> map, {bool isNeedToRebuild = false}) async { Future<GenericRespModel> createMergeAppointment(Map<String, dynamic> map, {bool isNeedToRebuild = false}) async {
@ -534,10 +501,10 @@ class AppointmentsVM extends BaseVM {
bool inNeedToEnableMergeButton = false; bool inNeedToEnableMergeButton = false;
void updateCheckBoxInMergeRequest(int currentIndex) { void updateCheckBoxInMergeRequest(int currentIndex) {
myFilteredAppointments2[selectedAppointmentIndex].customerAppointmentList![currentIndex].isSelected = myFilteredAppointmentsForProvider[selectedAppointmentIndex].customerAppointmentList![currentIndex].isSelected =
!(myFilteredAppointments2[selectedAppointmentIndex].customerAppointmentList?[currentIndex].isSelected ?? false); !(myFilteredAppointmentsForProvider[selectedAppointmentIndex].customerAppointmentList?[currentIndex].isSelected ?? false);
int count = countSelected(myFilteredAppointments2[selectedAppointmentIndex].customerAppointmentList ?? []); int count = countSelected(myFilteredAppointmentsForProvider[selectedAppointmentIndex].customerAppointmentList ?? []);
if (count > 1) { if (count > 1) {
inNeedToEnableMergeButton = true; inNeedToEnableMergeButton = true;
} else { } else {
@ -917,9 +884,8 @@ class AppointmentsVM extends BaseVM {
} }
if (genericRespModel.messageStatus == 1) { if (genericRespModel.messageStatus == 1) {
context.read<DashboardVmCustomer>().onNavbarTapped(1); context.read<DashboardVmCustomer>().onNavbarTapped(1);
applyFilterOnAppointmentsVM(appointmentStatusEnum: AppointmentStatusEnum.cancelled);
Utils.showToast(genericRespModel.message.toString()); Utils.showToast(genericRespModel.message.toString());
getMyAppointmentsForCustomer(); applyFilterOnAppointmentsVMForCustomers(appointmentStatusEnum: AppointmentStatusEnum.cancelled);
Utils.hideLoading(context); Utils.hideLoading(context);
navigateReplaceWithNameUntilRoute(context, AppRoutes.dashboard); navigateReplaceWithNameUntilRoute(context, AppRoutes.dashboard);
} }
@ -1011,6 +977,20 @@ class AppointmentsVM extends BaseVM {
} }
} }
Future<ProviderContactInfoModel?> getProvidersContactInfo({required int providerId, required BuildContext context}) async {
Utils.showLoading(context);
try {
ProviderContactInfoModel contactInfoModel = await commonRepo.getProvidersContactInfo(providerId: providerId);
Utils.hideLoading(context);
return contactInfoModel;
} catch (e, s) {
logger.e(s);
Utils.hideLoading(context);
Utils.showToast(e.toString());
return null;
}
}
// BRANCHES RELATED // BRANCHES RELATED
List<BranchDetailModel> nearbyBranches = []; List<BranchDetailModel> nearbyBranches = [];
@ -1827,105 +1807,120 @@ class AppointmentsVM extends BaseVM {
clearAppointmentFilterSelections(); clearAppointmentFilterSelections();
if (AppState().currentAppType == AppType.provider) { if (AppState().currentAppType == AppType.provider) {
getMyAppointmentsForProvider(branchID: selectedBranchIdForAppointments); applyFilterOnAppointmentsVMForProviders(appointmentStatusEnum: AppointmentStatusEnum.allAppointments, isNeedCustomerFilter: true);
} else { } else {
getMyAppointmentsForCustomer(); applyFilterOnAppointmentsVMForCustomers(appointmentStatusEnum: AppointmentStatusEnum.allAppointments);
} }
notifyListeners(); notifyListeners();
} }
Future<void> getAppointmentsBasedOnFiltersForCustomer() async { Future<List<AppointmentListModel>> getAppointmentsBasedOnFiltersForCustomer() async {
setState(ViewState.busy); try {
List<String> providersIdsList = []; setState(ViewState.busy);
if (appointmentFilterProviderSearchHistory.isNotEmpty) { List<String> providersIdsList = [];
for (var element in appointmentFilterProviderSearchHistory) { if (appointmentFilterProviderSearchHistory.isNotEmpty) {
providersIdsList.add(element.id.toString()); for (var element in appointmentFilterProviderSearchHistory) {
providersIdsList.add(element.id.toString());
}
} }
} List<String> categoryIdsList = [];
List<String> categoryIdsList = []; if (appointmentFilterCategorySearchHistory.isNotEmpty) {
if (appointmentFilterCategorySearchHistory.isNotEmpty) { for (var element in appointmentFilterCategorySearchHistory) {
for (var element in appointmentFilterCategorySearchHistory) { categoryIdsList.add(element.id.toString());
categoryIdsList.add(element.id.toString()); }
} }
} List<String> servicesIdsList = [];
List<String> servicesIdsList = []; if (appointmentFilterServicesSearchHistory.isNotEmpty) {
if (appointmentFilterServicesSearchHistory.isNotEmpty) { for (var element in appointmentFilterServicesSearchHistory) {
for (var element in appointmentFilterServicesSearchHistory) { servicesIdsList.add(element.id.toString());
servicesIdsList.add(element.id.toString()); }
} }
} List<String> itemIdsList = [];
List<String> itemIdsList = []; if (appointmentFilterItemsSearchHistory.isNotEmpty) {
if (appointmentFilterItemsSearchHistory.isNotEmpty) { for (var element in appointmentFilterItemsSearchHistory) {
for (var element in appointmentFilterItemsSearchHistory) { itemIdsList.add(element.id.toString());
itemIdsList.add(element.id.toString()); }
} }
} List<String> branchesIdsList = [];
List<String> branchesIdsList = []; if (appointmentFilterBranchSearchHistory.isNotEmpty) {
if (appointmentFilterBranchSearchHistory.isNotEmpty) { for (var element in appointmentFilterBranchSearchHistory) {
for (var element in appointmentFilterBranchSearchHistory) { branchesIdsList.add(element.id.toString());
branchesIdsList.add(element.id.toString()); }
} }
}
myAppointments = await appointmentRepo.getMyAppointmentsForCustomersByFilters( List<AppointmentListModel> myAppointments = await appointmentRepo.getMyAppointmentsForCustomersByFilters(
providerIdsList: providersIdsList, providerIdsList: providersIdsList,
categoryIdsList: categoryIdsList, categoryIdsList: categoryIdsList,
serviceIdsList: servicesIdsList, serviceIdsList: servicesIdsList,
itemIdsList: itemIdsList, itemIdsList: itemIdsList,
branchIdsList: branchesIdsList, branchIdsList: branchesIdsList,
); );
applyFilterOnAppointmentsVM(appointmentStatusEnum: AppointmentStatusEnum.allAppointments); setState(ViewState.idle);
setState(ViewState.idle);
return myAppointments;
} catch (e) {
logger.e(e);
setState(ViewState.idle);
Utils.showToast(e.toString());
return [];
}
} }
String selectedDateForAppointments = ""; String selectedDateForAppointments = "";
Future<void> getAppointmentsBasedOnFiltersForProviders({required int branchID}) async { Future<List<AppointmentListModel>> getAppointmentsBasedOnFiltersForProviders({required int branchID, AppointmentStatusEnum? appointmentStatus}) async {
setState(ViewState.busy); try {
setState(ViewState.busy);
List<String> servicesIdsList = []; List<String> servicesIdsList = [];
if (appointmentFilterServicesSearchHistory.isNotEmpty) { if (appointmentFilterServicesSearchHistory.isNotEmpty) {
for (var element in appointmentFilterServicesSearchHistory) { for (var element in appointmentFilterServicesSearchHistory) {
servicesIdsList.add(element.id.toString()); servicesIdsList.add(element.id.toString());
}
} }
}
List<String> customerNamesList = []; List<String> customerNamesList = [];
if (appointmentFilterCustomerNameSearchHistory.isNotEmpty) { if (appointmentFilterCustomerNameSearchHistory.isNotEmpty) {
for (var element in appointmentFilterCustomerNameSearchHistory) { for (var element in appointmentFilterCustomerNameSearchHistory) {
customerNamesList.add(element.toString()); customerNamesList.add(element.toString());
}
} }
}
List<String> customerPhonesList = []; List<String> customerPhonesList = [];
if (appointmentFilterMobilePhoneSearchHistory.isNotEmpty) { if (appointmentFilterMobilePhoneSearchHistory.isNotEmpty) {
for (var element in appointmentFilterMobilePhoneSearchHistory) { for (var element in appointmentFilterMobilePhoneSearchHistory) {
customerPhonesList.add(element.toString()); customerPhonesList.add(element.toString());
}
} }
} List<String> customerDeliveryTypesList = [];
List<String> customerDeliveryTypesList = []; if (appointmentFilterServiceDeliverySearchHistory.isNotEmpty) {
if (appointmentFilterServiceDeliverySearchHistory.isNotEmpty) { for (var element in appointmentFilterServiceDeliverySearchHistory) {
for (var element in appointmentFilterServiceDeliverySearchHistory) { customerDeliveryTypesList.add(element.id.toString());
customerDeliveryTypesList.add(element.id.toString()); }
} }
}
log("customerNamesList: $customerNamesList"); log("customerNamesList: $customerNamesList");
log("customerPhonesList: $customerPhonesList"); log("customerPhonesList: $customerPhonesList");
log("customerDeliveryTypesList: $customerDeliveryTypesList"); log("customerDeliveryTypesList: $customerDeliveryTypesList");
log("servicesIdsList: $servicesIdsList"); log("servicesIdsList: $servicesIdsList");
myAppointments = await appointmentRepo.getMyAppointmentsForProvidersByFilters( List<AppointmentListModel> myAppointments = await appointmentRepo.getMyAppointmentsForProvidersByFilters(
branchID: branchID, branchID: branchID,
customerNamesList: customerNamesList, customerNamesList: customerNamesList,
customerPhonesList: customerPhonesList, customerPhonesList: customerPhonesList,
deliveryTypeIdsList: customerDeliveryTypesList, deliveryTypeIdsList: customerDeliveryTypesList,
serviceProviderServiceIdsList: servicesIdsList, serviceProviderServiceIdsList: servicesIdsList,
fromDate: '', appointmentStatusEnum: appointmentStatus,
toDate: ''); fromDate: '',
toDate: '');
log(" myFilteredAppointments : ${myFilteredAppointments.length}");
applyFilterOnAppointmentsVM(appointmentStatusEnum: AppointmentStatusEnum.allAppointments, isNeedCustomerFilter: true); setState(ViewState.idle);
setState(ViewState.idle);
return myAppointments ?? [];
} catch (e) {
logger.e(e);
setState(ViewState.idle);
Utils.showToast(e.toString());
return [];
}
} }
Future<bool> addProviderToFavorite({required int serviceProviderID, required BuildContext context}) async { Future<bool> addProviderToFavorite({required int serviceProviderID, required BuildContext context}) async {

@ -67,7 +67,7 @@ class DashboardVmCustomer extends BaseVM {
appointmentsVM.populateAppointmentsFilterList(); appointmentsVM.populateAppointmentsFilterList();
adVM.populateAdsFilterList(); adVM.populateAdsFilterList();
requestsVM.populateDataForRequestsFilter(); requestsVM.populateDataForRequestsFilter();
await appointmentsVM.getMyAppointmentsForCustomer(); 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

@ -82,14 +82,13 @@ class DashboardVMProvider extends BaseVM {
appointmentVM.populateAppointmentsFilterList(); appointmentVM.populateAppointmentsFilterList();
shippingManagementVM.populateShippingRequestFilterList(); shippingManagementVM.populateShippingRequestFilterList();
await serviceVM.populateBranchServiceFilters(); await serviceVM.populateBranchServiceFilters();
await serviceVM.getBranchAndServices(); await serviceVM.getBranchAndServices();
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 appointmentVM.getMyAppointmentsForProvider(branchID: appointmentVM.selectedBranchIdForAppointments); await appointmentVM.applyFilterOnAppointmentsVMForProviders(appointmentStatusEnum: AppointmentStatusEnum.allAppointments, shouldPopulateUpcoming: true);
adVM.populateAdsFilterList(); adVM.populateAdsFilterList();
await requestsVM.getRequests(); await requestsVM.getRequests();
await subscriptionsVM.getSubscriptionBySP(AppState().getUser.data?.userInfo?.providerId.toString() ?? "", true); await subscriptionsVM.getSubscriptionBySP(AppState().getUser.data?.userInfo?.providerId.toString() ?? "", true);
@ -130,7 +129,7 @@ class DashboardVMProvider extends BaseVM {
void performCheckOnUsers(BuildContext context, Function() callBack) async { void performCheckOnUsers(BuildContext context, Function() callBack) async {
if (AppState().getproviderSubscription.isNotEmpty && AppState().getproviderSubscription.first.subUsersRemaining! > 0) { if (AppState().getproviderSubscription.isNotEmpty && AppState().getproviderSubscription.first.subUsersRemaining! > 0) {
showMyBottomSheet(context, isDismissible: false, isScrollControlled: true, child: AddPhoneNumWidget(), callBackFunc: callBack); showMyBottomSheet(context, isDismissible: false, isScrollControlled: true, child: AddPhoneNumWidget(), callBackFunc: callBack);
} else { } else {
Utils.showToast(LocaleKeys.upgradeSubUsers.tr()); Utils.showToast(LocaleKeys.upgradeSubUsers.tr());
} }

@ -275,7 +275,11 @@ class ServiceVM extends BaseVM {
context, context,
allowMultiple: false, allowMultiple: false,
); );
if (files != null && files.any((element) => element.path.split('.').last.toLowerCase() != 'pdf')) { if (files != null && files.any((element) =>
element.path
.split('.')
.last
.toLowerCase() != 'pdf')) {
Utils.showToast("Only PDF Files are allowed"); Utils.showToast("Only PDF Files are allowed");
return; return;
} }
@ -339,6 +343,67 @@ class ServiceVM extends BaseVM {
return await branchRepo.serviceProviderDocumentsUpdate(data); return await branchRepo.serviceProviderDocumentsUpdate(data);
} }
bool customServiceEnabledStatus = false;
void updateCustomServiceEnabledStatus(bool status) {
customServiceEnabledStatus = status;
notifyListeners();
}
String customServiceTitle = "";
void updateCustomServiceTitle(String title) {
customServiceTitle = title;
}
String customServicePrice = "";
void updateCustomServicePrice(String title) {
customServicePrice = title;
}
String customerServiceTax = "15";
void updateCustomerServiceTax(String title) {
customerServiceTax = title;
}
resetCustomServiceForm() {
customServiceTitle = "";
customServicePrice = "";
customerServiceTax = "15";
}
String customServiceTitleError = "";
String customServicePriceError = "";
String customerServiceTaxError = "";
bool isCustomServiceDetailValidated() {
bool isValidated = true;
if (customServiceTitle.isEmpty) {
customServiceTitleError = GlobalConsts.serviceNameError;
isValidated = false;
notifyListeners();
return isValidated;
} else {
customServiceTitleError = "";
}
if (customServicePrice.isEmpty) {
customServicePriceError = GlobalConsts.priceError;
isValidated = false;
} else {
customServicePriceError = "";
}
if (customerServiceTax.isEmpty) {
customerServiceTaxError = GlobalConsts.taxError;
isValidated = false;
} else {
customerServiceTaxError = "";
}
notifyListeners();
return isValidated;
}
// Create new branch // Create new branch
Future<void> getBranchAndServices() async { Future<void> getBranchAndServices() async {
setState(ViewState.busy); setState(ViewState.busy);
@ -466,10 +531,10 @@ class ServiceVM extends BaseVM {
DropValue( DropValue(
element.id ?? 0, element.id ?? 0,
((element.categoryName!.isEmpty ((element.categoryName!.isEmpty
? "N/A" ? "N/A"
: countryCode == "SA" : countryCode == "SA"
? element.categoryNameN ? element.categoryNameN
: element.categoryName) ?? : element.categoryName) ??
"N/A"), "N/A"),
"", "",
), ),
@ -527,18 +592,23 @@ class ServiceVM extends BaseVM {
Future<GenericRespModel> createService(List<Map<String, dynamic>> map) async { Future<GenericRespModel> createService(List<Map<String, dynamic>> map) async {
setState(ViewState.busy); setState(ViewState.busy);
return await branchRepo.createService(map); GenericRespModel response = await branchRepo.createService(map);
setState(ViewState.idle); setState(ViewState.idle);
return response;
} }
Future<GenericRespModel> updateServices(List<Map<String, dynamic>> map) async { Future<GenericRespModel> updateServices(List<Map<String, dynamic>> map) async {
return await branchRepo.updateService(map); return await branchRepo.updateService(map);
} }
Future<List<AppointmentBasicDetailsModel>> getAppointmentsByServiceID({required BuildContext context, required int branchId, required int serviceId}) async { Future<List<AppointmentBasicDetailsModel>> getAppointmentsByCategoryOrService({required BuildContext context, required int branchId, required int categoryId, required int serviceId}) async {
try { try {
Utils.showLoading(context); Utils.showLoading(context);
List<AppointmentBasicDetailsModel> appointmentList = await branchRepo.getAppointmentsByCategoryOrService(branchId: branchId, serviceId: serviceId); List<AppointmentBasicDetailsModel> appointmentList = await branchRepo.getAppointmentsByCategoryOrService(
branchId: branchId,
serviceId: serviceId,
categoryId: categoryId,
);
// log("list: ${mResponse.}"); // log("list: ${mResponse.}");
Utils.hideLoading(context); Utils.hideLoading(context);
@ -585,7 +655,8 @@ class ServiceVM extends BaseVM {
} }
} }
Future buildDealNotCompletedBottomSheetOptions({required BuildContext mainContext, required List<AppointmentBasicDetailsModel> appointments, required String branchName}) async { Future cannotDeactivateServiceOrCategoryBottomSheet(
{required BuildContext mainContext, required List<AppointmentBasicDetailsModel> appointments, required String branchName, required bool isService}) async {
return actionConfirmationBottomSheet( return actionConfirmationBottomSheet(
isOnlyOneButton: true, isOnlyOneButton: true,
context: mainContext, context: mainContext,
@ -770,7 +841,9 @@ class ServiceVM extends BaseVM {
File file = File(imageModel.filePath!); File file = File(imageModel.filePath!);
List<int> imageBytes = await file.readAsBytes(); List<int> imageBytes = await file.readAsBytes();
String image = base64Encode(imageBytes); String image = base64Encode(imageBytes);
String fileName = file.path.split('/').last; String fileName = file.path
.split('/')
.last;
branchPostingImages = BranchPostingImages( branchPostingImages = BranchPostingImages(
imageName: fileName, imageName: fileName,
imageStr: image, imageStr: image,

@ -4,6 +4,7 @@ import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/main.dart'; import 'package:mc_common_app/main.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/setting_utils_models/app_info_model.dart'; import 'package:mc_common_app/models/setting_utils_models/app_info_model.dart';
import 'package:mc_common_app/models/setting_utils_models/app_invitation_history_model.dart';
import 'package:mc_common_app/models/setting_utils_models/contact_infos_model.dart'; import 'package:mc_common_app/models/setting_utils_models/contact_infos_model.dart';
import 'package:mc_common_app/models/setting_utils_models/faqs_model.dart'; import 'package:mc_common_app/models/setting_utils_models/faqs_model.dart';
import 'package:mc_common_app/repositories/setting_options_repo.dart'; import 'package:mc_common_app/repositories/setting_options_repo.dart';
@ -82,11 +83,20 @@ class SettingOptionsVM extends BaseVM {
try { try {
GenericRespModel respModel = await settingOptionsRepo.appInvitationCreate(channelId: inviteTypeEnum.toIntFromEnum(), message: GlobalConsts.getAppInvitationLink()); GenericRespModel respModel = await settingOptionsRepo.appInvitationCreate(channelId: inviteTypeEnum.toIntFromEnum(), message: GlobalConsts.getAppInvitationLink());
await Utils.inviteFriend(inviteTypeEnum: inviteTypeEnum, message: GlobalConsts.getAppInvitationLink()); await Utils.inviteFriend(inviteTypeEnum: inviteTypeEnum, message: GlobalConsts.getAppInvitationLink());
Utils.hideLoading(context); Utils.hideLoading(context);
} catch (e) { } catch (e) {
logger.i(e.toString()); logger.i(e.toString());
Utils.hideLoading(context); Utils.hideLoading(context);
} }
} }
List<AppInvitationHistoryModel> appInvitationHistoryList = [];
Future<void> getAppInvitationHistoryList() async {
try {
appInvitationHistoryList = await settingOptionsRepo.getAppInvitationsHistory();
} catch (e) {
logger.i(e.toString());
}
}
} }

@ -10,7 +10,7 @@ class DottedRoundedCard extends StatelessWidget {
final String text; final String text;
final Widget icon; final Widget icon;
const DottedRoundedCard({Key? key, required this.onTap, required this.text, required this.icon}) : super(key: key); const DottedRoundedCard({super.key, required this.onTap, required this.text, required this.icon});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -48,44 +48,47 @@ class DottedRectContainer extends StatelessWidget {
final Widget icon; final Widget icon;
final String extensions; final String extensions;
const DottedRectContainer({Key? key, required this.onTap, required this.text, required this.icon, required this.extensions}) : super(key: key); const DottedRectContainer({super.key, required this.onTap, required this.text, required this.icon, required this.extensions});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return InkWell( return InkWell(
onTap: onTap, onTap: onTap,
child: Column( child: Container(
children: [ constraints: const BoxConstraints(minHeight: 60),
DashedRect( child: Column(
color: MyColors.lightIconColor, children: [
strokeWidth: 2.0, DashedRect(
gap: 4.0, color: MyColors.lightIconColor,
child: Row( strokeWidth: 2.0,
mainAxisAlignment: MainAxisAlignment.center, gap: 4.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
icon,
const SizedBox(width: 8),
text
.toText(
fontSize: 15,
isBold: true,
color: MyColors.darkPrimaryColor,
)
.paddingAll(10),
],
),
),
8.height,
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [ children: [
icon, "( $extensions )".toText(
const SizedBox(width: 8), fontSize: 8,
text color: MyColors.lightTextColor,
.toText( ),
fontSize: 15,
isBold: true,
color: MyColors.darkPrimaryColor,
)
.paddingAll(6),
], ],
), )
), ],
8.height, ),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
"( $extensions )".toText(
fontSize: 8,
color: MyColors.lightTextColor,
),
],
)
],
), ),
); );
} }

@ -6,6 +6,7 @@ import 'package:mc_common_app/classes/consts.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';
import 'package:mc_common_app/models/general_models/widgets_models.dart';
import 'package:mc_common_app/theme/colors.dart'; 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/utils.dart'; import 'package:mc_common_app/utils/utils.dart';
@ -22,6 +23,7 @@ class AdDuration extends StatelessWidget {
const AdDuration({super.key}); const AdDuration({super.key});
void onAddSpecialServiceButtonTapped(BuildContext context, AdVM adVM) { void onAddSpecialServiceButtonTapped(BuildContext context, AdVM adVM) {
adVM.updateSelectedVehicleAdsSpecialServicesId(SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""));
showModalBottomSheet( showModalBottomSheet(
context: context, context: context,
isScrollControlled: true, isScrollControlled: true,
@ -72,10 +74,7 @@ class AdDuration extends StatelessWidget {
value: adVM.vehicleAdDurationId.selectedOption, value: adVM.vehicleAdDurationId.selectedOption,
isNeedClickAll: true, isNeedClickAll: true,
postFixDataColor: MyColors.darkTextColor, postFixDataColor: MyColors.darkTextColor,
onTap: () async { onTap: () {},
final formattedDate = await Utils.pickDateFromDatePicker(context);
adVM.updateSelectionDurationStartDate(formattedDate);
},
), ),
], ],
// Builder(builder: (context) { // Builder(builder: (context) {

@ -26,10 +26,31 @@ class VehicleDetails extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Consumer(builder: (BuildContext context, AdVM adVM, Widget? child) { return Consumer(builder: (BuildContext context, AdVM adVM, Widget? child) {
String roleAppState = "";
String roleName = "";
if (AppState().getUser.data!.userInfo != null) {
roleAppState = AppState().getUser.data!.userInfo!.roleName ?? "";
List list = roleAppState.split('_');
if (list.length > 1) {
roleName = list[1];
}
}
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
LocaleKeys.vehicleDetail.tr().toText(fontSize: 18, isBold: true), LocaleKeys.vehicleDetail.tr().toText(fontSize: 18, isBold: true),
if (AppState().currentAppType == AppType.provider && roleName.isNotEmpty) ...[
8.height,
TxtField(
value: roleName,
isBackgroundEnabled: true,
isNeedClickAll: true,
hint: '',
onTap: () {},
),
],
8.height, 8.height,
Builder( Builder(
builder: (context) { builder: (context) {
@ -56,40 +77,32 @@ class VehicleDetails extends StatelessWidget {
).paddingAll(10), ).paddingAll(10),
] else ...[ ] else ...[
8.height, 8.height,
if (AppState().currentAppType == AppType.provider) ...[ // if (AppState().currentAppType == AppType.provider) ...[
Builder(builder: (context) { // Builder(builder: (context) {
List<DropValue> vehicleSellerTypesDrop = []; // List<DropValue> vehicleSellerTypesDrop = [];
for (var element in adVM.vehicleSellerTypes) { // for (var element in adVM.vehicleSellerTypes) {
log("${element.id} : ${element.sellerType}"); // log("${element.id} : ${element.sellerType}");
vehicleSellerTypesDrop.add(DropValue(element.id?.toInt() ?? 0, element.sellerType ?? "", "")); // vehicleSellerTypesDrop.add(DropValue(element.id?.toInt() ?? 0, element.sellerType ?? "", ""));
} // }
//
DropValue? model; // adVM.updateSelectionVehicleSellerTypeId(
int index = -1; // SelectionModel(
if (AppState().userType == UserType.providerDealer) { // selectedId: AppState().getUser.data!.userInfo!.roleId ?? GlobalConsts.providerIndividualRoleTypeId,
index = vehicleSellerTypesDrop.indexWhere((element) => element.id == GlobalConsts.providerDealerRoleTypeId); // selectedOption: AppState().getUser.data!.userInfo!.roleName ?? "",
} else { // ),
index = vehicleSellerTypesDrop.indexWhere((element) => element.id == GlobalConsts.providerIndividualRoleTypeId); // needRefresh: false);
} //
// return DropdownField(
if (index == -1) { // (DropValue value) => adVM.updateSelectionVehicleSellerTypeId(SelectionModel(selectedId: value.id, selectedOption: value.value)),
model = vehicleSellerTypesDrop.first; // isSelectAble: false,
} else { // list: vehicleSellerTypesDrop,
model = vehicleSellerTypesDrop[index]; // dropdownValue: adVM.vehicleSellerTypeId.selectedId != -1 ? DropValue(adVM.vehicleSellerTypeId.selectedId, adVM.vehicleSellerTypeId.selectedOption, "") : null,
} // hint: LocaleKeys.vehicleSellerType.tr(),
adVM.updateSelectionVehicleSellerTypeId(SelectionModel(selectedId: model.id, selectedOption: model.value), needRefresh: false); // errorValue: adVM.vehicleSellerTypeId.errorValue,
// );
return DropdownField( // }),
(DropValue value) => adVM.updateSelectionVehicleSellerTypeId(SelectionModel(selectedId: value.id, selectedOption: value.value)), // 8.height,
isSelectAble: false, // ],
list: vehicleSellerTypesDrop,
dropdownValue: adVM.vehicleSellerTypeId.selectedId != -1 ? DropValue(adVM.vehicleSellerTypeId.selectedId, adVM.vehicleSellerTypeId.selectedOption, "") : null,
hint: LocaleKeys.vehicleSellerType.tr(),
errorValue: adVM.vehicleSellerTypeId.errorValue,
);
}),
8.height,
],
Builder(builder: (context) { Builder(builder: (context) {
List<DropValue> vehicleModelsDrop = []; List<DropValue> vehicleModelsDrop = [];
for (var element in adVM.vehicleModels) { for (var element in adVM.vehicleModels) {

@ -364,7 +364,9 @@ class _AdsDetailViewState extends State<AdsDetailView> {
endDate.isNotEmpty ? endDate.toText(fontSize: 10) : const SizedBox(), endDate.isNotEmpty ? endDate.toText(fontSize: 10) : const SizedBox(),
], ],
), ),
(LocaleKeys.extendAd.tr()).toText(fontSize: 12, color: MyColors.darkPrimaryColor, isUnderLine: true).onPress(() async => await onExtendAdPressed()), if (widget.adDetails.adPostStatus == AdPostStatus.active || widget.adDetails.adPostStatus == AdPostStatus.expired) ...[
(LocaleKeys.extendAd.tr()).toText(fontSize: 12, color: MyColors.darkPrimaryColor, isUnderLine: true).onPress(() async => await onExtendAdPressed()),
],
], ],
), ),
], ],

@ -1,4 +1,5 @@
import 'dart:async'; import 'dart:async';
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/app_state.dart';
import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/classes/consts.dart';
@ -275,8 +276,13 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
void onBookPhotographyServiceClicked(BuildContext context, {required AdDetailsModel adDetailsModel}) async { void onBookPhotographyServiceClicked(BuildContext context, {required AdDetailsModel adDetailsModel}) async {
AdVM adVM = context.read<AdVM>(); AdVM adVM = context.read<AdVM>();
log("adDetailsModel.vehicle!.cityID: ${adDetailsModel.vehicle!.cityID}");
if (adVM.photoOfficeSelectedId.selectedId == -1) { if (adVM.photoOfficeSelectedId.selectedId == -1) {
adVM.getPhotographyServiceScheduleListByOffices(latitude: AppState().currentLocation.latitude, longitude: AppState().currentLocation.longitude, isNeedToRebuild: true); adVM.getPhotographyServiceScheduleListByOffices(
cityId: adDetailsModel.vehicle!.cityID ?? AppState().getUser.data!.userInfo!.cityId ?? 0,
latitude: AppState().currentLocation.latitude,
longitude: AppState().currentLocation.longitude,
isNeedToRebuild: true);
} }
return showModalBottomSheet( return showModalBottomSheet(
@ -716,7 +722,11 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
title: LocaleKeys.yes.tr(), title: LocaleKeys.yes.tr(),
fontSize: 15, fontSize: 15,
onPressed: () { onPressed: () {
adVM.deactivateTheAd(context, adId: adDetailsModel.id!, comment: comments); if (adVM.selectedDeActivateAdCommentModel.index == 0) {
adVM.markAdAsSold(context, adId: adDetailsModel.id!);
} else {
adVM.deactivateTheAd(context, adId: adDetailsModel.id!, comment: comments);
}
}, },
), ),
), ),

@ -1,4 +1,7 @@
import 'dart:developer';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/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';
@ -10,6 +13,7 @@ import 'package:mc_common_app/view_models/ad_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/common_widgets/time_slots.dart'; import 'package:mc_common_app/widgets/common_widgets/time_slots.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart'; import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
import 'package:mc_common_app/widgets/empty_widget.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';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -177,170 +181,186 @@ class BottomSheetAdSpecialServiceContent extends StatelessWidget {
builder: (BuildContext context, AdVM adVM, Widget? child) { builder: (BuildContext context, AdVM adVM, Widget? child) {
return SizedBox( return SizedBox(
height: MediaQuery.of(context).size.height * 0.7, height: MediaQuery.of(context).size.height * 0.7,
child: Column( child: adVM.vehicleAdsSpecialServices.isEmpty
children: [ ? Column(
Container( mainAxisAlignment: MainAxisAlignment.spaceBetween,
margin: const EdgeInsets.all(8),
height: 8,
width: 60,
decoration: const BoxDecoration(color: MyColors.lightTextColor, borderRadius: BorderRadius.all(Radius.circular(20))),
),
12.height,
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
LocaleKeys.addSpecialService.tr().toText(fontSize: 24, isBold: true), Container(
8.height, margin: const EdgeInsets.all(8),
Builder( height: 8,
builder: (context) { width: 60,
List<DropValue> vehicleAdsSpecialServices = []; decoration: const BoxDecoration(color: MyColors.lightTextColor, borderRadius: BorderRadius.all(Radius.circular(20))),
for (var element in adVM.vehicleAdsSpecialServices) {
if (!element.isSelected!) {
vehicleAdsSpecialServices.add(DropValue(element.id?.toInt() ?? 0, element.name ?? "", element.price == null ? "" : element.price!.toInt().toString()));
}
}
return DropdownField(
(DropValue value) => adVM.updateSelectedVehicleAdsSpecialServicesId(SelectionModel(selectedId: value.id, selectedOption: value.value, itemPrice: value.subValue)),
list: vehicleAdsSpecialServices,
hint: LocaleKeys.selectService.tr(),
dropdownValue: adVM.selectedVehicleAdsSpecialServicesId.selectedId != -1 ? DropValue(adVM.selectedVehicleAdsSpecialServicesId.selectedId, adVM.selectedVehicleAdsSpecialServicesId.selectedOption, "") : null,
);
},
), ),
if (adVM.selectedVehicleAdsSpecialServicesId.selectedId != -1) ...[ Center(child: LocaleKeys.noSpecialServicesAvailable.tr().toText(fontSize: 18, color: MyColors.lightTextColor, fontWeight: MyFonts.Medium)).paddingAll(30),
if (adVM.isFetchingLists) ...[ const SizedBox(),
Center(child: const CircularProgressIndicator().paddingAll(20)), ],
] else ...[ )
8.height, : Column(
if ((adVM.selectedVehicleAdsSpecialServicesId.selectedId == 1 && adVM.ssPhotoScheduleModel != null)) ...[ children: [
// Builder( Container(
// builder: (context) { margin: const EdgeInsets.all(8),
// List<DropValue> vehicleAdsSpecialServiceDates = adVM.populateScheduleDatesForAdPhotoService(); height: 8,
// width: 60,
// return DropdownField( decoration: const BoxDecoration(color: MyColors.lightTextColor, borderRadius: BorderRadius.all(Radius.circular(20))),
// (DropValue value) => adVM.updateVehicleVehicleAdsPhotoServiceDate(SelectionModel( ),
// selectedId: value.id, 12.height,
// selectedOption: value.value, Expanded(
// )), child: Column(
// list: vehicleAdsSpecialServiceDates, crossAxisAlignment: CrossAxisAlignment.start,
// hint: "Select Date", children: [
// dropdownValue: adVM.vehicleAdsPhotoServiceDate.selectedId != -1 LocaleKeys.addSpecialService.tr().toText(fontSize: 24, isBold: true),
// ? DropValue(
// adVM.vehicleAdsPhotoServiceDate.selectedId,
// adVM.vehicleAdsPhotoServiceDate.selectedOption,
// "",
// )
// : null,
// );
// },
// ),
// 22.height,
] else if ((adVM.selectedVehicleAdsSpecialServicesId.selectedId == 3 && adVM.ssCarCheckScheduleModel != null)) ...[
// Builder(
// builder: (context) {
// List<DropValue> vehicleAdsSpecialServiceDates = adVM.populateScheduleDatesForAdCarCheckService();
//
// return DropdownField(
// (DropValue value) => adVM.updateVehicleAdsCarCheckServicesDate(SelectionModel(
// selectedId: value.id,
// selectedOption: value.value,
// )),
// list: vehicleAdsSpecialServiceDates,
// hint: "Select Date",
// dropdownValue: adVM.vehicleAdsCarCheckServicesDate.selectedId != -1
// ? DropValue(
// adVM.vehicleAdsCarCheckServicesDate.selectedId,
// adVM.vehicleAdsCarCheckServicesDate.selectedOption,
// "",
// )
// : null,
// );
// },
// ),
// 22.height,
],
if (adVM.selectedVehicleAdsSpecialServicesId.selectedId != 3 && adVM.selectedVehicleAdsSpecialServicesId.selectedId != 1) ...[
descriptionCard(
description: adVM.vehicleAdsSpecialServices.firstWhere((element) => element.id == adVM.selectedVehicleAdsSpecialServicesId.selectedId).description ?? "",
),
],
if (adVM.adSSTimeSlots.isNotEmpty) ...[
LocaleKeys.availableSlots.tr().toText(fontSize: 15, isBold: true),
8.height, 8.height,
BuildTimeSlots( Builder(
timeSlots: adVM.adSSTimeSlots, builder: (context) {
onPressed: (index) => adVM.updateIsSelectedInSlots(index), List<DropValue> vehicleAdsSpecialServices = [];
for (var element in adVM.vehicleAdsSpecialServices) {
if (!element.isSelected!) {
vehicleAdsSpecialServices.add(DropValue(element.id?.toInt() ?? 0, element.name ?? "", element.price == null ? "" : element.price!.toInt().toString()));
}
}
return DropdownField(
(DropValue value) => adVM.updateSelectedVehicleAdsSpecialServicesId(SelectionModel(selectedId: value.id, selectedOption: value.value, itemPrice: value.subValue)),
list: vehicleAdsSpecialServices,
hint: LocaleKeys.selectService.tr(),
dropdownValue: adVM.selectedVehicleAdsSpecialServicesId.selectedId != -1
? DropValue(adVM.selectedVehicleAdsSpecialServicesId.selectedId, adVM.selectedVehicleAdsSpecialServicesId.selectedOption, "")
: null,
);
},
), ),
], if (adVM.selectedVehicleAdsSpecialServicesId.selectedId != -1) ...[
22.height, if (adVM.isFetchingLists) ...[
LocaleKeys.serviceAmount.tr().toText(fontSize: 16, isBold: true, color: MyColors.lightTextColor), Center(child: const CircularProgressIndicator().paddingAll(20)),
Row( ] else ...[
crossAxisAlignment: CrossAxisAlignment.end, 8.height,
children: [ if ((adVM.selectedVehicleAdsSpecialServicesId.selectedId == 1 && adVM.ssPhotoScheduleModel != null)) ...[
adVM.selectedVehicleAdsSpecialServicesId.itemPrice.toText(fontSize: 20, isBold: true), // Builder(
SizedBox(width: 1.w), // builder: (context) {
LocaleKeys.sar.tr().toText(fontSize: 12, isBold: true, color: MyColors.lightTextColor).paddingOnly(bottom: 2), // List<DropValue> vehicleAdsSpecialServiceDates = adVM.populateScheduleDatesForAdPhotoService();
//
// return DropdownField(
// (DropValue value) => adVM.updateVehicleVehicleAdsPhotoServiceDate(SelectionModel(
// selectedId: value.id,
// selectedOption: value.value,
// )),
// list: vehicleAdsSpecialServiceDates,
// hint: "Select Date",
// dropdownValue: adVM.vehicleAdsPhotoServiceDate.selectedId != -1
// ? DropValue(
// adVM.vehicleAdsPhotoServiceDate.selectedId,
// adVM.vehicleAdsPhotoServiceDate.selectedOption,
// "",
// )
// : null,
// );
// },
// ),
// 22.height,
] else if ((adVM.selectedVehicleAdsSpecialServicesId.selectedId == 3 && adVM.ssCarCheckScheduleModel != null)) ...[
// Builder(
// builder: (context) {
// List<DropValue> vehicleAdsSpecialServiceDates = adVM.populateScheduleDatesForAdCarCheckService();
//
// return DropdownField(
// (DropValue value) => adVM.updateVehicleAdsCarCheckServicesDate(SelectionModel(
// selectedId: value.id,
// selectedOption: value.value,
// )),
// list: vehicleAdsSpecialServiceDates,
// hint: "Select Date",
// dropdownValue: adVM.vehicleAdsCarCheckServicesDate.selectedId != -1
// ? DropValue(
// adVM.vehicleAdsCarCheckServicesDate.selectedId,
// adVM.vehicleAdsCarCheckServicesDate.selectedOption,
// "",
// )
// : null,
// );
// },
// ),
// 22.height,
],
if (adVM.selectedVehicleAdsSpecialServicesId.selectedId != 3 && adVM.selectedVehicleAdsSpecialServicesId.selectedId != 1) ...[
descriptionCard(
description: adVM.vehicleAdsSpecialServices.firstWhere((element) => element.id == adVM.selectedVehicleAdsSpecialServicesId.selectedId).description ?? "",
),
],
if (adVM.adSSTimeSlots.isNotEmpty) ...[
LocaleKeys.availableSlots.tr().toText(fontSize: 15, isBold: true),
8.height,
BuildTimeSlots(
timeSlots: adVM.adSSTimeSlots,
onPressed: (index) => adVM.updateIsSelectedInSlots(index),
),
],
22.height,
LocaleKeys.serviceAmount.tr().toText(fontSize: 16, isBold: true, color: MyColors.lightTextColor),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
adVM.selectedVehicleAdsSpecialServicesId.itemPrice.toText(fontSize: 20, isBold: true),
SizedBox(width: 1.w),
LocaleKeys.sar.tr().toText(fontSize: 12, isBold: true, color: MyColors.lightTextColor).paddingOnly(bottom: 2),
],
),
],
], ],
), ],
],
],
],
),
),
SizedBox(
width: double.infinity,
child: ShowFillButton(
backgroundColor: !isButtonTappable(adVM) ? MyColors.lightTextColor.withOpacity(0.6) : MyColors.darkPrimaryColor,
title: LocaleKeys.addService.tr(),
onPressed: () {
if (!isButtonTappable(adVM)) {
return;
}
Navigator.pop(context);
adVM.addNewSpecialServiceCard(
specialServiceCard: SpecialServiceCard(
serviceSelectedId: adVM.selectedVehicleAdsSpecialServicesId,
description: adVM.vehicleAdsSpecialServices.firstWhere((element) => element.id == adVM.selectedVehicleAdsSpecialServicesId.selectedId).description ?? "",
duration: "",
serviceDate: "",
serviceDateError: "",
serviceTimeError: "",
address: "",
serviceTime: "",
), ),
); ),
SizedBox(
width: double.infinity,
child: ShowFillButton(
backgroundColor: !isButtonTappable(adVM) ? MyColors.lightTextColor.withOpacity(0.6) : MyColors.darkPrimaryColor,
title: LocaleKeys.addService.tr(),
onPressed: () {
if (!isButtonTappable(adVM)) {
return;
}
Navigator.pop(context);
// adVM.addNewSpecialServiceCard( adVM.addNewSpecialServiceCard(
// specialServiceCard: SpecialServiceCard( specialServiceCard: SpecialServiceCard(
// serviceDate: adVM.vehicleAdsSpecialServicesId.selectedId == 1 serviceSelectedId: adVM.selectedVehicleAdsSpecialServicesId,
// ? adVM.vehicleAdsPhotoServiceDate.selectedOption description: adVM.vehicleAdsSpecialServices.firstWhere((element) => element.id == adVM.selectedVehicleAdsSpecialServicesId.selectedId).description ?? "",
// : adVM.vehicleAdsSpecialServicesId.selectedId == 3 duration: "",
// ? adVM.vehicleAdsCarCheckServicesDate.selectedOption serviceDate: "",
// : "", serviceDateError: "",
// serviceDateError: "", serviceTimeError: "",
// serviceSelectedId: adVM.vehicleAdsSpecialServicesId, address: "",
// serviceTimeError: "", serviceTime: "",
// description: adVM.vehicleAdsSpecialServices.firstWhere((element) => element.id == adVM.vehicleAdsSpecialServicesId.selectedId).description ?? "", ),
// duration: adVM.vehicleAdsSpecialServicesId.selectedId == 1 );
// ? adVM.ssPhotoScheduleModel!.distanceKM.toString()
// : adVM.vehicleAdsSpecialServicesId.selectedId == 3 // adVM.addNewSpecialServiceCard(
// ? adVM.ssCarCheckScheduleModel!.distanceKM.toString() // specialServiceCard: SpecialServiceCard(
// : "", // serviceDate: adVM.vehicleAdsSpecialServicesId.selectedId == 1
// address: adVM.vehicleAdsSpecialServicesId.selectedId == 1 // ? adVM.vehicleAdsPhotoServiceDate.selectedOption
// ? "${adVM.ssPhotoScheduleModel!.photoOfficeName} - ${adVM.ssPhotoScheduleModel!.areaName}" // : adVM.vehicleAdsSpecialServicesId.selectedId == 3
// : adVM.vehicleAdsSpecialServicesId.selectedId == 3 // ? adVM.vehicleAdsCarCheckServicesDate.selectedOption
// ? adVM.ssCarCheckScheduleModel!.address // : "",
// : "", // serviceDateError: "",
// serviceTime: adVM.slotSelectedIndex == null || adVM.adSSTimeSlots.isEmpty ? "" : adVM.adSSTimeSlots[adVM.slotSelectedIndex!].slot, // serviceSelectedId: adVM.vehicleAdsSpecialServicesId,
// ), // serviceTimeError: "",
// ); // description: adVM.vehicleAdsSpecialServices.firstWhere((element) => element.id == adVM.vehicleAdsSpecialServicesId.selectedId).description ?? "",
}, // duration: adVM.vehicleAdsSpecialServicesId.selectedId == 1
).paddingOnly(bottom: 10), // ? adVM.ssPhotoScheduleModel!.distanceKM.toString()
), // : adVM.vehicleAdsSpecialServicesId.selectedId == 3
], // ? adVM.ssCarCheckScheduleModel!.distanceKM.toString()
).horPaddingMain(), // : "",
// address: adVM.vehicleAdsSpecialServicesId.selectedId == 1
// ? "${adVM.ssPhotoScheduleModel!.photoOfficeName} - ${adVM.ssPhotoScheduleModel!.areaName}"
// : adVM.vehicleAdsSpecialServicesId.selectedId == 3
// ? adVM.ssCarCheckScheduleModel!.address
// : "",
// serviceTime: adVM.slotSelectedIndex == null || adVM.adSSTimeSlots.isEmpty ? "" : adVM.adSSTimeSlots[adVM.slotSelectedIndex!].slot,
// ),
// );
},
).paddingOnly(bottom: 10),
),
],
).horPaddingMain(),
); );
}, },
); );

@ -37,7 +37,6 @@ class _AdDamagePartPicturesSheetState extends State<AdDamagePartPicturesSheet> {
void populateDamagePartPictures() { void populateDamagePartPictures() {
for (var element in widget.adDamageReportList) { for (var element in widget.adDamageReportList) {
ImageModel imageModel = ImageModel(id: element.id!, filePath: element.imageUrl!, isFromNetwork: true); ImageModel imageModel = ImageModel(id: element.id!, filePath: element.imageUrl!, isFromNetwork: true);
VehicleDamageCard vehicleDamageCard = VehicleDamageCard( VehicleDamageCard vehicleDamageCard = VehicleDamageCard(
partSelectedId: SelectionModel( partSelectedId: SelectionModel(
selectedId: element.vehicleDamagePartID!, selectedId: element.vehicleDamagePartID!,
@ -46,7 +45,16 @@ class _AdDamagePartPicturesSheetState extends State<AdDamagePartPicturesSheet> {
damagePartDescription: element.comment ?? "", damagePartDescription: element.comment ?? "",
partImages: [imageModel], partImages: [imageModel],
); );
vehicleDamageCards.add(vehicleDamageCard);
int index = vehicleDamageCards.indexWhere((card) => card.partSelectedId!.selectedId == element.vehicleDamagePartID!);
if (index == -1) {
vehicleDamageCards.add(vehicleDamageCard);
} else {
if (vehicleDamageCards[index].partImages != null) {
vehicleDamageCards[index].partImages!.add(imageModel);
}
}
} }
setState(() {}); setState(() {});
} }
@ -56,7 +64,6 @@ class _AdDamagePartPicturesSheetState extends State<AdDamagePartPicturesSheet> {
return SizedBox( return SizedBox(
height: MediaQuery.of(context).size.height / 1.2, height: MediaQuery.of(context).size.height / 1.2,
child: ListView.builder( child: ListView.builder(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true, shrinkWrap: true,
itemCount: vehicleDamageCards.length, itemCount: vehicleDamageCards.length,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {

@ -80,7 +80,7 @@ class SelectAdTypeView extends StatelessWidget {
if (adVM.isAdEditEnabled) { if (adVM.isAdEditEnabled) {
adVM.autoFillSelectedVehicleAdsDetails(); adVM.autoFillSelectedVehicleAdsDetails();
} }
if (AppState().currentAppType == AppType.provider && AppState().userType == UserType.providerDealer) { if (AppState().currentAppType == AppType.provider) {
if (isFromExtendAd && !adVM.isAdEditEnabled) { if (isFromExtendAd && !adVM.isAdEditEnabled) {
bool status = await adVM.createAdExtensionOrder(context, adId: adsId, adsDurationId: adVM.vehicleAdDurationId.selectedId); bool status = await adVM.createAdExtensionOrder(context, adId: adsId, adsDurationId: adVM.vehicleAdDurationId.selectedId);
log("hereStatus: $status"); log("hereStatus: $status");

@ -293,11 +293,10 @@ class _AppointmentsFilterViewState extends State<AppointmentsFilterView> {
title: LocaleKeys.search.tr(), title: LocaleKeys.search.tr(),
onPressed: () { onPressed: () {
Navigator.pop(context); Navigator.pop(context);
if (AppState().currentAppType == AppType.provider) { if (AppState().currentAppType == AppType.provider) {
appointmentsVM.getAppointmentsBasedOnFiltersForProviders(branchID: appointmentsVM.selectedBranchIdForAppointments); appointmentsVM.applyFilterOnAppointmentsVMForProviders(appointmentStatusEnum: AppointmentStatusEnum.allAppointments, isNeedCustomerFilter: true);
} else { } else {
appointmentsVM.getAppointmentsBasedOnFiltersForCustomer(); appointmentsVM.applyFilterOnAppointmentsVMForCustomers(appointmentStatusEnum: AppointmentStatusEnum.allAppointments);
} }
}, },
backgroundColor: MyColors.darkPrimaryColor, backgroundColor: MyColors.darkPrimaryColor,

@ -1,3 +1,5 @@
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/classes/app_state.dart';
@ -6,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/appointments_models/service_schedule_model.dart'; import 'package:mc_common_app/models/appointments_models/service_schedule_model.dart';
import 'package:mc_common_app/models/provider_branches_models/provider_contact_info_model.dart';
import 'package:mc_common_app/models/services_models/item_model.dart'; import 'package:mc_common_app/models/services_models/item_model.dart';
import 'package:mc_common_app/models/services_models/service_model.dart'; import 'package:mc_common_app/models/services_models/service_model.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
@ -372,6 +375,7 @@ class ReviewAppointment extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
log("state: ${AppState().getUser.data!.userInfo!.customerId}");
return Scaffold( return Scaffold(
appBar: CustomAppBar( appBar: CustomAppBar(
title: LocaleKeys.reviewAppointment.tr(), title: LocaleKeys.reviewAppointment.tr(),
@ -380,8 +384,12 @@ class ReviewAppointment extends StatelessWidget {
onBackButtonTapped: () => Navigator.pop(context), onBackButtonTapped: () => Navigator.pop(context),
actions: [ actions: [
IconButton( IconButton(
onPressed: () { onPressed: () async {
// Utils.buildProviderContactInfoBottomSheet(context: context, email:, mobileNo:); final appointmentsVM = context.read<AppointmentsVM>();
ProviderContactInfoModel? contact = await appointmentsVM.getProvidersContactInfo(providerId: appointmentsVM.selectedBranchModel!.serviceProviderId ?? 0, context: context);
if (contact != null) {
Utils.buildProviderContactInfoBottomSheet(context: context, email: contact.email, mobileNo: contact.mobile);
}
}, },
icon: const Icon(Icons.help_outline_outlined).paddingOnly(right: 21), icon: const Icon(Icons.help_outline_outlined).paddingOnly(right: 21),
), ),

@ -287,6 +287,7 @@ class _ReviewRequestOfferState extends State<ReviewRequestOffer> {
IconButton( IconButton(
onPressed: () { onPressed: () {
final requestVM = context.read<RequestsVM>(); final requestVM = context.read<RequestsVM>();
Utils.buildProviderContactInfoBottomSheet( Utils.buildProviderContactInfoBottomSheet(
context: context, context: context,
email: requestVM.currentSelectedOffer!.email, email: requestVM.currentSelectedOffer!.email,

@ -5,6 +5,7 @@ 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';
import 'package:mc_common_app/models/setting_utils_models/app_invitation_history_model.dart';
import 'package:mc_common_app/theme/colors.dart'; 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';
@ -25,52 +26,82 @@ class SettingOptionsInviteFriends extends StatelessWidget {
isScrollControlled: true, isScrollControlled: true,
enableDrag: true, enableDrag: true,
builder: (BuildContext context) { builder: (BuildContext context) {
return InfoBottomSheet( return Consumer(
title: LocaleKeys.inviteFriends.tr().toText(fontSize: 28, isBold: true, letterSpacing: -1.44), builder: (BuildContext context, SettingOptionsVM settingsOptionsVM, Widget? child) {
description: Column( List<AppInvitationHistoryModel> list = settingsOptionsVM.appInvitationHistoryList;
crossAxisAlignment: CrossAxisAlignment.start, int whatsAppInvites = 0;
children: [ int smsAppInvites = 0;
CustomSettingOptionsTile( int emailAppInvites = 0;
leadingWidget: MyAssets.whatsAppIcon.buildSvg( for (var invite in list) {
height: 20, switch (invite.appInvitationEnumID) {
width: 20, case 1: // Assume 1 is WhatsApp channel
color: MyColors.greyColor, whatsAppInvites += invite.noOfInvites ?? 0;
), break;
titleText: LocaleKeys.inviteFriendsByWhatsApp.tr(), case 2: // Assume 2 is SMS channel
needBorderBelow: true, smsAppInvites += invite.noOfInvites ?? 0;
showTrailingArrow: false, break;
onTap: () async { case 3: // Assume 3 is Email channel
await context.read<SettingOptionsVM>().appInvitationCreate(context: context, inviteTypeEnum: InviteTypeEnum.whatsapp); emailAppInvites += invite.noOfInvites ?? 0;
}, break;
), default:
CustomSettingOptionsTile( break;
leadingWidget: const Icon( }
Icons.sms_outlined, }
size: 20,
color: MyColors.greyColor, return InfoBottomSheet(
title: LocaleKeys.inviteFriends.tr().toText(fontSize: 28, isBold: true, letterSpacing: -1.44),
description: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CustomSettingOptionsTile(
leadingWidget: MyAssets.whatsAppIcon.buildSvg(
height: 20,
width: 20,
color: MyColors.greyColor,
),
titleText: LocaleKeys.inviteFriendsByWhatsApp.tr(),
subTitle: " ${LocaleKeys.noOfInvites.tr()}: $whatsAppInvites",
subtitleTextColor: MyColors.lightTextColor,
needBorderBelow: true,
showTrailingArrow: false,
onTap: () async {
await settingsOptionsVM.appInvitationCreate(context: context, inviteTypeEnum: InviteTypeEnum.whatsapp);
},
), ),
titleText: LocaleKeys.inviteFriendsBySMS.tr(), CustomSettingOptionsTile(
needBorderBelow: true, leadingWidget: const Icon(
showTrailingArrow: false, Icons.sms_outlined,
onTap: () async { size: 20,
await context.read<SettingOptionsVM>().appInvitationCreate(context: context, inviteTypeEnum: InviteTypeEnum.sms); color: MyColors.greyColor,
}), ),
CustomSettingOptionsTile( titleText: LocaleKeys.inviteFriendsBySMS.tr(),
leadingWidget: const Icon( subTitle: " ${LocaleKeys.noOfInvites.tr()}: $smsAppInvites",
Icons.email_outlined, subtitleTextColor: MyColors.lightTextColor,
size: 20, needBorderBelow: true,
color: MyColors.greyColor, showTrailingArrow: false,
), onTap: () async {
titleText: LocaleKeys.inviteFriendsByEmail.tr(), await settingsOptionsVM.appInvitationCreate(context: context, inviteTypeEnum: InviteTypeEnum.sms);
needBorderBelow: false, }),
showTrailingArrow: false, CustomSettingOptionsTile(
onTap: () async { leadingWidget: const Icon(
await context.read<SettingOptionsVM>().appInvitationCreate(context: context, inviteTypeEnum: InviteTypeEnum.email); Icons.email_outlined,
}, size: 20,
color: MyColors.greyColor,
),
titleText: LocaleKeys.inviteFriendsByEmail.tr(),
subTitle: " ${LocaleKeys.noOfInvites.tr()}: $emailAppInvites",
subtitleTextColor: MyColors.lightTextColor,
needBorderBelow: false,
showTrailingArrow: false,
onTap: () async {
await settingsOptionsVM.appInvitationCreate(context: context, inviteTypeEnum: InviteTypeEnum.email);
},
),
30.height,
],
), ),
30.height, );
], },
),
); );
}, },
); );

@ -12,6 +12,7 @@ import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/dialogs_and_bottomsheets.dart'; import 'package:mc_common_app/utils/dialogs_and_bottomsheets.dart';
import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/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/setting_options_view_model.dart';
import 'package:mc_common_app/view_models/user_view_model.dart'; import 'package:mc_common_app/view_models/user_view_model.dart';
import 'package:mc_common_app/views/setting_options/widgets/custom_setting_options_tile.dart'; import 'package:mc_common_app/views/setting_options/widgets/custom_setting_options_tile.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart'; import 'package:mc_common_app/widgets/button/show_fill_button.dart';
@ -110,11 +111,13 @@ class _SettingOptionsMoreState extends State<SettingOptionsMore> {
), ),
], ],
CustomSettingOptionsTile( CustomSettingOptionsTile(
leadingWidget: const Icon(Icons.settings, size: 20), leadingWidget: const Icon(Icons.settings, size: 20),
titleText: LocaleKeys.settings.tr(), titleText: LocaleKeys.settings.tr(),
needBorderBelow: false, needBorderBelow: false,
onTap: () => navigateWithName(context, AppRoutes.settingOptionsInviteFriends), onTap: () {
), context.read<SettingOptionsVM>().getAppInvitationHistoryList();
navigateWithName(context, AppRoutes.settingOptionsInviteFriends);
}),
], ],
).toWhiteContainer(width: double.infinity, pading: const EdgeInsets.all(12), borderRadius: 0), ).toWhiteContainer(width: double.infinity, pading: const EdgeInsets.all(12), borderRadius: 0),
10.height, 10.height,

@ -184,7 +184,7 @@ class _ShippingManagementViewState extends State<ShippingManagementView> {
text: Utils.getNameByShippingRequestStatusEnum(shippingRequest.shippingStatusEnum ?? ShippingRequestStatusEnum.initiated), text: Utils.getNameByShippingRequestStatusEnum(shippingRequest.shippingStatusEnum ?? ShippingRequestStatusEnum.initiated),
chipColor: Utils.getChipColorByShippingRequestStatusEnum(shippingRequest.shippingStatusEnum ?? ShippingRequestStatusEnum.initiated), chipColor: Utils.getChipColorByShippingRequestStatusEnum(shippingRequest.shippingStatusEnum ?? ShippingRequestStatusEnum.initiated),
), ),
("${shippingRequest.request!.brand} ${shippingRequest.request!.model} | ${shippingRequest.id.toString()}").toText(fontSize: 16), ("${shippingRequest.request!.brand} ${shippingRequest.request!.model} | ${shippingRequest.requestID.toString()}").toText(fontSize: 16),
(shippingRequest.request!.description ?? "").toText(color: MyColors.lightTextColor, fontSize: 12, fontWeight: MyFonts.Medium), (shippingRequest.request!.description ?? "").toText(color: MyColors.lightTextColor, fontSize: 12, fontWeight: MyFonts.Medium),
if (shippingRequest.comment != null && shippingRequest.comment!.isNotEmpty) ...[ if (shippingRequest.comment != null && shippingRequest.comment!.isNotEmpty) ...[
("${LocaleKeys.comment.tr()}: ${shippingRequest.comment ?? ""}").toText(color: MyColors.lightTextColor, fontSize: 12, fontWeight: MyFonts.Medium), ("${LocaleKeys.comment.tr()}: ${shippingRequest.comment ?? ""}").toText(color: MyColors.lightTextColor, fontSize: 12, fontWeight: MyFonts.Medium),

@ -33,27 +33,14 @@ class ProviderDetailCard extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
String nameInitials = "";
if (title.isNotEmpty) {
nameInitials = title[0];
}
return Row( return Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
if (isFromFavoriteList) ...[ providerImageUrl.buildNetworkImage(
CircleAvatar( width: 80,
radius: 22, height: 85,
backgroundColor: MyColors.darkPrimaryColor, fit: BoxFit.cover,
child: nameInitials.toText(fontSize: 25, isBold: true), ),
),
] else ...[
Image.asset(
providerImageUrl,
width: 80,
height: 85,
fit: BoxFit.cover,
),
],
12.width, 12.width,
Expanded( Expanded(
child: Column( child: Column(

@ -33,7 +33,8 @@ class DropdownField extends StatefulWidget {
final TextStyle? textStyle; final TextStyle? textStyle;
final bool isSelectAble; final bool isSelectAble;
const DropdownField(this.onSelect, {super.key, this.hint, this.list, this.dropdownValue, this.errorValue = "", this.showAppointmentPickerVariant = false, this.textStyle, this.isSelectAble = true}); const DropdownField(this.onSelect,
{super.key, this.hint, this.list, this.dropdownValue, this.onTap, this.errorValue = "", this.showAppointmentPickerVariant = false, this.textStyle, this.isSelectAble = true});
@override @override
State<DropdownField> createState() => _DropdownFieldState(); State<DropdownField> createState() => _DropdownFieldState();
@ -51,7 +52,6 @@ class _DropdownFieldState extends State<DropdownField> {
super.initState(); super.initState();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
dropdownValue = widget.dropdownValue; dropdownValue = widget.dropdownValue;
@ -72,7 +72,6 @@ class _DropdownFieldState extends State<DropdownField> {
color: !widget.isSelectAble ? Colors.transparent : null, color: !widget.isSelectAble ? Colors.transparent : null,
size: 21, size: 21,
), ),
elevation: 16, elevation: 16,
iconSize: widget.showAppointmentPickerVariant ? 26 : 16, iconSize: widget.showAppointmentPickerVariant ? 26 : 16,
iconEnabledColor: borderColor, iconEnabledColor: borderColor,
@ -91,7 +90,6 @@ class _DropdownFieldState extends State<DropdownField> {
}); });
}, },
onTap: widget.onTap, onTap: widget.onTap,
items: (widget.list ?? defaultV).map<DropdownMenuItem<DropValue>>( items: (widget.list ?? defaultV).map<DropdownMenuItem<DropValue>>(
(DropValue value) { (DropValue value) {
return DropdownMenuItem<DropValue>( return DropdownMenuItem<DropValue>(

Loading…
Cancel
Save