Added Branch FilterView and their API integrations

localization_aamir
Faiz Hashmi 1 year ago
parent 342d9b2672
commit 55c3af0540

@ -50,6 +50,7 @@ class ApiConsts {
static String ServiceProviderService_Get = "${baseUrlServices}api/ServiceProviders/ServiceProviderService_Get";
static String BranchesAndServices = "${baseUrlServices}api/ServiceProviders/ServiceProviderDetail_Get";
static String serviceProviderDDLGet = "${baseUrlServices}api/ServiceProviders/ServiceProviderDDL_Get";
static String GetAllNearBranches = "${baseUrlServices}api/ServiceProviders/ServiceProviderBranchDetail_Get";
//Appointment APIs
@ -100,7 +101,7 @@ class ApiConsts {
static String vehicleDetailsMaster = "${baseUrlServices}api/Master";
static String vehicleAdsDurationGet = "${baseUrlServices}api/Advertisement/AdsDuration_Get";
static String vehicleAdsSpecialServicesGet = "${baseUrlServices}api/Common/SpecialService_Get";
static String vehicleAdsSingleStepCreate = "${baseUrlServices}api/Advertisement/AdsSingl`eStep_Create";
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 reserveAdsBankDetailsGet = "${baseUrlServices}api/Advertisement/MCBankAccountAd_Get";

@ -10,7 +10,6 @@ import 'package:mc_common_app/repositories/branch_repo.dart';
import 'package:mc_common_app/repositories/chat_repo.dart';
import 'package:mc_common_app/repositories/common_repo.dart';
import 'package:mc_common_app/repositories/payments_repo.dart';
import 'package:mc_common_app/repositories/provider_repo.dart';
import 'package:mc_common_app/repositories/user_repo.dart';
import 'package:mc_common_app/services/common_services.dart';
import 'package:mc_common_app/services/payments_service.dart';
@ -33,7 +32,6 @@ class AppDependencies {
injector.registerSingleton<AdsRepo>(() => AdsRepoImp());
injector.registerSingleton<PaymentsRepo>(() => PaymentsRepoImp());
injector.registerSingleton<RequestRepo>(() => RequestRepoImp());
injector.registerSingleton<ProviderRepo>(() => ProviderRepoImp());
injector.registerSingleton<AppointmentRepo>(() => AppointmentRepoImp());
injector.registerSingleton<ChatRepo>(() => ChatRepoImp());
injector.registerSingleton<BranchRepo>(() => BranchRepoImp());

@ -23,16 +23,14 @@ class ProviderModel {
final ProviderModelData? data;
final String? message;
factory ProviderModel.fromJson(Map<String, dynamic> json) =>
ProviderModel(
factory ProviderModel.fromJson(Map<String, dynamic> json) => ProviderModel(
messageStatus: json["messageStatus"],
totalItemsCount: json["totalItemsCount"],
data: json["data"] == null ? null : ProviderModelData.fromJson(json["data"]),
message: json["message"],
);
Map<String, dynamic> toJson() =>
{
Map<String, dynamic> toJson() => {
"messageStatus": messageStatus,
"totalItemsCount": totalItemsCount,
"data": data == null ? null : data!.toJson(),
@ -63,8 +61,7 @@ class ProviderModelData {
final String? userId;
final List<BranchDetailModel>? serviceProviderBranch;
factory ProviderModelData.fromJson(Map<String, dynamic> json) =>
ProviderModelData(
factory ProviderModelData.fromJson(Map<String, dynamic> json) => ProviderModelData(
id: json["id"],
companyName: json["companyName"],
countryName: json["countryName"],
@ -76,8 +73,7 @@ class ProviderModelData {
serviceProviderBranch: json["serviceProviderBranch"] == null ? null : List<BranchDetailModel>.from(json["serviceProviderBranch"].map((x) => BranchDetailModel.fromJson(x))),
);
Map<String, dynamic> toJson() =>
{
Map<String, dynamic> toJson() => {
"id": id,
"companyName": companyName,
"companyDescription": companyDescription,
@ -88,3 +84,24 @@ class ProviderModelData {
};
}
class ProviderBasicDataModel {
int? id;
String? providerName;
String? providerDescription;
ProviderBasicDataModel({this.id, this.providerName, this.providerDescription});
ProviderBasicDataModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
providerName = json['providerName'];
providerDescription = json['providerDescription'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['providerName'] = providerName;
data['providerDescription'] = providerDescription;
return data;
}
}

@ -4,14 +4,18 @@ import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/dependencies.dart';
import 'package:mc_common_app/models/general_models/generic_resp_model.dart';
import 'package:mc_common_app/models/general_models/m_response.dart';
import 'package:flutter/cupertino.dart';
import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/branch.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/categroy.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/document.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/services.dart';
import 'package:mc_common_app/models/provider_branches_models/provider_model.dart';
import 'package:mc_common_app/models/provider_branches_models/provider_profile_model.dart';
import 'package:mc_common_app/models/services_models/item_model.dart';
abstract class BranchRepo {
Future<MResponse> createBranch(String branchName, String branchDescription, String cityId, String address, String latitude, String longitude);
@ -34,6 +38,8 @@ abstract class BranchRepo {
Future<ProviderModel> getBranchAndServices();
Future<List<ProviderBasicDataModel>> getAllProvidersWitheBasicData();
Future<MResponse> createService(List<Map<String, dynamic>> map);
Future<MResponse> updateService(List<Map<String, dynamic>> map);
@ -51,9 +57,28 @@ abstract class BranchRepo {
Future<MResponse> removeDealerFromBranch(Map<String, dynamic> map);
Future<MResponse> addNewServicesInAppointment(Map<String, dynamic> map);
Future<List<BranchDetailModel>> getAllNearBranchAndServices();
Future<List<ItemData>> getServiceItems(int serviceId);
Future<ProviderProfileModel> getBranchAndServicesByProviderId(int providerId);
Future<List<BranchDetailModel>> getBranchesByFilters({
List<int>? providerIdsList,
List<int>? categoryIdsList,
List<int>? serviceIdsList,
int? distanceKm,
int? rating,
double? latitude,
double? longitude,
});
}
class BranchRepoImp implements BranchRepo {
ApiClient apiClient = injector.get<ApiClient>();
AppState appState = injector.get<AppState>();
@override
Future<MResponse> createBranch(String branchName, String branchDescription, String cityId, String address, String latitude, String longitude) async {
var postParams = {
@ -67,35 +92,34 @@ class BranchRepoImp implements BranchRepo {
"isActive": true
};
String t = AppState().getUser.data!.accessToken ?? "";
debugPrint("token " + t);
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.createProviderBranch, postParams, token: t);
return await apiClient.postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.createProviderBranch, postParams, token: t);
}
@override
Future<Branch> fetchAllBranches() async {
var postParams = {"ServiceProviderID": AppState().getUser.data?.userInfo?.providerId.toString() ?? ""};
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().getJsonForObject((json) => Branch.fromJson(json), ApiConsts.ServiceProviderBranchGet, queryParameters: postParams, token: t);
return await apiClient.getJsonForObject((json) => Branch.fromJson(json), ApiConsts.ServiceProviderBranchGet, queryParameters: postParams, token: t);
}
@override
Future<Category> fetchBranchCategory() async {
var postParams = {"ServiceProviderID": AppState().getUser.data?.userInfo?.providerId.toString() ?? ""};
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().getJsonForObject((json) => Category.fromJson(json), ApiConsts.ServiceCategory_Get, queryParameters: postParams, token: t);
return await apiClient.getJsonForObject((json) => Category.fromJson(json), ApiConsts.ServiceCategory_Get, queryParameters: postParams, token: t);
}
@override
Future<Services> fetchServicesByCategoryId({required int serviceCategoryId}) async {
var postParams = {"ServiceCategoryID": serviceCategoryId};
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().getJsonForObject((json) => Services.fromJson(json), ApiConsts.Services_Get, queryParameters: serviceCategoryId != -1 ? postParams : null, token: t);
return await apiClient.getJsonForObject((json) => Services.fromJson(json), ApiConsts.Services_Get, queryParameters: serviceCategoryId != -1 ? postParams : null, token: t);
}
@override
Future<MResponse> createNewService(List<Map<String, dynamic>> map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.ServiceProviderService_Create, map, token: t);
return await apiClient.postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.ServiceProviderService_Create, map, token: t);
}
@override
@ -127,16 +151,27 @@ class BranchRepoImp implements BranchRepo {
}
}
String t = AppState().getUser.data!.accessToken ?? "";
debugPrint("token " + t);
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.ServiceProviderDocument_Update, map, token: t);
return await apiClient.postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.ServiceProviderDocument_Update, map, token: t);
}
@override
Future<ProviderModel> getBranchAndServices() async {
var postParams = {"serviceProviderID": AppState().getUser.data?.userInfo?.providerId.toString() ?? ""};
String t = AppState().getUser.data!.accessToken ?? "";
print("tokeen121 " + t);
return await injector.get<ApiClient>().getJsonForObject((json) => ProviderModel.fromJson(json), ApiConsts.BranchesAndServices, queryParameters: postParams, token: t);
return await apiClient.getJsonForObject((json) => ProviderModel.fromJson(json), ApiConsts.BranchesAndServices, queryParameters: postParams, token: t);
}
@override
Future<List<ProviderBasicDataModel>> getAllProvidersWitheBasicData() async {
String t = AppState().getUser.data!.accessToken ?? "";
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
token: t,
(json) => GenericRespModel.fromJson(json),
ApiConsts.serviceProviderDDLGet,
);
List<ProviderBasicDataModel> providersList = List.generate(adsGenericModel.data.length, (index) => ProviderBasicDataModel.fromJson(adsGenericModel.data[index]));
return providersList;
}
@override
@ -158,19 +193,19 @@ class BranchRepoImp implements BranchRepo {
"isActive": isNeedToDelete
};
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.updateProviderBranch, postParams, token: t);
return await apiClient.postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.updateProviderBranch, postParams, token: t);
}
@override
Future<MResponse> createService(List<Map<String, dynamic>> map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.ServiceProviderService_Create, map, token: t);
return await apiClient.postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.ServiceProviderService_Create, map, token: t);
}
@override
Future<MResponse> updateService(List<Map<String, dynamic>> map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.ServiceProviderService_Update, map, token: t);
return await apiClient.postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.ServiceProviderService_Update, map, token: t);
}
@override
@ -181,37 +216,37 @@ class BranchRepoImp implements BranchRepo {
"CategoryID": categoryId.toString(),
};
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().getJsonForObject((json) => MResponse.fromJson(json), ApiConsts.getMatchedServices, queryParameters: postParams, token: t);
return await apiClient.getJsonForObject((json) => MResponse.fromJson(json), ApiConsts.getMatchedServices, queryParameters: postParams, token: t);
}
@override
Future<MResponse> duplicateItems(Map<String, dynamic> map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.duplicateItems, map, token: t);
return await apiClient.postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.duplicateItems, map, token: t);
}
@override
Future<MResponse> getAllProviderDealers(Map<String, dynamic> map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().getJsonForObject((json) => MResponse.fromJson(json), ApiConsts.getAllProviderDealers, queryParameters: map, token: t);
return await apiClient.getJsonForObject((json) => MResponse.fromJson(json), ApiConsts.getAllProviderDealers, queryParameters: map, token: t);
}
@override
Future<MResponse> getBranchUsers(Map<String, dynamic> map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().getJsonForObject((json) => MResponse.fromJson(json), ApiConsts.getBranchUser, queryParameters: map, token: t);
return await apiClient.getJsonForObject((json) => MResponse.fromJson(json), ApiConsts.getBranchUser, queryParameters: map, token: t);
}
@override
Future<MResponse> assignDealerToBranch(Map<String, dynamic> map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.assignDealerToBranch, map, token: t);
return await apiClient.postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.assignDealerToBranch, map, token: t);
}
@override
Future<MResponse> removeDealerFromBranch(Map<String, dynamic> map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.removeDealerFromBranch, map, token: t);
return await apiClient.postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.removeDealerFromBranch, map, token: t);
}
@override
@ -222,12 +257,92 @@ class BranchRepoImp implements BranchRepo {
};
String t = AppState().getUser.data!.accessToken ?? "";
debugPrint("token " + t);
return await injector.get<ApiClient>().getJsonForObject((json) => Services.fromJson(json), ApiConsts.GetProviderServices, queryParameters: postParams, token: t);
return await apiClient.getJsonForObject((json) => Services.fromJson(json), ApiConsts.GetProviderServices, queryParameters: postParams, token: t);
}
@override
Future<MResponse> addNewServicesInAppointment(Map<String, dynamic> map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.AddNewServicesInAppointment, map, token: t);
return await apiClient.postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.AddNewServicesInAppointment, map, token: t);
}
@override
Future<List<BranchDetailModel>> getAllNearBranchAndServices() async {
GenericRespModel adsGenericModel = await apiClient.getJsonForObject((json) => GenericRespModel.fromJson(json), ApiConsts.GetAllNearBranches, token: appState.getUser.data!.accessToken);
List<BranchDetailModel> nearBranches = List.generate(adsGenericModel.data.length, (index) => BranchDetailModel.fromJson(adsGenericModel.data[index]));
return nearBranches;
}
@override
Future<List<ItemData>> getServiceItems(int serviceId) async {
var queryParameters = {
"ServiceProviderServiceID": serviceId.toString(),
};
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.getServiceItems,
token: appState.getUser.data!.accessToken,
queryParameters: queryParameters,
);
List<ItemData> serviceItems = List.generate(adsGenericModel.data.length, (index) => ItemData.fromJson(adsGenericModel.data[index]));
return serviceItems;
}
@override
Future<ProviderProfileModel> getBranchAndServicesByProviderId(int providerId) async {
var postParams = {"serviceProviderID": providerId.toString()};
GenericRespModel adsGenericModel =
await apiClient.getJsonForObject((json) => GenericRespModel.fromJson(json), ApiConsts.BranchesAndServices, token: appState.getUser.data!.accessToken, queryParameters: postParams);
return ProviderProfileModel.fromJson(adsGenericModel.data);
}
@override
Future<List<BranchDetailModel>> getBranchesByFilters({
List<int>? providerIdsList,
List<int>? categoryIdsList,
List<int>? serviceIdsList,
int? distanceKm,
int? rating,
double? latitude,
double? longitude,
}) async {
List<String> providerIds = [];
if (providerIdsList != null) {
for (var element in providerIdsList) {
providerIds.add(element.toString());
}
}
List<String> categoryIds = [];
if (categoryIdsList != null) {
for (var element in categoryIdsList) {
categoryIds.add(element.toString());
}
}
List<String> serviceIds = [];
if (serviceIdsList != null) {
for (var element in serviceIdsList) {
serviceIds.add(element.toString());
}
}
var postParams = {
"ServiceProviderIDs": providerIds,
"ServiceCategoryIDs": categoryIds,
"ServiceIDs": serviceIds,
"DistanceByKM": "${distanceKm ?? 0}",
"Rating": "${rating ?? 0}",
"Latitude": latitude.toString(),
"Longitude": longitude.toString(),
};
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.GetAllNearBranches,
token: appState.getUser.data!.accessToken,
queryParameters: postParams,
);
List<BranchDetailModel> nearBranches = List.generate(adsGenericModel.data.length, (index) => BranchDetailModel.fromJson(adsGenericModel.data[index]));
return nearBranches;
}
}

