Compare commits

...

3 Commits

@ -118,6 +118,13 @@ class ApiConsts {
static String assignDealerToBranch = "${baseUrlServices}api/ServiceProviders/BranchUser_Create";
static String removeDealerFromBranch = "${baseUrlServices}api/ServiceProviders/BranchUser_Update";
//Master & Common
static String getEnumTypeValues = "${baseUrlServices}api/Common/GetEnumTypeValues";
//Requests
static String createRequest = "${baseUrlServices}api/RequestManagement/Request_Create";
static String getRequest = "${baseUrlServices}api/RequestManagement/Request_Get";
static List<String> closingUrls = ["PayFortResponse"];
}

@ -11,6 +11,8 @@ import 'package:mc_common_app/repositories/user_repo.dart';
import 'package:mc_common_app/services/common_services.dart';
import 'package:mc_common_app/services/payments_service.dart';
import '../repositories/request_repo.dart';
Injector injector = Injector.appInstance;
class AppDependencies {
@ -26,5 +28,6 @@ class AppDependencies {
injector.registerSingleton<CommonRepo>(() => CommonRepoImp());
injector.registerSingleton<AdsRepo>(() => AdsRepoImp());
injector.registerSingleton<PaymentsRepo>(() => PaymentsRepoImp());
injector.registerSingleton<RequestRepo>(() => RequestRepoImp());
}
}

