Ad Module Commit

pull/3/head
Faiz Hashmi 2 years ago
parent d93947152a
commit a841c232de

@ -93,6 +93,7 @@ class ApiConsts {
static String vehicleAdsSpecialServicesGet = "${baseUrlServices}api/Common/SpecialService_Get";
static String vehicleAdsSingleStepCreate = "${baseUrlServices}api/Advertisement/AdsSingleStep_Create";
static String vehicleAdsGet = "${baseUrlServices}api/Advertisement/Ads_Get";
static String myAdsReserveGet = "${baseUrlServices}api/Advertisement/AdsReserve_Get";
static String adsCarCheckupSPBranchScheduleSlotGet = "${baseUrlServices}api/Advertisement/AdsCarCheckupSPBranchScheduleSlot_Get";
static String adsPhotoOfficeAppointmentScheduleSlotGet = "${baseUrlServices}api/Advertisement/PhotoOfficeAppointmentScheduleSlot_Get";

@ -182,6 +182,63 @@ extension AdPostEnum on int {
}
}
extension AdPostStatusToInt on AdPostStatus {
int getIdFromAdPostStatusEnum() {
switch (this) {
case AdPostStatus.pendingForReview:
return 1;
case AdPostStatus.pendingForPayment:
return 2;
case AdPostStatus.rejected:
return 3;
case AdPostStatus.cancelled:
return 4;
case AdPostStatus.pendingForPost:
return 5;
case AdPostStatus.active:
return 6;
case AdPostStatus.expired:
return 7;
case AdPostStatus.sold:
return 8;
case AdPostStatus.reserved:
return 9;
case AdPostStatus.buyingService:
return 10;
case AdPostStatus.reserveCancel:
return 11;
default:
return -1;
}
}
}
extension CreatedByRoleEnumToInt on CreatedByRoleEnum {
int getIdFromCreatedByRoleEnum() {
switch (this) {
case CreatedByRoleEnum.admin:
return 1;
case CreatedByRoleEnum.customer:
return 2;
case CreatedByRoleEnum.provider:
return 3;
case CreatedByRoleEnum.allAds:
return -1;
default:
return 1;
}
}
}
extension AdReserveStatusEnum on int {
AdReserveStatus toAdRserveStatusEnum() {
if (this == 0) {
@ -199,15 +256,17 @@ extension AdReserveStatusEnum on int {
}
extension AdOwnerEnum on int {
AdOwner toAdOwnerEnum() {
if (this == 0) {
return AdOwner.customer;
CreatedByRoleEnum toCreatedByRoleEnum() {
if (this == -1) {
return CreatedByRoleEnum.allAds;
} else if (this == 1) {
return AdOwner.provider;
return CreatedByRoleEnum.admin;
} else if (this == 2) {
return AdOwner.mowater;
return CreatedByRoleEnum.customer;
} else if (this == 3) {
return CreatedByRoleEnum.provider;
}
return AdOwner.customer;
return CreatedByRoleEnum.customer;
}
}

@ -1,3 +1,5 @@
import 'dart:math';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/advertisment_models/special_service_model.dart';
import 'package:mc_common_app/utils/enums.dart';
@ -38,7 +40,9 @@ class AdDetailsModel {
AdPostStatus? adPostStatus;
AdReserveStatus? adReserveStatus;
bool? isMyAd;
AdOwner? adOwnerEnum;
String? phoneNo;
String? whatsAppNo;
CreatedByRoleEnum? createdByRoleEnum;
AdDetailsModel(
{this.id,
@ -74,9 +78,17 @@ class AdDetailsModel {
this.adPostStatus,
this.adReserveStatus,
this.isMyAd,
this.adOwnerEnum,
this.phoneNo,
this.whatsAppNo,
this.createdByRoleEnum,
this.modifiedOn});
int getRandomValue({required int min, required int max}) {
Random random = Random();
int randomNumber = random.nextInt(max - min);
return randomNumber;
}
AdDetailsModel.fromJson(Map<String, dynamic> json, bool isMyAds) {
id = json['id'];
startdate = json['startdate'];
@ -88,12 +100,6 @@ class AdDetailsModel {
specialservice!.add(SpecialServiceModel.fromJson(v));
});
}
// if (json['reserved'] != null) {
// reserved = <Null>[];
// json['reserved'].forEach((v) {
// reserved!.add(Null.fromJson(v));
// });
// }
statusID = json['statusID'];
statuslabel = json['statuslabel'];
adsDurationPrice = json['adsDurationPrice'];
@ -119,11 +125,13 @@ class AdDetailsModel {
reservePrice = json['reservePrice'];
isMCHandled = json['isMCHandled'];
modifiedOn = json['modifiedOn'];
whatsAppNo = json['phoneNo'];
modifiedOn = json['whatsAppNo'];
adPostStatus = (json['statusID'] as int).toAdPostEnum();
//TODO: THIS ID SHOULD BE UPDATED!
adReserveStatus = AdReserveStatus.defaultStatus;
// adReserveStatus = (json['adReserveStatusID'] as int).toAdRserveStatusEnum();
adOwnerEnum = (json['statusID'] as int).toAdOwnerEnum();
createdByRoleEnum = CreatedByRoleEnum.admin;
// createdByRoleEnum = (json['createdByRole'] as int).toCreatedByRoleEnum();
isMyAd = isMyAds;
}

@ -0,0 +1,36 @@
class MyReservedAdsRespModel {
int? id;
int? adsID;
int? customerID;
int? paymentStatus;
int? reservationTimeID;
double? reservationBasePrice;
double? refundAmount;
String? refundDate;
MyReservedAdsRespModel({this.id, this.adsID, this.customerID, this.paymentStatus, this.reservationTimeID, this.reservationBasePrice, this.refundAmount, this.refundDate});
MyReservedAdsRespModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
adsID = json['adsID'];
customerID = json['customerID'];
paymentStatus = json['paymentStatus'];
reservationTimeID = json['reservationTimeID'];
reservationBasePrice = json['reservationBasePrice'];
refundAmount = json['refundAmount'];
refundDate = json['refundDate'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['adsID'] = adsID;
data['customerID'] = customerID;
data['paymentStatus'] = paymentStatus;
data['reservationTimeID'] = reservationTimeID;
data['reservationBasePrice'] = reservationBasePrice;
data['refundAmount'] = refundAmount;
data['refundDate'] = refundDate;
return data;
}
}

@ -23,16 +23,7 @@ class GenericRespModel {
}
var json = {
"ads": {
"id": 0,
"adsDurationID": 1,
"startDate": "2023-04-12T10:10:20.905Z",
"countryId": 1,
"specialServiceIDs": [
],
"isMCHandled": false
},
"ads": {"id": 0, "adsDurationID": 1, "startDate": "2023-04-12T10:10:20.905Z", "countryId": 1, "specialServiceIDs": [], "isMCHandled": false},
"vehiclePosting": {
"id": 0,
"userID": "1A1597B3-D5A0-433A-098B-08DB189E51EC",
@ -56,24 +47,10 @@ var json = {
"demandAmount": 34,
"adStatus": 1,
"vehiclePostingImages": [
{
"id": 0,
"imageName": "onon",
"imageUrl": "string",
"imageStr": null,
"vehiclePostingID": 0,
"vehiclePosting": null
}
{"id": 0, "imageName": "onon", "imageUrl": "string", "imageStr": null, "vehiclePostingID": 0, "vehiclePosting": null}
],
"vehiclePostingDamageParts": [
{
"id": 0,
"comment": "hhsa",
"vehicleImageBase64": null,
"vehicleDamagePartID": 1,
"vehiclePostingID": 0,
"isActive": true
}
{"id": 0, "comment": "hhsa", "vehicleImageBase64": null, "vehicleDamagePartID": 1, "vehiclePostingID": 0, "isActive": true}
]
}
};
@ -86,9 +63,7 @@ class AdsCreationPayloadModel {
AdsCreationPayloadModel.fromJson(Map<String, dynamic> json) {
ads = json['ads'] != null ? Ads.fromJson(json['ads']) : null;
vehiclePosting = json['vehiclePosting'] != null
? VehiclePosting.fromJson(json['vehiclePosting'])
: null;
vehiclePosting = json['vehiclePosting'] != null ? VehiclePosting.fromJson(json['vehiclePosting']) : null;
}
Map<String, dynamic> toJson() {
@ -111,13 +86,7 @@ class Ads {
List<int>? specialServiceIDs;
bool? isMCHandled;
Ads(
{this.id,
this.adsDurationID,
this.startDate,
this.countryId,
this.specialServiceIDs,
this.isMCHandled});
Ads({this.id, this.adsDurationID, this.startDate, this.countryId, this.specialServiceIDs, this.isMCHandled});
Ads.fromJson(Map<String, dynamic> json) {
id = json['id'];
@ -164,31 +133,35 @@ class VehiclePosting {
int? adStatus;
List<VehiclePostingImages>? vehiclePostingImages;
List<VehiclePostingDamageParts>? vehiclePostingDamageParts;
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.vehiclePostingImages,
this.vehiclePostingDamageParts});
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'];
@ -212,6 +185,8 @@ class VehiclePosting {
warantyYears = json['warantyYears'];
demandAmount = json['demandAmount'];
adStatus = json['adStatus'];
phoneNo = json['phoneNo'];
whatsAppNo = json['whatsAppNo'];
if (json['vehiclePostingImages'] != null) {
vehiclePostingImages = <VehiclePostingImages>[];
json['vehiclePostingImages'].forEach((v) {
@ -221,8 +196,7 @@ class VehiclePosting {
if (json['vehiclePostingDamageParts'] != null) {
vehiclePostingDamageParts = <VehiclePostingDamageParts>[];
json['vehiclePostingDamageParts'].forEach((v) {
vehiclePostingDamageParts!
.add(VehiclePostingDamageParts.fromJson(v));
vehiclePostingDamageParts!.add(VehiclePostingDamageParts.fromJson(v));
});
}
}
@ -250,16 +224,21 @@ class VehiclePosting {
data['warantyYears'] = warantyYears;
data['demandAmount'] = demandAmount;
data['adStatus'] = adStatus;
data['phoneNo'] = phoneNo;
data['whatsAppNo'] = whatsAppNo;
if (vehiclePostingImages != null) {
data['vehiclePostingImages'] =
vehiclePostingImages!.map((v) => v.toJson()).toList();
data['vehiclePostingImages'] = vehiclePostingImages!.map((v) => v.toJson()).toList();
}
if (vehiclePostingDamageParts != null) {
data['vehiclePostingDamageParts'] =
vehiclePostingDamageParts!.map((v) => v.toJson()).toList();
data['vehiclePostingDamageParts'] = vehiclePostingDamageParts!.map((v) => v.toJson()).toList();
}
return data;
}
@override
String toString() {
return 'VehiclePosting{id: $id, userID: $userID, vehicleType: $vehicleType, vehicleModelID: $vehicleModelID, vehicleModelYearID: $vehicleModelYearID, vehicleColorID: $vehicleColorID, vehicleCategoryID: $vehicleCategoryID, vehicleConditionID: $vehicleConditionID, vehicleMileageID: $vehicleMileageID, vehicleTransmissionID: $vehicleTransmissionID, vehicleSellerTypeID: $vehicleSellerTypeID, cityID: $cityID, price: $price, vehicleVIN: $vehicleVIN, vehicleDescription: $vehicleDescription, vehicleTitle: $vehicleTitle, vehicleDescriptionN: $vehicleDescriptionN, isFinanceAvailable: $isFinanceAvailable, warantyYears: $warantyYears, demandAmount: $demandAmount, adStatus: $adStatus, vehiclePostingImages: $vehiclePostingImages, vehiclePostingDamageParts: $vehiclePostingDamageParts, phoneNo: $phoneNo, whatsAppNo: $whatsAppNo}';
}
}
class VehiclePostingImages {
@ -270,13 +249,7 @@ class VehiclePostingImages {
int? vehiclePostingID;
String? vehiclePosting;
VehiclePostingImages(
{this.id,
this.imageName,
this.imageUrl,
this.imageStr,
this.vehiclePostingID,
this.vehiclePosting});
VehiclePostingImages({this.id, this.imageName, this.imageUrl, this.imageStr, this.vehiclePostingID, this.vehiclePosting});
VehiclePostingImages.fromJson(Map<String, dynamic> json) {
id = json['id'];
@ -307,13 +280,7 @@ class VehiclePostingDamageParts {
int? vehiclePostingID;
bool? isActive;
VehiclePostingDamageParts(
{this.id,
this.comment,
this.vehicleImageBase64,
this.vehicleDamagePartID,
this.vehiclePostingID,
this.isActive});
VehiclePostingDamageParts({this.id, this.comment, this.vehicleImageBase64, this.vehicleDamagePartID, this.vehiclePostingID, this.isActive});
VehiclePostingDamageParts.fromJson(Map<String, dynamic> json) {
id = json['id'];

@ -30,6 +30,11 @@ class PayOrderDetailRespModel {
this.serviceAppointmentID,
this.providerSubscriptionID});
@override
String toString() {
return 'PayOrderDetailRespModel{id: $id, userFullName: $userFullName, userMobile: $userMobile, userEmail: $userEmail, userID: $userID, amount: $amount, currency: $currency, payFortProjectID: $payFortProjectID, payFortServiceID: $payFortServiceID, description: $description, isPaid: $isPaid, language: $language, serviceAppointmentID: $serviceAppointmentID, providerSubscriptionID: $providerSubscriptionID}';
}
PayOrderDetailRespModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
userFullName = json['userFullName'];

@ -4,11 +4,14 @@ 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/extensions/string_extensions.dart';
import 'package:mc_common_app/models/advertisment_models/ad_details_model.dart';
import 'package:mc_common_app/models/advertisment_models/ads_duration_model.dart';
import 'package:mc_common_app/models/advertisment_models/reserved_ads_models.dart';
import 'package:mc_common_app/models/advertisment_models/special_service_model.dart';
import 'package:mc_common_app/models/advertisment_models/vehicle_details_models.dart';
import 'package:mc_common_app/models/generic_resp_model.dart';
import 'package:mc_common_app/utils/enums.dart';
abstract class AdsRepo {
Future<List<VehicleTypeModel>> getVehicleTypes();
@ -47,6 +50,8 @@ abstract class AdsRepo {
Future<List<AdDetailsModel>> getAllAds({required bool isMyAds});
Future<List<MyReservedAdsRespModel>> getMyReservedAds();
Future<List<AdDetailsModel>> getMyAds();
}
@ -315,27 +320,46 @@ class AdsRepoImp implements AdsRepo {
postParams,
token: token,
);
log("value: ${adsGenericModel}");
return Future.value(adsGenericModel);
}
@override
Future<List<AdDetailsModel>> getAllAds({required isMyAds}) async {
var params = {
var onlyMyAdsParams = {
"userID": appState.getUser.data!.userInfo!.userId ?? "",
};
var allAdsParams = {
"AdsStatuses": ["${AdPostStatus.active.getIdFromAdPostStatusEnum()}"], //only Active ADS
"IsPaid": "true", //only Active ADS
};
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
token: appState.getUser.data!.accessToken,
(json) => GenericRespModel.fromJson(json),
ApiConsts.vehicleAdsGet,
queryParameters: isMyAds ? params : null,
queryParameters: isMyAds ? onlyMyAdsParams : allAdsParams,
);
List<AdDetailsModel> vehicleAdsDetails = List.generate(adsGenericModel.data.length, (index) => AdDetailsModel.fromJson(adsGenericModel.data[index], isMyAds));
return vehicleAdsDetails;
}
@override
Future<List<MyReservedAdsRespModel>> getMyReservedAds() async {
var params = {
"userID": appState.getUser.data!.userInfo!.userId ?? "",
};
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
token: appState.getUser.data!.accessToken,
(json) => GenericRespModel.fromJson(json),
ApiConsts.myAdsReserveGet,
queryParameters: params,
);
List<MyReservedAdsRespModel> vehicleAdsDetails = List.generate(adsGenericModel.data.length, (index) => MyReservedAdsRespModel.fromJson(adsGenericModel.data[index]));
return vehicleAdsDetails;
}
@override
Future<List<AdDetailsModel>> getMyAds() async {
var params = {

@ -50,10 +50,11 @@ class PaymentServiceImp implements PaymentService {
required Function() onSuccess,
required Function() onFailure,
}) async {
print("PaymentUrl: ${ApiConsts.paymentWebViewUrl}?PaymentType=$paymentType&AdsID=$id");
myInAppBrowser = MyInAppBrowser(onExitCallback: () {
log("Browser Exited");
}, onLoadStartCallback: (String url) {
log("Browser LoadStart");
log("Browser LoadStart for : $url");
onBrowserLoadStart(onFailure: onFailure, onSuccess: onSuccess, url: url);
});
await myInAppBrowser!.openUrlRequest(

@ -19,11 +19,7 @@ enum AdReserveStatus {
cancelledByAdmin,
}
enum AdOwner {
customer,
provider,
mowater,
}
enum CreatedByRoleEnum { customer, provider, admin, allAds }
enum AdPostStatus {
pendingForReview,

@ -23,13 +23,7 @@ class Utils {
static void showToast(String message) {
Fluttertoast.showToast(
msg: message,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 2,
backgroundColor: Colors.black54,
textColor: Colors.white,
fontSize: 16.0);
msg: message, toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.BOTTOM, timeInSecForIosWeb: 2, backgroundColor: Colors.black54, textColor: Colors.white, fontSize: 16.0);
}
static Future<String> pickDateFromDatePicker(BuildContext context, {DateTime? firstDate, DateTime? lastDate}) async {
@ -54,11 +48,7 @@ class Utils {
return "";
}
return ("${timeOfDay.hour
.toString()
.length == 1 ? "0" : ""}${timeOfDay.hour}:${timeOfDay.minute
.toString()
.length == 1 ? "0" : ""}${timeOfDay.minute}").toString();
return ("${timeOfDay.hour.toString().length == 1 ? "0" : ""}${timeOfDay.hour}:${timeOfDay.minute.toString().length == 1 ? "0" : ""}${timeOfDay.minute}").toString();
}
static dynamic getNotNullValue(List<dynamic> list, int index) {
@ -214,7 +204,6 @@ class Utils {
}
}
static statusContainerChip({required String text, EdgeInsetsGeometry padding = const EdgeInsets.symmetric(vertical: 3, horizontal: 6), Color chipColor = MyColors.greenColor}) {
return Container(
decoration: BoxDecoration(
@ -358,7 +347,7 @@ class Utils {
border: Border.all(
width: w, //
color: color // <--- border width here
),
),
borderRadius: BorderRadius.circular(radius),
);
}
@ -381,7 +370,7 @@ class Utils {
border: Border.all(
width: 1, //
color: color // <--- border width here
),
),
borderRadius: BorderRadius.circular(radius),
);
}

@ -9,6 +9,7 @@ import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/advertisment_models/ad_details_model.dart';
import 'package:mc_common_app/models/advertisment_models/ads_duration_model.dart';
import 'package:mc_common_app/models/advertisment_models/reserved_ads_models.dart';
import 'package:mc_common_app/models/advertisment_models/special_service_model.dart';
import 'package:mc_common_app/models/advertisment_models/ss_car_check_schedule_model.dart';
import 'package:mc_common_app/models/advertisment_models/ss_photo_schedule_model.dart';
@ -71,6 +72,7 @@ class AdVM extends BaseVM {
List<AdDetailsModel> exploreAdsFilteredList = [];
List<AdDetailsModel> myAdsFilteredList = [];
List<AdDetailsModel> myAds = [];
List<MyReservedAdsRespModel> myReservedAdsRespModel = [];
List<AdDetailsModel> myActiveAdsForHome = [];
List<VehicleDamageCard> vehicleDamageCards = [];
@ -140,9 +142,10 @@ class AdVM extends BaseVM {
isExploreAdsTapped = value;
//To show the Active Ads
applyFilterOnMyAds(index: 0, selectedFilterId: 6);
applyFilterOnMyAds(index: 0, adPostStatusEnum: AdPostStatus.active);
applyFilterOnExploreAds(index: 0, createdByRoleFilter: CreatedByRoleEnum.allAds);
// if (value) {
// await getAllAds();
// await getExploreAds();
// }
notifyListeners();
}
@ -151,13 +154,12 @@ class AdVM extends BaseVM {
List<FilterListModel> myAdsFilterOptions = [];
populateAdsFilterList() {
exploreAdsFilterOptions.clear();
exploreAdsFilterOptions.clear();
exploreAdsFilterOptions = [
FilterListModel(title: "All Ads", isSelected: true, id: -1),
FilterListModel(title: "Customer Ads", isSelected: false, id: 0),
FilterListModel(title: "Provider Ads", isSelected: false, id: 1),
FilterListModel(title: "Mowater Ads", isSelected: false, id: 2),
FilterListModel(title: "Mowater Ads", isSelected: false, id: 1),
FilterListModel(title: "Customer Ads", isSelected: false, id: 2),
FilterListModel(title: "Provider Ads", isSelected: false, id: 3),
];
myAdsFilterOptions = [
@ -172,7 +174,7 @@ class AdVM extends BaseVM {
notifyListeners();
}
applyFilterOnExploreAds({required int index}) {
applyFilterOnExploreAds({required int index, required CreatedByRoleEnum createdByRoleFilter}) {
if (exploreAdsFilterOptions.isEmpty) return;
for (var value in exploreAdsFilterOptions) {
value.isSelected = false;
@ -180,25 +182,39 @@ class AdVM extends BaseVM {
exploreAdsFilterOptions[index].isSelected = true;
// TODO: --> here we will filter the allAds list
// TODO: --> and get the updated list into this new list everytime filter changes
if (createdByRoleFilter == CreatedByRoleEnum.allAds) {
exploreAdsFilteredList = exploreAds;
notifyListeners();
return;
}
exploreAdsFilteredList = exploreAds.where((element) => element.createdByRoleEnum == createdByRoleFilter).toList();
exploreAdsFilteredList = exploreAds;
notifyListeners();
}
applyFilterOnMyAds({required int index, required int selectedFilterId}) {
applyFilterOnMyAds({required int index, required AdPostStatus adPostStatusEnum}) {
if (myAdsFilterOptions.isEmpty) return;
for (var value in myAdsFilterOptions) {
value.isSelected = false;
}
myAdsFilterOptions[index].isSelected = true;
if (selectedFilterId == -1) {
if (adPostStatusEnum.getIdFromAdPostStatusEnum() == -1) {
myAdsFilteredList = myAds;
notifyListeners();
return;
}
// this means if the filter is reserved ads
dynamic selectedIds = [];
if (index == 3 && adPostStatusEnum.getIdFromAdPostStatusEnum() == 9) {
selectedIds = myReservedAdsRespModel.map((component) => component.adsID).toList();
myAdsFilteredList = myAds.where((element) => selectedIds.contains(element.id)).toList();
notifyListeners();
return;
}
myAdsFilteredList = myAds.where((element) => element.statusID! == selectedFilterId).toList();
myAdsFilteredList = myAds.where((element) => element.statusID! == adPostStatusEnum.getIdFromAdPostStatusEnum()).toList();
notifyListeners();
}
@ -208,15 +224,23 @@ class AdVM extends BaseVM {
myAds = await adsRepo.getAllAds(isMyAds: true);
final myActiveAds = myAds.where((element) => element.adPostStatus == AdPostStatus.active).toList();
myActiveAdsForHome = myActiveAds.length >= 3 ? myActiveAds.take(3).toList() : myActiveAds;
await getMyReservedAds();
isFetchingLists = true;
setState(ViewState.idle);
}
Future<void> getMyReservedAds() async {
isFetchingLists = true;
setState(ViewState.busy);
myReservedAdsRespModel = await adsRepo.getMyReservedAds();
isFetchingLists = false;
setState(ViewState.idle);
}
Future<void> getExploreAds() async {
setState(ViewState.busy);
exploreAds = await adsRepo.getAllAds(isMyAds: false);
myAdsFilteredList = exploreAds;
exploreAdsFilteredList = exploreAds;
setState(ViewState.idle);
}
@ -844,7 +868,7 @@ class AdVM extends BaseVM {
currentProgressStep = AdCreationStepsEnum.vehicleDetails;
resetValues();
updateIsExploreAds(false);
applyFilterOnMyAds(index: 1, selectedFilterId: 1);
applyFilterOnMyAds(index: 1, adPostStatusEnum: AdPostStatus.pendingForReview); //pending for review
navigateReplaceWithName(context, AppRoutes.dashboard);
} catch (e) {
Utils.hideLoading(context);
@ -1044,6 +1068,8 @@ class AdVM extends BaseVM {
demandAmount: int.parse(vehicleDemandAmount),
vehiclePostingImages: vehicleImages,
vehiclePostingDamageParts: vehicleDamageImages,
phoneNo: isPhoneNumberShown ? adPhoneNumberDialCode + adPhoneNumber : null,
whatsAppNo: (isPhoneNumberShown && isNumberOnWhatsApp) ? adPhoneNumberDialCode + adPhoneNumber : null,
);
AdsCreationPayloadModel adsCreationPayloadModel = AdsCreationPayloadModel(ads: ads, vehiclePosting: vehiclePosting);

@ -27,13 +27,13 @@ class PaymentVM extends ChangeNotifier {
notifyListeners();
}
Future<void> onContinuePressed(BuildContext context) async {
Future<void> onContinuePressed(BuildContext context, {required PaymentTypesEnum paymentType}) async {
switch (selectedPaymentMethod) {
case PaymentMethodsEnum.mada:
// TODO: Handle this case.
break;
case PaymentMethodsEnum.visa:
await onVisaCardSelected(context);
await onVisaCardSelected(context, paymentType);
break;
case PaymentMethodsEnum.applePay:
// TODO: Handle this case.
@ -49,7 +49,8 @@ class PaymentVM extends ChangeNotifier {
return;
}
Future<void> onVisaCardSelected(BuildContext context) async {
Future<void> onVisaCardSelected(BuildContext context, PaymentTypesEnum paymentType) async {
currentPaymentType = paymentType;
switch (currentPaymentType) {
case PaymentTypesEnum.subscription:
// TODO: Handle this case.
@ -68,10 +69,12 @@ class PaymentVM extends ChangeNotifier {
},
onSuccess: () async {
Utils.showLoading(context);
PayOrderDetailRespModel payOrderDetailRespModel = await paymentRepo.getPayOrderDetails(paymentId: paymentType, adId: 3);
await Future.delayed(Duration(seconds: 2));
PayOrderDetailRespModel payOrderDetailRespModel = await paymentRepo.getPayOrderDetails(paymentId: paymentType, adId: currentAdId);
await Future.delayed(const Duration(seconds: 2));
Utils.hideLoading(context);
print("payOrderDetailRespModel: ${payOrderDetailRespModel.toString()}");
if (payOrderDetailRespModel.isPaid == null || !payOrderDetailRespModel.isPaid!) {
Utils.showToast("Payment Failed!");
return;
@ -85,7 +88,33 @@ class PaymentVM extends ChangeNotifier {
);
break;
case PaymentTypesEnum.adReserve:
// TODO: Handle this case.
if (currentAdId == -1) return;
int paymentType = 4;
await paymentService.placeAdPayment(
id: currentAdId,
paymentType: paymentType,
onFailure: () {
Utils.showToast("Payment Failed!");
},
onSuccess: () async {
Utils.showLoading(context);
PayOrderDetailRespModel payOrderDetailRespModel = await paymentRepo.getPayOrderDetails(paymentId: paymentType, adId: currentAdId);
await Future.delayed(const Duration(seconds: 2));
Utils.hideLoading(context);
print("payOrderDetailRespModel: ${payOrderDetailRespModel.toString()}");
if (payOrderDetailRespModel.isPaid == null || !payOrderDetailRespModel.isPaid!) {
Utils.showToast("Payment Failed!");
return;
}
if (payOrderDetailRespModel.isPaid != null && payOrderDetailRespModel.isPaid!) {
Utils.showToast("Payment Successfully Completed!");
navigateReplaceWithNameUntilRoute(context, AppRoutes.dashboard);
}
},
);
break;
case PaymentTypesEnum.request:
// TODO: Handle this case.

@ -22,17 +22,16 @@ class AdsDetailView extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("adId: ${adDetails.isMyAd}");
print("adId: ${adDetails.id}");
print("statusID: ${adDetails.adPostStatus}");
return Scaffold(
appBar: CustomAppBar(
title: "Ads",
profileImageUrl: MyAssets.bnCar,
isRemoveBackButton: false,
isDrawerEnabled: false,
actions: [Icon(Icons.chat_outlined).paddingOnly(right: 21)],
onTap: () {
print("heyyyy");
},
actions: [const Icon(Icons.chat_outlined).paddingOnly(right: 21)],
onTap: () {},
),
body: Container(
padding: const EdgeInsets.only(bottom: 10, left: 21, right: 21),
@ -116,9 +115,7 @@ class AdsDetailView extends StatelessWidget {
],
),
14.height,
adDetails.isMyAd ?? false
? BuildAdDetailsActionButtonForMyAds(adPostStatus: adDetails.adPostStatus!, adId: adDetails.id!)
: BuildAdDetailsActionButtonForExploreAds(adPostStatus: adDetails.adPostStatus!, adId: adDetails.id!),
adDetails.isMyAd ?? false ? BuildAdDetailsActionButtonForMyAds(adDetailsModel: adDetails) : BuildAdDetailsActionButtonForExploreAds(adDetailsModel: adDetails),
],
),
)
@ -130,73 +127,159 @@ class AdsDetailView extends StatelessWidget {
}
class BuildAdDetailsActionButtonForExploreAds extends StatelessWidget {
final AdPostStatus adPostStatus;
final int adId;
final AdDetailsModel adDetailsModel;
const BuildAdDetailsActionButtonForExploreAds({Key? key, required this.adPostStatus, required this.adId}) : super(key: key);
const BuildAdDetailsActionButtonForExploreAds({Key? key, required this.adDetailsModel}) : super(key: key);
Widget pendingForPaymentAction(BuildContext context, {required int adID}) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Row(
children: [
Expanded(
child: ShowFillButton(
maxHeight: 55,
title: "Pay Now",
onPressed: () {
navigateWithName(context, AppRoutes.paymentMethodsView);
},
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
InkWell(
onTap: () {},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: "Delete Ad".toText(fontSize: 15, isBold: true, color: MyColors.redColor),
),
),
],
)
],
);
}
Widget markAsSoldAction(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Row(
children: [
Expanded(
child: ShowFillButton(
maxHeight: 55,
title: "Mark As Sold",
onPressed: () {},
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
InkWell(
onTap: () {},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: "Delete Ad".toText(fontSize: 15, isBold: true, color: MyColors.redColor),
),
),
],
)
],
);
void reserveAdPriceBreakDownClicked(BuildContext context, AdDetailsModel adDetailsModel) {
showModalBottomSheet(
context: context,
isScrollControlled: true,
enableDrag: true,
builder: (BuildContext context) {
return InfoBottomSheet(
title: "Reserve Ad",
description: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Reservation Amounts".toText(fontSize: 16, isBold: true),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"${adDetailsModel.reservePrice}".toText(fontSize: 19, isBold: true),
2.width,
"SAR".toText(color: MyColors.lightTextColor, fontSize: 10, isBold: true).paddingOnly(bottom: 3),
],
)
],
),
const Divider(),
"Below Amount that you will pay later".toText(fontSize: 12),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"Car Price".toText(fontSize: 16, isBold: true),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"${adDetailsModel.vehicle!.demandAmount ?? 0.0}".toText(fontSize: 19, isBold: true),
2.width,
"SAR".toText(color: MyColors.lightTextColor, fontSize: 10, isBold: true).paddingOnly(bottom: 3),
],
)
],
),
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// "Tax".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
// Row(
// crossAxisAlignment: CrossAxisAlignment.end,
// children: [
// "${adDetailsModel.taxPrice}".toText(fontSize: 16, isBold: true),
// 2.width,
// "SAR".toText(color: MyColors.lightTextColor, fontSize: 10, isBold: true).paddingOnly(bottom: 0),
// ],
// )
// ],
// ),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.end,
children: [
"VAT Excluded".toText(fontSize: 10, isBold: true),
],
),
const Divider(),
"Special Services".toText(fontSize: 16, isBold: true),
5.height,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Car insurance Service".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor, fontWeight: FontWeight.w500),
"To be Decided".toText(fontSize: 12, isBold: true),
],
),
5.height,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Registration & Car Plates".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
"To be Decided".toText(fontSize: 12, isBold: true),
],
),
5.height,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Home Delivery Service".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
"To be Decided".toText(fontSize: 12, isBold: true),
],
),
12.height,
"Special service charges will be added based on desired insurance and delivery Location".toText(fontSize: 12),
30.height,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Total Amount ".toText(fontSize: 16, isBold: true),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"${(adDetailsModel.vehicle!.demandAmount ?? 0.0)}".toText(fontSize: 19, isBold: true),
2.width,
"SAR".toText(color: MyColors.lightTextColor, fontSize: 10, isBold: true).paddingOnly(bottom: 3),
],
)
],
),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.end,
children: [
"Estimated".toText(fontSize: 10, isBold: true),
],
),
44.height,
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
const Icon(
Icons.warning,
color: MyColors.adPendingStatusColor,
size: 19,
).paddingOnly(bottom: 2),
3.width,
"Some services are mandatory while reserving the Ad.".toText(
color: MyColors.adPendingStatusColor,
fontSize: 12,
isItalic: true,
),
],
),
15.height,
Row(
children: [
Expanded(
child: ShowFillButton(
maxHeight: 55,
title: "Complete Reservation",
onPressed: () {
Navigator.pop(context);
navigateWithName(context, AppRoutes.paymentMethodsView, arguments: PaymentTypesEnum.adReserve);
},
),
),
],
),
19.height,
],
));
});
}
Widget cancelReservationAction(BuildContext context) {
@ -217,151 +300,7 @@ class BuildAdDetailsActionButtonForExploreAds extends StatelessWidget {
);
}
Widget defaultAction(BuildContext context) {
void reserveAdPriceBreakDownClicked(BuildContext context) {
showModalBottomSheet(
context: context,
isScrollControlled: true,
enableDrag: true,
builder: (BuildContext context) {
return InfoBottomSheet(
title: "Reserve Ad",
description: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Reservation Amounts".toText(fontSize: 16, isBold: true),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"500".toText(fontSize: 19, isBold: true),
2.width,
"SAR".toText(color: MyColors.lightTextColor, fontSize: 10, isBold: true).paddingOnly(bottom: 3),
],
)
],
),
const Divider(),
"Below Amount that you will pay later".toText(fontSize: 12),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"Car Price".toText(fontSize: 16, isBold: true),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"30,000".toText(fontSize: 19, isBold: true),
2.width,
"SAR".toText(color: MyColors.lightTextColor, fontSize: 10, isBold: true).paddingOnly(bottom: 3),
],
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Tax".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"4,500".toText(fontSize: 16, isBold: true),
2.width,
"SAR".toText(color: MyColors.lightTextColor, fontSize: 10, isBold: true).paddingOnly(bottom: 0),
],
)
],
),
const Divider(),
"Special Services".toText(fontSize: 16, isBold: true),
5.height,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Car insurance Service".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor, fontWeight: FontWeight.w500),
"To be Decided".toText(fontSize: 12, isBold: true),
],
),
5.height,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Registration & Car Plates".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
"To be Decided".toText(fontSize: 12, isBold: true),
],
),
5.height,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Home Delivery Service".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
"To be Decided".toText(fontSize: 12, isBold: true),
],
),
12.height,
"Special service charges will be added based on desired insurance and delivery Location".toText(fontSize: 12),
30.height,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Total Amount ".toText(fontSize: 16, isBold: true),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"34,500".toText(fontSize: 19, isBold: true),
2.width,
"SAR".toText(color: MyColors.lightTextColor, fontSize: 10, isBold: true).paddingOnly(bottom: 3),
],
)
],
),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.end,
children: [
"Estimated".toText(fontSize: 10, isBold: true),
],
),
44.height,
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
const Icon(
Icons.warning,
color: MyColors.adPendingStatusColor,
size: 19,
).paddingOnly(bottom: 2),
3.width,
"Some services are mandatory while reserving the Ad.".toText(
color: MyColors.adPendingStatusColor,
fontSize: 12,
isItalic: true,
),
],
),
15.height,
Row(
children: [
Expanded(
child: ShowFillButton(
maxHeight: 55,
title: "Complete Reservation",
onPressed: () {
Navigator.pop(context);
navigateWithName(context, AppRoutes.paymentMethodsView);
},
),
),
],
),
19.height,
],
));
});
}
Widget reserveAdAction(BuildContext context, AdDetailsModel adDetailsModel) {
return Row(
children: [
Expanded(
@ -369,67 +308,274 @@ class BuildAdDetailsActionButtonForExploreAds extends StatelessWidget {
maxHeight: 55,
title: "Reserve Ad",
onPressed: () {
reserveAdPriceBreakDownClicked(context);
reserveAdPriceBreakDownClicked(context, adDetailsModel);
// navigateWithName(context, AppRoutes.paymentMethodsView);
},
),
),
8.width,
Container(
height: 55,
width: 55,
alignment: Alignment.center,
decoration: BoxDecoration(border: Border.all(color: MyColors.black, width: 2)),
//TODO: It Will be replaced by a WhatsApp Icon
child: const Icon(Icons.message, color: MyColors.black),
).onPress(() {}),
8.width,
Container(
height: 55,
width: 55,
alignment: Alignment.center,
decoration: BoxDecoration(border: Border.all(color: MyColors.black, width: 2)),
child: const Icon(Icons.phone, color: MyColors.black),
).onPress(() {}),
if (adDetailsModel.whatsAppNo != null) ...[
8.width,
Container(
height: 55,
width: 55,
alignment: Alignment.center,
decoration: BoxDecoration(border: Border.all(color: MyColors.black, width: 2)),
//TODO: It Will be replaced by a WhatsApp Icon
child: const Icon(Icons.message, color: MyColors.black),
).onPress(() {}),
],
if (adDetailsModel.phoneNo != null) ...[
8.width,
Container(
height: 55,
width: 55,
alignment: Alignment.center,
decoration: BoxDecoration(border: Border.all(color: MyColors.black, width: 2)),
child: const Icon(Icons.phone, color: MyColors.black),
).onPress(() {}),
]
],
);
}
Widget defaultActionForProviderAndCustomer(BuildContext context, AdDetailsModel adDetailsModel) {
return (adDetailsModel.phoneNo != null)
? Row(
children: [
Expanded(
child: ShowFillButton(
maxHeight: 55,
title: "Contact",
fontSize: 18,
isBold: false,
iconWidget: const Padding(
padding: EdgeInsets.only(right: 10),
child: Icon(Icons.phone, color: MyColors.white, size: 24),
),
onPressed: () {},
),
),
if (adDetailsModel.whatsAppNo != null) ...[
8.width,
Container(
height: 55,
width: 55,
alignment: Alignment.center,
decoration: BoxDecoration(border: Border.all(color: MyColors.black, width: 2)),
//TODO: It Will be replaced by a WhatsApp Icon
child: const Icon(Icons.message, color: MyColors.black),
).onPress(() {}),
],
],
)
: const SizedBox.shrink();
}
@override
Widget build(BuildContext context) {
context.read<PaymentVM>().updateCurrentAdId(id: adId);
switch (adPostStatus) {
case AdPostStatus.pendingForPayment:
return pendingForPaymentAction(context, adID: adId);
case AdPostStatus.active:
return markAsSoldAction(context);
case AdPostStatus.reserved:
return cancelReservationAction(context);
case AdPostStatus.buyingService:
case AdPostStatus.reserveCancel:
case AdPostStatus.rejected:
case AdPostStatus.cancelled:
case AdPostStatus.pendingForPost:
case AdPostStatus.pendingForReview:
return pendingForPaymentAction(context, adID: adId);
return defaultAction(context);
context.read<PaymentVM>().updateCurrentAdId(id: adDetailsModel.id!);
// switch (adPostStatus) {
// case AdPostStatus.pendingForPayment:
// break;
// case AdPostStatus.active:
// break;
// case AdPostStatus.reserved:
// return cancelReservationAction(context);
//
// case AdPostStatus.buyingService:
// case AdPostStatus.reserveCancel:
// case AdPostStatus.rejected:
// case AdPostStatus.cancelled:
// case AdPostStatus.pendingForPost:
// case AdPostStatus.pendingForReview:
// case AdPostStatus.sold:
// case AdPostStatus.expired:
// break;
// }
// return defaultAction(context);
return pendingForPaymentAction(context, adID: adId);
case AdPostStatus.sold:
case AdPostStatus.expired:
break;
switch (adDetailsModel.createdByRoleEnum!) {
case CreatedByRoleEnum.customer:
case CreatedByRoleEnum.provider:
return defaultActionForProviderAndCustomer(context, adDetailsModel);
case CreatedByRoleEnum.admin:
return reserveAdAction(context, adDetailsModel);
case CreatedByRoleEnum.allAds:
return SizedBox.shrink();
}
return defaultAction(context);
}
}
class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
final AdPostStatus adPostStatus;
final int adId;
final AdDetailsModel adDetailsModel;
const BuildAdDetailsActionButtonForMyAds({Key? key, required this.adPostStatus, required this.adId}) : super(key: key);
const BuildAdDetailsActionButtonForMyAds({Key? key, required this.adDetailsModel}) : super(key: key);
void reserveAdPriceBreakDownClicked(BuildContext context) {
showModalBottomSheet(
context: context,
isScrollControlled: true,
enableDrag: true,
builder: (BuildContext context) {
return InfoBottomSheet(
title: "Reserve Ad",
description: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Reservation Amounts".toText(fontSize: 16, isBold: true),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"500".toText(fontSize: 19, isBold: true),
2.width,
"SAR".toText(color: MyColors.lightTextColor, fontSize: 10, isBold: true).paddingOnly(bottom: 3),
],
)
],
),
const Divider(),
"Below Amount that you will pay later".toText(fontSize: 12),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"Car Price".toText(fontSize: 16, isBold: true),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"30,000".toText(fontSize: 19, isBold: true),
2.width,
"SAR".toText(color: MyColors.lightTextColor, fontSize: 10, isBold: true).paddingOnly(bottom: 3),
],
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Tax".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"4,500".toText(fontSize: 16, isBold: true),
2.width,
"SAR".toText(color: MyColors.lightTextColor, fontSize: 10, isBold: true).paddingOnly(bottom: 0),
],
)
],
),
const Divider(),
"Special Services".toText(fontSize: 16, isBold: true),
5.height,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Car insurance Service".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor, fontWeight: FontWeight.w500),
"To be Decided".toText(fontSize: 12, isBold: true),
],
),
5.height,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Registration & Car Plates".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
"To be Decided".toText(fontSize: 12, isBold: true),
],
),
5.height,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Home Delivery Service".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
"To be Decided".toText(fontSize: 12, isBold: true),
],
),
12.height,
"Special service charges will be added based on desired insurance and delivery Location".toText(fontSize: 12),
30.height,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Total Amount ".toText(fontSize: 16, isBold: true),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"34,500".toText(fontSize: 19, isBold: true),
2.width,
"SAR".toText(color: MyColors.lightTextColor, fontSize: 10, isBold: true).paddingOnly(bottom: 3),
],
)
],
),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.end,
children: [
"Estimated".toText(fontSize: 10, isBold: true),
],
),
44.height,
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
const Icon(
Icons.warning,
color: MyColors.adPendingStatusColor,
size: 19,
).paddingOnly(bottom: 2),
3.width,
"Some services are mandatory while reserving the Ad.".toText(
color: MyColors.adPendingStatusColor,
fontSize: 12,
isItalic: true,
),
],
),
15.height,
Row(
children: [
Expanded(
child: ShowFillButton(
maxHeight: 55,
title: "Complete Reservation",
onPressed: () {
Navigator.pop(context);
navigateWithName(context, AppRoutes.paymentMethodsView);
},
),
),
],
),
19.height,
],
));
});
}
Widget pendingForReviewAction(BuildContext context, {required int adID}) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Row(
children: [
Expanded(
child: ShowFillButton(
backgroundColor: MyColors.grey98Color.withOpacity(0.3),
txtColor: MyColors.lightTextColor,
maxHeight: 55,
title: "Waiting for Admins Approval",
isBold: false,
onPressed: () {},
),
),
],
),
],
);
}
Widget pendingForPaymentAction(BuildContext context, {required int adID}) {
return Column(
@ -442,7 +588,7 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
maxHeight: 55,
title: "Pay Now",
onPressed: () {
navigateWithName(context, AppRoutes.paymentMethodsView);
navigateWithName(context, AppRoutes.paymentMethodsView, arguments: PaymentTypesEnum.ads);
},
),
),
@ -480,17 +626,18 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
InkWell(
onTap: () {},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: "Delete Ad".toText(fontSize: 15, isBold: true, color: MyColors.redColor),
Expanded(
child: ShowFillButton(
isFilled: true,
borderColor: MyColors.darkPrimaryColor,
maxHeight: 55,
title: "Deactivate Ad",
onPressed: () {},
),
),
],
)
),
],
);
}
@ -514,150 +661,6 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
}
Widget defaultAction(BuildContext context) {
void reserveAdPriceBreakDownClicked(BuildContext context) {
showModalBottomSheet(
context: context,
isScrollControlled: true,
enableDrag: true,
builder: (BuildContext context) {
return InfoBottomSheet(
title: "Reserve Ad",
description: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Reservation Amounts".toText(fontSize: 16, isBold: true),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"500".toText(fontSize: 19, isBold: true),
2.width,
"SAR".toText(color: MyColors.lightTextColor, fontSize: 10, isBold: true).paddingOnly(bottom: 3),
],
)
],
),
const Divider(),
"Below Amount that you will pay later".toText(fontSize: 12),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"Car Price".toText(fontSize: 16, isBold: true),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"30,000".toText(fontSize: 19, isBold: true),
2.width,
"SAR".toText(color: MyColors.lightTextColor, fontSize: 10, isBold: true).paddingOnly(bottom: 3),
],
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Tax".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"4,500".toText(fontSize: 16, isBold: true),
2.width,
"SAR".toText(color: MyColors.lightTextColor, fontSize: 10, isBold: true).paddingOnly(bottom: 0),
],
)
],
),
const Divider(),
"Special Services".toText(fontSize: 16, isBold: true),
5.height,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Car insurance Service".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor, fontWeight: FontWeight.w500),
"To be Decided".toText(fontSize: 12, isBold: true),
],
),
5.height,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Registration & Car Plates".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
"To be Decided".toText(fontSize: 12, isBold: true),
],
),
5.height,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Home Delivery Service".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
"To be Decided".toText(fontSize: 12, isBold: true),
],
),
12.height,
"Special service charges will be added based on desired insurance and delivery Location".toText(fontSize: 12),
30.height,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Total Amount ".toText(fontSize: 16, isBold: true),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"34,500".toText(fontSize: 19, isBold: true),
2.width,
"SAR".toText(color: MyColors.lightTextColor, fontSize: 10, isBold: true).paddingOnly(bottom: 3),
],
)
],
),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.end,
children: [
"Estimated".toText(fontSize: 10, isBold: true),
],
),
44.height,
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
const Icon(
Icons.warning,
color: MyColors.adPendingStatusColor,
size: 19,
).paddingOnly(bottom: 2),
3.width,
"Some services are mandatory while reserving the Ad.".toText(
color: MyColors.adPendingStatusColor,
fontSize: 12,
isItalic: true,
),
],
),
15.height,
Row(
children: [
Expanded(
child: ShowFillButton(
maxHeight: 55,
title: "Complete Reservation",
onPressed: () {
Navigator.pop(context);
navigateWithName(context, AppRoutes.paymentMethodsView);
},
),
),
],
),
19.height,
],
));
});
}
return Row(
children: [
Expanded(
@ -693,10 +696,10 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
@override
Widget build(BuildContext context) {
context.read<PaymentVM>().updateCurrentAdId(id: adId);
switch (adPostStatus) {
context.read<PaymentVM>().updateCurrentAdId(id: adDetailsModel.id!);
switch (adDetailsModel.adPostStatus!) {
case AdPostStatus.pendingForPayment:
return pendingForPaymentAction(context, adID: adId);
return pendingForPaymentAction(context, adID: adDetailsModel.id!);
case AdPostStatus.active:
return markAsSoldAction(context);
case AdPostStatus.reserved:
@ -707,10 +710,9 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
case AdPostStatus.cancelled:
case AdPostStatus.pendingForPost:
case AdPostStatus.pendingForReview:
break;
return defaultAction(context);
return pendingForReviewAction(context, adID: adDetailsModel.id!);
return pendingForPaymentAction(context, adID: adId);
// return pendingForPaymentAction(context, adID: adId);
case AdPostStatus.sold:
case AdPostStatus.expired:
break;

@ -53,7 +53,7 @@ class BuildAdsList extends StatelessWidget {
separatorBuilder: (BuildContext context, int index) {
return 12.height;
},
padding: EdgeInsets.symmetric(horizontal: 21),
padding: const EdgeInsets.symmetric(horizontal: 21),
);
}
}
@ -99,10 +99,7 @@ class AdCard extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
if (isAdsFragment && context.read<AdVM>().isExploreAdsTapped) ...[
Utils.statusContainerChip(text: adDetails.statuslabel!, chipColor: Utils.getChipColorByAdStatus(adDetails.adPostStatus!)),
],
if (shouldShowAdStatus) ...[
if (isAdsFragment && !context.read<AdVM>().isExploreAdsTapped) ...[
Utils.statusContainerChip(text: adDetails.statuslabel!, chipColor: Utils.getChipColorByAdStatus(adDetails.adPostStatus!)),
],
(adDetails.vehicle!.vehicleTitle ?? "").toText(fontSize: 16, isBold: true),

@ -104,7 +104,6 @@ class _BottomSheetListContentState extends State<BottomSheetListContent> {
const SizedBox(width: 20),
vehiclePart.partName.toString().toText(
fontSize: 16,
isBold: true,
color: vehiclePart.isSelected! ? MyColors.lightTextColor : MyColors.black,
)
],

@ -11,7 +11,9 @@ import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:provider/provider.dart';
class PaymentMethodsView extends StatelessWidget {
const PaymentMethodsView({Key? key}) : super(key: key);
final PaymentTypesEnum paymentType;
const PaymentMethodsView({Key? key, required this.paymentType}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -68,7 +70,7 @@ class PaymentMethodsView extends StatelessWidget {
maxHeight: 55,
title: "Continue",
onPressed: () {
context.read<PaymentVM>().onContinuePressed(context);
context.read<PaymentVM>().onContinuePressed(context, paymentType: paymentType);
},
backgroundColor: MyColors.darkPrimaryColor,
),

@ -29,7 +29,7 @@ class _LoginWithPasswordState extends State<LoginWithPassword> {
ClassType type = ClassType.EMAIL;
//TODO: ONLY FOR DEVELOPMENT PURPOSE
String phoneNum = "966504278212", password = "Fa@123";
String phoneNum = "966504278213", password = "Fa@1234";
String email = "";
String countryCode = "";
Country? _country;

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
class ShowFillButton extends StatelessWidget {
String title;
@ -12,6 +13,7 @@ class ShowFillButton extends StatelessWidget {
EdgeInsets? margin;
bool isFilled;
Color borderColor;
Widget? iconWidget;
ShowFillButton({
super.key,
@ -31,6 +33,7 @@ class ShowFillButton extends StatelessWidget {
this.horizontalMargin = 0,
this.verticalMargin = 0,
this.margin,
this.iconWidget,
this.borderColor = MyColors.primaryColor,
});
@ -62,21 +65,37 @@ class ShowFillButton extends StatelessWidget {
Widget showButton() {
return Container(
// decoration: isFlatButton ? null : MyColors.gradientButton,
color: isFlatButton ? null : isFilled ? backgroundColor : null,
color: isFlatButton
? null
: isFilled
? backgroundColor
: null,
margin: EdgeInsets.symmetric(horizontal: horizontalMargin, vertical: verticalMargin),
child: MaterialButton(
onPressed: onPressed,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(radius),
side: isFilled ? BorderSide.none: BorderSide(width: 2, color: borderColor),
),
child: title.toText(
fontSize: fontSize,
isBold: isBold,
color: txtColor,
maxLines: 1,
side: isFilled ? BorderSide.none : BorderSide(width: 2, color: borderColor),
),
child: iconWidget != null
? Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
iconWidget!,
title.toText(
fontSize: fontSize,
isBold: isBold,
color: txtColor,
maxLines: 1,
),
],
)
: title.toText(
fontSize: fontSize,
isBold: isBold,
color: txtColor,
maxLines: 1,
),
),
);
}

Loading…
Cancel
Save