@ -146,8 +146,8 @@ class CommonRepoImp implements CommonRepo {
token: appState.getUser.data!.accessToken,
);
List<EnumsModel> vehicleCities = List.generate(enumGenericModel.data.length, (index) => EnumsModel.fromJson(enumGenericModel.data[index]));
return vehicleCities;
List<EnumsModel> enums = List.generate(enumGenericModel.data.length, (index) => EnumsModel.fromJson(enumGenericModel.data[index]));
return enums;
}
@override

@ -1,55 +0,0 @@
import 'dart:async';
import 'package:mc_common_app/api/api_client.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/dependencies.dart';
import 'package:mc_common_app/models/general_models/generic_resp_model.dart';
import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart';
import 'package:mc_common_app/models/provider_branches_models/provider_profile_model.dart';
import 'package:mc_common_app/models/services_models/item_model.dart';
abstract class ProviderRepo {
Future<List<BranchDetailModel>> getAllNearBranchAndServices();
Future<List<ItemData>> getServiceItems(int serviceId);
Future<ProviderProfileModel> getBranchAndServices(int providerId);
}
class ProviderRepoImp implements ProviderRepo {
ApiClient apiClient = injector.get<ApiClient>();
AppState appState = injector.get<AppState>();
@override
Future<List<BranchDetailModel>> getAllNearBranchAndServices() async {
GenericRespModel adsGenericModel = await apiClient.getJsonForObject((json) => GenericRespModel.fromJson(json), ApiConsts.GetAllNearBranches, token: appState.getUser.data!.accessToken);
List<BranchDetailModel> nearBranches = List.generate(adsGenericModel.data.length, (index) => BranchDetailModel.fromJson(adsGenericModel.data[index]));
return nearBranches;
}
@override
Future<List<ItemData>> getServiceItems(int serviceId) async {
var queryParameters = {
"ServiceProviderServiceID": serviceId.toString(),
};
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.getServiceItems,
token: appState.getUser.data!.accessToken,
queryParameters: queryParameters,
);
List<ItemData> serviceItems = List.generate(adsGenericModel.data.length, (index) => ItemData.fromJson(adsGenericModel.data[index]));
return serviceItems;
}
@override
Future<ProviderProfileModel> getBranchAndServices(int providerId) async {
var postParams = {"serviceProviderID": providerId.toString()};
GenericRespModel adsGenericModel =
await apiClient.getJsonForObject((json) => GenericRespModel.fromJson(json), ApiConsts.BranchesAndServices, token: appState.getUser.data!.accessToken, queryParameters: postParams);
return ProviderProfileModel.fromJson(adsGenericModel.data);
}
}

