addnew service fix

aamir_dev
Faiz Hashmi 11 months ago
parent a97fc8c08d
commit 30cffc364b

@ -752,5 +752,7 @@
"youCannotDeactivateThisServiceRightNow": "لا يمكنك تعطيل هذه الخدمة الآن لأن لديك مواعيد معلقة لهذه الخدمة. تفاصيل آخر موعد هي:",
"done": "تم",
"notice": "إشعار",
"serviceDeactivated": "تم تعطيل الخدمة"
"serviceDeactivated": "تم تعطيل الخدمة",
"totalNumberOfServices": "إجمالي عدد الخدمات:",
"noAvailableOfficesInCity": "لا توجد مكاتب متاحة في مدينتك لخدمتك."
}

@ -750,5 +750,7 @@
"youCannotDeactivateThisServiceRightNow": "You cannot deactivate this service right now because you have pending appointments for this service. The last appointment details are:",
"done": "Done",
"notice": "Notice",
"serviceDeactivated": "Service Deactivated"
"serviceDeactivated": "Service Deactivated",
"totalNumberOfServices": "Total number of services:",
"noAvailableOfficesInCity": "There are no available offices in your city for your service."
}

@ -768,7 +768,9 @@ class CodegenLoader extends AssetLoader{
"youCannotDeactivateThisServiceRightNow": "لا يمكنك تعطيل هذه الخدمة الآن لأن لديك مواعيد معلقة لهذه الخدمة. تفاصيل آخر موعد هي:",
"done": "تم",
"notice": "إشعار",
"serviceDeactivated": "تم تعطيل الخدمة"
"serviceDeactivated": "تم تعطيل الخدمة",
"totalNumberOfServices": "إجمالي عدد الخدمات:",
"noAvailableOfficesInCity": "لا توجد مكاتب متاحة في مدينتك لخدمتك."
};
static const Map<String,dynamic> en_US = {
"firstTimeLogIn": "First Time Log In",
@ -1522,7 +1524,9 @@ static const Map<String,dynamic> en_US = {
"youCannotDeactivateThisServiceRightNow": "You cannot deactivate this service right now because you have pending appointments for this service. The last appointment details are:",
"done": "Done",
"notice": "Notice",
"serviceDeactivated": "Service Deactivated"
"serviceDeactivated": "Service Deactivated",
"totalNumberOfServices": "Total number of services:",
"noAvailableOfficesInCity": "There are no available offices in your city for your service."
};
static const Map<String, Map<String,dynamic>> mapLocales = {"ar_SA": ar_SA, "en_US": en_US};
}

@ -732,5 +732,7 @@ abstract class LocaleKeys {
static const done = 'done';
static const notice = 'notice';
static const serviceDeactivated = 'serviceDeactivated';
static const totalNumberOfServices = 'totalNumberOfServices';
static const noAvailableOfficesInCity = 'noAvailableOfficesInCity';
}

