Book Appointment 1.0

mirza_development
Mirza.Shafique@cloudsolutions.com.sa 2 years ago
parent 6245aa9ef4
commit 5999804bc6

@ -46,6 +46,7 @@ class ApiConsts {
static String Services_Get = "${baseUrlServices}api/ServiceProviders/Services_Get";
static String ServiceProviderService_Create = "${baseUrlServices}api/ServiceProviders/ServiceProviderService_Create";
static String ServiceProviderService_Update = "${baseUrlServices}api/ServiceProviders/ServiceProviderService_Update";
static String GetProviderServices = "${baseUrlServices}api/ServiceProviders/ServiceProviderService_Get";
static String ServiceProviderService_Get = "${baseUrlServices}api/ServiceProviders/ServiceProviderService_Get";
static String BranchesAndServices = "${baseUrlServices}api/ServiceProviders/ServiceProviderDetail_Get";
@ -58,6 +59,7 @@ class ApiConsts {
static String GetServiceItemAppointmentScheduleSlots = "${baseUrlServices}api/ServiceProviders/ServiceItemAppointmentScheduleSlots_GetByAppointmentType";
static String ServiceProvidersAppointmentCreate = "${baseUrlServices}api/ServiceProviders/ServiceProvidersAppointmentList_Create";
static String ServiceProviderAppointmentRescheduleCancelAppointment = "${baseUrlServices}api/ServiceProviders/ServiceProviderAppointment_RescheduleCancelAppointment";
static String AddNewServicesInAppointment = "${baseUrlServices}api/ServiceProviders/ServiceProviderAppointment_ServiceItemAdd";
//ServiceProvidersServiceID as params
// static String servicesGet = "${baseUrlServices}api/ServiceProviders/Services_Get";
@ -103,6 +105,9 @@ class ApiConsts {
static String adsPhotoOfficeAppointmentScheduleSlotGet = "${baseUrlServices}api/Advertisement/PhotoOfficeAppointmentScheduleSlot_Get";
static String adsPhotoOfficeAppointmentCreate = "${baseUrlServices}api/Advertisement/PhotoOfficeAppointment_Create";
static String adsMCBankAccountAdGet = "${baseUrlServices}api/Advertisement/MCBankAccountAd_Get";
static String getAppointmentSlots = "${baseUrlServices}api/ServiceProviders/ScheduleSlotsInfo_Get";
static String updateAppointmentStatus = "${baseUrlServices}api/ServiceProviders/ServiceProvidersAppointmentStatus_Update";
static String updateAppointmentPaymentStatus = "${baseUrlServices}api/ServiceProviders/ServiceProviderAppointmentServiceItemPaymentStatus_Update";
//Subscription
static String getAllSubscriptions = "${baseUrlServices}api/Common/Subscription_Get";

@ -25,7 +25,9 @@ extension EmailValidator on String {
style: TextStyle(
fontStyle: isItalic ? FontStyle.italic : null,
height: height,
decoration: isUnderLine ? TextDecoration.underline : textDecoration ?? TextDecoration.none,
decoration: isUnderLine
? TextDecoration.underline
: textDecoration ?? TextDecoration.none,
fontSize: fontSize ?? 10,
fontWeight: isBold ? FontWeight.bold : fontWeight ?? FontWeight.w600,
color: color ?? MyColors.darkTextColor,
@ -34,7 +36,9 @@ extension EmailValidator on String {
);
bool isValidEmail() {
return RegExp(r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$').hasMatch(this);
return RegExp(
r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$')
.hasMatch(this);
}
bool isNum() {
@ -206,6 +210,40 @@ extension AdPostEnum on int {
}
}
extension AppointmentStatusToInt on AppointmentStatusEnum {
int getIdFromAppointmentStatusEnum() {
switch (this) {
case AppointmentStatusEnum.booked:
return 1;
case AppointmentStatusEnum.confirmed:
return 2;
case AppointmentStatusEnum.arrived:
return 3;
case AppointmentStatusEnum.cancelled:
return 4;
case AppointmentStatusEnum.rescheduled:
return 5;
case AppointmentStatusEnum.upcoming:
return 6;
case AppointmentStatusEnum.inProgress:
return 7;
case AppointmentStatusEnum.completed:
return 8;
default:
return 0;
}
}
}
//TODO: Need to verify Enum on upcoming and inprogress with the database
extension AppointmentEnum on int {
AppointmentStatusEnum toAppointmentStatusEnum() {
if (this == 1) {
@ -218,12 +256,60 @@ extension AppointmentEnum on int {
return AppointmentStatusEnum.cancelled;
} else if (this == 5) {
return AppointmentStatusEnum.rescheduled;
} else if (this == 6) {
return AppointmentStatusEnum.upcoming;
} else if (this == 7) {
return AppointmentStatusEnum.inProgress;
} else if (this == 8) {
return AppointmentStatusEnum.completed;
} else {
return AppointmentStatusEnum.allAppointments;
}
}
}
extension AppointmentPaymentStatusToInt on AppointmentPaymentStatusEnum {
int getIdFromAppointmentPaymentStatusEnum() {
switch (this) {
case AppointmentPaymentStatusEnum.notConfirmed:
return 1;
case AppointmentPaymentStatusEnum.payNow:
return 2;
case AppointmentPaymentStatusEnum.paid:
return 3;
case AppointmentPaymentStatusEnum.payLater:
return 4;
case AppointmentPaymentStatusEnum.payPartial:
return 5;
default:
return 1;
}
}
}
extension AppointmentPaymentEnum on int {
AppointmentPaymentStatusEnum toAppointmentPaymentStatusEnum() {
if (this == 1) {
return AppointmentPaymentStatusEnum.notConfirmed;
} else if (this == 2) {
return AppointmentPaymentStatusEnum.payNow;
} else if (this == 3) {
return AppointmentPaymentStatusEnum.paid;
} else if (this == 4) {
return AppointmentPaymentStatusEnum.payLater;
} else if (this == 5) {
return AppointmentPaymentStatusEnum.payPartial;
} else {
return AppointmentPaymentStatusEnum.notConfirmed;
}
}
}
extension RequestTypeTypeEnum on int {
RequestsTypeEnum toRequestTypeStatusEnum() {
if (this == 1) {
@ -314,30 +400,6 @@ extension PaymentTypesToInt on PaymentTypes {
}
}
extension AppointmentStatusToInt on AppointmentStatusEnum {
int getIdFromAppointmentStatusEnum() {
switch (this) {
case AppointmentStatusEnum.booked:
return 1;
case AppointmentStatusEnum.confirmed:
return 2;
case AppointmentStatusEnum.arrived:
return 3;
case AppointmentStatusEnum.cancelled:
return 4;
case AppointmentStatusEnum.rescheduled:
return 5;
default:
return 0;
}
}
}
extension CreatedByRoleEnumToInt on CreatedByRoleEnum {
int getIdFromCreatedByRoleEnum() {
switch (this) {

@ -14,11 +14,20 @@ class AppointmentListModel {
int? paymentStatus;
String? paymentStatusText;
String? customerName;
String? customerMobileNum;
int? appointmentType;
String? providerName;
String? duration;
String? appointmentDate;
String? branchName;
int? branchId;
int? servicePaymentStatus;
double? totalAmount;
double? remainingAmount;
AppointmentStatusEnum? appointmentStatusEnum;
AppointmentPaymentStatusEnum? appointmentPaymentStatusEnum;
List<ServiceModel>? appointmentServicesList;
List<AppointmentListModel>? customerAppointmentList;
AppointmentListModel(
{this.id,
@ -32,10 +41,18 @@ class AppointmentListModel {
this.paymentStatus,
this.paymentStatusText,
this.customerName,
this.customerMobileNum,
this.appointmentType,
this.providerName,
this.duration,
this.branchName,
this.branchId,
this.servicePaymentStatus,
this.totalAmount,
this.remainingAmount,
this.appointmentDate,
this.appointmentServicesList});
this.appointmentServicesList,
this.customerAppointmentList});
@override
String toString() {
@ -54,15 +71,26 @@ class AppointmentListModel {
paymentStatus = json['paymentStatus'];
paymentStatusText = json['paymentStatusText'];
customerName = json['customerName'];
customerMobileNum = json['customerMobile'];
appointmentType = json['appointmentType'];
providerName = json['providerName'];
duration = json['duration'];
appointmentDate = json['appointmentDate'];
appointmentStatusEnum = (json['appointmentStatusID'] as int).toAppointmentStatusEnum();
branchName = json['branchName'];
branchId = json['branchID'];
servicePaymentStatus = json['servicePaymentStatus'];
totalAmount = json['amountTotal'];
remainingAmount = json['amountRem'];
appointmentStatusEnum =
(json['appointmentStatusID'] as int).toAppointmentStatusEnum();
appointmentPaymentStatusEnum =
(json['servicePaymentStatus'] as int).toAppointmentPaymentStatusEnum();
if (json['serviceList'] != null) {
appointmentServicesList = <ServiceModel>[];
json['serviceList'].forEach((v) {
appointmentServicesList!.add(ServiceModel.fromJson(v, isForAppointment: true));
appointmentServicesList!
.add(ServiceModel.fromJson(v, isForAppointment: true));
});
}
}
@ -74,7 +102,11 @@ class ServiceAppointmentItems {
String? serviceItemName;
String? serviceItemDescription;
ServiceAppointmentItems({this.id, this.serviceItemID, this.serviceItemName, this.serviceItemDescription});
ServiceAppointmentItems(
{this.id,
this.serviceItemID,
this.serviceItemName,
this.serviceItemDescription});
ServiceAppointmentItems.fromJson(Map<String, dynamic> json) {
id = json['id'];
@ -92,3 +124,15 @@ class ServiceAppointmentItems {
return data;
}
}
// Data Model Class with 'customerName' and 'customerID'
class CustomerData {
final int customerID;
final String customerName;
final List<AppointmentListModel> appointmentList;
CustomerData(
{required this.customerID,
required this.customerName,
required this.appointmentList});
}

@ -0,0 +1,24 @@
class AppointmentSlots {
int totalSlots;
int occupiedSlots;
int emptySlots;
AppointmentSlots({
required this.totalSlots,
required this.occupiedSlots,
required this.emptySlots,
});
factory AppointmentSlots.fromJson(Map<String, dynamic> json) =>
AppointmentSlots(
totalSlots: json["totalSlots"],
occupiedSlots: json["occupiedSlots"],
emptySlots: json["emptySlots"],
);
Map<String, dynamic> toJson() => {
"totalSlots": totalSlots,
"occupiedSlots": occupiedSlots,
"emptySlots": emptySlots,
};
}

@ -11,7 +11,20 @@ import 'package:mc_common_app/models/appointments_models/schedule_model.dart';
import 'package:mc_common_app/models/appointments_models/service_schedule_model.dart';
import 'package:mc_common_app/utils/enums.dart';
import '../models/appointments_models/appointment_list_model.dart';
abstract class AppointmentRepo {
Future<List<AppointmentListModel>> getMyAppointments(
Map<String, dynamic> map);
Future<MResponse> updateAppointmentStatus(
Map<String, dynamic> map);
Future<MResponse> updateAppointmentPaymentStatus(
Map<String, dynamic> map);
Future<MResponse> getAppointmentSlots(Map<String, dynamic> map);
Future<Services> getAllServices(String branchId);
Future<MResponse> createSchedule(Map map);
@ -24,14 +37,20 @@ abstract class AppointmentRepo {
Future<MResponse> updateServicesInSchedule(Map map);
Future<List<ServiceAppointmentScheduleModel>> mergeServiceIntoAvailableSchedules({
Future<List<ServiceAppointmentScheduleModel>>
mergeServiceIntoAvailableSchedules({
required List<String> serviceItemIdsForHome,
required List<String> serviceItemIdsForWorkshop,
});
Future<GenericRespModel> createServiceAppointment({required List<ServiceAppointmentScheduleModel> schedules, required int serviceProviderID});
Future<GenericRespModel> createServiceAppointment(
{required List<ServiceAppointmentScheduleModel> schedules,
required int serviceProviderID});
Future<GenericRespModel> cancelOrRescheduleServiceAppointment({required int serviceAppointmentID, required int serviceSlotID, required int appointmentScheduleAction});
Future<GenericRespModel> cancelOrRescheduleServiceAppointment(
{required int serviceAppointmentID,
required int serviceSlotID,
required int appointmentScheduleAction});
}
class AppointmentRepoImp implements AppointmentRepo {
@ -39,19 +58,25 @@ class AppointmentRepoImp implements AppointmentRepo {
Future<Services> getAllServices(String branchId) async {
Map<String, dynamic> map = {"ProviderBranchID": branchId};
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().getJsonForObject((json) => Services.fromJson(json), ApiConsts.getServicesOfBranch, token: t, queryParameters: map);
return await injector.get<ApiClient>().getJsonForObject(
(json) => Services.fromJson(json), ApiConsts.getServicesOfBranch,
token: t, queryParameters: map);
}
@override
Future<MResponse> createSchedule(Map map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.createSchedule, map, token: t);
return await injector.get<ApiClient>().postJsonForObject(
(json) => MResponse.fromJson(json), ApiConsts.createSchedule, map,
token: t);
}
@override
Future<MResponse> addServicesInSchedule(Map map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.createGroup, map, token: t);
return await injector.get<ApiClient>().postJsonForObject(
(json) => MResponse.fromJson(json), ApiConsts.createGroup, map,
token: t);
}
@override
@ -59,29 +84,36 @@ class AppointmentRepoImp implements AppointmentRepo {
Map<String, dynamic> map = {"ServiceProviderBranchID": branchId};
String t = AppState().getUser.data!.accessToken ?? "";
GenericRespModel adsGenericModel = await injector.get<ApiClient>().getJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.getSchedule,
token: t,
queryParameters: map,
);
GenericRespModel adsGenericModel =
await injector.get<ApiClient>().getJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.getSchedule,
token: t,
queryParameters: map,
);
return List.generate(adsGenericModel.data.length, (index) => ScheduleData.fromJson(adsGenericModel.data[index]));
return List.generate(adsGenericModel.data.length,
(index) => ScheduleData.fromJson(adsGenericModel.data[index]));
}
@override
Future<MResponse> updateSchedule(Map map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.updateSchedule, map, token: t);
return await injector.get<ApiClient>().postJsonForObject(
(json) => MResponse.fromJson(json), ApiConsts.updateSchedule, map,
token: t);
}
@override
Future<MResponse> updateServicesInSchedule(Map map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.updateGroup, map, token: t);
return await injector.get<ApiClient>().postJsonForObject(
(json) => MResponse.fromJson(json), ApiConsts.updateGroup, map,
token: t);
}
Future<List<ServiceAppointmentScheduleModel>> mergeServiceIntoAvailableSchedules({
Future<List<ServiceAppointmentScheduleModel>>
mergeServiceIntoAvailableSchedules({
required List<String> serviceItemIdsForHome,
required List<String> serviceItemIdsForWorkshop,
}) async {
@ -96,21 +128,28 @@ class AppointmentRepoImp implements AppointmentRepo {
"ServiceItemIDs": serviceItemIdsForWorkshop,
}
];
GenericRespModel adsGenericModel = await injector.get<ApiClient>().postJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.GetServiceItemAppointmentScheduleSlots,
queryParameters,
token: t,
);
GenericRespModel adsGenericModel =
await injector.get<ApiClient>().postJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.GetServiceItemAppointmentScheduleSlots,
queryParameters,
token: t,
);
if (adsGenericModel.data == null) {
return [];
}
List<ServiceAppointmentScheduleModel> serviceAppointmentScheduleModel =
List.generate(adsGenericModel.data.length, (index) => ServiceAppointmentScheduleModel.fromJson(adsGenericModel.data[index], isForAppointment: true));
List.generate(
adsGenericModel.data.length,
(index) => ServiceAppointmentScheduleModel.fromJson(
adsGenericModel.data[index],
isForAppointment: true));
return serviceAppointmentScheduleModel;
}
Future<GenericRespModel> createServiceAppointment({required List<ServiceAppointmentScheduleModel> schedules, required int serviceProviderID}) async {
Future<GenericRespModel> createServiceAppointment(
{required List<ServiceAppointmentScheduleModel> schedules,
required int serviceProviderID}) async {
String t = AppState().getUser.data!.accessToken ?? "";
int customerId = AppState().getUser.data!.userInfo!.customerId ?? 0;
@ -130,18 +169,22 @@ class AppointmentRepoImp implements AppointmentRepo {
});
});
GenericRespModel adsGenericModel = await injector.get<ApiClient>().postJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.ServiceProvidersAppointmentCreate,
mapList,
token: t,
);
GenericRespModel adsGenericModel =
await injector.get<ApiClient>().postJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.ServiceProvidersAppointmentCreate,
mapList,
token: t,
);
return adsGenericModel;
}
@override
Future<GenericRespModel> cancelOrRescheduleServiceAppointment({required int serviceAppointmentID, required int serviceSlotID, required int appointmentScheduleAction}) async {
Future<GenericRespModel> cancelOrRescheduleServiceAppointment(
{required int serviceAppointmentID,
required int serviceSlotID,
required int appointmentScheduleAction}) async {
String t = AppState().getUser.data!.accessToken ?? "";
final payload = {
@ -150,13 +193,63 @@ class AppointmentRepoImp implements AppointmentRepo {
"appointmentScheduleAction": appointmentScheduleAction,
};
GenericRespModel adsGenericModel = await injector.get<ApiClient>().postJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.ServiceProviderAppointmentRescheduleCancelAppointment,
payload,
token: t,
);
GenericRespModel adsGenericModel =
await injector.get<ApiClient>().postJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.ServiceProviderAppointmentRescheduleCancelAppointment,
payload,
token: t,
);
return adsGenericModel;
}
@override
Future<List<AppointmentListModel>> getMyAppointments(
Map<String, dynamic> map) async {
String t = AppState().getUser.data!.accessToken ?? "";
GenericRespModel genericRespModel =
await injector.get<ApiClient>().getJsonForObject(
token: t,
(json) => GenericRespModel.fromJson(json),
queryParameters: map,
ApiConsts.serviceProvidersAppointmentGet,
);
List<AppointmentListModel> appointmentList = List.generate(
genericRespModel.data.length,
(index) => AppointmentListModel.fromJson(genericRespModel.data[index]));
return appointmentList;
}
@override
Future<MResponse> getAppointmentSlots(Map<String, dynamic> map) async {
String t = AppState().getUser.data!.accessToken ?? "";
MResponse adsGenericModel =
await injector.get<ApiClient>().getJsonForObject(
(json) => MResponse.fromJson(json),
ApiConsts.getAppointmentSlots,
token: t,
queryParameters: map,
);
return adsGenericModel;
}
@override
Future<MResponse> updateAppointmentPaymentStatus(Map<String, dynamic> map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject(
(json) => MResponse.fromJson(json), ApiConsts.updateAppointmentPaymentStatus, map,
token: t);
}
@override
Future<MResponse> updateAppointmentStatus(Map<String, dynamic> map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject(
(json) => MResponse.fromJson(json), ApiConsts.updateAppointmentStatus, map,
token: t);
}
}

@ -12,7 +12,6 @@ import 'package:mc_common_app/models/user_models/cities.dart';
import 'package:mc_common_app/models/user_models/country.dart';
import 'package:mc_common_app/models/user_models/role.dart';
abstract class CommonRepo {
Future<Country> getAllCountries();
@ -25,9 +24,12 @@ abstract class CommonRepo {
Future<List<AppointmentListModel>> getMyAppointments();
Future<SSCarCheckScheduleModel> getCarCheckServiceScheduleDetails({required double lat, required double long});
Future<SSCarCheckScheduleModel> getCarCheckServiceScheduleDetails(
{required double lat, required double long});
Future<List<SSPhotoOfficeScheduleModel>> getPhotographyServiceScheduleListByOffices({required double lat, required double long});
Future<List<SSPhotoOfficeScheduleModel>>
getPhotographyServiceScheduleListByOffices(
{required double lat, required double long});
// Future<List<ProviderCategoryModel>> getProviderServiceCategories();
@ -36,9 +38,11 @@ abstract class CommonRepo {
Future<List<VehicleTypeModel>> getVehicleTypes();
//TODO: Needs to remove common methods from AD's repo and delete all repeated methods.
Future<VehicleDetailsModel> getVehicleDetails({int? vehicleTypeId, int? vehicleBrandId});
Future<VehicleDetailsModel> getVehicleDetails(
{int? vehicleTypeId, int? vehicleBrandId});
Future<List<EnumsModel>> getEnumTypeValues({int? enumTypeID, String? enumTypeName});
Future<List<EnumsModel>> getEnumTypeValues(
{int? enumTypeID, String? enumTypeName});
}
class CommonRepoImp implements CommonRepo {
@ -47,7 +51,8 @@ class CommonRepoImp implements CommonRepo {
@override
Future<Country> getAllCountries() async {
return await apiClient.getJsonForObject((json) => Country.fromJson(json), ApiConsts.GetAllCountry);
return await apiClient.getJsonForObject(
(json) => Country.fromJson(json), ApiConsts.GetAllCountry);
}
@override
@ -55,18 +60,22 @@ class CommonRepoImp implements CommonRepo {
var postParams = {
"CountryID": countryId,
};
return await apiClient.getJsonForObject((json) => Cities.fromJson(json), ApiConsts.GetAllCities, queryParameters: postParams);
return await apiClient.getJsonForObject(
(json) => Cities.fromJson(json), ApiConsts.GetAllCities,
queryParameters: postParams);
}
@override
Future<Role> getRoles() async {
return await apiClient.getJsonForObject((json) => Role.fromJson(json), ApiConsts.GetProviderRoles);
return await apiClient.getJsonForObject(
(json) => Role.fromJson(json), ApiConsts.GetProviderRoles);
}
@override
Future<List<AppointmentListModel>> getMyAppointments() async {
var params = {
"customerID": appState.getUser.data!.userInfo!.customerId.toString() ?? "",
"customerID":
appState.getUser.data!.userInfo!.customerId.toString() ?? "",
};
GenericRespModel genericRespModel = await apiClient.getJsonForObject(
token: appState.getUser.data!.accessToken,
@ -74,12 +83,15 @@ class CommonRepoImp implements CommonRepo {
queryParameters: params,
ApiConsts.serviceProvidersAppointmentGet,
);
List<AppointmentListModel> appointmentList = List.generate(genericRespModel.data.length, (index) => AppointmentListModel.fromJson(genericRespModel.data[index]));
List<AppointmentListModel> appointmentList = List.generate(
genericRespModel.data.length,
(index) => AppointmentListModel.fromJson(genericRespModel.data[index]));
return appointmentList;
}
@override
Future<SSCarCheckScheduleModel> getCarCheckServiceScheduleDetails({required double lat, required double long}) async {
Future<SSCarCheckScheduleModel> getCarCheckServiceScheduleDetails(
{required double lat, required double long}) async {
var params = {
"Latitude": lat.toString(),
"Longitude": long.toString(),
@ -90,12 +102,15 @@ class CommonRepoImp implements CommonRepo {
queryParameters: params,
ApiConsts.adsCarCheckupSPBranchScheduleSlotGet,
);
SSCarCheckScheduleModel ssCarCheckScheduleModel = SSCarCheckScheduleModel.fromJson(genericRespModel.data[0]);
SSCarCheckScheduleModel ssCarCheckScheduleModel =
SSCarCheckScheduleModel.fromJson(genericRespModel.data[0]);
return ssCarCheckScheduleModel;
}
@override
Future<List<SSPhotoOfficeScheduleModel>> getPhotographyServiceScheduleListByOffices({required double lat, required double long}) async {
Future<List<SSPhotoOfficeScheduleModel>>
getPhotographyServiceScheduleListByOffices(
{required double lat, required double long}) async {
var params = {
"Latitude": lat.toString(),
"Longitude": long.toString(),
@ -109,19 +124,28 @@ class CommonRepoImp implements CommonRepo {
if (genericRespModel.data == null) {
return [];
}
List<SSPhotoOfficeScheduleModel> ssPhotoScheduleModel = List.generate(genericRespModel.data.length, (index) => SSPhotoOfficeScheduleModel.fromJson(genericRespModel.data[index]));
List<SSPhotoOfficeScheduleModel> ssPhotoScheduleModel = List.generate(
genericRespModel.data.length,
(index) =>
SSPhotoOfficeScheduleModel.fromJson(genericRespModel.data[index]));
return ssPhotoScheduleModel ?? [];
}
@override
Future<List<VehicleTypeModel>> getVehicleTypes() async {
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleTypeGet);
List<VehicleTypeModel> vehicleTypes = List.generate(adsGenericModel.data.length, (index) => VehicleTypeModel.fromJson(adsGenericModel.data[index]));
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
token: appState.getUser.data!.accessToken,
(json) => GenericRespModel.fromJson(json),
ApiConsts.vehicleTypeGet);
List<VehicleTypeModel> vehicleTypes = List.generate(
adsGenericModel.data.length,
(index) => VehicleTypeModel.fromJson(adsGenericModel.data[index]));
return vehicleTypes;
}
@override
Future<VehicleDetailsModel> getVehicleDetails({int? vehicleTypeId, int? vehicleBrandId}) async {
Future<VehicleDetailsModel> getVehicleDetails(
{int? vehicleTypeId, int? vehicleBrandId}) async {
var postParams = {
"vehicleType": vehicleTypeId ?? 0,
"isVehicleBrand": "true",
@ -146,24 +170,35 @@ class CommonRepoImp implements CommonRepo {
postParams,
token: token,
);
VehicleDetailsModel vehicleDetails = VehicleDetailsModel.fromJson(adsGenericModel.data);
VehicleDetailsModel vehicleDetails =
VehicleDetailsModel.fromJson(adsGenericModel.data);
return vehicleDetails;
}
@override
Future<List<VehicleCityModel>> getVehicleCities({required int countryId}) async {
Future<List<VehicleCityModel>> getVehicleCities(
{required int countryId}) async {
var postParams = {
"CountryID": countryId.toString(),
};
GenericRespModel adsGenericModel =
await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleCityGet, queryParameters: postParams);
List<VehicleCityModel> vehicleCities = List.generate(adsGenericModel.data.length, (index) => VehicleCityModel.fromJson(adsGenericModel.data[index]));
GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
token: appState.getUser.data!.accessToken,
(json) => GenericRespModel.fromJson(json),
ApiConsts.vehicleCityGet,
queryParameters: postParams);
List<VehicleCityModel> vehicleCities = List.generate(
adsGenericModel.data.length,
(index) => VehicleCityModel.fromJson(adsGenericModel.data[index]));
return vehicleCities;
}
@override
Future<List<EnumsModel>> getEnumTypeValues({int? enumTypeID, String? enumTypeName}) async {
var postParams = {"enumTypeID": (enumTypeID ?? 0).toString(), "enumTypeName": enumTypeName ?? ""};
Future<List<EnumsModel>> getEnumTypeValues(
{int? enumTypeID, String? enumTypeName}) async {
var postParams = {
"enumTypeID": (enumTypeID ?? 0).toString(),
"enumTypeName": enumTypeName ?? ""
};
GenericRespModel enumGenericModel = await apiClient.postJsonForObject(
(json) => GenericRespModel.fromJson(json),
ApiConsts.getEnumTypeValues,
@ -171,7 +206,8 @@ class CommonRepoImp implements CommonRepo {
token: appState.getUser.data!.accessToken,
);
List<EnumsModel> vehicleCities = List.generate(enumGenericModel.data.length, (index) => EnumsModel.fromJson(enumGenericModel.data[index]));
List<EnumsModel> vehicleCities = List.generate(enumGenericModel.data.length,
(index) => EnumsModel.fromJson(enumGenericModel.data[index]));
return vehicleCities;
}
//

@ -149,6 +149,17 @@ enum AppointmentStatusEnum {
cancelled,
rescheduled,
allAppointments,
upcoming,
inProgress,
completed,
}
enum AppointmentPaymentStatusEnum {
notConfirmed,
payNow,
paid,
payLater,
payPartial,
}
enum RequestsTypeEnum {

@ -6,6 +6,7 @@ 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/general_models/enums_model.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: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/appointments_models/service_schedule_model.dart';
@ -30,20 +31,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';
import '../models/appointments_models/appointment_slots.dart';
class AppointmentsVM extends BaseVM {
final CommonRepo commonRepo;
final CommonAppServices commonServices;
final ProviderRepo providerRepo;
final AppointmentRepo scheduleRepo;
AppointmentsVM({required this.commonServices, required this.scheduleRepo, required this.providerRepo, required this.commonRepo});
AppointmentsVM({required this.commonServices,
required this.scheduleRepo,
required this.providerRepo,
required this.commonRepo});
bool isFetchingLists = false;
int selectedBranch = 0;
int selectedAppointmentIndex = 0;
int selectedAppointmentSubIndex = 0;
int selectedAppointmentId = 0;
List<AppointmentListModel> myAppointments = [];
List<AppointmentListModel> myUpComingAppointments = [];
List<AppointmentListModel> myFilteredAppointments = [];
List<FilterListModel> appointmentsFilterOptions = [];
List<CustomerData> customersAppointments = [];
List<AppointmentListModel> myFilteredAppointments2 = [];
// List<ScheduleData> availableSchedules = [];
@ -56,7 +68,8 @@ class AppointmentsVM extends BaseVM {
List<ServiceAppointmentScheduleModel> serviceAppointmentScheduleList = [];
bool ifItemAlreadySelected(int id) {
int indexFound = allSelectedItemsInAppointments.indexWhere((element) => element.id == id);
int indexFound = allSelectedItemsInAppointments
.indexWhere((element) => element.id == id);
if (indexFound != -1) {
return true;
}
@ -65,9 +78,24 @@ class AppointmentsVM extends BaseVM {
List<ItemData> allSelectedItemsInAppointments = [];
setupProviderAppointmentFilter() {
appointmentsFilterOptions.clear();
appointmentsFilterOptions.add(
FilterListModel(id: 0, title: "All Appointments", isSelected: true));
appointmentsFilterOptions
.add(FilterListModel(id: 6, title: "Upcoming", isSelected: false));
appointmentsFilterOptions
.add(FilterListModel(id: 3, title: "Arrived", isSelected: false));
appointmentsFilterOptions
.add(FilterListModel(id: 7, title: "In Progress", isSelected: false));
appointmentsFilterOptions
.add(FilterListModel(id: 8, title: "Completed", isSelected: false));
}
Future<void> onItemsSelectedInService() async {
if (currentServiceSelection != null) {
int index = servicesInCurrentAppointment.indexWhere((element) => element.serviceId == currentServiceSelection!.serviceId!);
int index = servicesInCurrentAppointment.indexWhere((element) =>
element.serviceId == currentServiceSelection!.serviceId!);
if (index == -1) {
double totalPrice = 0.0;
@ -88,12 +116,14 @@ class AppointmentsVM extends BaseVM {
bool isSuccess = false;
List<int> appointmentIdsList = [];
try {
GenericRespModel genericRespModel = await scheduleRepo.createServiceAppointment(
GenericRespModel genericRespModel =
await scheduleRepo.createServiceAppointment(
schedules: serviceAppointmentScheduleList,
serviceProviderID: selectedBranchModel!.serviceProviderId ?? 0,
);
if (genericRespModel.messageStatus == 2 || genericRespModel.data == null) {
if (genericRespModel.messageStatus == 2 ||
genericRespModel.data == null) {
Utils.hideLoading(context);
Utils.showToast("${genericRespModel.message.toString()}");
return;
@ -111,13 +141,17 @@ class AppointmentsVM extends BaseVM {
}
context.read<DashboardVmCustomer>().onNavbarTapped(1);
applyFilterOnAppointmentsVM(appointmentStatusEnum: AppointmentStatusEnum.booked);
applyFilterOnAppointmentsVM(
appointmentStatusEnum: AppointmentStatusEnum.booked);
Utils.hideLoading(context);
resetAfterBookingAppointment();
if (isSuccess) {
if (amountToPayForAppointment > 0) {
context.read<PaymentVM>().updateAppointmentIdsForPayment(ids: appointmentIdsList);
navigateWithName(context, AppRoutes.paymentMethodsView, arguments: PaymentTypes.appointment);
context
.read<PaymentVM>()
.updateAppointmentIdsForPayment(ids: appointmentIdsList);
navigateWithName(context, AppRoutes.paymentMethodsView,
arguments: PaymentTypes.appointment);
} else {
Utils.showToast("Your appointment has been booked successfully!");
getMyAppointments();
@ -129,28 +163,36 @@ class AppointmentsVM extends BaseVM {
}
}
Future<void> onConfirmAppointmentPressed({required BuildContext context, required appointmentId}) async {
context.read<PaymentVM>().updateAppointmentIdsForPayment(ids: [appointmentId]);
navigateWithName(context, AppRoutes.paymentMethodsView, arguments: PaymentTypes.appointment);
Future<void> onConfirmAppointmentPressed(
{required BuildContext context, required appointmentId}) async {
context
.read<PaymentVM>()
.updateAppointmentIdsForPayment(ids: [appointmentId]);
navigateWithName(context, AppRoutes.paymentMethodsView,
arguments: PaymentTypes.appointment);
}
Future<void> onCancelAppointmentPressed({required BuildContext context, required AppointmentListModel appointmentListModel}) async {
Future<void> onCancelAppointmentPressed({required BuildContext context,
required AppointmentListModel appointmentListModel}) async {
Utils.showLoading(context);
try {
GenericRespModel genericRespModel = await scheduleRepo.cancelOrRescheduleServiceAppointment(
GenericRespModel genericRespModel =
await scheduleRepo.cancelOrRescheduleServiceAppointment(
serviceAppointmentID: appointmentListModel.id ?? 0,
serviceSlotID: appointmentListModel.serviceSlotID ?? 0,
appointmentScheduleAction: 2, // 1 for Reschedule and 2 for Cancel
);
if (genericRespModel.messageStatus == 2 || genericRespModel.data == null) {
if (genericRespModel.messageStatus == 2 ||
genericRespModel.data == null) {
Utils.hideLoading(context);
Utils.showToast("${genericRespModel.message.toString()}");
return;
}
if (genericRespModel.data == 1) {
context.read<DashboardVmCustomer>().onNavbarTapped(1);
applyFilterOnAppointmentsVM(appointmentStatusEnum: AppointmentStatusEnum.cancelled);
applyFilterOnAppointmentsVM(
appointmentStatusEnum: AppointmentStatusEnum.cancelled);
Utils.showToast("${genericRespModel.message.toString()}");
await getMyAppointments();
Utils.hideLoading(context);
@ -181,7 +223,8 @@ class AppointmentsVM extends BaseVM {
notifyListeners();
}
SelectionModel branchSelectedCategoryId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
SelectionModel branchSelectedCategoryId =
SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updateProviderCategoryId(SelectionModel id) {
branchSelectedCategoryId = id;
@ -200,23 +243,30 @@ class AppointmentsVM extends BaseVM {
void updateBranchServiceId(SelectionModel id) async {
branchSelectedServiceId = id;
currentServiceSelection = branchServices.firstWhere((element) => element.serviceProviderServiceId == id.selectedId);
currentServiceSelection = branchServices.firstWhere(
(element) => element.serviceProviderServiceId == id.selectedId);
notifyListeners();
}
void removeServiceInCurrentAppointment(int index) {
int serviceId = servicesInCurrentAppointment.elementAt(index).serviceProviderServiceId ?? -1;
allSelectedItemsInAppointments.removeWhere((element) => element.serviceProviderServiceId == serviceId);
int serviceId = servicesInCurrentAppointment
.elementAt(index)
.serviceProviderServiceId ??
-1;
allSelectedItemsInAppointments.removeWhere(
(element) => element.serviceProviderServiceId == serviceId);
servicesInCurrentAppointment.removeAt(index);
notifyListeners();
}
resetCategorySelectionBottomSheet() {
selectedSubServicesCounter = 0;
branchSelectedCategoryId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
branchSelectedCategoryId =
SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
isHomeTapped = false;
branchSelectedServiceId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
branchSelectedServiceId =
SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
currentServiceSelection = null;
}
@ -231,76 +281,222 @@ class AppointmentsVM extends BaseVM {
populateAppointmentsFilterList() async {
appointmentsFilterOptions.clear();
myAppointmentsEnum = await commonRepo.getEnumTypeValues(enumTypeID: 13); //TODO: 13 is to get Appointments Filter Enums
myAppointmentsEnum = await commonRepo.getEnumTypeValues(
enumTypeID: 13); //TODO: 13 is to get Appointments Filter Enums
for (int i = 0; i < myAppointmentsEnum.length; i++) {
appointmentsFilterOptions.add(FilterListModel(title: myAppointmentsEnum[i].enumValueStr, isSelected: false, id: myAppointmentsEnum[i].enumValue));
appointmentsFilterOptions.add(FilterListModel(
title: myAppointmentsEnum[i].enumValueStr,
isSelected: false,
id: myAppointmentsEnum[i].enumValue));
}
appointmentsFilterOptions.insert(0, FilterListModel(title: "All Appointments", isSelected: true, id: 0));
appointmentsFilterOptions.insert(
0, FilterListModel(title: "All Appointments", isSelected: true, id: 0));
notifyListeners();
}
applyFilterOnAppointmentsVM({required AppointmentStatusEnum appointmentStatusEnum}) {
applyFilterOnAppointmentsVM(
{required AppointmentStatusEnum appointmentStatusEnum,
bool isNeedCustomerFilter = false}) {
if (appointmentsFilterOptions.isEmpty) return;
for (var value in appointmentsFilterOptions) {
value.isSelected = false;
}
appointmentsFilterOptions[appointmentStatusEnum.getIdFromAppointmentStatusEnum()].isSelected = true;
appointmentsFilterOptions.forEach((element) {
if (element.id ==
appointmentStatusEnum.getIdFromAppointmentStatusEnum()) {
element.isSelected = true;
}
});
// appointmentsFilterOptions[
// appointmentStatusEnum.getIdFromAppointmentStatusEnum()]
// .isSelected = true;
if (appointmentStatusEnum.getIdFromAppointmentStatusEnum() == 0) {
myFilteredAppointments = myAppointments;
if (isNeedCustomerFilter) findAppointmentsBasedOnCustomers();
notifyListeners();
return;
}
myFilteredAppointments = myAppointments.where((element) => element.appointmentStatusID! == appointmentStatusEnum.getIdFromAppointmentStatusEnum()).toList();
myFilteredAppointments = myAppointments
.where((element) =>
element.appointmentStatusID! ==
appointmentStatusEnum.getIdFromAppointmentStatusEnum())
.toList();
if (isNeedCustomerFilter) findAppointmentsBasedOnCustomers();
notifyListeners();
}
findAppointmentsBasedOnCustomers() {
// Use a Set to ensure uniqueness of customerIDs
Set<int> uniqueCustomerIDs = Set<int>();
// Extract unique customerIDs
for (var item in myFilteredAppointments) {
uniqueCustomerIDs.add(item.customerID ?? 0);
}
// Create a list of CustomerData instances
myFilteredAppointments2 = uniqueCustomerIDs.map((id) {
List<AppointmentListModel> list = myFilteredAppointments
.where((item) => item.customerID == id)
.toList();
AppointmentListModel model = list.first;
model.customerAppointmentList = list;
return model;
}).toList();
// customersAppointments = uniqueCustomerIDs.map((id) {
// List<AppointmentListModel> list = myFilteredAppointments
// .where((item) => item.customerID == id)
// .toList();
// var customerItem =
// myFilteredAppointments.firstWhere((item) => item.customerID == id);
//
// return CustomerData(
// customerID: id,
// customerName: customerItem.customerName ?? "",
// appointmentList: list,
// );
// }).toList();
}
Future<void> getMyAppointments({bool isNeedToRebuild = false}) async {
if (isNeedToRebuild) setState(ViewState.busy);
myAppointments = await commonRepo.getMyAppointments();
myFilteredAppointments = myAppointments;
myUpComingAppointments = myAppointments.where((element) => element.appointmentStatusEnum == AppointmentStatusEnum.booked).toList();
myUpComingAppointments = myAppointments
.where((element) =>
element.appointmentStatusEnum == AppointmentStatusEnum.booked)
.toList();
setState(ViewState.idle);
// applyFilterOnAppointmentsVM(appointmentStatusEnum: AppointmentStatusEnum.allAppointments);
notifyListeners();
}
AppointmentSlots? appointmentSlots;
Future<void> getAppointmentSlotsInfo({required Map<String, dynamic> map,
required BuildContext context,
bool isNeedToRebuild = false}) async {
if (isNeedToRebuild) setState(ViewState.busy);
try {
MResponse genericRespModel = await scheduleRepo.getAppointmentSlots(map);
if (genericRespModel.messageStatus == 1) {
appointmentSlots = AppointmentSlots.fromJson(genericRespModel.data);
} else {
Utils.showToast(genericRespModel.message.toString());
}
} catch (e) {
Utils.showToast(e.toString());
}
}
Future<void> getProviderMyAppointments(Map<String, dynamic> map,
{bool isNeedToRebuild = false}) async {
if (isNeedToRebuild) setState(ViewState.busy);
myAppointments = await scheduleRepo.getMyAppointments(map);
myFilteredAppointments = myAppointments;
// myUpComingAppointments = myAppointments
// .where((element) =>
// element.appointmentStatusEnum == AppointmentStatusEnum.booked)
// .toList();
setState(ViewState.idle);
applyFilterOnAppointmentsVM(
appointmentStatusEnum: AppointmentStatusEnum.allAppointments,
isNeedCustomerFilter: true);
notifyListeners();
}
updateSelectedBranch(BranchDetailModel branchDetailModel) {
selectedBranchModel = branchDetailModel;
getBranchCategories();
notifyListeners();
}
updateSelectedAppointmentDate({required int dateIndex, required int scheduleIndex}) {
for (var element in serviceAppointmentScheduleList[scheduleIndex].customTimeDateSlotList!) {
updateAppointmentStatus(Map<String, dynamic> map,{bool isNeedToRebuild = false}) async {
if (isNeedToRebuild) setState(ViewState.busy);
try {
MResponse genericRespModel = await scheduleRepo.updateAppointmentStatus(map);
if (genericRespModel.messageStatus == 1) {
Utils.showToast("appointment status updated");
} else {
Utils.showToast(genericRespModel.message.toString());
}
} catch (e) {
Utils.showToast(e.toString());
}
}
updateAppointmentPaymentStatus(Map<String, dynamic> map,{bool isNeedToRebuild = false}) async {
if (isNeedToRebuild) setState(ViewState.busy);
try {
MResponse genericRespModel = await scheduleRepo.updateAppointmentPaymentStatus(map);
if (genericRespModel.messageStatus == 1) {
Utils.showToast("payment status updated");
} else {
Utils.showToast(genericRespModel.message.toString());
}
} catch (e) {
Utils.showToast(e.toString());
}
}
updateSelectedAppointmentDate(
{required int dateIndex, required int scheduleIndex}) {
for (var element in serviceAppointmentScheduleList[scheduleIndex]
.customTimeDateSlotList!) {
element.date!.isSelected = false;
}
serviceAppointmentScheduleList[scheduleIndex].customTimeDateSlotList![dateIndex].date!.isSelected = true;
serviceAppointmentScheduleList[scheduleIndex]
.customTimeDateSlotList![dateIndex]
.date!
.isSelected = true;
serviceAppointmentScheduleList[scheduleIndex].selectedDateIndex = dateIndex;
final date = TimeSlotModel(
date: serviceAppointmentScheduleList[scheduleIndex].customTimeDateSlotList![dateIndex].date!.date,
slotId: serviceAppointmentScheduleList[scheduleIndex].customTimeDateSlotList![dateIndex].date!.slotId,
date: serviceAppointmentScheduleList[scheduleIndex]
.customTimeDateSlotList![dateIndex]
.date!
.date,
slotId: serviceAppointmentScheduleList[scheduleIndex]
.customTimeDateSlotList![dateIndex]
.date!
.slotId,
isSelected: true,
slot: "",
);
serviceAppointmentScheduleList[scheduleIndex].selectedCustomTimeDateSlotModel = CustomTimeDateSlotModel(date: date);
serviceAppointmentScheduleList[scheduleIndex]
.selectedCustomTimeDateSlotModel = CustomTimeDateSlotModel(date: date);
notifyListeners();
}
updateSelectedAppointmentSlotByDate({required int scheduleIndex, required int slotIndex}) {
for (var element in serviceAppointmentScheduleList[scheduleIndex].customTimeDateSlotList!) {
updateSelectedAppointmentSlotByDate(
{required int scheduleIndex, required int slotIndex}) {
for (var element in serviceAppointmentScheduleList[scheduleIndex]
.customTimeDateSlotList!) {
for (var element in element.availableSlots!) {
element.isSelected = false;
}
}
int index = serviceAppointmentScheduleList[scheduleIndex].selectedDateIndex!;
serviceAppointmentScheduleList[scheduleIndex].customTimeDateSlotList![index].availableSlots![slotIndex].isSelected = true;
serviceAppointmentScheduleList[scheduleIndex].selectedCustomTimeDateSlotModel!.availableSlots = serviceAppointmentScheduleList[scheduleIndex].customTimeDateSlotList![index].availableSlots!;
int index =
serviceAppointmentScheduleList[scheduleIndex].selectedDateIndex!;
serviceAppointmentScheduleList[scheduleIndex]
.customTimeDateSlotList![index]
.availableSlots![slotIndex]
.isSelected = true;
serviceAppointmentScheduleList[scheduleIndex]
.selectedCustomTimeDateSlotModel!
.availableSlots =
serviceAppointmentScheduleList[scheduleIndex]
.customTimeDateSlotList![index]
.availableSlots!;
notifyListeners();
}
@ -314,7 +510,9 @@ class AppointmentsVM extends BaseVM {
int selectedSubServicesCounter = 0;
onItemUpdateOrSelected(int index, bool selected, int itemId) {
int serviceIndex = servicesInCurrentAppointment.indexWhere((element) => element.serviceId == currentServiceSelection!.serviceId!);
int serviceIndex = servicesInCurrentAppointment.indexWhere(
(element) =>
element.serviceId == currentServiceSelection!.serviceId!);
// print("servicesInCurrentAppointment: ${servicesInCurrentAppointment.length}");
// if (serviceIndex == -1) {
// return;
@ -329,19 +527,28 @@ class AppointmentsVM extends BaseVM {
allSelectedItemsInAppointments.add(serviceItemsFromApi[index]);
for (var element in allSelectedItemsInAppointments) {
if (!ifItemAlreadySelected(element.id!)) {
servicesInCurrentAppointment[serviceIndex].serviceItems!.add(serviceItemsFromApi[index]);
servicesInCurrentAppointment[serviceIndex]
.serviceItems!
.add(serviceItemsFromApi[index]);
servicesInCurrentAppointment[serviceIndex].currentTotalServicePrice =
servicesInCurrentAppointment[serviceIndex].currentTotalServicePrice + double.parse((serviceItemsFromApi[index].price) ?? "0.0");
servicesInCurrentAppointment[serviceIndex]
.currentTotalServicePrice +
double.parse((serviceItemsFromApi[index].price) ?? "0.0");
}
}
}
if (!selected) {
selectedSubServicesCounter = selectedSubServicesCounter - 1;
currentServiceSelection!.serviceItems!.removeWhere((element) => element.id == itemId);
allSelectedItemsInAppointments.removeWhere((element) => element.id == itemId);
currentServiceSelection!.serviceItems!
.removeWhere((element) => element.id == itemId);
allSelectedItemsInAppointments
.removeWhere((element) => element.id == itemId);
servicesInCurrentAppointment[serviceIndex].currentTotalServicePrice =
servicesInCurrentAppointment[serviceIndex].currentTotalServicePrice - double.parse((serviceItemsFromApi[index].price) ?? "0.0");
servicesInCurrentAppointment[serviceIndex].serviceItems!.removeWhere((element) => element.id == itemId);
servicesInCurrentAppointment[serviceIndex].currentTotalServicePrice -
double.parse((serviceItemsFromApi[index].price) ?? "0.0");
servicesInCurrentAppointment[serviceIndex]
.serviceItems!
.removeWhere((element) => element.id == itemId);
}
notifyListeners();
}
@ -397,7 +604,8 @@ class AppointmentsVM extends BaseVM {
String pickHomeLocationError = "";
String selectSubServicesError = "";
SelectionModel branchSelectedServiceId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
SelectionModel branchSelectedServiceId =
SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
bool isCategoryAlreadyPresent(int id) {
final contain = branchCategories.where((element) => element.id == id);
@ -410,14 +618,16 @@ class AppointmentsVM extends BaseVM {
void getBranchCategories() async {
for (var value in selectedBranchModel!.branchServices!) {
if (!isCategoryAlreadyPresent(value.categoryId!)) {
branchCategories.add(DropValue(value.categoryId!, value.categoryName!, ""));
branchCategories
.add(DropValue(value.categoryId!, value.categoryName!, ""));
}
}
notifyListeners();
}
getBranchServices({required int categoryId}) async {
branchSelectedServiceId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
branchSelectedServiceId =
SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
isHomeTapped = false;
pickedHomeLocation = "";
pickHomeLocationError = "";
@ -430,7 +640,9 @@ class AppointmentsVM extends BaseVM {
}
List<ServiceModel> getFilteredBranchServices({required int categoryId}) {
List<ServiceModel> filteredServices = selectedBranchModel!.branchServices!.where((element) => element.categoryId == categoryId).toList();
List<ServiceModel> filteredServices = selectedBranchModel!.branchServices!
.where((element) => element.categoryId == categoryId)
.toList();
return filteredServices;
}
@ -472,7 +684,8 @@ class AppointmentsVM extends BaseVM {
return totalPrice.toString();
}
void openTheAddServiceBottomSheet(BuildContext context, AppointmentsVM appointmentsVM) {
void openTheAddServiceBottomSheet(BuildContext context,
AppointmentsVM appointmentsVM) {
showModalBottomSheet(
context: context,
isScrollControlled: true,
@ -483,7 +696,8 @@ class AppointmentsVM extends BaseVM {
);
}
void priceBreakDownClicked(BuildContext context, ServiceModel selectedService) {
void priceBreakDownClicked(BuildContext context,
ServiceModel selectedService) {
showModalBottomSheet(
context: context,
isScrollControlled: true,
@ -499,19 +713,27 @@ class AppointmentsVM extends BaseVM {
Column(
children: List.generate(
selectedService.serviceItems!.length,
(index) => Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"${selectedService.serviceItems![index].name}".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
"${selectedService.serviceItems![index].price} SAR".toText(fontSize: 12, isBold: true),
],
),
(index) =>
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"${selectedService.serviceItems![index].name}"
.toText(
fontSize: 12,
color: MyColors.lightTextColor,
isBold: true),
"${selectedService.serviceItems![index]
.price} SAR"
.toText(fontSize: 12, isBold: true),
],
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
"${selectedService.currentTotalServicePrice} SAR".toText(fontSize: 16, isBold: true),
"${selectedService.currentTotalServicePrice} SAR"
.toText(fontSize: 16, isBold: true),
],
),
if (selectedService.isHomeSelected) ...[
@ -520,15 +742,20 @@ class AppointmentsVM extends BaseVM {
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"${totalKms}km ".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
"${selectedService.rangePricePerKm} x $totalKms".toText(fontSize: 12, isBold: true),
"${totalKms}km ".toText(
fontSize: 12,
color: MyColors.lightTextColor,
isBold: true),
"${selectedService.rangePricePerKm} x $totalKms"
.toText(fontSize: 12, isBold: true),
],
),
8.height,
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
"${selectedService.rangePricePerKm ?? 0 * totalKms} SAR".toText(fontSize: 16, isBold: true),
"${selectedService.rangePricePerKm ?? 0 * totalKms} SAR"
.toText(fontSize: 16, isBold: true),
],
),
],
@ -541,11 +768,18 @@ class AppointmentsVM extends BaseVM {
crossAxisAlignment: CrossAxisAlignment.end,
children: [
(selectedService.isHomeSelected
? "${(selectedService.currentTotalServicePrice) + (double.parse((selectedService.rangePricePerKm ?? "0.0")) * totalKms)}"
: "${selectedService.currentTotalServicePrice}")
? "${(selectedService.currentTotalServicePrice) +
(double.parse((selectedService.rangePricePerKm ??
"0.0")) * totalKms)}"
: "${selectedService.currentTotalServicePrice}")
.toText(fontSize: 29, isBold: true),
2.width,
"SAR".toText(color: MyColors.lightTextColor, fontSize: 16, isBold: true).paddingOnly(bottom: 5),
"SAR"
.toText(
color: MyColors.lightTextColor,
fontSize: 16,
isBold: true)
.paddingOnly(bottom: 5),
],
)
],
@ -565,7 +799,8 @@ class AppointmentsVM extends BaseVM {
isValidated = false;
break;
}
if (schedule.selectedCustomTimeDateSlotModel!.date == null || !schedule.selectedCustomTimeDateSlotModel!.date!.isSelected) {
if (schedule.selectedCustomTimeDateSlotModel!.date == null ||
!schedule.selectedCustomTimeDateSlotModel!.date!.isSelected) {
isValidated = false;
break;
} else {
@ -573,7 +808,9 @@ class AppointmentsVM extends BaseVM {
isValidated = false;
break;
} else {
TimeSlotModel slot = schedule.selectedCustomTimeDateSlotModel!.availableSlots!.firstWhere((element) => element.isSelected);
TimeSlotModel slot = schedule
.selectedCustomTimeDateSlotModel!.availableSlots!
.firstWhere((element) => element.isSelected);
if (slot.date.isNotEmpty) {
isValidated = true;
break;
@ -582,7 +819,8 @@ class AppointmentsVM extends BaseVM {
}
}
if (!isValidated) {
Utils.showToast("You must select appointment time for each schedule's appointment.");
Utils.showToast(
"You must select appointment time for each schedule's appointment.");
return;
}
navigateWithName(context, AppRoutes.reviewAppointmentView);
@ -601,30 +839,36 @@ class AppointmentsVM extends BaseVM {
}
}
serviceAppointmentScheduleList = await scheduleRepo.mergeServiceIntoAvailableSchedules(
serviceAppointmentScheduleList =
await scheduleRepo.mergeServiceIntoAvailableSchedules(
serviceItemIdsForHome: serviceItemIdsForHome,
serviceItemIdsForWorkshop: serviceItemIdsForWorkshop,
);
if (serviceAppointmentScheduleList.isEmpty) {
Utils.hideLoading(context);
Utils.showToast("There are no available appointments for selected Items.");
Utils.showToast(
"There are no available appointments for selected Items.");
return;
}
totalAmount = 0.0;
amountToPayForAppointment = 0.0;
for (var schedule in serviceAppointmentScheduleList) {
amountToPayForAppointment = amountToPayForAppointment + (schedule.amountToPay ?? 0.0);
amountToPayForAppointment =
amountToPayForAppointment + (schedule.amountToPay ?? 0.0);
totalAmount = totalAmount + (schedule.amountTotal ?? 0.0);
}
Utils.hideLoading(context);
navigateWithName(context, AppRoutes.bookAppointmenSchedulesView, arguments: ScreenArgumentsForAppointmentDetailPage(routeFlag: 1, appointmentId: 0)); // 1 For Creating an Appointment
navigateWithName(context, AppRoutes.bookAppointmenSchedulesView,
arguments: ScreenArgumentsForAppointmentDetailPage(
routeFlag: 1, appointmentId: 0)); // 1 For Creating an Appointment
notifyListeners();
}
Future<void> onRescheduleAppointmentPressed({required BuildContext context, required AppointmentListModel appointmentListModel}) async {
Future<void> onRescheduleAppointmentPressed({required BuildContext context,
required AppointmentListModel appointmentListModel}) async {
Utils.showLoading(context);
List<String> serviceItemIdsForHome = [];
@ -641,14 +885,16 @@ class AppointmentsVM extends BaseVM {
}
}
serviceAppointmentScheduleList = await scheduleRepo.mergeServiceIntoAvailableSchedules(
serviceAppointmentScheduleList =
await scheduleRepo.mergeServiceIntoAvailableSchedules(
serviceItemIdsForHome: serviceItemIdsForHome,
serviceItemIdsForWorkshop: serviceItemIdsForWorkshop,
);
if (serviceAppointmentScheduleList.isEmpty) {
Utils.hideLoading(context);
Utils.showToast("There are no available appointments for selected Items.");
Utils.showToast(
"There are no available appointments for selected Items.");
return;
}
Utils.hideLoading(context);
@ -656,29 +902,36 @@ class AppointmentsVM extends BaseVM {
navigateWithName(
context,
AppRoutes.bookAppointmenSchedulesView,
arguments: ScreenArgumentsForAppointmentDetailPage(routeFlag: 2, appointmentId: appointmentListModel.id ?? 0),
arguments: ScreenArgumentsForAppointmentDetailPage(
routeFlag: 2, appointmentId: appointmentListModel.id ?? 0),
); // 2 For Rescheduling an Appointment
notifyListeners();
}
Future<void> onRescheduleAppointmentConfirmPressed({required BuildContext context, required int appointmentId, required int selectedSlotId}) async {
Future<void> onRescheduleAppointmentConfirmPressed(
{required BuildContext context,
required int appointmentId,
required int selectedSlotId}) async {
Utils.showLoading(context);
try {
GenericRespModel genericRespModel = await scheduleRepo.cancelOrRescheduleServiceAppointment(
GenericRespModel genericRespModel =
await scheduleRepo.cancelOrRescheduleServiceAppointment(
serviceAppointmentID: appointmentId,
serviceSlotID: selectedSlotId,
appointmentScheduleAction: 1, // 1 for Reschedule and 2 for Cancel
);
if (genericRespModel.messageStatus == 2 || genericRespModel.data == null) {
if (genericRespModel.messageStatus == 2 ||
genericRespModel.data == null) {
Utils.hideLoading(context);
Utils.showToast("${genericRespModel.message.toString()}");
return;
}
if (genericRespModel.data == 1) {
context.read<DashboardVmCustomer>().onNavbarTapped(1);
applyFilterOnAppointmentsVM(appointmentStatusEnum: AppointmentStatusEnum.cancelled);
applyFilterOnAppointmentsVM(
appointmentStatusEnum: AppointmentStatusEnum.cancelled);
Utils.showToast("${genericRespModel.message.toString()}");
getMyAppointments();
Utils.hideLoading(context);

@ -17,9 +17,14 @@ import 'package:provider/provider.dart';
class AppointmentDetailView extends StatelessWidget {
final AppointmentListModel appointmentListModel;
AppointmentDetailView({Key? key, required this.appointmentListModel}) : super(key: key);
AppointmentDetailView({Key? key, required this.appointmentListModel})
: super(key: key);
Widget getBaseActionButtonWidget({required Color color, required String text, Color textColor = MyColors.white, required Function() onPressed}) {
Widget getBaseActionButtonWidget(
{required Color color,
required String text,
Color textColor = MyColors.white,
required Function() onPressed}) {
return Expanded(
child: ShowFillButton(
maxHeight: 55,
@ -32,19 +37,26 @@ class AppointmentDetailView extends StatelessWidget {
);
}
Widget buildBottomActionButton({required AppointmentStatusEnum appointmentStatusEnum, required BuildContext context}) {
Widget buildBottomActionButton(
{required AppointmentStatusEnum appointmentStatusEnum,
required BuildContext context}) {
switch (appointmentStatusEnum) {
case AppointmentStatusEnum.booked:
return Align(
alignment: Alignment.bottomCenter,
child: Row(
children: [
getBaseActionButtonWidget(color: MyColors.redColor, onPressed: () => appointmentCancelConfirmationSheet(context), text: "Cancel"),
getBaseActionButtonWidget(
color: MyColors.redColor,
onPressed: () => appointmentCancelConfirmationSheet(context),
text: "Cancel"),
12.width,
getBaseActionButtonWidget(
color: MyColors.greenColor,
onPressed: () {
context.read<AppointmentsVM>().onConfirmAppointmentPressed(context: context, appointmentId: appointmentListModel.id);
context.read<AppointmentsVM>().onConfirmAppointmentPressed(
context: context,
appointmentId: appointmentListModel.id);
},
text: "Confirm"),
],
@ -55,7 +67,10 @@ class AppointmentDetailView extends StatelessWidget {
alignment: Alignment.bottomCenter,
child: Row(
children: [
getBaseActionButtonWidget(color: MyColors.redColor, onPressed: () => appointmentCancelConfirmationSheet(context), text: "Cancel"),
getBaseActionButtonWidget(
color: MyColors.redColor,
onPressed: () => appointmentCancelConfirmationSheet(context),
text: "Cancel"),
],
),
);
@ -64,7 +79,11 @@ class AppointmentDetailView extends StatelessWidget {
alignment: Alignment.bottomCenter,
child: Row(
children: [
getBaseActionButtonWidget(color: MyColors.grey98Color.withOpacity(0.3), textColor: MyColors.lightTextColor, onPressed: () {}, text: "In Progress"),
getBaseActionButtonWidget(
color: MyColors.grey98Color.withOpacity(0.3),
textColor: MyColors.lightTextColor,
onPressed: () {},
text: "In Progress"),
],
),
);
@ -73,7 +92,11 @@ class AppointmentDetailView extends StatelessWidget {
alignment: Alignment.bottomCenter,
child: Row(
children: [
getBaseActionButtonWidget(color: MyColors.grey98Color.withOpacity(0.3), textColor: MyColors.lightTextColor, onPressed: () {}, text: "Cancelled"),
getBaseActionButtonWidget(
color: MyColors.grey98Color.withOpacity(0.3),
textColor: MyColors.lightTextColor,
onPressed: () {},
text: "Cancelled"),
],
),
);
@ -84,17 +107,24 @@ class AppointmentDetailView extends StatelessWidget {
alignment: Alignment.bottomCenter,
child: Row(
children: [
getBaseActionButtonWidget(color: MyColors.redColor, onPressed: () => appointmentCancelConfirmationSheet(context), text: "Cancel"),
getBaseActionButtonWidget(
color: MyColors.redColor,
onPressed: () => appointmentCancelConfirmationSheet(context),
text: "Cancel"),
12.width,
getBaseActionButtonWidget(
color: MyColors.greenColor,
onPressed: () {
context.read<AppointmentsVM>().onConfirmAppointmentPressed(context: context, appointmentId: appointmentListModel.id);
context.read<AppointmentsVM>().onConfirmAppointmentPressed(
context: context,
appointmentId: appointmentListModel.id);
},
text: "Confirm"),
],
),
);
default:
return SizedBox();
}
}
@ -102,8 +132,10 @@ class AppointmentDetailView extends StatelessWidget {
final appointmentsVm = context.read<AppointmentsVM>();
return actionConfirmationBottomSheet(
context: context,
title: "Do you want to cancel this appointment?".toText(fontSize: 28, isBold: true, letterSpacing: -1.44),
subtitle: "Your appointment will be cancelled and you cannot undo this action.",
title: "Do you want to cancel this appointment?"
.toText(fontSize: 28, isBold: true, letterSpacing: -1.44),
subtitle:
"Your appointment will be cancelled and you cannot undo this action.",
actionButtonYes: Expanded(
child: ShowFillButton(
maxHeight: 55,
@ -111,7 +143,8 @@ class AppointmentDetailView extends StatelessWidget {
fontSize: 15,
onPressed: () {
Navigator.pop(context);
appointmentsVm.onCancelAppointmentPressed(context: context, appointmentListModel: appointmentListModel);
appointmentsVm.onCancelAppointmentPressed(
context: context, appointmentListModel: appointmentListModel);
},
),
),
@ -149,7 +182,8 @@ class AppointmentDetailView extends StatelessWidget {
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
appointmentListModel.providerName!.toText(fontSize: 16, isBold: true),
appointmentListModel.providerName!
.toText(fontSize: 16, isBold: true),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
@ -159,14 +193,23 @@ class AppointmentDetailView extends StatelessWidget {
fit: BoxFit.fill,
),
5.width,
"${appointmentListModel.duration ?? ""} ${appointmentListModel.appointmentDate!.toFormattedDateWithoutTime()}".toText(fontSize: 12, isBold: true, color: MyColors.lightTextColor),
"${appointmentListModel.duration ?? ""} ${appointmentListModel.appointmentDate!.toFormattedDateWithoutTime()}"
.toText(
fontSize: 12,
isBold: true,
color: MyColors.lightTextColor),
],
),
13.height,
if (appointmentListModel.appointmentServicesList != null && appointmentListModel.appointmentServicesList!.isNotEmpty) ...[
if (appointmentListModel.appointmentServicesList != null &&
appointmentListModel
.appointmentServicesList!.isNotEmpty) ...[
Column(
children: List.generate(appointmentListModel.appointmentServicesList!.length, (index) {
ServiceModel service = appointmentListModel.appointmentServicesList![index];
children: List.generate(
appointmentListModel.appointmentServicesList!.length,
(index) {
ServiceModel service =
appointmentListModel.appointmentServicesList![index];
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@ -178,14 +221,18 @@ class AppointmentDetailView extends StatelessWidget {
// fit: BoxFit.fill,
// ),
// 10.width,
"${index + 1}. ${service.providerServiceDescription}".toText(fontSize: 14, isBold: true),
"${index + 1}. ${service.providerServiceDescription}"
.toText(fontSize: 14, isBold: true),
],
),
if (service.serviceItems != null && service.serviceItems!.isNotEmpty) ...[
if (service.serviceItems != null &&
service.serviceItems!.isNotEmpty) ...[
Column(
children: List.generate(
service.serviceItems!.length,
(index) => "${service.serviceItems![index].name}".toText(
(index) =>
"${service.serviceItems![index].name}"
.toText(
textAlign: TextAlign.start,
fontSize: 12,
color: MyColors.lightTextColor,
@ -197,15 +244,22 @@ class AppointmentDetailView extends StatelessWidget {
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
((service.currentTotalServicePrice).toString()).toText(fontSize: 25, isBold: true),
((service.currentTotalServicePrice).toString())
.toText(fontSize: 25, isBold: true),
2.width,
"SAR".toText(color: MyColors.lightTextColor, fontSize: 16, isBold: true).paddingOnly(bottom: 5),
"SAR"
.toText(
color: MyColors.lightTextColor,
fontSize: 16,
isBold: true)
.paddingOnly(bottom: 5),
Icon(
Icons.arrow_drop_down,
size: 30,
)
],
).onPress(() => appointmentsVM.priceBreakDownClicked(context, service)),
).onPress(() => appointmentsVM.priceBreakDownClicked(
context, service)),
],
);
}),
@ -217,16 +271,25 @@ class AppointmentDetailView extends StatelessWidget {
CardButtonWithIcon(
title: "Reschedule Appointment",
onCardTapped: () {
context.read<AppointmentsVM>().onRescheduleAppointmentPressed(context: context, appointmentListModel: appointmentListModel);
context
.read<AppointmentsVM>()
.onRescheduleAppointmentPressed(
context: context,
appointmentListModel: appointmentListModel);
},
icon: MyAssets.scheduleAppointmentIcon.buildSvg(),
),
if (appointmentListModel.appointmentStatusEnum == AppointmentStatusEnum.booked) ...[
if (appointmentListModel.appointmentStatusEnum ==
AppointmentStatusEnum.booked) ...[
10.width,
CardButtonWithIcon(
title: "Pay for Appointment",
onCardTapped: () {
context.read<AppointmentsVM>().onConfirmAppointmentPressed(context: context, appointmentId: appointmentListModel.id);
context
.read<AppointmentsVM>()
.onConfirmAppointmentPressed(
context: context,
appointmentId: appointmentListModel.id);
},
icon: MyAssets.creditCardIcon.buildSvg(),
),
@ -236,7 +299,10 @@ class AppointmentDetailView extends StatelessWidget {
15.height,
],
).toWhiteContainer(width: double.infinity, allPading: 12),
buildBottomActionButton(appointmentStatusEnum: appointmentListModel.appointmentStatusEnum!, context: context),
buildBottomActionButton(
appointmentStatusEnum:
appointmentListModel.appointmentStatusEnum!,
context: context),
],
),
),

@ -12,8 +12,8 @@ void showMyBottomSheet(BuildContext context, {bool isDismissible = true, require
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topRight: Radius.circular(25),
topLeft: Radius.circular(25),
topRight: Radius.circular(0),
topLeft: Radius.circular(0),
),
),
clipBehavior: Clip.antiAlias,

@ -7,8 +7,15 @@ class FiltersList extends StatelessWidget {
final List<FilterListModel> filterList;
final Function(int, int) onFilterTapped;
final bool needLeftPadding;
EdgeInsets? padding;
const FiltersList({Key? key, required this.filterList, this.needLeftPadding = true, required this.onFilterTapped}) : super(key: key);
FiltersList({
Key? key,
this.padding,
required this.filterList,
this.needLeftPadding = true,
required this.onFilterTapped,
}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -16,7 +23,7 @@ class FiltersList extends StatelessWidget {
height: 37,
width: double.infinity,
child: ListView.builder(
padding: EdgeInsets.only(left: needLeftPadding ? 12 : 0),
padding: padding ?? EdgeInsets.only(left: needLeftPadding ? 12 : 0),
itemCount: filterList.length,
scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext context, int index) {
@ -29,15 +36,20 @@ class FiltersList extends StatelessWidget {
padding: const EdgeInsets.symmetric(horizontal: 8),
margin: const EdgeInsets.symmetric(horizontal: 4),
decoration: BoxDecoration(
color: filterList[index].isSelected ? MyColors.darkIconColor : null,
color: filterList[index].isSelected
? MyColors.darkIconColor
: null,
border: Border.all(
color: filterList[index].isSelected ? MyColors.darkIconColor : MyColors.primaryColor,
color: filterList[index].isSelected
? MyColors.darkIconColor
: MyColors.primaryColor,
width: 2,
),
),
child: filterList[index].title.toText(
fontSize: 12,
color: filterList[index].isSelected ? MyColors.white : null,
color:
filterList[index].isSelected ? MyColors.white : null,
),
),
);

@ -93,10 +93,10 @@ packages:
dependency: transitive
description:
name: collection
sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c"
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
url: "https://pub.dev"
source: hosted
version: "1.17.1"
version: "1.18.0"
country_code_picker:
dependency: "direct main"
description:
@ -513,10 +513,10 @@ packages:
dependency: "direct main"
description:
name: intl
sha256: a3715e3bc90294e971cb7dc063fbf3cd9ee0ebf8604ffeafabd9e6f16abbdbe6
sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
url: "https://pub.dev"
source: hosted
version: "0.18.0"
version: "0.18.1"
js:
dependency: transitive
description:
@ -601,26 +601,26 @@ packages:
dependency: transitive
description:
name: matcher
sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb"
sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
url: "https://pub.dev"
source: hosted
version: "0.12.15"
version: "0.12.16"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
url: "https://pub.dev"
source: hosted
version: "0.2.0"
version: "0.5.0"
meta:
dependency: transitive
description:
name: meta
sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
url: "https://pub.dev"
source: hosted
version: "1.9.1"
version: "1.10.0"
mime:
dependency: transitive
description:
@ -717,6 +717,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.7"
percent_indicator:
dependency: "direct main"
description:
name: percent_indicator
sha256: c37099ad833a883c9d71782321cb65c3a848c21b6939b6185f0ff6640d05814c
url: "https://pub.dev"
source: hosted
version: "4.2.3"
permission_handler:
dependency: "direct main"
description:
@ -902,10 +910,10 @@ packages:
dependency: transitive
description:
name: source_span
sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
url: "https://pub.dev"
source: hosted
version: "1.9.1"
version: "1.10.0"
sqflite:
dependency: transitive
description:
@ -934,18 +942,18 @@ packages:
dependency: transitive
description:
name: stack_trace
sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
url: "https://pub.dev"
source: hosted
version: "1.11.0"
version: "1.11.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
url: "https://pub.dev"
source: hosted
version: "2.1.1"
version: "2.1.2"
stream_transform:
dependency: transitive
description:
@ -990,10 +998,10 @@ packages:
dependency: transitive
description:
name: test_api
sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
url: "https://pub.dev"
source: hosted
version: "0.5.1"
version: "0.6.1"
tuple:
dependency: transitive
description:
@ -1098,6 +1106,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.4"
web:
dependency: transitive
description:
name: web
sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152
url: "https://pub.dev"
source: hosted
version: "0.3.0"
web_socket_channel:
dependency: transitive
description:
@ -1131,5 +1147,5 @@ packages:
source: hosted
version: "6.3.0"
sdks:
dart: ">=3.0.0 <4.0.0"
dart: ">=3.2.0-194.0.dev <4.0.0"
flutter: ">=3.10.0"

@ -41,6 +41,7 @@ dependencies:
intl: any
signalr_core: ^1.1.1
logging: ^1.2.0
percent_indicator: ^4.2.3
# google

Loading…
Cancel
Save