@ -1,9 +1,12 @@
import 'dart:developer';
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/appointments_models/appointment_list_model.dart';
import 'package:mc_common_app/models/appointments_models/appointment_slots.dart';
import 'package:mc_common_app/models/appointments_models/service_schedule_model.dart';
import 'package:mc_common_app/models/general_models/enums_model.dart';
import 'package:mc_common_app/models/general_models/generic_resp_model.dart';
@ -12,13 +15,13 @@ import 'package:mc_common_app/models/general_models/widgets_models.dart';
import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/categroy.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/services.dart';
import 'package:mc_common_app/models/provider_branches_models/provider_model.dart';
import 'package:mc_common_app/models/provider_branches_models/provider_profile_model.dart';
import 'package:mc_common_app/models/services_models/item_model.dart';
import 'package:mc_common_app/models/services_models/service_model.dart';
import 'package:mc_common_app/repositories/appointment_repo.dart';
import 'package:mc_common_app/repositories/branch_repo.dart';
import 'package:mc_common_app/repositories/common_repo.dart';
import 'package:mc_common_app/repositories/provider_repo.dart';
import 'package:mc_common_app/services/common_services.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart';
@ -34,16 +37,13 @@ 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 '../models/appointments_models/appointment_slots.dart';
class AppointmentsVM extends BaseVM {
final CommonRepo commonRepo;
final CommonAppServices commonServices;
final ProviderRepo providerRepo;
final BranchRepo branchRepo;
final AppointmentRepo scheduleRepo;
AppointmentsVM({required this.commonServices, required this.scheduleRepo, required this.providerRepo, required this.commonRepo, required this.branchRepo});
AppointmentsVM({required this.commonServices, required this.scheduleRepo, required this.commonRepo, required this.branchRepo});
bool isUpcommingEnabled = true;
bool isFetchingLists = false;
@ -221,7 +221,7 @@ class AppointmentsVM extends BaseVM {
notifyListeners();
}
List<FilterListModel> providersFilterOptions = [];
List<FilterListModel> branchesFilterOptions = [];
List<ServiceModel> servicesInCurrentAppointment = [];
ServiceModel? currentServiceSelection;
@ -279,11 +279,11 @@ class AppointmentsVM extends BaseVM {
value.isSelected = false;
}
appointmentsFilterOptions.forEach((element) {
for (var element in appointmentsFilterOptions) {
if (element.id == appointmentStatusEnum.getIdFromAppointmentStatusEnum()) {
element.isSelected = true;
}
});
}
// appointmentsFilterOptions[
// appointmentStatusEnum.getIdFromAppointmentStatusEnum()]
// .isSelected = true;
@ -495,18 +495,20 @@ class AppointmentsVM extends BaseVM {
notifyListeners();
}
applyFilterOnProviders({required int index}) {
if (providersFilterOptions.isEmpty) return;
for (var value in providersFilterOptions) {
applyFilterOnBranches({required int index}) async {
if (branchesFilterOptions.isEmpty) return;
for (var value in branchesFilterOptions) {
value.isSelected = false;
}
providersFilterOptions[index].isSelected = true;
branchesFilterOptions[index].isSelected = true;
await getBranchesBasedOnCategoryFilters(categoryId: branchesFilterOptions[index].id);
notifyListeners();
}
Future<List<ItemData>> getServiceItems(int serviceId) async {
serviceItemsFromApi.clear();
serviceItemsFromApi = await providerRepo.getServiceItems(serviceId);
serviceItemsFromApi = await branchRepo.getServiceItems(serviceId);
for (var item in serviceItemsFromApi) {
if (ifItemAlreadySelected(item.id!)) {
item.isUpdateOrSelected = true;
@ -783,24 +785,43 @@ class AppointmentsVM extends BaseVM {
List<ServiceModel> branchServices = [];
populateBranchesFilterList() {
providersFilterOptions.clear(); // TODO: THIS SHOULD BE DYNAMIC AND FILTERS SHOULD COME FORM API
providersFilterOptions = [
FilterListModel(title: "All Providers", isSelected: true, id: 0),
FilterListModel(title: "Maintenance", isSelected: false, id: 1),
FilterListModel(title: "Oil Service", isSelected: false, id: 2),
FilterListModel(title: "Accessories", isSelected: false, id: 3),
FilterListModel(title: "Tire Service", isSelected: false, id: 4),
FilterListModel(title: "Dent and Paint", isSelected: false, id: 5),
];
// populateBranchesFilterList() {
// branchesFilterOptions.clear(); // TODO: THIS SHOULD BE DYNAMIC AND FILTERS SHOULD COME FORM API
// branchesFilterOptions = [
// FilterListModel(title: "All Branches", isSelected: true, id: 0),
// FilterListModel(title: "Maintenance", isSelected: false, id: 1),
// FilterListModel(title: "Oil Service", isSelected: false, id: 2),
// FilterListModel(title: "Accessories", isSelected: false, id: 3),
// FilterListModel(title: "Tire Service", isSelected: false, id: 4),
// FilterListModel(title: "Dent and Paint", isSelected: false, id: 5),
// ];
// notifyListeners();
// }
Future<void> populateBranchesFilterList() async {
if (branchesFilterOptions.isNotEmpty) return;
branchesFilterOptions.clear();
setOnlyState(ViewState.busy);
Category category = await branchRepo.fetchBranchCategory();
category.data?.forEach((element) {
branchesFilterOptions.add(FilterListModel(id: element.id ?? 0, isSelected: false, title: element.categoryName ?? "N/A"));
});
branchesFilterOptions.insert(0, FilterListModel(id: 0, isSelected: true, title: "All Branches"));
notifyListeners();
setState(ViewState.idle);
}
getAllNearBranches({bool isNeedToRebuild = false}) async {
//TODO: needs to lat,long into API
getAllNearBranches({bool isNeedToRebuild = false, bool isFromRefresh = false}) async {
nearbyBranches.clear();
if (isNeedToRebuild) setState(ViewState.busy);
nearbyBranches = await providerRepo.getAllNearBranchAndServices();
if (isFromRefresh) {
var selectedBranch = branchesFilterOptions.firstWhere((element) => element.isSelected);
nearbyBranches = await branchRepo.getBranchesByFilters(categoryIdsList: [selectedBranch.id]);
setState(ViewState.idle);
return;
}
nearbyBranches = await branchRepo.getAllNearBranchAndServices();
setState(ViewState.idle);
}
@ -833,7 +854,7 @@ class AppointmentsVM extends BaseVM {
getBranchAndServices(int providerId) async {
providerProfileModel = null;
providerProfileModel = await providerRepo.getBranchAndServices(providerId);
providerProfileModel = await branchRepo.getBranchAndServicesByProviderId(providerId);
setState(ViewState.idle);
}
@ -851,6 +872,13 @@ class AppointmentsVM extends BaseVM {
notifyListeners();
}
int branchFiltersCounter = 0;
updateBranchFiltersCounter(int value) {
branchFiltersCounter = value;
notifyListeners();
}
double branchFilterCurrentDistance = 25.0;
updateBranchFilterCurrentDistance(double value) {
@ -868,17 +896,33 @@ class AppointmentsVM extends BaseVM {
return;
}
branchFilterProviderSearchHistory.removeAt(index);
if (branchFilterProviderSearchHistory.isEmpty) {
updateBranchFiltersCounter(branchFiltersCounter - 1);
}
notifyListeners();
}
void addBranchFilterProviderSearchHistory({required DropValue value}) {
if (branchFilterProviderSearchHistory.isEmpty) {
updateBranchFiltersCounter(branchFiltersCounter + 1);
}
branchFilterProviderSearchHistory.add(value);
notifyListeners();
}
SelectionModel branchFilterSelectedProviderId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updateBranchFilterSelectedProviderId(SelectionModel id, {bool isForSearch = false}) async {}
void updateBranchFilterSelectedProviderId(SelectionModel id, {bool isForSearch = false}) async {
if (isForSearch) {
DropValue providerDrop = providersDropList.firstWhere((element) => element.id == id.selectedId);
if (!ifAlreadyExist(list: branchFilterProviderSearchHistory, value: providerDrop)) {
addBranchFilterProviderSearchHistory(value: providerDrop);
}
}
branchFilterSelectedProviderId = id;
notifyListeners();
}
// Category Filter
List<DropValue> branchFilterCategorySearchHistory = [];
@ -890,10 +934,16 @@ class AppointmentsVM extends BaseVM {
return;
}
branchFilterCategorySearchHistory.removeAt(index);
if (branchFilterCategorySearchHistory.isEmpty) {
updateBranchFiltersCounter(branchFiltersCounter - 1);
}
notifyListeners();
}
void addBranchFilterCategorySearchHistory({required DropValue value}) {
if (branchFilterCategorySearchHistory.isEmpty) {
updateBranchFiltersCounter(branchFiltersCounter + 1);
}
branchFilterCategorySearchHistory.add(value);
notifyListeners();
}
@ -912,8 +962,6 @@ class AppointmentsVM extends BaseVM {
notifyListeners();
}
// Services Filter
List<DropValue> branchFilterServicesSearchHistory = [];
@ -924,10 +972,16 @@ class AppointmentsVM extends BaseVM {
return;
}
branchFilterServicesSearchHistory.removeAt(index);
if (branchFilterServicesSearchHistory.isEmpty) {
updateBranchFiltersCounter(branchFiltersCounter - 1);
}
notifyListeners();
}
void addBranchFilterServicesSearchHistory({required DropValue value}) {
if (branchFilterServicesSearchHistory.isEmpty) {
updateBranchFiltersCounter(branchFiltersCounter + 1);
}
branchFilterServicesSearchHistory.add(value);
notifyListeners();
}
@ -936,7 +990,7 @@ class AppointmentsVM extends BaseVM {
void updateBranchFilterSelectedServiceId(SelectionModel id, {bool isForSearch = false}) async {
if (isForSearch) {
DropValue serviceDrop = categoryDropList.firstWhere((element) => element.id == id.selectedId);
DropValue serviceDrop = servicesDropList.firstWhere((element) => element.id == id.selectedId);
if (!ifAlreadyExist(list: branchFilterServicesSearchHistory, value: serviceDrop)) {
addBranchFilterServicesSearchHistory(value: serviceDrop);
}
@ -944,7 +998,6 @@ class AppointmentsVM extends BaseVM {
branchFilterSelectedServiceId = id;
notifyListeners();
}
ifAlreadyExist({required List<DropValue> list, required DropValue value}) {
@ -959,39 +1012,57 @@ class AppointmentsVM extends BaseVM {
return false;
}
// Rating filter
double branchFilterByRating = 4.0;
updateBranchFilterByRating(double value) {
branchFilterByRating = value;
notifyListeners();
}
List<DropValue> categoryDropList = [];
List<DropValue> servicesDropList = [];
List<DropValue> providersDropList = [];
Future<void> fetchAllProviders() async {
if (providersDropList.isNotEmpty) return;
providersDropList.clear();
setOnlyState(ViewState.busy);
providersDropList.clear(); // IN PROGRESS
List<ProviderBasicDataModel> providers = await branchRepo.getAllProvidersWitheBasicData();
for (var element in providers) {
providersDropList.add(
DropValue(element.id ?? 0, element.providerName ?? "N/A", ""),
);
}
setState(ViewState.idle);
}
Future<void> fetchAllCategories(String countryCode) async {
if (categoryDropList.isNotEmpty) return;
categoryDropList.clear();
setOnlyState(ViewState.busy);
Category category = await branchRepo.fetchBranchCategory();
category.data?.forEach((element) {
categoryDropList.add(
DropValue(
element.id ?? 0,
((element.categoryName!.isEmpty
? "N/A"
: countryCode == "SA"
? element.categoryNameN
: element.categoryName) ??
"N/A"),
"",
),
element.id ?? 0,
((element.categoryName!.isEmpty
? "N/A"
: countryCode == "SA"
? element.categoryNameN
: element.categoryName) ??
"N/A"),
""),
);
});
setState(ViewState.idle);
}
Future<void> fetchAllServices() async {
servicesDropList = [];
if (servicesDropList.isNotEmpty) return;
servicesDropList.clear();
setState(ViewState.busy);
Services services = await branchRepo.fetchServicesByCategoryId(serviceCategoryId: -1); // to get all services
@ -1008,8 +1079,72 @@ class AppointmentsVM extends BaseVM {
}
Future<void> populateDataForBranchesFilter() async {
await fetchAllProviders(); // saudi arabia
await fetchAllCategories("SA"); // saudi arabia
await fetchAllServices(); // saudi arabia
updateBranchFilterCurrentDistance(25.0);
}
void clearBranchFilters() {
branchFilterServicesSearchHistory.clear();
branchFilterCategorySearchHistory.clear();
branchFilterProviderSearchHistory.clear();
branchFilterByRating = 4.0;
branchFilterCurrentDistance = 25.0;
branchFiltersCounter = 0;
clearBranchFilterSelections();
notifyListeners();
}
void clearBranchFilterSelections() {
branchFilterSelectedProviderId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
branchFilterSelectedCategoryId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
branchFilterSelectedServiceId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
}
Future<void> getBranchesBasedOnFilters() async {
nearbyBranches.clear();
setState(ViewState.busy);
List<int> providersIdsList = [];
if (branchFilterProviderSearchHistory.isNotEmpty) {
for (var element in branchFilterProviderSearchHistory) {
providersIdsList.add(element.id);
}
}
List<int> categoryIdsList = [];
if (branchFilterCategorySearchHistory.isNotEmpty) {
for (var element in branchFilterCategorySearchHistory) {
categoryIdsList.add(element.id);
}
}
List<int> servicesIdsList = [];
if (branchFilterServicesSearchHistory.isNotEmpty) {
for (var element in branchFilterServicesSearchHistory) {
servicesIdsList.add(element.id);
}
}
nearbyBranches = await branchRepo.getBranchesByFilters(
providerIdsList: providersIdsList.isNotEmpty ? providersIdsList : null,
categoryIdsList: categoryIdsList.isNotEmpty ? categoryIdsList : null,
serviceIdsList: servicesIdsList.isNotEmpty ? servicesIdsList : null,
distanceKm: branchFilterCurrentDistance.toInt(),
rating: branchFilterByRating.toInt(),
latitude: 24.694969,
longitude: 46.724129,
);
setState(ViewState.idle);
}
Future<void> getBranchesBasedOnCategoryFilters({required int categoryId}) async {
if (categoryId == 0) {
await getAllNearBranches();
return;
}
setState(ViewState.busy);
nearbyBranches.clear();
nearbyBranches = await branchRepo.getBranchesByFilters(categoryIdsList: [categoryId]);
setState(ViewState.idle);
}
}

@ -154,7 +154,7 @@ class AdDuration extends StatelessWidget {
child: CupertinoSwitch(
activeColor: MyColors.darkPrimaryColor,
trackColor: MyColors.white,
thumbColor: MyColors.grey98Color,
thumbColor: MyColors.greyButtonColor,
value: adVM.isPhoneNumberShown,
onChanged: (value) {
adVM.updateIsPhoneNumberShownStatus(value);
@ -190,6 +190,7 @@ class AdDuration extends StatelessWidget {
),
errorValue: adVM.adPhoneNumberError,
hint: '123456789',
keyboardType: TextInputType.number,
value: adVM.adPhoneNumber,
onChanged: (v) => adVM.updateAdPhoneNumber(v),
),

@ -15,10 +15,10 @@ class ReviewAd extends StatelessWidget {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
VehicleDetailsReview().toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 4)),
DamagePartsReview().toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 4)),
AdDurationReview().toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 4)),
AdContactDetailsReview(),
const VehicleDetailsReview().toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 4)),
const DamagePartsReview(),
const AdDurationReview().toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 4)),
const AdContactDetailsReview(),
],
);
}
@ -160,14 +160,16 @@ class DamagePartsReview extends StatelessWidget {
@override
Widget build(BuildContext context) {
AdVM adVM = context.read<AdVM>();
if (adVM.vehicleDamageCards.isEmpty) {
return const SizedBox.shrink();
}
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Vehicle Damage Part".toText(fontSize: 18, isBold: true),
buildDamagePartList(adVM),
],
);
).toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 4));
}
}

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
@ -14,9 +16,31 @@ 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';
class BranchesFilterView extends StatelessWidget {
class BranchesFilterView extends StatefulWidget {
const BranchesFilterView({super.key});
@override
State<BranchesFilterView> createState() => _BranchesFilterViewState();
}
class _BranchesFilterViewState extends State<BranchesFilterView> {
late AppointmentsVM appointmentsVM;
@override
void initState() {
appointmentsVM = context.read<AppointmentsVM>();
scheduleMicrotask(() async {
await appointmentsVM.populateDataForBranchesFilter();
});
super.initState();
}
@override
void dispose() {
appointmentsVM.clearBranchFilterSelections();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
@ -43,7 +67,7 @@ class BranchesFilterView extends StatelessWidget {
children: [
20.height,
SearchEntityWidget(
title: "Search By Provider Name",
title: "Search By Provider",
actionWidget: Builder(
builder: (context) {
return DropdownField(
@ -63,22 +87,28 @@ class BranchesFilterView extends StatelessWidget {
onHistoryItemTapped: (DropValue value) =>
appointmentsVM.updateBranchFilterSelectedProviderId(SelectionModel(selectedId: value.id, selectedOption: value.value), isForSearch: true),
),
const Divider(thickness: 1.2).paddingOnly(top: 7, bottom: 7),
Row(
const Divider(thickness: 1.2).paddingOnly(top: 5, bottom: 5),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"0 KM".toText(fontSize: 12, isBold: true),
Expanded(
child: SliderWidget(
minValue: 0,
maxValue: 100,
value: appointmentsVM.branchFilterCurrentDistance,
onChanged: appointmentsVM.updateBranchFilterCurrentDistance,
),
"Search By Distance".toText(fontSize: 16, isBold: true),
Row(
children: [
"0 KM".toText(fontSize: 12, isBold: true),
Expanded(
child: SliderWidget(
minValue: 0,
maxValue: 100,
value: appointmentsVM.branchFilterCurrentDistance,
onChanged: appointmentsVM.updateBranchFilterCurrentDistance,
),
),
"${appointmentsVM.branchFilterCurrentDistance.toInt()} KM".toText(fontSize: 12, isBold: true),
],
),
"${appointmentsVM.branchFilterCurrentDistance.toInt()} KM".toText(fontSize: 12, isBold: true),
],
),
const Divider(thickness: 1.2).paddingOnly(top: 7, bottom: 7),
const Divider(thickness: 1.2).paddingOnly(top: 5, bottom: 5),
SearchEntityWidget(
title: "Search By Category",
actionWidget: Builder(
@ -100,9 +130,9 @@ class BranchesFilterView extends StatelessWidget {
onHistoryItemTapped: (DropValue value) =>
appointmentsVM.updateBranchFilterSelectedCategoryId(SelectionModel(selectedId: value.id, selectedOption: value.value), isForSearch: true),
),
const Divider(thickness: 1.2).paddingOnly(top: 7, bottom: 7),
const Divider(thickness: 1.2).paddingOnly(top: 5, bottom: 5),
SearchEntityWidget(
title: "Search By Services",
title: "Search By Service",
actionWidget: Builder(builder: (context) {
return DropdownField(
(DropValue value) => appointmentsVM.updateBranchFilterSelectedServiceId(SelectionModel(selectedId: value.id, selectedOption: value.value), isForSearch: true),
@ -115,9 +145,29 @@ class BranchesFilterView extends StatelessWidget {
}),
historyContent: appointmentsVM.branchFilterServicesSearchHistory,
onHistoryItemDeleted: (index) => appointmentsVM.removeBranchFilterServicesSearchHistory(index: index),
onHistoryItemTapped: (DropValue value) =>
appointmentsVM.updateBranchFilterSelectedServiceId(SelectionModel(selectedId: value.id, selectedOption: value.value), isForSearch: true),
)
onHistoryItemTapped: (DropValue value) => null,
),
const Divider(thickness: 1.2).paddingOnly(top: 5, bottom: 5),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Search By Minimum Ratings".toText(fontSize: 16, isBold: true),
Row(
children: [
"1 Star".toText(fontSize: 12, isBold: true),
Expanded(
child: SliderWidget(
minValue: 0,
maxValue: 5,
value: appointmentsVM.branchFilterByRating,
onChanged: appointmentsVM.updateBranchFilterByRating,
),
),
"${appointmentsVM.branchFilterByRating.toInt()} Star".toText(fontSize: 12, isBold: true),
],
),
],
),
],
).expand(),
Container(
@ -131,7 +181,10 @@ class BranchesFilterView extends StatelessWidget {
child: ShowFillButton(
maxHeight: 55,
title: "Search",
onPressed: () {},
onPressed: () {
Navigator.pop(context);
appointmentsVM.getBranchesBasedOnFilters();
},
backgroundColor: MyColors.darkPrimaryColor,
txtColor: MyColors.white,
fontSize: 18,
@ -139,6 +192,15 @@ class BranchesFilterView extends StatelessWidget {
)
],
),
8.height,
InkWell(
onTap: () => appointmentsVM.clearBranchFilters(),
child: "Clear Filters".toText(
fontSize: 14,
isBold: true,
color: MyColors.darkPrimaryColor,
),
),
10.height,
],
),

Loading…
Cancel
Save