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

@ -1,4 +1,5 @@
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';
class AppointmentListModel {
@ -17,7 +18,7 @@ class AppointmentListModel {
String? duration;
String? appointmentDate;
AppointmentStatusEnum? appointmentStatusEnum;
List<ServiceAppointmentItems>? serviceAppointmentItems;
List<ServiceModel>? appointmentServicesList;
AppointmentListModel(
{this.id,
@ -34,11 +35,11 @@ class AppointmentListModel {
this.providerName,
this.duration,
this.appointmentDate,
this.serviceAppointmentItems});
this.appointmentServicesList});
@override
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) {
@ -57,10 +58,11 @@ class AppointmentListModel {
duration = json['duration'];
appointmentDate = json['appointmentDate'];
appointmentStatusEnum = (json['appointmentStatusID'] as int).toAppointmentStatusEnum();
if (json['serviceAppointmentItems'] != null) {
serviceAppointmentItems = <ServiceAppointmentItems>[];
json['serviceAppointmentItems'].forEach((v) {
serviceAppointmentItems!.add(ServiceAppointmentItems.fromJson(v));
if (json['serviceList'] != null) {
appointmentServicesList = <ServiceModel>[];
json['serviceList'].forEach((v) {
appointmentServicesList!.add(ServiceModel.fromJson(v, isForAppointment: true));
});
}
}

@ -38,7 +38,7 @@ class ServiceAppointmentScheduleModel {
for (var element in serviceSlotList!) {
if (!isAlreadyThere(element.slotDate!, customTimeDateSlotList)) {
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!),
));
}
@ -97,12 +97,9 @@ class ServiceAppointmentScheduleModel {
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.
//TODO: AFTER THAT, I WILL
//comprehensive checkup and body checkup
ServiceAppointmentScheduleModel.fromJson
(Map<String, dynamic> json, {bool isForAppointment = false}) {
ServiceAppointmentScheduleModel.fromJson(Map<String, dynamic> json, {bool isForAppointment = false}) {
if (json['serviceSlotList'] != null) {
serviceSlotList = <ServiceSlotList>[];
json['serviceSlotList'].forEach((v) {

@ -86,8 +86,8 @@ class AdsRepoImp implements AdsRepo {
var postParams = {
"CountryID": countryId.toString(),
};
GenericRespModel adsGenericModel =
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleCityGet, queryParameters: postParams);
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
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]));
return vehicleCities;
}
@ -141,8 +141,12 @@ class AdsRepoImp implements AdsRepo {
var postParams = {
"VehicleType": vehicleTypeId.toString(),
};
GenericRespModel adsGenericModel =
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleModelYearGet, queryParameters: postParams);
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
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]));
return vehicleModelYears;
}
@ -152,8 +156,12 @@ class AdsRepoImp implements AdsRepo {
var postParams = {
"VehicleType": vehicleTypeId.toString(),
};
GenericRespModel adsGenericModel =
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleModelGet, queryParameters: postParams);
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
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]));
return vehicleModels;
}
@ -163,8 +171,12 @@ class AdsRepoImp implements AdsRepo {
var postParams = {
"VehicleType": vehicleTypeId.toString(),
};
GenericRespModel adsGenericModel =
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleBrandGet, queryParameters: postParams);
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
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]));
return vehicleBrands;
}
@ -174,8 +186,12 @@ class AdsRepoImp implements AdsRepo {
var postParams = {
"VehicleType": vehicleTypeId.toString(),
};
GenericRespModel adsGenericModel =
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleSellerTypeGet, queryParameters: postParams);
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
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]));
return vehicleSellerTypes;
}
@ -185,8 +201,12 @@ class AdsRepoImp implements AdsRepo {
var postParams = {
"VehicleType": vehicleTypeId.toString(),
};
GenericRespModel adsGenericModel =
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleTransmissionGet, queryParameters: postParams);
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
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]));
return vehicleTransmissions;
}

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

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

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