@ -66,6 +66,11 @@ class AppRoutes {
static const String mySubscriptionsPage = "/mySubscriptionsPage";
static const String subscriptionsPage = "/subscriptionsPage";
//Requests
static const String createRequestPage = "/createRequestPage";
static const String offersListPage = "/offersListPage";
static const String initialRoute = splash;
static final Map<String, WidgetBuilder> routes = {

@ -152,6 +152,28 @@ extension FormatDate on String {
}
}
extension RequestEnum on int {
RequestStatus toRequestStatusEnum() {
if (this == 1) {
return RequestStatus.submitted;
} else if (this == 2) {
return RequestStatus.inProgress;
} else if (this == 3) {
return RequestStatus.completed;
} else if (this == 4) {
return RequestStatus.cancelled;
} else if (this == 5) {
return RequestStatus.paid;
} else if (this == 6) {
return RequestStatus.expired;
} else if (this == 7) {
return RequestStatus.shipping;
} else {
return RequestStatus.pending;
}
}
}
extension AdPostEnum on int {
AdPostStatus toAdPostEnum() {
if (this == 1) {

@ -0,0 +1,31 @@
class Enums {
int id;
int enumTypeId;
String enumValueStr;
int enumValue;
bool isActive;
Enums({
required this.id,
required this.enumTypeId,
required this.enumValueStr,
required this.enumValue,
required this.isActive,
});
factory Enums.fromJson(Map<String, dynamic> json) => Enums(
id: json["id"],
enumTypeId: json["enumTypeID"],
enumValueStr: json["enumValueStr"],
enumValue: json["enumValue"],
isActive: json["isActive"],
);
Map<String, dynamic> toJson() => {
"id": id,
"enumTypeID": enumTypeId,
"enumValueStr": enumValueStr,
"enumValue": enumValue,
"isActive": isActive,
};
}

@ -2,23 +2,29 @@ class GenericRespModel {
GenericRespModel({
this.data,
this.messageStatus,
this.totalItemsCount,
this.totalItemsCount, this.message,
});
dynamic data;
int? messageStatus;
int? totalItemsCount;
String? message;
factory GenericRespModel.fromJson(Map<String, dynamic> json) => GenericRespModel(
factory GenericRespModel.fromJson(Map<String, dynamic> json) =>
GenericRespModel(
data: json["data"],
messageStatus: json["messageStatus"],
totalItemsCount: json["totalItemsCount"],
message: json["message"],
);
Map<String, dynamic> toJson() => {
Map<String, dynamic> toJson() =>
{
"data": data,
"messageStatus": messageStatus,
"totalItemsCount": totalItemsCount,
"message": message,
};
}
@ -136,32 +142,31 @@ class VehiclePosting {
String? phoneNo;
String? whatsAppNo;
VehiclePosting(
{this.id,
this.userID,
this.vehicleType,
this.vehicleModelID,
this.vehicleModelYearID,
this.vehicleColorID,
this.vehicleCategoryID,
this.vehicleConditionID,
this.vehicleMileageID,
this.vehicleTransmissionID,
this.vehicleSellerTypeID,
this.cityID,
this.price,
this.vehicleVIN,
this.vehicleDescription,
this.vehicleTitle,
this.vehicleDescriptionN,
this.isFinanceAvailable,
this.warantyYears,
this.demandAmount,
this.adStatus,
this.phoneNo,
this.whatsAppNo,
this.vehiclePostingImages,
this.vehiclePostingDamageParts});
VehiclePosting({this.id,
this.userID,
this.vehicleType,
this.vehicleModelID,
this.vehicleModelYearID,
this.vehicleColorID,
this.vehicleCategoryID,
this.vehicleConditionID,
this.vehicleMileageID,
this.vehicleTransmissionID,
this.vehicleSellerTypeID,
this.cityID,
this.price,
this.vehicleVIN,
this.vehicleDescription,
this.vehicleTitle,
this.vehicleDescriptionN,
this.isFinanceAvailable,
this.warantyYears,
this.demandAmount,
this.adStatus,
this.phoneNo,
this.whatsAppNo,
this.vehiclePostingImages,
this.vehiclePostingDamageParts});
VehiclePosting.fromJson(Map<String, dynamic> json) {
id = json['id'];

@ -59,6 +59,7 @@ class ServicesData {
dynamic? categoryName;
bool? isSelected;
factory ServicesData.fromJson(Map<String, dynamic> json) =>
ServicesData(
id: json["id"],

@ -0,0 +1,138 @@
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/utils/enums.dart';
class RequestModel {
int requestType;
String requestTypeName;
String requestStatusName;
RequestStatus requestStatus;
String cityName;
String vehicleTypeName;
String countryName;
String customerName;
dynamic serviceProviders;
int offerCount;
int id;
int customerId;
dynamic customer;
String brand;
String model;
int year;
bool isNew;
String description;
List<dynamic> requestImages;
int cityId;
dynamic city;
double price;
int paymentStatus;
int vehicleTypeId;
int countryId;
List<dynamic> requestProviderItem;
bool isActive;
int createdBy;
DateTime createdOn;
dynamic modifiedBy;
dynamic modifiedOn;
RequestModel({
required this.requestType,
required this.requestTypeName,
required this.requestStatusName,
required this.requestStatus,
required this.cityName,
required this.vehicleTypeName,
required this.countryName,
required this.customerName,
required this.serviceProviders,
required this.offerCount,
required this.id,
required this.customerId,
required this.customer,
required this.brand,
required this.model,
required this.year,
required this.isNew,
required this.description,
required this.requestImages,
required this.cityId,
required this.city,
required this.price,
required this.paymentStatus,
required this.vehicleTypeId,
required this.countryId,
required this.requestProviderItem,
required this.isActive,
required this.createdBy,
required this.createdOn,
required this.modifiedBy,
required this.modifiedOn,
});
factory RequestModel.fromJson(Map<String, dynamic> json) => RequestModel(
requestType: json["requestType"],
requestTypeName: json["requestTypeName"],
requestStatusName: json["requestStatusName"],
requestStatus: (json['requestStatus'] as int).toRequestStatusEnum(),
cityName: json["cityName"],
vehicleTypeName: json["vehicleTypeName"],
countryName: json["countryName"],
customerName: json["customerName"],
serviceProviders: json["serviceProviders"],
offerCount: json["offerCount"],
id: json["id"],
customerId: json["customerID"],
customer: json["customer"],
brand: json["brand"],
model: json["model"],
year: json["year"],
isNew: json["isNew"],
description: json["description"],
requestImages: List<dynamic>.from(json["requestImages"].map((x) => x)),
cityId: json["cityID"],
city: json["city"],
price: json["price"],
paymentStatus: json["paymentStatus"],
vehicleTypeId: json["vehicleTypeID"],
countryId: json["countryID"],
requestProviderItem: List<dynamic>.from(json["requestProviderItem"].map((x) => x)),
isActive: json["isActive"],
createdBy: json["createdBy"],
createdOn: DateTime.parse(json["createdOn"]),
modifiedBy: json["modifiedBy"],
modifiedOn: json["modifiedOn"],
);
Map<String, dynamic> toJson() => {
"requestType": requestType,
"requestTypeName": requestTypeName,
"requestStatusName": requestStatusName,
"requestStatus": requestStatus,
"cityName": cityName,
"vehicleTypeName": vehicleTypeName,
"countryName": countryName,
"customerName": customerName,
"serviceProviders": serviceProviders,
"offerCount": offerCount,
"id": id,
"customerID": customerId,
"customer": customer,
"brand": brand,
"model": model,
"year": year,
"isNew": isNew,
"description": description,
"requestImages": List<dynamic>.from(requestImages.map((x) => x)),
"cityID": cityId,
"city": city,
"price": price,
"paymentStatus": paymentStatus,
"vehicleTypeID": vehicleTypeId,
"countryID": countryId,
"requestProviderItem": List<dynamic>.from(requestProviderItem.map((x) => x)),
"isActive": isActive,
"createdBy": createdBy,
"createdOn": createdOn.toIso8601String(),
"modifiedBy": modifiedBy,
"modifiedOn": modifiedOn,
};
}

@ -1,4 +1,3 @@
import 'package:mc_common_app/models/services/item_model.dart';
class ServiceModel {
@ -18,6 +17,8 @@ class ServiceModel {
final int? itemsCount;
List<ItemData>? serviceItems;
bool isExpandedOrSelected;
int providerServiceId;
String providerServiceName;
ServiceModel({
this.serviceProviderServiceId,
@ -36,6 +37,8 @@ class ServiceModel {
this.itemsCount,
this.serviceItems,
required this.isExpandedOrSelected,
required this.providerServiceId,
required this.providerServiceName,
});
factory ServiceModel.fromJson(Map<String, dynamic> json) =>
@ -56,6 +59,8 @@ class ServiceModel {
itemsCount: json["itemsCount"],
serviceItems: json["branchServiceItems"] == null ? [] : List<ItemData>.from(json["branchServiceItems"]!.map((x) => ItemData.fromJson(x))),
isExpandedOrSelected: false,
providerServiceId: 0,
providerServiceName: "",
);
Map<String, dynamic> toJson() =>

@ -10,11 +10,17 @@ import 'package:mc_common_app/models/user/cities.dart';
import 'package:mc_common_app/models/user/country.dart';
import 'package:mc_common_app/models/user/role.dart';
import '../models/advertisment_models/vehicle_details_models.dart';
import '../models/enums.dart';
abstract class CommonRepo {
Future<Country> getAllCountries();
Future<Cities> getAllCites(String countryId);
//TODO: Needs to remove cities method one of them
Future<List<VehicleCityModel>> getVehicleCities({required int countryId});
Future<Role> getRoles();
Future<List<AppointmentListModel>> getMyAppointments();
@ -26,6 +32,13 @@ abstract class CommonRepo {
// Future<List<ProviderCategoryModel>> getProviderServiceCategories();
// Future<List<ProviderServiceModel>> getProviderServices({required int categoryId});
Future<List<VehicleTypeModel>> getVehicleTypes();
//TODO: Needs to remove common methods from AD's repo and delete all repeated methods.
Future<VehicleDetailsModel> getVehicleDetails({int? vehicleTypeId, int? vehicleBrandId});
Future<List<Enums>> getEnumTypeValues({int? enumTypeID, String? enumTypeName});
}
class CommonRepoImp implements CommonRepo {
@ -96,7 +109,69 @@ class CommonRepoImp implements CommonRepo {
SSPhotoScheduleModel ssPhotoScheduleModel = SSPhotoScheduleModel.fromJson(genericRespModel.data[0]);
return ssPhotoScheduleModel;
}
//
@override
Future<List<VehicleTypeModel>> getVehicleTypes() async {
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleTypeGet);
List<VehicleTypeModel> vehicleTypes = List.generate(adsGenericModel.data.length, (index) => VehicleTypeModel.fromJson(adsGenericModel.data[index]));
return vehicleTypes;
}
@override
Future<VehicleDetailsModel> getVehicleDetails({int? vehicleTypeId, int? vehicleBrandId}) async {
var postParams = {
"vehicleType": vehicleTypeId ?? 0,
"isVehicleBrand": "true",
"vehicleBrand": vehicleBrandId ?? 0,
"isVehicleCategory": "true",
"isVehicleColor": "true",
"isVehicleCondition": "true",
"isVehicleMileage": "true",
"isVehicleModel": "true",
"isVehicleModelYear": "true",
"isVehiclePriceRange": "true",
"isVehiclePricingMethod": "true",
"isVehcileSellerType": "true",
"isVehicleTransmission": "true",
"isCountry": "true"
};
String token = appState.getUser.data!.accessToken ?? "";
GenericRespModel adsGenericModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.vehicleDetailsMaster,
postParams,
token: token,
);
VehicleDetailsModel vehicleDetails = VehicleDetailsModel.fromJson(adsGenericModel.data);
return vehicleDetails;
}
@override
Future<List<VehicleCityModel>> getVehicleCities({required int countryId}) async {
var postParams = {
"CountryID": countryId.toString(),
};
GenericRespModel adsGenericModel =
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleCityGet, queryParameters: postParams);
List<VehicleCityModel> vehicleCities = List.generate(adsGenericModel.data.length, (index) => VehicleCityModel.fromJson(adsGenericModel.data[index]));
return vehicleCities;
}
@override
Future<List<Enums>> getEnumTypeValues({int? enumTypeID, String? enumTypeName}) async {
var postParams = {"enumTypeID": (enumTypeID ?? 0).toString(), "enumTypeName": enumTypeName ?? ""};
GenericRespModel enumGenericModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.getEnumTypeValues,
postParams,
token: appState.getUser.data!.accessToken,
);
List<Enums> vehicleCities = List.generate(enumGenericModel.data.length, (index) => Enums.fromJson(enumGenericModel.data[index]));
return vehicleCities;
}
//
// @override
// Future<List<ProviderCategoryModel>> getProviderServiceCategories() async {
// GenericRespModel adsGenericModel = await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.serviceCategoryGet);

@ -0,0 +1,45 @@
import 'package:mc_common_app/api/api_client.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/dependencies.dart';
import 'package:mc_common_app/models/generic_resp_model.dart';
import 'package:mc_common_app/models/requests/request_model.dart';
abstract class RequestRepo {
Future<GenericRespModel> createRequest(Map<String, dynamic> map);
Future<List<RequestModel>> getRequests(Map<String, dynamic> postParams);
}
class RequestRepoImp implements RequestRepo {
ApiClient apiClient = injector.get<ApiClient>();
AppState appState = injector.get<AppState>();
@override
Future<GenericRespModel> createRequest(Map<String, dynamic> postParams) async {
GenericRespModel enumGenericModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.createRequest,
postParams,
token: appState.getUser.data!.accessToken,
);
return enumGenericModel;
}
@override
Future<List<RequestModel>> getRequests(Map<String, dynamic> postParams) async {
GenericRespModel enumGenericModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.getRequest,
postParams,
token: appState.getUser.data!.accessToken,
);
List<RequestModel> requests = List.generate(
enumGenericModel.data.length,
(index) => RequestModel.fromJson(
enumGenericModel.data[index],
),
);
return requests;
}
}

@ -41,6 +41,33 @@ enum AdPostStatus {
reserveCancel,
}
enum RequestStatus {
pending,
submitted,
inProgress,
completed,
cancelled,
paid,
expired,
shipping,
}
//TODO: Needs to remove
// public enum RequestType : int
// {
// Special_Car_Request = 1,
// Service_Request = 2 //SparePart
// }
// public enum OfferStatus : int
// {
// Offer = 1,//SP
// Negotiate = 2,
// Accepted = 3,
// Rejected = 4,
// Cancelled = 5 //SP
// }
enum PaymentMethodsEnum {
mada,
visa,

@ -232,7 +232,8 @@ class AdVM extends BaseVM {
Future<void> getMyReservedAds() async {
isFetchingLists = true;
setState(ViewState.busy);
myReservedAdsRespModel = await adsRepo.getMyReservedAds();
//TODO: BREAKING
// myReservedAdsRespModel = await adsRepo.getMyReservedAds();
isFetchingLists = false;
setState(ViewState.idle);
}

@ -0,0 +1,272 @@
import 'dart:io';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/models/advertisment_models/vehicle_details_models.dart';
import 'package:mc_common_app/models/enums.dart';
import 'package:mc_common_app/models/generic_resp_model.dart';
import 'package:mc_common_app/models/requests/request_model.dart';
import 'package:mc_common_app/models/widgets_models.dart';
import 'package:mc_common_app/repositories/common_repo.dart';
import 'package:mc_common_app/services/common_services.dart';
import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/base_view_model.dart';
import '../repositories/request_repo.dart';
class RequestsVM extends BaseVM {
final CommonAppServices commonServices;
final CommonRepo commonRepo;
final RequestRepo requestRepo;
RequestsVM({required this.commonServices, required this.commonRepo, required this.requestRepo});
List<FilterListModel> requestsFilterOptions = [];
populateRequestsFilterList() {
requestsFilterOptions.clear();
requestsFilterOptions = [
FilterListModel(title: "Cars", isSelected: true, id: 1),
FilterListModel(title: "Spare Parts", isSelected: false, id: 2),
];
notifyListeners();
}
applyFilterOnRequestsVM({required int index}) {
if (requestsFilterOptions.isEmpty) return;
for (var value in requestsFilterOptions) {
value.isSelected = false;
}
requestsFilterOptions[index].isSelected = true;
notifyListeners();
}
List<File> pickedVehicleImages = [];
String vehicleImageError = "";
void removeImageFromList(String filePath) {
int index = pickedVehicleImages.indexWhere((element) => element.path == filePath);
if (index == -1) {
return;
}
pickedVehicleImages.removeAt(index);
notifyListeners();
}
void pickMultipleImages() async {
List<File> Images = await commonServices.pickMultipleImages();
pickedVehicleImages.addAll(Images);
if (pickedVehicleImages.isNotEmpty) vehicleImageError = "";
notifyListeners();
}
bool isFetchingRequestType = false;
bool isFetchingVehicleType = true;
bool isFetchingVehicleDetail = false;
List<Enums> requestTypes = [];
List<VehicleTypeModel> vehicleTypes = [];
VehicleDetailsModel? vehicleDetails;
List<VehicleBrandsModel> vehicleBrands = [];
List<VehicleModel> vehicleModels = [];
List<VehicleYearModel> vehicleModelYears = [];
List<VehicleCountryModel> vehicleCountries = [];
List<VehicleCityModel> vehicleCities = [];
SelectionModel requestTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
getRequestTypes() async {
requestTypeId.selectedId = -1;
isFetchingRequestType = true;
requestTypes = await commonRepo.getEnumTypeValues(enumTypeID: 16); //TODO: 16 is to get Request types
isFetchingRequestType = false;
notifyListeners();
}
void updateSelectionRequestTypeId(SelectionModel id) async {
requestTypeId = id;
getVehicleTypes();
notifyListeners();
}
SelectionModel vehicleTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
Future<void> getVehicleTypes() async {
reset();
isFetchingVehicleType = true;
vehicleTypes = await commonRepo.getVehicleTypes();
isFetchingVehicleType = false;
notifyListeners();
}
reset() {
vehicleTypeId.selectedId = -1;
vehicleBrandId.selectedId = -1;
vehicleModelId.selectedId = -1;
vehicleModelYearId.selectedId = -1;
vehicleCountryId.selectedId = -1;
vehicleCityId.selectedId = -1;
}
void updateSelectionVehicleTypeId(SelectionModel id) async {
vehicleTypeId = id;
getVehicleBrandsByVehicleTypeId();
notifyListeners();
}
Future<void> getVehicleBrandsByVehicleTypeId() async {
// if (vehicleBrandId.selectedId == -1) {
// return;
// }
isFetchingVehicleDetail = true;
notifyListeners();
vehicleDetails = await commonRepo.getVehicleDetails(vehicleTypeId: vehicleTypeId.selectedId);
if (vehicleDetails != null) {
vehicleBrands = vehicleDetails!.vehicleBrands!;
vehicleModels = vehicleDetails!.vehicleModels!;
vehicleModelYears = vehicleDetails!.vehicleModelYears!;
vehicleCountries = vehicleDetails!.vehicleCountries!;
}
isFetchingVehicleDetail = false;
notifyListeners();
}
SelectionModel vehicleBrandId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updateSelectionVehicleBrandId(SelectionModel id) {
vehicleBrandId = id;
vehicleModelId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
vehicleModelYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
notifyListeners();
}
SelectionModel vehicleModelId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updateSelectionVehicleModelId(SelectionModel id) {
vehicleModelId = id;
vehicleModelYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
notifyListeners();
}
SelectionModel vehicleModelYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updateSelectionVehicleModelYearId(SelectionModel id) {
vehicleModelYearId = id;
notifyListeners();
}
bool isShippingDeliveryEnabled = false;
void updateShippingDeliverEnabled(bool v) {
isShippingDeliveryEnabled = v;
notifyListeners();
}
bool isCountryFetching = false;
SelectionModel vehicleCountryId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updateSelectionVehicleCountryId(SelectionModel id) async {
vehicleCountryId = id;
isCountryFetching = true;
notifyListeners();
vehicleCities = await commonRepo.getVehicleCities(countryId: vehicleCountryId.selectedId);
isCountryFetching = false;
notifyListeners();
}
SelectionModel vehicleCityId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updateSelectionVehicleCityId(SelectionModel id) {
vehicleCityId = id;
notifyListeners();
}
//Request Management
String price = "", description = "";
updatePrice(String v) {
price = v;
}
updateDescription(String v) {
description = v;
}
Future<GenericRespModel?> createRequest() async {
if (validate()) {
Map<String, dynamic> m = {
"customerID": AppState().getUser.data!.userInfo!.customerId ?? 0,
"requestType": requestTypeId.selectedId,
"vehicleTypeID": vehicleTypeId.selectedId,
"brand": vehicleBrandId.selectedOption,
"model": vehicleModelId.selectedOption,
"year": vehicleModelYearId.selectedOption,
"isNew": true,
"countryID": vehicleCountryId.selectedId,
"cityID": vehicleCityId.selectedId,
"price": price,
"description": description,
"isSpecialServiceNeeded": false,
"requestImages": []
};
GenericRespModel respModel = await requestRepo.createRequest(m);
return respModel;
} else {
return null;
}
}
bool validate() {
bool isValid = true;
if (requestTypeId.selectedId == -1) {
Utils.showToast("Please select valid Request Type");
isValid = false;
} else if (vehicleTypeId.selectedId == -1) {
Utils.showToast("Please select valid Vehicle Type");
isValid = false;
} else if (vehicleBrandId.selectedId == -1) {
Utils.showToast("Please select valid Brand");
isValid = false;
} else if (vehicleModelId.selectedId == -1) {
Utils.showToast("Please select valid Model");
isValid = false;
} else if (vehicleModelYearId.selectedId == -1) {
Utils.showToast("Please select valid Year");
isValid = false;
} else if (vehicleCountryId.selectedId == -1) {
Utils.showToast("Please select valid Country");
isValid = false;
} else if (vehicleCityId.selectedId == -1) {
Utils.showToast("Please select valid City");
isValid = false;
} else if (price.isEmpty) {
Utils.showToast("Please add valid Price");
isValid = false;
} else if (description.isEmpty) {
Utils.showToast("Please add valid Description");
isValid = false;
}
return isValid;
}
bool isRequestLoading = true;
List<RequestModel> requests = [];
getRequests() async {
isRequestLoading = true;
notifyListeners();
int selectedRequestType;
// Find the FilterListModel with isSelected equal to true
requests = await requestRepo.getRequests(
{
"customerID": AppState().getUser.data!.userInfo!.customerId,
"pageSize": 100,
"pageIndex": 0,
"requestType": requestsFilterOptions.firstWhere((element) => element.isSelected).id,
},
);
isRequestLoading = false;
notifyListeners();
}
}

@ -129,7 +129,14 @@ class DamageParts extends StatelessWidget {
).paddingOnly(right: 10)
],
],
).toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 4));
).toWhiteContainer(
width: double.infinity,
allPading: 12,
margin: const EdgeInsets.symmetric(
horizontal: 21,
vertical: 4,
),
);
},
),
// DottedRectContainer(

@ -0,0 +1,120 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/requests/request_model.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/views/requests/widget/request_status_chip.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
class RequestItem extends StatelessWidget {
RequestModel request;
RequestItem(this.request);
@override
Widget build(BuildContext context) {
return Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
RequestStatusChip(request),
6.height,
"${request.brand} ${request.model}".toText(fontSize: 16, isBold: true),
showItem("Model:", "${request.year}"),
showItem("Customer Name:", "${request.customerName}"),
],
),
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Center(
child: "${request.offerCount}".toText(
color: Colors.white,
isBold: true,
fontSize: 10,
),
).toContainer(
backgroundColor: MyColors.redColor,
borderRadius: 100,
paddingAll: 1,
width: 20,
height: 20,
),
2.height,
request.cityName.toText(
color: MyColors.lightTextColor,
),
"9 Hours Ago".toText(
color: MyColors.lightTextColor,
)
],
)
],
),
showItem("Description: ", request.description),
showItem("Price Range: ", ""),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
request.price.toString().toText(
fontSize: 20,
color: Colors.black,
isBold: true,
),
2.width,
"SAR"
.toText(
color: MyColors.lightTextColor,
fontSize: 10,
)
.paddingOnly(
bottom: 3,
),
],
),
Icon(
Icons.arrow_forward,
color: MyColors.darkIconColor,
size: 18,
),
],
),
],
)
.toContainer(
isShadowEnabled: true,
)
.onPress(() {
navigateWithName(context, AppRoutes.offersListPage);
});
}
Widget showItem(String title, String value) {
return Row(
children: [
title.toText(
color: MyColors.lightTextColor,
),
2.width,
value.toText(
isBold: true,
),
],
);
}
}

