Added Appoinment Module and Ads Filter

models_removal
Faiz Hashmi 2 years ago
parent 057a202ed9
commit 8a8efa37f2

@ -54,7 +54,7 @@ class AppRoutes {
static const String selectAdTypeView = "/selectAdTypeView"; static const String selectAdTypeView = "/selectAdTypeView";
static const String adsDetailView = "/adsDetailView"; static const String adsDetailView = "/adsDetailView";
static const String createAdView = "/createAdView"; static const String createAdView = "/createAdView";
static const String adsSearchFilterScreen = "/adsSearchFilterScreen"; static const String adsFilterView = "/adsFilterView";
// Payments // Payments
static const String paymentMethodsView = "/paymentMethodsView"; static const String paymentMethodsView = "/paymentMethodsView";
@ -71,7 +71,6 @@ class AppRoutes {
static const String createRequestPage = "/createRequestPage"; static const String createRequestPage = "/createRequestPage";
static const String offersListPage = "/offersListPage"; static const String offersListPage = "/offersListPage";
static const String initialRoute = splash; static const String initialRoute = splash;
static final Map<String, WidgetBuilder> routes = { static final Map<String, WidgetBuilder> routes = {

@ -1,4 +1,5 @@
import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/services/service_model.dart';
import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/enums.dart';
class AppointmentListModel { class AppointmentListModel {
@ -17,7 +18,7 @@ class AppointmentListModel {
String? duration; String? duration;
String? appointmentDate; String? appointmentDate;
AppointmentStatusEnum? appointmentStatusEnum; AppointmentStatusEnum? appointmentStatusEnum;
List<ServiceAppointmentItems>? serviceAppointmentItems; List<ServiceModel>? appointmentServicesList;
AppointmentListModel( AppointmentListModel(
{this.id, {this.id,
@ -34,11 +35,11 @@ class AppointmentListModel {
this.providerName, this.providerName,
this.duration, this.duration,
this.appointmentDate, this.appointmentDate,
this.serviceAppointmentItems}); this.appointmentServicesList});
@override @override
String toString() { String toString() {
return 'AppointmentListModel{id: $id, serviceSlotID: $serviceSlotID, appointmentStatusID: $appointmentStatusID, appointmentStatusText: $appointmentStatusText, serviceProviderID: $serviceProviderID, customerID: $customerID, isActive: $isActive, isPaymentRequired: $isPaymentRequired, paymentStatus: $paymentStatus, paymentStatusText: $paymentStatusText, customerName: $customerName, providerName: $providerName, duration: $duration, appointmentDate: $appointmentDate, appointmentStatusEnum: $appointmentStatusEnum, serviceAppointmentItems: $serviceAppointmentItems}'; return 'AppointmentListModel{id: $id, serviceSlotID: $serviceSlotID, appointmentStatusID: $appointmentStatusID, appointmentStatusText: $appointmentStatusText, serviceProviderID: $serviceProviderID, customerID: $customerID, isActive: $isActive, isPaymentRequired: $isPaymentRequired, paymentStatus: $paymentStatus, paymentStatusText: $paymentStatusText, customerName: $customerName, providerName: $providerName, duration: $duration, appointmentDate: $appointmentDate, appointmentStatusEnum: $appointmentStatusEnum, appointmentServicesList: $appointmentServicesList}';
} }
AppointmentListModel.fromJson(Map<String, dynamic> json) { AppointmentListModel.fromJson(Map<String, dynamic> json) {
@ -57,10 +58,11 @@ class AppointmentListModel {
duration = json['duration']; duration = json['duration'];
appointmentDate = json['appointmentDate']; appointmentDate = json['appointmentDate'];
appointmentStatusEnum = (json['appointmentStatusID'] as int).toAppointmentStatusEnum(); appointmentStatusEnum = (json['appointmentStatusID'] as int).toAppointmentStatusEnum();
if (json['serviceAppointmentItems'] != null) {
serviceAppointmentItems = <ServiceAppointmentItems>[]; if (json['serviceList'] != null) {
json['serviceAppointmentItems'].forEach((v) { appointmentServicesList = <ServiceModel>[];
serviceAppointmentItems!.add(ServiceAppointmentItems.fromJson(v)); json['serviceList'].forEach((v) {
appointmentServicesList!.add(ServiceModel.fromJson(v, isForAppointment: true));
}); });
} }
} }

@ -38,7 +38,7 @@ class ServiceAppointmentScheduleModel {
for (var element in serviceSlotList!) { for (var element in serviceSlotList!) {
if (!isAlreadyThere(element.slotDate!, customTimeDateSlotList)) { if (!isAlreadyThere(element.slotDate!, customTimeDateSlotList)) {
customTimeDateSlotList.add(CustomTimeDateSlotModel( customTimeDateSlotList.add(CustomTimeDateSlotModel(
date: TimeSlotModel(slotId: element.id!, isSelected: false, date: element.slotDate!, allowAppointment: true), date: TimeSlotModel(slotId: element.id!, isSelected: false, date: element.slotDate!, allowAppointment: (element.allowAppointment ?? 0) > (element.bookAppointment ?? 0)),
availableSlots: getAvailableSlotsByDate(element.slotDate!), availableSlots: getAvailableSlotsByDate(element.slotDate!),
)); ));
} }
@ -97,12 +97,9 @@ class ServiceAppointmentScheduleModel {
return slotDates; return slotDates;
} }
//TODO: I WILL START FROM HERE; I NEED TO ONLY PICK THE DISTINCT DATES FROM THE RESPONSE AND THEN BASED ON THE DATE SELECTION I WILL PICK THEIR SLOTS. //comprehensive checkup and body checkup
//TODO: AFTER THAT, I WILL
ServiceAppointmentScheduleModel.fromJson ServiceAppointmentScheduleModel.fromJson(Map<String, dynamic> json, {bool isForAppointment = false}) {
(Map<String, dynamic> json, {bool isForAppointment = false}) {
if (json['serviceSlotList'] != null) { if (json['serviceSlotList'] != null) {
serviceSlotList = <ServiceSlotList>[]; serviceSlotList = <ServiceSlotList>[];
json['serviceSlotList'].forEach((v) { json['serviceSlotList'].forEach((v) {

@ -86,8 +86,8 @@ class AdsRepoImp implements AdsRepo {
var postParams = { var postParams = {
"CountryID": countryId.toString(), "CountryID": countryId.toString(),
}; };
GenericRespModel adsGenericModel = GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleCityGet, queryParameters: postParams); token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleCityGet, queryParameters: countryId != -1 ? postParams : null);
List<VehicleCityModel> vehicleCities = List.generate(adsGenericModel.data.length, (index) => VehicleCityModel.fromJson(adsGenericModel.data[index])); List<VehicleCityModel> vehicleCities = List.generate(adsGenericModel.data.length, (index) => VehicleCityModel.fromJson(adsGenericModel.data[index]));
return vehicleCities; return vehicleCities;
} }
@ -141,8 +141,12 @@ class AdsRepoImp implements AdsRepo {
var postParams = { var postParams = {
"VehicleType": vehicleTypeId.toString(), "VehicleType": vehicleTypeId.toString(),
}; };
GenericRespModel adsGenericModel = GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleModelYearGet, queryParameters: postParams); token: appState.getUser.data!.accessToken,
(json) => GenericRespModel.fromJson(json),
ApiConsts.vehicleModelYearGet,
queryParameters: vehicleTypeId != -1 ? postParams : null,
);
List<VehicleYearModel> vehicleModelYears = List.generate(adsGenericModel.data.length, (index) => VehicleYearModel.fromJson(adsGenericModel.data[index])); List<VehicleYearModel> vehicleModelYears = List.generate(adsGenericModel.data.length, (index) => VehicleYearModel.fromJson(adsGenericModel.data[index]));
return vehicleModelYears; return vehicleModelYears;
} }
@ -152,8 +156,12 @@ class AdsRepoImp implements AdsRepo {
var postParams = { var postParams = {
"VehicleType": vehicleTypeId.toString(), "VehicleType": vehicleTypeId.toString(),
}; };
GenericRespModel adsGenericModel = GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleModelGet, queryParameters: postParams); token: appState.getUser.data!.accessToken,
(json) => GenericRespModel.fromJson(json),
ApiConsts.vehicleModelGet,
queryParameters: postParams,
);
List<VehicleModel> vehicleModels = List.generate(adsGenericModel.data.length, (index) => VehicleModel.fromJson(adsGenericModel.data[index])); List<VehicleModel> vehicleModels = List.generate(adsGenericModel.data.length, (index) => VehicleModel.fromJson(adsGenericModel.data[index]));
return vehicleModels; return vehicleModels;
} }
@ -163,8 +171,12 @@ class AdsRepoImp implements AdsRepo {
var postParams = { var postParams = {
"VehicleType": vehicleTypeId.toString(), "VehicleType": vehicleTypeId.toString(),
}; };
GenericRespModel adsGenericModel = GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleBrandGet, queryParameters: postParams); token: appState.getUser.data!.accessToken,
(json) => GenericRespModel.fromJson(json),
ApiConsts.vehicleBrandGet,
queryParameters: vehicleTypeId != -1 ? postParams : null,
);
List<VehicleBrandsModel> vehicleBrands = List.generate(adsGenericModel.data.length, (index) => VehicleBrandsModel.fromJson(adsGenericModel.data[index])); List<VehicleBrandsModel> vehicleBrands = List.generate(adsGenericModel.data.length, (index) => VehicleBrandsModel.fromJson(adsGenericModel.data[index]));
return vehicleBrands; return vehicleBrands;
} }
@ -174,8 +186,12 @@ class AdsRepoImp implements AdsRepo {
var postParams = { var postParams = {
"VehicleType": vehicleTypeId.toString(), "VehicleType": vehicleTypeId.toString(),
}; };
GenericRespModel adsGenericModel = GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleSellerTypeGet, queryParameters: postParams); token: appState.getUser.data!.accessToken,
(json) => GenericRespModel.fromJson(json),
ApiConsts.vehicleSellerTypeGet,
queryParameters: postParams,
);
List<VehicleSellerTypeModel> vehicleSellerTypes = List.generate(adsGenericModel.data.length, (index) => VehicleSellerTypeModel.fromJson(adsGenericModel.data[index])); List<VehicleSellerTypeModel> vehicleSellerTypes = List.generate(adsGenericModel.data.length, (index) => VehicleSellerTypeModel.fromJson(adsGenericModel.data[index]));
return vehicleSellerTypes; return vehicleSellerTypes;
} }
@ -185,8 +201,12 @@ class AdsRepoImp implements AdsRepo {
var postParams = { var postParams = {
"VehicleType": vehicleTypeId.toString(), "VehicleType": vehicleTypeId.toString(),
}; };
GenericRespModel adsGenericModel = GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleTransmissionGet, queryParameters: postParams); token: appState.getUser.data!.accessToken,
(json) => GenericRespModel.fromJson(json),
ApiConsts.vehicleTransmissionGet,
queryParameters: postParams,
);
List<VehicleTransmissionModel> vehicleTransmissions = List.generate(adsGenericModel.data.length, (index) => VehicleTransmissionModel.fromJson(adsGenericModel.data[index])); List<VehicleTransmissionModel> vehicleTransmissions = List.generate(adsGenericModel.data.length, (index) => VehicleTransmissionModel.fromJson(adsGenericModel.data[index]));
return vehicleTransmissions; return vehicleTransmissions;
} }

@ -66,7 +66,7 @@ class CommonRepoImp implements CommonRepo {
@override @override
Future<List<AppointmentListModel>> getMyAppointments() async { Future<List<AppointmentListModel>> getMyAppointments() async {
var params = { var params = {
"userID": appState.getUser.data!.userInfo!.userId ?? "", "customerID": appState.getUser.data!.userInfo!.customerId.toString() ?? "",
}; };
GenericRespModel genericRespModel = await apiClient.getJsonForObject( GenericRespModel genericRespModel = await apiClient.getJsonForObject(
token: appState.getUser.data!.accessToken, token: appState.getUser.data!.accessToken,

@ -3,6 +3,7 @@ import 'dart:developer';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/services/my_in_app_browser.dart'; import 'package:mc_common_app/services/my_in_app_browser.dart';
@ -55,31 +56,38 @@ class PaymentServiceImp implements PaymentService {
required Function() onFailure, required Function() onFailure,
}) async { }) async {
String urlRequest = ""; String urlRequest = "";
int customerId = AppState().getUser.data!.userInfo!.customerId ?? 0;
switch (paymentType) { switch (paymentType) {
case PaymentTypes.subscription: case PaymentTypes.subscription:
urlRequest = ""; urlRequest = "${ApiConsts.paymentWebViewUrl}?PaymentType=${paymentType.getIdFromPaymentTypesEnum()}&OrderProviderSubscriptionID=$id";
break; break;
case PaymentTypes.appointment: case PaymentTypes.appointment:
String appointIds = ''; String appointIds = '';
for (var element in appointmentIds!) { for (int i = 0; i < appointmentIds!.length; i++) {
appointIds = "$appointIds$element:"; var element = appointmentIds[i];
if (i == appointmentIds.length - 1) {
appointIds = "$appointIds$element";
} else {
appointIds = "$appointIds$element:";
}
} }
urlRequest = "${ApiConsts.paymentWebViewUrl}?PaymentType=${paymentType.getIdFromPaymentTypesEnum()}&AppointmentIDs=$appointIds"; urlRequest = "${ApiConsts.paymentWebViewUrl}?PaymentType=${paymentType.getIdFromPaymentTypesEnum()}&CustomerID=$customerId&AppointmentIDs=$appointIds";
break; break;
case PaymentTypes.adReserve: case PaymentTypes.adReserve:
urlRequest = "${ApiConsts.paymentWebViewUrl}?PaymentType=${paymentType.getIdFromPaymentTypesEnum()}&AdsID=$id"; urlRequest = "${ApiConsts.paymentWebViewUrl}?PaymentType=${paymentType.getIdFromPaymentTypesEnum()}&CustomerID=$customerId&AdsID=$id";
break; break;
case PaymentTypes.ads: case PaymentTypes.ads:
urlRequest = "${ApiConsts.paymentWebViewUrl}?PaymentType=${paymentType.getIdFromPaymentTypesEnum()}&AdsID=$id"; urlRequest = "${ApiConsts.paymentWebViewUrl}?PaymentType=${paymentType.getIdFromPaymentTypesEnum()}&CustomerID=$customerId&AdsID=$id";
break;
case PaymentTypes.request:
urlRequest = "";
break; break;
case PaymentTypes.extendAds: case PaymentTypes.extendAds:
urlRequest = ""; urlRequest = "${ApiConsts.paymentWebViewUrl}?PaymentType=${paymentType.getIdFromPaymentTypesEnum()}&CustomerID=$customerId&AdsID=$id";
break;
case PaymentTypes.request:
urlRequest = "${ApiConsts.paymentWebViewUrl}?PaymentType=${paymentType.getIdFromPaymentTypesEnum()}&CustomerID=$customerId&RequestID=$id";
break; break;
} }
print("PaymentUrl: $urlRequest"); log("PaymentUrl: $urlRequest");
myInAppBrowser = MyInAppBrowser(onExitCallback: () { myInAppBrowser = MyInAppBrowser(onExitCallback: () {
log("Browser Exited"); log("Browser Exited");
}, onLoadStartCallback: (String url) { }, onLoadStartCallback: (String url) {

@ -21,6 +21,7 @@ class MyColors {
static const Color grey70Color = Color(0xff707070); static const Color grey70Color = Color(0xff707070);
static const Color greyACColor = Color(0xffACACAC); static const Color greyACColor = Color(0xffACACAC);
static const Color chipColor = Color(0xffE6E6E6); static const Color chipColor = Color(0xffE6E6E6);
static const Color roundedCrossBgColor = Color(0xFFA3A3A3);
static const Color greyShadowColor = Color(0xFFE8E7E7); static const Color greyShadowColor = Color(0xFFE8E7E7);
static const Color grey98Color = Color(0xff989898); static const Color grey98Color = Color(0xff989898);
static const Color lightGreyEFColor = Color(0xffEFEFEF); static const Color lightGreyEFColor = Color(0xffEFEFEF);

@ -417,7 +417,14 @@ class AdVM extends BaseVM {
SelectionModel vehicleBrandId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); SelectionModel vehicleBrandId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updateSelectionVehicleBrandId(SelectionModel id) { void updateSelectionVehicleBrandId(SelectionModel id, {bool isForSearch = false}) {
if (isForSearch) {
VehicleBrandsModel brand = vehicleBrands.firstWhere((element) => element.id == id.selectedId);
DropValue brandValue = DropValue(brand.id ?? 0, brand.vehicleBrandDescription ?? "", "");
if (!ifAlreadyExist(list: vehicleBrandsAdSearchHistory, value: brandValue)) {
addToVehicleBrandsAdSearchHistory(value: brandValue);
}
}
vehicleBrandId = id; vehicleBrandId = id;
getVehicleDetailsByVehicleBrandId(); getVehicleDetailsByVehicleBrandId();
@ -433,7 +440,14 @@ class AdVM extends BaseVM {
SelectionModel vehicleModelYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); SelectionModel vehicleModelYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updateSelectionVehicleModelYearId(SelectionModel id) { void updateSelectionVehicleModelYearId(SelectionModel id, {bool isForSearch = false}) {
if (isForSearch) {
VehicleYearModel year = vehicleModelYears.firstWhere((element) => element.id == id.selectedId);
DropValue yearValue = DropValue(year.id ?? 0, year.modelYear ?? "", "");
if (!ifAlreadyExist(list: vehicleYearAdSearchHistory, value: yearValue)) {
addToVehicleYearAdSearchHistory(value: yearValue);
}
}
vehicleModelYearId = id; vehicleModelYearId = id;
notifyListeners(); notifyListeners();
} }
@ -534,7 +548,14 @@ class AdVM extends BaseVM {
SelectionModel vehicleCityId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); SelectionModel vehicleCityId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updateSelectionVehicleCityId(SelectionModel id) { void updateSelectionVehicleCityId(SelectionModel id, {bool isForSearch = false}) async {
if (isForSearch) {
VehicleCityModel city = vehicleCities.firstWhere((element) => element.id == id.selectedId);
DropValue cityValue = DropValue(city.id ?? 0, city.cityName ?? "", "");
if (!ifAlreadyExist(list: vehicleLocationAdSearchHistory, value: cityValue)) {
addToVehicleLocationAdSearchHistory(value: cityValue);
}
}
vehicleCityId = id; vehicleCityId = id;
notifyListeners(); notifyListeners();
} }
@ -1161,6 +1182,102 @@ class AdVM extends BaseVM {
); );
return vehiclePostingDamageParts; return vehiclePostingDamageParts;
} }
// ************ ADS SEARCH VIEW ****************
Future<void> populateDataForAdFilter() async {
if (vehicleBrands.isEmpty) {
vehicleBrands = await adsRepo.getVehicleBrands(vehicleTypeId: -1);
}
if (vehicleModelYears.isEmpty) {
vehicleModelYears = await adsRepo.getVehicleModelYears(vehicleTypeId: -1);
}
vehicleCities = await adsRepo.getVehicleCities(countryId: -1); // fetch all the cities
}
ifAlreadyExist({required List<DropValue> list, required DropValue value}) {
int index = list.indexWhere((element) {
return element.id == value.id;
});
if (index != -1) {
return true;
}
return false;
}
//BRANDS
List<DropValue> vehicleBrandsAdSearchHistory = [];
void removeVehicleBrandsAdSearchHistory({bool isClear = false, required int index}) {
if (isClear) {
vehicleBrandsAdSearchHistory.clear();
notifyListeners();
return;
}
vehicleBrandsAdSearchHistory.removeAt(index);
notifyListeners();
}
void addToVehicleBrandsAdSearchHistory({required DropValue value}) {
vehicleBrandsAdSearchHistory.add(value);
notifyListeners();
}
// LOCATION
List<DropValue> vehicleLocationAdSearchHistory = [];
void removeVehicleLocationAdSearchHistory({bool isClear = false, required int index}) {
if (isClear) {
vehicleLocationAdSearchHistory.clear();
notifyListeners();
return;
}
vehicleLocationAdSearchHistory.removeAt(index);
notifyListeners();
}
void addToVehicleLocationAdSearchHistory({required DropValue value}) {
vehicleLocationAdSearchHistory.add(value);
notifyListeners();
}
// OWNER
List<DropValue> vehicleAdOwnerSearchHistory = [];
void removeVehicleAdOwnerSearchHistory({bool isClear = false, required int index}) {
if (isClear) {
vehicleAdOwnerSearchHistory.clear();
notifyListeners();
return;
}
vehicleAdOwnerSearchHistory.removeAt(index);
notifyListeners();
}
void addToVehicleAdOwnerSearchHistory({required DropValue value}) {
vehicleAdOwnerSearchHistory.add(value);
notifyListeners();
}
// YEAR
List<DropValue> vehicleYearAdSearchHistory = [];
void removeVehicleYearAdSearchHistory({bool isClear = false, required int index}) {
if (isClear) {
vehicleYearAdSearchHistory.clear();
notifyListeners();
return;
}
vehicleYearAdSearchHistory.removeAt(index);
notifyListeners();
}
void addToVehicleYearAdSearchHistory({required DropValue value}) {
vehicleYearAdSearchHistory.add(value);
notifyListeners();
}
} }
class VehicleDamageCard { class VehicleDamageCard {

@ -1,3 +1,5 @@
import 'dart:developer';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart';
@ -23,6 +25,25 @@ class PaymentVM extends ChangeNotifier {
currentAdId = id; currentAdId = id;
} }
int requestId = -1;
void updateRequestId({required int id}) {
requestId = id;
}
int orderProviderSubscriptionId = -1;
void updateOrderProviderSubscriptionId({required int id}) {
orderProviderSubscriptionId = id;
}
List<int> appointmentIdsForPayment = [];
void updateAppointmentIdsForPayment({required List<int> ids}) {
log("appointmetList: $ids");
appointmentIdsForPayment = ids;
}
updateSelectedPaymentMethod(PaymentMethods selectedMethod) { updateSelectedPaymentMethod(PaymentMethods selectedMethod) {
selectedPaymentMethod = selectedMethod; selectedPaymentMethod = selectedMethod;
notifyListeners(); notifyListeners();
@ -69,9 +90,46 @@ class PaymentVM extends ChangeNotifier {
} }
} }
Future<void> placeThePayment({required int adId, required PaymentTypes paymentTypeEnum, required BuildContext context}) async { Future<void> onAppointmentPaymentSuccess({required BuildContext context, required int currentAdId, required int paymentTypeId}) async {
Utils.showLoading(context);
//TODO: CONFIRM FROM ZAHOOR THAT WILL THIS METHOD WORK FOR APPOINTMENT
PayOrderDetailRespModel payOrderDetailRespModel = await paymentRepo.getPayOrderDetails(paymentId: paymentTypeId, 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 Successful");
navigateReplaceWithNameUntilRoute(context, AppRoutes.dashboard);
}
}
int getIdTypeByPaymentType(PaymentTypes paymentTypes) {
switch (paymentTypes) {
case PaymentTypes.subscription:
return orderProviderSubscriptionId;
case PaymentTypes.appointment:
return -1;
case PaymentTypes.request:
return requestId;
case PaymentTypes.adReserve:
case PaymentTypes.ads:
case PaymentTypes.extendAds:
return currentAdId;
}
}
Future<void> placeThePayment({required PaymentTypes paymentTypeEnum, required BuildContext context}) async {
await paymentService.placePayment( await paymentService.placePayment(
id: currentAdId, // This will be request ID for request payment || ad ID for Ad Related Payment || OrderProviderSubscriptionID for SubscriptionPayment
id: getIdTypeByPaymentType(paymentTypeEnum),
appointmentIds: appointmentIdsForPayment,
paymentType: paymentTypeEnum, paymentType: paymentTypeEnum,
onFailure: () { onFailure: () {
Utils.showToast("Payment Failed!"); Utils.showToast("Payment Failed!");
@ -81,6 +139,7 @@ class PaymentVM extends ChangeNotifier {
break; break;
case PaymentTypes.appointment: case PaymentTypes.appointment:
// TODO: Handle this case. // TODO: Handle this case.
log("Appointment Payment has been Failed!!");
break; break;
case PaymentTypes.adReserve: case PaymentTypes.adReserve:
// TODO: Handle this case. // TODO: Handle this case.
@ -99,22 +158,16 @@ class PaymentVM extends ChangeNotifier {
onSuccess: () async { onSuccess: () async {
switch (paymentTypeEnum) { switch (paymentTypeEnum) {
case PaymentTypes.subscription: case PaymentTypes.subscription:
// TODO: Handle this case.
break; break;
case PaymentTypes.appointment: case PaymentTypes.appointment:
// TODO: Handle this case. log("Appointment Payment has been Succeeded");
break;
case PaymentTypes.adReserve:
// TODO: Handle this case.
break;
case PaymentTypes.ads:
await onAdsPaymentSuccess(context: context, paymentTypeId: paymentTypeEnum.getIdFromPaymentTypesEnum(), currentAdId: currentAdId);
break; break;
case PaymentTypes.request: case PaymentTypes.request:
// TODO: Handle this case.
break; break;
case PaymentTypes.adReserve:
case PaymentTypes.ads:
case PaymentTypes.extendAds: case PaymentTypes.extendAds:
// TODO: Handle this case. await onAdsPaymentSuccess(context: context, paymentTypeId: paymentTypeEnum.getIdFromPaymentTypesEnum(), currentAdId: currentAdId);
break; break;
} }
}, },
@ -125,32 +178,21 @@ class PaymentVM extends ChangeNotifier {
currentPaymentType = paymentType; currentPaymentType = paymentType;
switch (currentPaymentType) { switch (currentPaymentType) {
case PaymentTypes.appointment: case PaymentTypes.appointment:
if (appointmentIdsForPayment.isEmpty) return;
await placeThePayment(context: context, paymentTypeEnum: paymentType);
break; break;
case PaymentTypes.ads:
if (currentAdId == -1) return;
await placeThePayment(adId: currentAdId, context: context, paymentTypeEnum: paymentType);
break;
case PaymentTypes.adReserve:
if (currentAdId == -1) return;
await placeThePayment(adId: currentAdId, context: context, paymentTypeEnum: paymentType);
break;
case PaymentTypes.extendAds:
if (currentAdId == -1) return;
await placeThePayment(adId: currentAdId, context: context, paymentTypeEnum: paymentType);
break;
case PaymentTypes.request: case PaymentTypes.request:
// TODO: Handle this case. // TODO: Handle this case.
break; break;
case PaymentTypes.subscription: case PaymentTypes.subscription:
// TODO: Handle this case. // TODO: Handle this case.
break; break;
case PaymentTypes.ads:
case PaymentTypes.adReserve:
case PaymentTypes.extendAds:
if (currentAdId == -1) return;
await placeThePayment(context: context, paymentTypeEnum: paymentType);
break;
} }
} }
} }

@ -141,6 +141,7 @@ class VehicleDetails extends StatelessWidget {
(DropValue value) => adVM.updateSelectionVehicleTransmissionId(SelectionModel(selectedId: value.id, selectedOption: value.value)), (DropValue value) => adVM.updateSelectionVehicleTransmissionId(SelectionModel(selectedId: value.id, selectedOption: value.value)),
list: vehicleTransmissionsDrop, list: vehicleTransmissionsDrop,
hint: "Vehicle Transmission", hint: "Vehicle Transmission",
dropdownValue: adVM.vehicleTransmissionId.selectedId != -1 ? DropValue(adVM.vehicleTransmissionId.selectedId, adVM.vehicleTransmissionId.selectedOption, "") : null,
errorValue: adVM.vehicleTransmissionId.errorValue, errorValue: adVM.vehicleTransmissionId.errorValue,
); );
}), }),

@ -65,6 +65,7 @@ class AdsDetailView extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
print("adId: ${adDetails.id}"); print("adId: ${adDetails.id}");
print("statusID: ${adDetails.statusID}"); print("statusID: ${adDetails.statusID}");
context.read<PaymentVM>().updateCurrentAdId(id: adDetails.id!);
return Scaffold( return Scaffold(
appBar: CustomAppBar( appBar: CustomAppBar(
title: "Ads", title: "Ads",
@ -467,7 +468,6 @@ class BuildAdDetailsActionButtonForExploreAds extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
context.read<PaymentVM>().updateCurrentAdId(id: adDetailsModel.id!);
// switch (adPostStatus) { // switch (adPostStatus) {
// case AdPostStatus.pendingForPayment: // case AdPostStatus.pendingForPayment:
// break; // break;
@ -802,7 +802,6 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
adVM.updateSelectionVehicleTypeId( adVM.updateSelectionVehicleTypeId(
SelectionModel(selectedId: adDetailsModel.vehicle!.vehicleType!, selectedOption: (adDetailsModel.vehicle!.vehicleType!).toVehicleTypeString(), errorValue: ""), SelectionModel(selectedId: adDetailsModel.vehicle!.vehicleType!, selectedOption: (adDetailsModel.vehicle!.vehicleType!).toVehicleTypeString(), errorValue: ""),
); );
showMyBottomSheet(context, child: const AdDurationSelectionSheetContent(isFromExtendAd: true, isUpdateAdSelected: true)); showMyBottomSheet(context, child: const AdDurationSelectionSheetContent(isFromExtendAd: true, isUpdateAdSelected: true));
}, },
), ),
@ -868,7 +867,6 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
context.read<PaymentVM>().updateCurrentAdId(id: adDetailsModel.id!);
switch (adDetailsModel.adPostStatus!) { switch (adDetailsModel.adPostStatus!) {
case AdPostStatus.pendingForPayment: case AdPostStatus.pendingForPayment:
return pendingForPaymentAction(context, adID: adDetailsModel.id!); return pendingForPaymentAction(context, adID: adDetailsModel.id!);

@ -0,0 +1,138 @@
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/models/widgets_models.dart';
import 'package:mc_common_app/theme/colors.dart';
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/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/common_widgets/search_entity_widget.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart';
import 'package:sizer/sizer.dart';
class AdsFilterView extends StatelessWidget {
const AdsFilterView({super.key});
//
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
title: "Ads Filter",
profileImageUrl: MyAssets.bnCar,
isRemoveBackButton: false,
isDrawerEnabled: false,
onBackButtonTapped: () {
context.read<AdVM>().resetValues();
Navigator.pop(context);
},
),
body: Consumer<AdVM>(
builder: (BuildContext context, AdVM adVM, Widget? child) {
return WillPopScope(
onWillPop: () async {
context.read<AdVM>().resetValues();
return true;
},
child: Column(
children: [
ListView(
children: [
20.height,
SearchEntityWidget(
title: "Search By Location",
actionWidget: Builder(builder: (context) {
List<DropValue> vehicleBrandsDrop = [];
for (var element in adVM.vehicleCities) {
vehicleBrandsDrop.add(DropValue(element.id?.toInt() ?? 0, element.cityName ?? "", ""));
}
return DropdownField(
(DropValue value) => adVM.updateSelectionVehicleCityId(SelectionModel(selectedId: value.id, selectedOption: value.value), isForSearch: true),
list: vehicleBrandsDrop,
dropdownValue: adVM.vehicleCityId.selectedId != -1 ? DropValue(adVM.vehicleCityId.selectedId, adVM.vehicleCityId.selectedOption, "") : null,
hint: "Select Location",
errorValue: adVM.vehicleCityId.errorValue,
);
}),
historyContent: adVM.vehicleLocationAdSearchHistory,
onHistoryItemDeleted: (index) {
adVM.removeVehicleLocationAdSearchHistory(index: index);
},
onHistoryItemTapped: (DropValue value) => adVM.updateSelectionVehicleCityId(SelectionModel(selectedId: value.id, selectedOption: value.value), isForSearch: true),
),
const Divider(thickness: 1.2).paddingOnly(top: 7, bottom: 7),
SearchEntityWidget(
title: "Search By Brand Name",
actionWidget: Builder(builder: (context) {
List<DropValue> vehicleBrandsDrop = [];
for (var element in adVM.vehicleBrands) {
vehicleBrandsDrop.add(DropValue(element.id?.toInt() ?? 0, element.vehicleBrandDescription ?? "", ""));
}
return DropdownField(
(DropValue value) => adVM.updateSelectionVehicleBrandId(SelectionModel(selectedId: value.id, selectedOption: value.value), isForSearch: true),
list: vehicleBrandsDrop,
dropdownValue: adVM.vehicleBrandId.selectedId != -1 ? DropValue(adVM.vehicleBrandId.selectedId, adVM.vehicleBrandId.selectedOption, "") : null,
hint: "Select Vehicle Brand",
errorValue: adVM.vehicleBrandId.errorValue,
);
}),
historyContent: adVM.vehicleBrandsAdSearchHistory,
onHistoryItemDeleted: (index) => adVM.removeVehicleBrandsAdSearchHistory(index: index),
onHistoryItemTapped: (DropValue value) => adVM.updateSelectionVehicleBrandId(SelectionModel(selectedId: value.id, selectedOption: value.value), isForSearch: true),
),
const Divider(thickness: 1.2).paddingOnly(top: 7, bottom: 7),
SearchEntityWidget(
title: "Search By Year",
actionWidget: Builder(builder: (context) {
List<DropValue> vehicleBrandsDrop = [];
for (var element in adVM.vehicleModelYears) {
vehicleBrandsDrop.add(DropValue(element.id?.toInt() ?? 0, element.modelYear ?? "", ""));
}
return DropdownField(
(DropValue value) => adVM.updateSelectionVehicleModelYearId(SelectionModel(selectedId: value.id, selectedOption: value.value), isForSearch: true),
list: vehicleBrandsDrop,
dropdownValue: adVM.vehicleModelYearId.selectedId != -1 ? DropValue(adVM.vehicleModelYearId.selectedId, adVM.vehicleModelYearId.selectedOption, "") : null,
hint: "Select Year",
errorValue: adVM.vehicleModelYearId.errorValue,
);
}),
historyContent: adVM.vehicleYearAdSearchHistory,
onHistoryItemDeleted: (index) => adVM.removeVehicleYearAdSearchHistory(index: index),
onHistoryItemTapped: (DropValue value) => adVM.updateSelectionVehicleModelYearId(SelectionModel(selectedId: value.id, selectedOption: value.value), isForSearch: true),
)
],
).expand(),
Container(
color: MyColors.white,
child: Column(
children: [
5.height,
Row(
children: [
Expanded(
child: ShowFillButton(
maxHeight: 55,
title: "Search",
onPressed: () {},
backgroundColor: MyColors.darkPrimaryColor,
txtColor: MyColors.white,
fontSize: 18,
),
)
],
),
10.height,
],
),
),
],
).horPaddingMain(),
);
},
),
);
}
}

@ -1,19 +0,0 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
class AdsSearchFilterView extends StatelessWidget {
const AdsSearchFilterView({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
title: "Filter Ads",
profileImageUrl: MyAssets.bnCar,
isRemoveBackButton: false,
isDrawerEnabled: false,
),
);
}
}

@ -0,0 +1,50 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/extensions/int_extensions.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 CustomRectangleChip extends StatelessWidget {
final String text;
final double? height;
final double? width;
final Color bgColor;
final Color textColor;
final Function() onHistoryItemDeleted;
final Function() onHistoryItemTapped;
const CustomRectangleChip({
super.key,
this.bgColor = MyColors.chipColor,
required this.text,
this.textColor = MyColors.darkTextColor,
this.width,
this.height = 28,
required this.onHistoryItemDeleted,
required this.onHistoryItemTapped,
});
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 10),
color: bgColor,
height: height,
child: Row(
children: [
text.toText(fontSize: 15, color: MyColors.darkTextColor),
8.width,
Container(
height: 15,
width: 15,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: MyColors.roundedCrossBgColor,
),
child: const Icon(Icons.close, color: MyColors.white, size: 10),
).onPress(onHistoryItemDeleted),
],
),
).onPress(onHistoryItemTapped);
}
}

@ -1,11 +1,16 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
class ServiceProviderWidget extends StatelessWidget { class ServiceProviderWidget extends StatelessWidget {
const ServiceProviderWidget({Key? key}) : super(key: key); final List<BranchDetailModel> nearbyBranches;
const ServiceProviderWidget({Key? key, required this.nearbyBranches}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -13,10 +18,11 @@ class ServiceProviderWidget extends StatelessWidget {
width: double.infinity, width: double.infinity,
height: 140, height: 140,
child: ListView.builder( child: ListView.builder(
itemCount: 9, itemCount: nearbyBranches.length,
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
shrinkWrap: true, shrinkWrap: true,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
BranchDetailModel branchDetailModel = nearbyBranches[index];
return SizedBox( return SizedBox(
width: 90, width: 90,
child: Column( child: Column(
@ -28,10 +34,12 @@ class ServiceProviderWidget extends StatelessWidget {
fit: BoxFit.cover, fit: BoxFit.cover,
).toCircle(borderRadius: 100), ).toCircle(borderRadius: 100),
8.height, 8.height,
"Olaya Branch".toText(fontSize: 14, isBold: true, textAlign: TextAlign.center), "${branchDetailModel.branchName}".toText(fontSize: 14, isBold: true, textAlign: TextAlign.center),
], ],
), ),
); ).onPress(() {
navigateWithName(context, AppRoutes.branchDetailPage, arguments: branchDetailModel);
});
}, },
), ),
); );