@ -417,7 +417,14 @@ class AdVM extends BaseVM {
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;
getVehicleDetailsByVehicleBrandId();
@ -433,7 +440,14 @@ class AdVM extends BaseVM {
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;
notifyListeners();
}
@ -534,7 +548,14 @@ class AdVM extends BaseVM {
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;
notifyListeners();
}
@ -1161,6 +1182,102 @@ class AdVM extends BaseVM {
);
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 {

@ -1,3 +1,5 @@
import 'dart:developer';
import 'package:flutter/cupertino.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
@ -23,6 +25,25 @@ class PaymentVM extends ChangeNotifier {
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) {
selectedPaymentMethod = selectedMethod;
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(
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,
onFailure: () {
Utils.showToast("Payment Failed!");
@ -81,6 +139,7 @@ class PaymentVM extends ChangeNotifier {
break;
case PaymentTypes.appointment:
// TODO: Handle this case.
log("Appointment Payment has been Failed!!");
break;
case PaymentTypes.adReserve:
// TODO: Handle this case.
@ -99,22 +158,16 @@ class PaymentVM extends ChangeNotifier {
onSuccess: () async {
switch (paymentTypeEnum) {
case PaymentTypes.subscription:
// TODO: Handle this case.
break;
case PaymentTypes.appointment:
// TODO: Handle this case.
break;
case PaymentTypes.adReserve:
// TODO: Handle this case.
break;
case PaymentTypes.ads:
await onAdsPaymentSuccess(context: context, paymentTypeId: paymentTypeEnum.getIdFromPaymentTypesEnum(), currentAdId: currentAdId);
log("Appointment Payment has been Succeeded");
break;
case PaymentTypes.request:
// TODO: Handle this case.
break;
case PaymentTypes.adReserve:
case PaymentTypes.ads:
case PaymentTypes.extendAds:
// TODO: Handle this case.
await onAdsPaymentSuccess(context: context, paymentTypeId: paymentTypeEnum.getIdFromPaymentTypesEnum(), currentAdId: currentAdId);
break;
}
},
@ -125,32 +178,21 @@ class PaymentVM extends ChangeNotifier {
currentPaymentType = paymentType;
switch (currentPaymentType) {
case PaymentTypes.appointment:
if (appointmentIdsForPayment.isEmpty) return;
await placeThePayment(context: context, paymentTypeEnum: paymentType);
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:
// TODO: Handle this case.
break;
case PaymentTypes.subscription:
// TODO: Handle this case.
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)),
list: vehicleTransmissionsDrop,
hint: "Vehicle Transmission",
dropdownValue: adVM.vehicleTransmissionId.selectedId != -1 ? DropValue(adVM.vehicleTransmissionId.selectedId, adVM.vehicleTransmissionId.selectedOption, "") : null,
errorValue: adVM.vehicleTransmissionId.errorValue,
);
}),

@ -65,6 +65,7 @@ class AdsDetailView extends StatelessWidget {
Widget build(BuildContext context) {
print("adId: ${adDetails.id}");
print("statusID: ${adDetails.statusID}");
context.read<PaymentVM>().updateCurrentAdId(id: adDetails.id!);
return Scaffold(
appBar: CustomAppBar(
title: "Ads",
@ -467,7 +468,6 @@ class BuildAdDetailsActionButtonForExploreAds extends StatelessWidget {
@override
Widget build(BuildContext context) {
context.read<PaymentVM>().updateCurrentAdId(id: adDetailsModel.id!);
// switch (adPostStatus) {
// case AdPostStatus.pendingForPayment:
// break;
@ -802,7 +802,6 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
adVM.updateSelectionVehicleTypeId(
SelectionModel(selectedId: adDetailsModel.vehicle!.vehicleType!, selectedOption: (adDetailsModel.vehicle!.vehicleType!).toVehicleTypeString(), errorValue: ""),
);
showMyBottomSheet(context, child: const AdDurationSelectionSheetContent(isFromExtendAd: true, isUpdateAdSelected: true));
},
),
@ -868,7 +867,6 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
@override
Widget build(BuildContext context) {
context.read<PaymentVM>().updateCurrentAdId(id: adDetailsModel.id!);
switch (adDetailsModel.adPostStatus!) {
case AdPostStatus.pendingForPayment:
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: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/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';
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
Widget build(BuildContext context) {
@ -13,10 +18,11 @@ class ServiceProviderWidget extends StatelessWidget {
width: double.infinity,
height: 140,
child: ListView.builder(
itemCount: 9,
itemCount: nearbyBranches.length,
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
BranchDetailModel branchDetailModel = nearbyBranches[index];
return SizedBox(
width: 90,
child: Column(
@ -28,10 +34,12 @@ class ServiceProviderWidget extends StatelessWidget {
fit: BoxFit.cover,
).toCircle(borderRadius: 100),
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) {
return InkWell(
onTap: () {
if (!timeSlots[index].allowAppointment) {
return;
}
onPressed(index);
},
child: Container(
@ -31,9 +34,9 @@ class BuildTimeSlots extends StatelessWidget {
// width: 50,
padding: const EdgeInsets.symmetric(horizontal: 9),
decoration: BoxDecoration(
color: timeSlots[index].isSelected ? MyColors.darkIconColor : null,
color: timeSlots[index].allowAppointment ? (timeSlots[index].isSelected ? MyColors.darkIconColor : null) : null,
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(

@ -55,7 +55,7 @@ class _DropdownFieldState extends State<DropdownField> {
Container(
decoration: widget.showAppointmentPickerVariant ? null : Utils.containerColorRadiusBorderWidth(MyColors.white, 0, MyColors.darkPrimaryColor, 2),
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,
child: DropdownButton<DropValue>(
value: dropdownValue,

Loading…
Cancel
Save