@ -0,0 +1,30 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/requests/request_model.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
class RequestStatusChip extends StatelessWidget {
RequestModel request;
RequestStatusChip(this.request, {super.key});
@override
Widget build(BuildContext context) {
return request.requestStatusName
.toText(
fontSize: 8,
color: Colors.white,
)
.toContainer(
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
backgroundColor: request.requestStatus == RequestStatus.pending
? MyColors.adPendingStatusColor
: request.requestStatus == RequestStatus.cancelled
? MyColors.redColor
: MyColors.greenColor,
borderRadius: 100,
);
}
}

@ -2,6 +2,7 @@ import 'dart:async';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
@ -17,6 +18,8 @@ import 'package:mc_common_app/widgets/tab/login_email_tab.dart';
import 'package:mc_common_app/widgets/txt_field.dart';
import 'package:provider/provider.dart';
import '../../utils/enums.dart';
class LoginWithPassword extends StatefulWidget {
const LoginWithPassword({Key? key}) : super(key: key);
@ -28,6 +31,7 @@ class _LoginWithPasswordState extends State<LoginWithPassword> {
int otpType = 1;
ClassType type = ClassType.EMAIL;
//TODO: ONLY FOR DEVELOPMENT PURPOSE
String phoneNum = "966504278213", password = "Fa@1234";
String email = "";
@ -39,7 +43,10 @@ class _LoginWithPasswordState extends State<LoginWithPassword> {
@override
void initState() {
super.initState();
if (AppState().currentAppType == AppType.provider) {
phoneNum = "966580816976";
password = "123@Shf";
}
scheduleMicrotask(() {
userVM = Provider.of(context, listen: false);
getCountryList();
@ -54,7 +61,7 @@ class _LoginWithPasswordState extends State<LoginWithPassword> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(isRemoveBackButton: true, title: ""),
appBar: const CustomAppBar(isRemoveBackButton: true, title: ""),
body: Container(
width: double.infinity,
height: double.infinity,

@ -0,0 +1,101 @@
import 'package:flutter/material.dart';
import 'dart:math' as math;
class DashedRect extends StatelessWidget {
final Color color;
final double strokeWidth;
final double gap;
DashedRect({this.color = Colors.black, this.strokeWidth = 1.0, this.gap = 5.0});
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(strokeWidth / 2),
child: CustomPaint(
painter: DashRectPainter(color: color, strokeWidth: strokeWidth, gap: gap),
),
);
}
}
class DashRectPainter extends CustomPainter {
double strokeWidth;
Color color;
double gap;
DashRectPainter({this.strokeWidth = 5.0, this.color = Colors.red, this.gap = 5.0});
@override
void paint(Canvas canvas, Size size) {
Paint dashedPaint = Paint()
..color = color
..strokeWidth = strokeWidth
..style = PaintingStyle.stroke;
double x = size.width;
double y = size.height;
Path _topPath = getDashedPath(
a: math.Point(0, 0),
b: math.Point(x, 0),
gap: gap,
);
Path _rightPath = getDashedPath(
a: math.Point(x, 0),
b: math.Point(x, y),
gap: gap,
);
Path _bottomPath = getDashedPath(
a: math.Point(0, y),
b: math.Point(x, y),
gap: gap,
);
Path _leftPath = getDashedPath(
a: math.Point(0, 0),
b: math.Point(0.001, y),
gap: gap,
);
canvas.drawPath(_topPath, dashedPaint);
canvas.drawPath(_rightPath, dashedPaint);
canvas.drawPath(_bottomPath, dashedPaint);
canvas.drawPath(_leftPath, dashedPaint);
}
Path getDashedPath({
required math.Point<double> a,
required math.Point<double> b,
required gap,
}) {
Size size = Size(b.x - a.x, b.y - a.y);
Path path = Path();
path.moveTo(a.x, a.y);
bool shouldDraw = true;
math.Point currentPoint = math.Point(a.x, a.y);
num radians = math.atan(size.height / size.width);
num dx = math.cos(radians) * gap < 0 ? math.cos(radians) * gap * -1 : math.cos(radians) * gap;
num dy = math.sin(radians) * gap < 0 ? math.sin(radians) * gap * -1 : math.sin(radians) * gap;
while (currentPoint.x <= b.x && currentPoint.y <= b.y) {
shouldDraw ? path.lineTo(currentPoint.x.toDouble(), currentPoint.y.toDouble()) : path.moveTo(currentPoint.x.toDouble(), currentPoint.y.toDouble());
shouldDraw = !shouldDraw;
currentPoint = math.Point(
currentPoint.x + dx,
currentPoint.y + dy,
);
}
return path;
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}

@ -43,11 +43,12 @@ class _DropdownFieldState extends State<DropdownField> {
@override
void initState() {
super.initState();
dropdownValue = widget.dropdownValue;
}
@override
Widget build(BuildContext context) {
dropdownValue = widget.dropdownValue;
return Column(
children: [
Container(

Loading…
Cancel
Save