@ -0,0 +1,56 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/widgets/common_widgets/custom_rectangle_chip.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
class SearchEntityWidget extends StatelessWidget {
final String title;
final Widget actionWidget;
final List<DropValue> historyContent;
final Function(int) onHistoryItemDeleted;
final Function(DropValue) onHistoryItemTapped;
const SearchEntityWidget({
super.key,
required this.title,
required this.actionWidget,
required this.historyContent,
required this.onHistoryItemDeleted,
required this.onHistoryItemTapped,
});
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
title.toText(fontSize: 16, isBold: true),
8.height,
actionWidget,
10.height,
historyContent.isNotEmpty
? SizedBox(
height: 33,
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: historyContent.length,
itemBuilder: (BuildContext context, int index) {
return CustomRectangleChip(
text: historyContent[index].value,
onHistoryItemDeleted: () {
onHistoryItemDeleted(index);
},
onHistoryItemTapped: () {
onHistoryItemTapped(historyContent[index]);
},
).paddingOnly(right: 10);
}),
)
: const SizedBox.shrink(),
],
);
}
}

@ -23,6 +23,9 @@ class BuildTimeSlots extends StatelessWidget {
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
return InkWell( return InkWell(
onTap: () { onTap: () {
if (!timeSlots[index].allowAppointment) {
return;
}
onPressed(index); onPressed(index);
}, },
child: Container( child: Container(
@ -31,9 +34,9 @@ class BuildTimeSlots extends StatelessWidget {
// width: 50, // width: 50,
padding: const EdgeInsets.symmetric(horizontal: 9), padding: const EdgeInsets.symmetric(horizontal: 9),
decoration: BoxDecoration( decoration: BoxDecoration(
color: timeSlots[index].isSelected ? MyColors.darkIconColor : null, color: timeSlots[index].allowAppointment ? (timeSlots[index].isSelected ? MyColors.darkIconColor : null) : null,
border: Border.all( border: Border.all(
color: timeSlots[index].isSelected ? MyColors.darkIconColor : MyColors.primaryColor, color: timeSlots[index].allowAppointment ? (timeSlots[index].isSelected ? MyColors.darkIconColor : MyColors.primaryColor) : Colors.grey,
), ),
), ),
child: timeSlots[index].slot.toText( child: timeSlots[index].slot.toText(

@ -55,7 +55,7 @@ class _DropdownFieldState extends State<DropdownField> {
Container( Container(
decoration: widget.showAppointmentPickerVariant ? null : Utils.containerColorRadiusBorderWidth(MyColors.white, 0, MyColors.darkPrimaryColor, 2), decoration: widget.showAppointmentPickerVariant ? null : Utils.containerColorRadiusBorderWidth(MyColors.white, 0, MyColors.darkPrimaryColor, 2),
margin: const EdgeInsets.all(0), margin: const EdgeInsets.all(0),
// padding: const EdgeInsets.only(left: 0, right: ), padding: const EdgeInsets.only(left: 8, right: 8),
width: widget.showAppointmentPickerVariant ? 170 : null, width: widget.showAppointmentPickerVariant ? 170 : null,
child: DropdownButton<DropValue>( child: DropdownButton<DropValue>(
value: dropdownValue, value: dropdownValue,

Loading…
Cancel
Save