@ -12,7 +12,7 @@ class SSPhotoOfficeScheduleModel {
String? areaName;
String? latitude;
String? longitude;
int? distanceKM;
double? distanceKM;
int? totalItemsCount;
List<PhotoOfficeScheduleSlots>? photoOfficeScheduleSlots;
List<CustomTimeDateSlotModel>? customTimeDateSlotList;

@ -51,15 +51,17 @@ class CategoryData extends Equatable {
this.services,
this.branchId,
this.branchName,
this.isDeactivated,
});
int? id;
String? categoryName;
String? categoryNameN;
dynamic? serviceCategoryIconUrl;
dynamic? serviceCategoryImageUrl;
String? serviceCategoryIconUrl;
String? serviceCategoryImageUrl;
String? branchId;
String? branchName;
bool? isDeactivated;
List<ServiceModel>? services;
factory CategoryData.fromJson(Map<String, dynamic> json) => CategoryData(
@ -69,6 +71,7 @@ class CategoryData extends Equatable {
serviceCategoryIconUrl: json["serviceCategoryIconUrl"],
serviceCategoryImageUrl: json["serviceCategoryImageUrl"],
services: [],
isDeactivated: false,
);
Map<String, dynamic> toJson() => {

@ -252,17 +252,6 @@ class AppointmentsVM extends BaseVM {
notifyListeners();
}
// String pickedHomeLocation = "";
//
// void updatePickedHomeLocation(String value) {
// pickedHomeLocation = value;
// pickHomeLocationError = "";
// if (currentServiceSelection != null) {
// currentServiceSelection!.homeLocation = value;
// }
// notifyListeners();
// }
SelectionModel branchSelectedCategoryId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updateProviderCategoryId(SelectionModel id) {
@ -305,9 +294,6 @@ class AppointmentsVM extends BaseVM {
return;
}
servicesInCurrentAppointment.forEach((i) {
log("hlo1: ${i.serviceDescription} ${i.servicelocationInfo.homeChargesInCurrentService}");
});
if (!(currentServiceSelection!.isAllowAppointmentHome ?? false)) {
updateIsHomeTapped(false);
return;
@ -321,19 +307,8 @@ class AppointmentsVM extends BaseVM {
distanceToBranch: currentLocationInfoModel!.distanceToBranch,
homeChargesInCurrentService: double.parse(currentServiceSelection!.rangePricePerKm ?? "0.0"),
);
// for (var service in servicesInCurrentAppointment) {
// service.servicelocationInfo.address = currentLocationInfoModel!.address;
// service.servicelocationInfo.latitude = currentLocationInfoModel!.latitude;
// service.servicelocationInfo.longitude = currentLocationInfoModel!.longitude;
// service.servicelocationInfo.distanceToBranch = currentLocationInfoModel!.distanceToBranch;
// }
}
servicesInCurrentAppointment.forEach((i) {
log("hlo2: ${i.serviceDescription} ${i.servicelocationInfo.homeChargesInCurrentService}");
});
notifyListeners();
}
@ -384,7 +359,7 @@ class AppointmentsVM extends BaseVM {
}
applyFilterOnAppointmentsVM({required AppointmentStatusEnum appointmentStatusEnum, bool isNeedCustomerFilter = false}) {
log("appointmentStatusEnum: ${appointmentStatusEnum}");
log("appointmentStatusEnum: $appointmentStatusEnum");
// isNeedCustomerFilter IS ONLY FOR THE PROVIDER APP
if (appointmentsFilterOptions.isEmpty) return;
for (var value in appointmentsFilterOptions) {
@ -467,13 +442,15 @@ class AppointmentsVM extends BaseVM {
myAppointments = await appointmentRepo.getMyAppointmentsForCustomersByFilters();
// myFilteredAppointments = myAppointments;
setState(ViewState.idle);
applyFilterOnAppointmentsVM(appointmentStatusEnum: AppointmentStatusEnum.allAppointments);
myUpComingAppointments = myAppointments
.where((element) =>
(element.appointmentStatusEnum == AppointmentStatusEnum.booked || element.appointmentStatusEnum == AppointmentStatusEnum.confirmed) &&
(DateHelper.parseStringToDate(element.appointmentDate!).isAfter(DateTime.now())))
.toList();
setState(ViewState.idle);
applyFilterOnAppointmentsVM(appointmentStatusEnum: AppointmentStatusEnum.allAppointments);
notifyListeners();
}

@ -950,6 +950,14 @@ class RequestsVM extends BaseVM {
notifyListeners();
}
bool isBase64String(String input) {
// This regex checks if the string is a valid Base64 string
final base64Regex = RegExp(r'^[A-Za-z0-9+/=]+$');
// Check if the string matches the Base64 pattern
return base64Regex.hasMatch(input) && (input.length % 4 == 0);
}
MessageImageModel convertFileToMessageImageModel({required ImageModel imageModel, required int offerId}) {
MessageImageModel offerImages;
@ -961,15 +969,23 @@ class RequestsVM extends BaseVM {
reqOfferID: offerId,
);
} else {
File file = File(imageModel.filePath!);
List<int> imageBytes = file.readAsBytesSync();
String image = base64Encode(imageBytes);
File? file;
List<int> imageBytes = [];
String image = '';
if (!isBase64String(imageModel.filePath!)) {
file = File(imageModel.filePath!);
imageBytes = file.readAsBytesSync();
image = base64Encode(imageBytes);
} else {
image = imageModel.filePath!;
}
offerImages = MessageImageModel(
id: 0,
imageStr: image,
isFromNetwork: false,
reqOfferID: offerId,
imagePath: file.path,
imagePath: file?.path,
);
}

@ -164,6 +164,7 @@ class ServiceVM extends BaseVM {
final BranchDetailModel currentBranch = branches!.data!.serviceProviderBranch!.firstWhere((element) => element.id == selectedBranchId);
for (var element in currentBranch.branchServices!) {
// TODO: Here , we need to add the category deactivated status.
categories.add(
CategoryData(
id: element.categoryId,

@ -293,24 +293,24 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
20.height,
adVM.state == ViewState.busy
? const Center(child: CircularProgressIndicator())
: Builder(
builder: (context) {
List<DropValue> vehicleCitiesDrop = [];
for (int i = 0; i < adVM.photoSSSchedulesByOffices.length; i++) {
var element = adVM.photoSSSchedulesByOffices[i];
vehicleCitiesDrop.add(DropValue(element.photoOfficeID?.toInt() ?? 0, element.photoOfficeName ?? "", i.toString()));
}
return DropdownField(
(DropValue value) => adVM.updatePhotoOfficeSelectedId(SelectionModel(selectedId: value.id, selectedOption: value.value, itemPrice: value.subValue)),
// here the item price is the index of the selected option
list: vehicleCitiesDrop,
dropdownValue: adVM.photoOfficeSelectedId.selectedId != -1 ? DropValue(adVM.photoOfficeSelectedId.selectedId, adVM.photoOfficeSelectedId.selectedOption, "") : null,
hint: LocaleKeys.selectOffice.tr(),
errorValue: adVM.photoOfficeSelectedId.errorValue,
);
},
),
: adVM.photoSSSchedulesByOffices.isEmpty
? LocaleKeys.noAvailableOfficesInCity.tr().toText(fontSize: 14, height: 1.2)
: Builder(
builder: (context) {
List<DropValue> vehicleCitiesDrop = [];
for (int i = 0; i < adVM.photoSSSchedulesByOffices.length; i++) {
var element = adVM.photoSSSchedulesByOffices[i];
vehicleCitiesDrop.add(DropValue(element.photoOfficeID?.toInt() ?? 0, element.photoOfficeName ?? "", i.toString()));
}
return DropdownField(
(DropValue value) => adVM.updatePhotoOfficeSelectedId(SelectionModel(selectedId: value.id, selectedOption: value.value, itemPrice: value.subValue)),
list: vehicleCitiesDrop,
dropdownValue: adVM.photoOfficeSelectedId.selectedId != -1 ? DropValue(adVM.photoOfficeSelectedId.selectedId, adVM.photoOfficeSelectedId.selectedOption, "") : null,
hint: LocaleKeys.selectOffice.tr(),
errorValue: adVM.photoOfficeSelectedId.errorValue,
);
},
),
if (adVM.photoOfficeSelectedId.selectedId != -1) ...[
9.height,
CustomCalenderAppointmentWidget(

@ -1,5 +1,5 @@
import 'dart:developer';
import 'dart:io';
import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart';
@ -33,9 +33,6 @@ class PickedFilesContainer extends StatelessWidget {
@override
Widget build(BuildContext context) {
pickedFiles.forEach((i) {
log("isFromNetwork: ${i.isFromNetwork}");
});
return GridView.count(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
@ -95,8 +92,20 @@ class BuildFilesContainer extends StatelessWidget {
this.isPdf = false,
});
bool isBase64String(String input) {
// This regex checks if the string is a valid Base64 string
final base64Regex = RegExp(r'^[A-Za-z0-9+/=]+$');
// Check if the string matches the Base64 pattern
return base64Regex.hasMatch(input) && (input.length % 4 == 0);
}
@override
Widget build(BuildContext context) {
Uint8List? bytes;
if ((image.isFromNetwork == null || image.isFromNetwork == false) && isBase64String(image.filePath ?? "")) {
bytes = (base64Decode(image.filePath!)) as Uint8List?;
}
return Stack(
children: [
SizedBox(
@ -124,13 +133,20 @@ class BuildFilesContainer extends StatelessWidget {
width: 73,
)
.paddingAll(8)
: image.filePath!
.buildFileImage(
fit: BoxFit.fill,
height: 72,
width: 70,
)
.paddingAll(8),
: isBase64String(image.filePath!)
? Image.memory(
bytes!,
fit: BoxFit.fill,
height: 72,
width: 70,
).paddingAll(8)
: image.filePath!
.buildFileImage(
fit: BoxFit.fill,
height: 72,
width: 70,
)
.paddingAll(8),
if (!isReview) ...[
Align(
alignment: Alignment.topRight,

@ -221,6 +221,7 @@ class _ChatViewState extends State<ChatView> {
size: 30,
).onPress(
() {
requestVM.resetSendOfferBottomSheet();
RequestDetailPageArguments requestDetailArguments = RequestDetailPageArguments(
requestIndex: chatViewArgumentsForRequest!.requestIndex,
requestModel: chatViewArgumentsForRequest!.requestModel!,

@ -742,13 +742,13 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
requestVM.updateIsDeliveryAvailableStatus((offer.isDeliveryAvailable ?? false));
if (offer.reqOfferImages != null && offer.reqOfferImages!.isNotEmpty) {
for (var element in offer.reqOfferImages!) {
log("element: ${element.imageStr != null && element.imageStr!.isNotEmpty}");
if (element.imageUrl != null || element.imageStr != null) {
ImageModel imageModel = ImageModel(
id: element.id,
filePath: element.imageStr != null && element.imageStr!.isNotEmpty ? element.imageStr : element.imageUrl,
isFromNetwork: element.imageStr != null && element.imageStr!.isNotEmpty ? false : true);
log("imageModelimageModel: ${imageModel.toString()}");
requestVM.addImageToPickedVehicleImages(imageModel);
}
}

@ -3,6 +3,7 @@ import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/models/requests_models/request_model.dart';
import 'package:mc_common_app/utils/dialogs_and_bottomsheets.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/view_models/requests_view_model.dart';
@ -156,11 +157,25 @@ class MyRequestsFragment extends StatelessWidget {
return;
},
child: RequestItem(
request: requestsVM.myFilteredRequests[index],
appType: AppState().currentAppType,
requestIndex: index,
shouldShowStatuses: AppState().currentAppType == AppType.customer,
),
request: requestsVM.myFilteredRequests[index],
shouldShowStatuses: AppState().currentAppType == AppType.customer,
onTap: () async {
RequestModel request = requestsVM.myFilteredRequests[index];
requestsVM.updateCurrentSelectedRequest(request);
if (request.requestStatus == RequestStatusEnum.pending ||
request.requestStatus == RequestStatusEnum.cancelled ||
request.requestStatus == RequestStatusEnum.expired) {
return;
}
if (AppState().currentAppType == AppType.provider) {
RequestDetailPageArguments requestDetailPageArguments = RequestDetailPageArguments(requestIndex: index, requestModel: request);
navigateWithName(context, AppRoutes.requestsDetailPage, arguments: requestDetailPageArguments);
} else {
requestsVM.myFilteredRequests[index].offerCount = 0;
requestsVM.notifyListeners();
navigateWithName(context, AppRoutes.offersListPage, arguments: request.id);
}
}),
);
},
separatorBuilder: (context, index) {

@ -80,19 +80,21 @@ class _OfferListPageState extends State<OfferListPage> {
fontSize: 16,
isBold: true,
),
Center(
child: "${offersModel.offerCount}".toText(
color: Colors.white,
isBold: true,
fontSize: 10,
if (offersModel.offerCount != null && offersModel.offerCount! > 0) ...[
Center(
child: "${offersModel.offerCount}".toText(
color: Colors.white,
isBold: true,
fontSize: 10,
),
).toContainer(
backgroundColor: MyColors.cancelledColor,
borderRadius: 100,
paddingAll: 1,
width: 22,
height: 22,
),
).toContainer(
backgroundColor: MyColors.cancelledColor,
borderRadius: 100,
paddingAll: 1,
width: 22,
height: 22,
),
],
],
),
8.height,
@ -131,13 +133,16 @@ class _OfferListPageState extends State<OfferListPage> {
await chatVM
.getRequestsChatMessagesForCustomer(
context: context,
providerId: offersModel.providerId ?? 0,
requestOfferId: 0,
requestId: widget.requestId,
providerOfferIndex: index,
)
.whenComplete(() => navigateWithName(context, AppRoutes.chatView, arguments: chatViewArguments));
context: context,
providerId: offersModel.providerId ?? 0,
requestOfferId: 0,
requestId: widget.requestId,
providerOfferIndex: index,
)
.whenComplete(() {
chatVM.serviceProviderOffersList[index].offerCount = 0;
navigateWithName(context, AppRoutes.chatView, arguments: chatViewArguments);
});
}).toContainer(isShadowEnabled: true);
},
separatorBuilder: (context, index) => 16.height,

@ -2,27 +2,22 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/models/requests_models/request_model.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/chat_view_model.dart';
import 'package:mc_common_app/view_models/requests_view_model.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart';
class RequestItem extends StatelessWidget {
final RequestModel request;
final AppType appType;
final int requestIndex;
final bool shouldShowStatuses;
final Function() onTap;
const RequestItem({super.key, required this.request, required this.appType, required this.requestIndex, this.shouldShowStatuses = true});
const RequestItem({super.key, required this.request, this.shouldShowStatuses = true, required this.onTap});
@override
Widget build(BuildContext context) {
@ -65,7 +60,7 @@ class RequestItem extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
if (request.offerCount > 0 && appType == AppType.customer && request.requestStatus == RequestStatusEnum.submitted) ...[
if (request.offerCount > 0 && AppState().currentAppType == AppType.customer && request.requestStatus == RequestStatusEnum.submitted) ...[
Center(
child: "${request.offerCount}".toText(
color: Colors.white,
@ -112,17 +107,7 @@ class RequestItem extends StatelessWidget {
// ),
],
).toContainer(isShadowEnabled: true).onPress(() async {
RequestsVM requestsVM = context.read<RequestsVM>();
requestsVM.updateCurrentSelectedRequest(request);
if (request.requestStatus == RequestStatusEnum.pending || request.requestStatus == RequestStatusEnum.cancelled || request.requestStatus == RequestStatusEnum.expired) {
return;
}
if (appType == AppType.provider) {
RequestDetailPageArguments requestDetailPageArguments = RequestDetailPageArguments(requestIndex: requestIndex, requestModel: request);
navigateWithName(context, AppRoutes.requestsDetailPage, arguments: requestDetailPageArguments);
} else {
navigateWithName(context, AppRoutes.offersListPage, arguments: request.id);
}
onTap();
});
}

@ -5,6 +5,7 @@ import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/models/requests_models/request_model.dart';
import 'package:mc_common_app/utils/dialogs_and_bottomsheets.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/view_models/requests_view_model.dart';
@ -80,7 +81,24 @@ class _ProviderAcceptedRequestsViewState extends State<ProviderAcceptedRequestsV
)
: ListView.separated(
itemBuilder: (context, index) {
return RequestItem(request: requestsVM.providersAcceptedRequestsList[index], appType: AppState().currentAppType, requestIndex: index);
return RequestItem(
request: requestsVM.providersAcceptedRequestsList[index],
onTap: () async {
RequestModel request = requestsVM.myFilteredRequests[index];
requestsVM.updateCurrentSelectedRequest(request);
if (request.requestStatus == RequestStatusEnum.pending ||
request.requestStatus == RequestStatusEnum.cancelled ||
request.requestStatus == RequestStatusEnum.expired) {
return;
}
if (AppState().currentAppType == AppType.provider) {
RequestDetailPageArguments requestDetailPageArguments = RequestDetailPageArguments(requestIndex: index, requestModel: request);
navigateWithName(context, AppRoutes.requestsDetailPage, arguments: requestDetailPageArguments);
} else {
navigateWithName(context, AppRoutes.offersListPage, arguments: request.id);
}
},
);
},
separatorBuilder: (context, index) {
return 16.height;

@ -57,14 +57,6 @@ class CustomSettingOptionsTile extends StatelessWidget {
),
isForLanguage
? LocaleKeys.english.tr().toText(fontSize: 12, isUnderLine: true, color: MyColors.primaryColor)
// const Icon(
// Icons.language,
// size: 18,
// color: MyColors.primaryColor,
// )
//
: showTrailingArrow
? const Icon(Icons.arrow_forward, size: 18)
: const SizedBox()

Loading…
Cancel
Save