Service Request Done

master_new_changes
Faiz Hashmi 2 years ago
parent e7fa2bfac8
commit c3696586f3

@ -5,7 +5,7 @@ import 'package:mc_common_app/models/requests_models/request_model.dart';
import 'package:mc_common_app/models/user_models/register_user.dart'; import 'package:mc_common_app/models/user_models/register_user.dart';
import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/views/advertisement/ads_buyer_chats_view.dart'; import 'package:mc_common_app/views/advertisement/ads_buyer_chats_view.dart';
import 'package:mc_common_app/views/advertisement/ads_detail_view.dart'; import 'package:mc_common_app/views/advertisement/ads_detail_view/ads_detail_view.dart';
import 'package:mc_common_app/views/advertisement/ads_filter_view.dart'; import 'package:mc_common_app/views/advertisement/ads_filter_view.dart';
import 'package:mc_common_app/views/advertisement/create_ad_view.dart'; import 'package:mc_common_app/views/advertisement/create_ad_view.dart';
import 'package:mc_common_app/views/advertisement/select_ad_type_view.dart'; import 'package:mc_common_app/views/advertisement/select_ad_type_view.dart';
@ -14,6 +14,7 @@ import 'package:mc_common_app/views/payments/payment_methods_view.dart';
import 'package:mc_common_app/views/profile/profile_view.dart'; import 'package:mc_common_app/views/profile/profile_view.dart';
import 'package:mc_common_app/views/requests/create_request_page.dart'; import 'package:mc_common_app/views/requests/create_request_page.dart';
import 'package:mc_common_app/views/requests/offer_list_page.dart'; import 'package:mc_common_app/views/requests/offer_list_page.dart';
import 'package:mc_common_app/views/requests/request_detail_page.dart';
import 'package:mc_common_app/views/setting_options/provider_license_page.dart'; import 'package:mc_common_app/views/setting_options/provider_license_page.dart';
import 'package:mc_common_app/views/setting_options/setting_option_help.dart'; import 'package:mc_common_app/views/setting_options/setting_option_help.dart';
import 'package:mc_common_app/views/setting_options/setting_options_faqs.dart'; import 'package:mc_common_app/views/setting_options/setting_options_faqs.dart';
@ -148,12 +149,17 @@ class AppRoutes {
AppRoutes.adsFilterView: (context) => const AdsFilterView(), AppRoutes.adsFilterView: (context) => const AdsFilterView(),
AppRoutes.selectAdTypeView: (context) => SelectAdTypeView(arguments: ModalRoute.of(context)!.settings.arguments as List<bool>), AppRoutes.selectAdTypeView: (context) => SelectAdTypeView(arguments: ModalRoute.of(context)!.settings.arguments as List<bool>),
AppRoutes.chatView: (context) => ChatView(chatViewArguments: ModalRoute.of(context)!.settings.arguments as ChatViewArguments), AppRoutes.chatView: (context) => ChatView(chatViewArguments: ModalRoute.of(context)!.settings.arguments as ChatViewArguments),
AppRoutes.offersListPage: (context) => OfferListPage(offerListPageArguments: ModalRoute.of(context)!.settings.arguments as OfferListPageArguments),
AppRoutes.adsBuyerChatsListView: (context) => AdsBuyerChatsView(buyersListViewArguments: ModalRoute.of(context)!.settings.arguments as List<BuyersChatForAdsModel>), AppRoutes.adsBuyerChatsListView: (context) => AdsBuyerChatsView(buyersListViewArguments: ModalRoute.of(context)!.settings.arguments as List<BuyersChatForAdsModel>),
AppRoutes.createRequestPage: (context) => const CreateRequestPage(),
AppRoutes.settingOptionsFaqs: (context) => const SettingOptionsFAQs(), AppRoutes.settingOptionsFaqs: (context) => const SettingOptionsFAQs(),
AppRoutes.settingOptionsInviteFriends: (context) => const SettingOptionsInviteFriends(), AppRoutes.settingOptionsInviteFriends: (context) => const SettingOptionsInviteFriends(),
AppRoutes.paymentMethodsView: (context) => PaymentMethodsView(paymentType: ModalRoute.of(context)!.settings.arguments as PaymentTypes), AppRoutes.paymentMethodsView: (context) => PaymentMethodsView(paymentType: ModalRoute.of(context)!.settings.arguments as PaymentTypes),
//Requests
AppRoutes.requestsDetailPage: (context) => RequestDetailPage(requestDetailPageArguments: ModalRoute.of(context)!.settings.arguments as RequestDetailPageArguments),
AppRoutes.createRequestPage: (context) => const CreateRequestPage(),
AppRoutes.offersListPage: (context) => OfferListPage(offerListPageArguments: ModalRoute.of(context)!.settings.arguments as OfferListPageArguments),
}; };
} }

@ -3,6 +3,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/main.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/enums.dart';
@ -32,7 +33,7 @@ extension EmailValidator on String {
fontStyle: isItalic ? FontStyle.italic : null, fontStyle: isItalic ? FontStyle.italic : null,
height: height, height: height,
decoration: isUnderLine ? TextDecoration.underline : textDecoration ?? TextDecoration.none, decoration: isUnderLine ? TextDecoration.underline : textDecoration ?? TextDecoration.none,
decorationColor: decorationColor ?? MyColors.provTextColor, decorationColor: decorationColor ?? color ?? MyColors.darkTextColor,
fontSize: fontSize ?? 10, fontSize: fontSize ?? 10,
fontFamily: isArabic ? MyFonts.gessTwoFont : MyFonts.poppinsFont, fontFamily: isArabic ? MyFonts.gessTwoFont : MyFonts.poppinsFont,
fontWeight: isBold ? FontWeight.bold : fontWeight ?? MyFonts.SemiBold, fontWeight: isBold ? FontWeight.bold : fontWeight ?? MyFonts.SemiBold,
@ -378,8 +379,6 @@ extension RequestTypeStatusToInt on RequestsTypeEnum {
} }
} }
// 290223243016
extension AdPostStatusToInt on AdPostStatus { extension AdPostStatusToInt on AdPostStatus {
int getIdFromAdPostStatusEnum() { int getIdFromAdPostStatusEnum() {
switch (this) { switch (this) {
@ -665,6 +664,23 @@ extension FormatMonthByNumber on String {
} }
} }
extension NameExtensions on String {
String getInitials() {
final name = trim();
String initials = "U";
if (name.isEmpty) {
return initials;
}
final list = name.split(' ');
if (list.length > 1) {
initials = list[0][0].toUpperCase() + list[1][0].toUpperCase();
}
return initials;
}
}
extension ChatMessageTypeEnumExt on int { extension ChatMessageTypeEnumExt on int {
//FreeText = 1, //FreeText = 1,
// Image = 2, // Image = 2,

@ -71,9 +71,9 @@ class ReqOffer {
int? offerStatus; int? offerStatus;
String? offerStatusText; String? offerStatusText;
String? comment; String? comment;
String? serviceItem; String? serviceItemName;
String? itemManufacturer; int? manufacturedById;
String? manufacturedDate; String? manufacturedOn;
double? price; double? price;
RequestsTypeEnum? requestsTypeEnum; RequestsTypeEnum? requestsTypeEnum;
RequestOfferStatusEnum? requestOfferStatusEnum; RequestOfferStatusEnum? requestOfferStatusEnum;
@ -85,9 +85,9 @@ class ReqOffer {
this.offerStatus, this.offerStatus,
this.offerStatusText, this.offerStatusText,
this.comment, this.comment,
this.serviceItem, this.serviceItemName,
this.itemManufacturer, this.manufacturedById,
this.manufacturedDate, this.manufacturedOn,
this.price, this.price,
this.requestOfferStatusEnum, this.requestOfferStatusEnum,
this.requestsTypeEnum, this.requestsTypeEnum,
@ -100,9 +100,9 @@ class ReqOffer {
offerStatus = json['offerStatus']; offerStatus = json['offerStatus'];
offerStatusText = json['offerStatusText']; offerStatusText = json['offerStatusText'];
comment = json['comment']; comment = json['comment'];
serviceItem = json['serviceItem']; serviceItemName = json['serviceItem'];
itemManufacturer = json['itemManufacturer']; manufacturedById = json['itemManufacturer'];
manufacturedDate = json['manufacturedDate']; manufacturedOn = json['manufacturedDate'];
price = json['price']; price = json['price'];
requestOfferStatusEnum = ((json['offerStatus']) as int).toRequestOfferStatusEnum(); requestOfferStatusEnum = ((json['offerStatus']) as int).toRequestOfferStatusEnum();
requestsTypeEnum = RequestsTypeEnum.serviceRequest; // TODO: THIS SHOULD COME FROM API requestsTypeEnum = RequestsTypeEnum.serviceRequest; // TODO: THIS SHOULD COME FROM API

@ -53,6 +53,7 @@ class ChatRepoImp implements ChatRepo {
client: IOClient(HttpClient()..badCertificateCallback = (x, y, z) => true), client: IOClient(HttpClient()..badCertificateCallback = (x, y, z) => true),
logging: (level, message) {}, logging: (level, message) {},
)) ))
.withAutomaticReconnect()
.build(); .build();
return hub; return hub;
} }

@ -232,7 +232,7 @@ class AdVM extends BaseVM {
return; return;
} }
// this means if the filter is reserved ads // this means if the filter is reserved ads
if (adPostStatusEnum.getIdFromAdPostStatusEnum() == 9) { if (adPostStatusEnum == AdPostStatus.reserved) {
myAdsFilteredList = myReservedAds; myAdsFilteredList = myReservedAds;
for (var ad in myAdsFilteredList) { for (var ad in myAdsFilteredList) {
ad.isReservedByMe = true; ad.isReservedByMe = true;
@ -245,24 +245,6 @@ class AdVM extends BaseVM {
notifyListeners(); notifyListeners();
} }
Future<void> getMyAds() async {
setState(ViewState.busy);
myAds = await adsRepo.getAllAds(isMyAds: true);
final myActiveAds = myAds.where((element) => element.adPostStatus == AdPostStatus.active).toList();
myActiveAdsForHome = myActiveAds.length >= 3 ? myActiveAds.take(3).toList() : myActiveAds;
await getMyReservedAds();
notifyListeners();
setState(ViewState.idle);
}
Future<List<AdDetailsModel>> getMyReservedAds() async {
setState(ViewState.busy);
myReservedAds = await adsRepo.getMyReservedAds();
isFetchingLists = false;
setState(ViewState.idle);
return myReservedAds;
}
Future<bool> createReserveAd({required int adId, required BuildContext context}) async { Future<bool> createReserveAd({required int adId, required BuildContext context}) async {
Utils.showLoading(context); Utils.showLoading(context);
GenericRespModel genericRespModel = await adsRepo.createReserveAd(adId: adId); GenericRespModel genericRespModel = await adsRepo.createReserveAd(adId: adId);
@ -284,6 +266,25 @@ class AdVM extends BaseVM {
setState(ViewState.idle); setState(ViewState.idle);
} }
Future<void> getMyAds() async {
setState(ViewState.busy);
myAds = await adsRepo.getAllAds(isMyAds: true);
myAdsFilteredList = myAds;
final myActiveAds = myAds.where((element) => element.adPostStatus == AdPostStatus.active).toList();
myActiveAdsForHome = myActiveAds.length >= 3 ? myActiveAds.take(3).toList() : myActiveAds;
await getMyReservedAds();
notifyListeners();
setState(ViewState.idle);
}
Future<List<AdDetailsModel>> getMyReservedAds() async {
setState(ViewState.busy);
myReservedAds = await adsRepo.getMyReservedAds();
isFetchingLists = false;
setState(ViewState.idle);
return myReservedAds;
}
Future<void> getVehicleTypes() async { Future<void> getVehicleTypes() async {
vehicleTypes = await commonRepo.getVehicleTypes(); vehicleTypes = await commonRepo.getVehicleTypes();
notifyListeners(); notifyListeners();

@ -221,12 +221,16 @@ class ChatVM extends ChangeNotifier {
required String message, required String message,
required int requestId, required int requestId,
required String offerPrice, required String offerPrice,
required String serviceItemName,
required int manufacturedById,
required String manufacturedOn,
required BuildContext context, required BuildContext context,
}) async { }) async {
if (hubConnection == null || hubConnection!.state != HubConnectionState.connected) { if (hubConnection == null || hubConnection!.state != HubConnectionState.connected) {
logger.i("Hub Not Connected!!"); logger.i("Hub Not Connected!!");
await buildHubConnection(context); await buildHubConnection(context);
} }
if (hubConnection!.state == HubConnectionState.connected) { if (hubConnection!.state == HubConnectionState.connected) {
final providerId = AppState().getUser.data!.userInfo!.providerId; final providerId = AppState().getUser.data!.userInfo!.providerId;
final obj = <String, dynamic>{ final obj = <String, dynamic>{
@ -238,6 +242,9 @@ class ChatVM extends ChangeNotifier {
"ReqOffer": <String, dynamic>{ "ReqOffer": <String, dynamic>{
"RequestID": requestId, "RequestID": requestId,
"Price": double.parse(offerPrice), "Price": double.parse(offerPrice),
"ServiceItem": serviceItemName,
"OfferedItemCreatedBy": manufacturedById, // TODO: The ID should be used from the manufacturer database
// "OfferedItemCreatedOn": manufacturedOn, // TODO: This should be in String on Server, Right now it is in DateTime
"ServiceProviderID": providerId, "ServiceProviderID": providerId,
"OfferStatus": RequestOfferStatusEnum.offer.getIdFromRequestOfferStatusEnum(), "OfferStatus": RequestOfferStatusEnum.offer.getIdFromRequestOfferStatusEnum(),
"Comment": message, "Comment": message,
@ -314,7 +321,10 @@ class ChatVM extends ChangeNotifier {
serviceProviderOffersList[providerIndex].chatMessages!.add(chatMessageModel); serviceProviderOffersList[providerIndex].chatMessages!.add(chatMessageModel);
} }
} else { } else {
int providerIndex = context.read<RequestsVM>().myFilteredRequests.indexWhere((element) => (element.customerUserID == receiverId && element.id == requestId)); int providerIndex = context
.read<RequestsVM>()
.myFilteredRequests
.indexWhere((element) => (element.customerUserID == receiverId && element.id == requestId));
log("providerIndex2:$providerIndex"); log("providerIndex2:$providerIndex");
if (providerIndex != -1) { if (providerIndex != -1) {
context.read<RequestsVM>().addChatMessagesInRequestsModel(msg: chatMessageModel, index: providerIndex); context.read<RequestsVM>().addChatMessagesInRequestsModel(msg: chatMessageModel, index: providerIndex);
@ -412,6 +422,9 @@ class ChatVM extends ChangeNotifier {
required int serviceProviderID, required int serviceProviderID,
required int requestOfferID, required int requestOfferID,
required String offerPrice, required String offerPrice,
required String serviceItemName,
required int manufacturedById,
required String manufacturedOn,
required RequestOfferStatusEnum requestOfferStatusEnum, required RequestOfferStatusEnum requestOfferStatusEnum,
required BuildContext context, required BuildContext context,
}) async { }) async {
@ -431,6 +444,9 @@ class ChatVM extends ChangeNotifier {
"ID": requestOfferID, "ID": requestOfferID,
"RequestID": requestId, "RequestID": requestId,
"Price": double.parse(offerPrice), "Price": double.parse(offerPrice),
"ServiceItem": serviceItemName,
"OfferedItemCreatedBy": manufacturedById, // TODO: The ID should be used from the manufacturer database
// "OfferedItemCreatedOn": manufacturedOn, // TODO: This should be in String on Server, Right now it is in DateTime
"ServiceProviderID": serviceProviderID, "ServiceProviderID": serviceProviderID,
"OfferStatus": requestOfferStatusEnum.getIdFromRequestOfferStatusEnum(), "OfferStatus": requestOfferStatusEnum.getIdFromRequestOfferStatusEnum(),
"Comment": comments, "Comment": comments,
@ -545,8 +561,7 @@ class ChatVM extends ChangeNotifier {
notifyListeners(); notifyListeners();
if (AppState().currentAppType == AppType.customer) { if (AppState().currentAppType == AppType.customer) {} else {}
} else {}
return true; return true;
} }
return false; return false;

@ -449,6 +449,9 @@ class RequestsVM extends BaseVM {
required String message, required String message,
required int requestId, required int requestId,
required String offerPrice, required String offerPrice,
required String serviceItemName,
required int manufacturedById,
required String manufacturedOn,
required RequestModel requestModel, required RequestModel requestModel,
required int requestIndex, required int requestIndex,
required bool isFromChatScreen, required bool isFromChatScreen,
@ -461,6 +464,9 @@ class RequestsVM extends BaseVM {
message: message, message: message,
requestId: requestId, requestId: requestId,
offerPrice: offerPrice, offerPrice: offerPrice,
manufacturedById: manufacturedById,
manufacturedOn: manufacturedOn,
serviceItemName: serviceItemName,
context: context, context: context,
); );
@ -470,23 +476,27 @@ class RequestsVM extends BaseVM {
resetSendOfferBottomSheet(); resetSendOfferBottomSheet();
Navigator.pop(context); Navigator.pop(context);
ChatMessageModel chatMessageModel = ChatMessageModel( ChatMessageModel chatMessageModel = ChatMessageModel(
isMyMessage: true, isMyMessage: true,
chatText: message, chatText: message,
messageType: ChatMessageTypeEnum.offer.getIdFromChatMessageTypeEnum(), messageType: ChatMessageTypeEnum.offer.getIdFromChatMessageTypeEnum(),
senderName: senderName, senderName: senderName,
senderUserID: senderId, senderUserID: senderId,
receiverUserID: receiverId, receiverUserID: receiverId,
chatMessageTypeEnum: ChatMessageTypeEnum.offer, chatMessageTypeEnum: ChatMessageTypeEnum.offer,
requestID: requestModel.id, requestID: requestModel.id,
offerStatus: RequestOfferStatusEnum.offer.getIdFromRequestOfferStatusEnum(),
reqOffer: ReqOffer(
offerStatus: RequestOfferStatusEnum.offer.getIdFromRequestOfferStatusEnum(), offerStatus: RequestOfferStatusEnum.offer.getIdFromRequestOfferStatusEnum(),
reqOffer: ReqOffer( requestID: requestModel.id,
offerStatus: RequestOfferStatusEnum.offer.getIdFromRequestOfferStatusEnum(), price: double.parse(offerPrice),
requestID: requestModel.id, manufacturedById: manufacturedById,
price: double.parse(offerPrice), manufacturedOn: manufacturedOn,
requestOfferStatusEnum: RequestOfferStatusEnum.offer, serviceItemName: serviceItemName,
comment: message, requestOfferStatusEnum: RequestOfferStatusEnum.offer,
offerStatusText: "", comment: message,
)); offerStatusText: "",
),
);
context.read<ChatVM>().onNewMessageReceivedForRequestOffer(messages: [chatMessageModel], requestsVM: this, isMyOwnOffer: true); context.read<ChatVM>().onNewMessageReceivedForRequestOffer(messages: [chatMessageModel], requestsVM: this, isMyOwnOffer: true);
if (!isFromChatScreen) { if (!isFromChatScreen) {

@ -207,6 +207,12 @@ class ServiceVM extends BaseVM {
countryCode == "SA" ? (element.cityNameN ?? "") : (element.cityName ?? ""), countryCode == "SA" ? (element.cityNameN ?? "") : (element.cityName ?? ""),
(element.id ?? "").toString(), (element.id ?? "").toString(),
); );
if (branchData.branchImages != null && branchData.branchImages!.isNotEmpty) {
for (var element in branchData.branchImages!) {
ImageModel image = ImageModel(id: element.id, isFromNetwork: true, filePath: element.imageUrl);
pickedBranchImages.add(image);
}
}
} }
} }
citiesDropList.add( citiesDropList.add(

@ -39,11 +39,12 @@ class AdsBuyerChatsView extends StatelessWidget {
Row( Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Image.asset( Container(
MyAssets.bnCar,
width: 34, width: 34,
height: 34, height: 34,
fit: BoxFit.fill, alignment: Alignment.center,
color: MyColors.darkTextColor,
child: ((chatForAdsModel.buyerName ?? "").getInitials()).toText(color: MyColors.white, fontSize: 15),
).toCircle(borderRadius: 100), ).toCircle(borderRadius: 100),
SizedBox(width: 2.w), SizedBox(width: 2.w),
Expanded( Expanded(

@ -0,0 +1,371 @@
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';
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/advertisment_models/ad_details_model.dart';
import 'package:mc_common_app/models/general_models/widgets_models.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/dialogs_and_bottomsheets.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/view_models/payment_view_model.dart';
import 'package:mc_common_app/views/advertisement/ads_detail_view/components.dart';
import 'package:mc_common_app/views/advertisement/bottom_sheets/ads_damage_part_pictures_sheet.dart';
import 'package:mc_common_app/views/advertisement/components/ads_images_corousel_widget.dart';
import 'package:mc_common_app/widgets/bottom_sheet.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart';
class AdsDetailView extends StatefulWidget {
final AdDetailsModel adDetails;
const AdsDetailView({Key? key, required this.adDetails}) : super(key: key);
@override
State<AdsDetailView> createState() => _AdsDetailViewState();
}
class _AdsDetailViewState extends State<AdsDetailView> {
late AdVM adVM;
late List<VehicleDamageCard> damagePartsPictures;
@override
void initState() {
adVM = context.read<AdVM>();
damagePartsPictures = [];
scheduleMicrotask(() {
onAdDetailsLoaded();
populateDamagePartPictures();
});
super.initState();
}
Future<void> onAdDetailsLoaded() async {
context.read<PaymentVM>().updateCurrentAdId(id: widget.adDetails.id!);
if ((widget.adDetails.isMyAd ?? false) && (widget.adDetails.adPostStatus == AdPostStatus.reserved)) {
await adVM.getAdBankingAccountInfo(adId: widget.adDetails.id!);
}
}
void populateDamagePartPictures() {
if (widget.adDetails.vehicle!.damagereport != null && widget.adDetails.vehicle!.damagereport!.isNotEmpty) {
for (var element in widget.adDetails.vehicle!.damagereport!) {
int index = -1;
ImageModel imageModel = ImageModel(id: element.id!, filePath: element.imageUrl!, isFromNetwork: true);
VehicleDamageCard vehicleDamageCard = VehicleDamageCard(
partSelectedId: SelectionModel(
selectedId: element.vehicleDamagePartID!,
selectedOption: element.partName ?? "",
),
partImages: [imageModel],
);
damagePartsPictures.add(vehicleDamageCard);
}
}
}
void deleteAdBottomSheet(BuildContext context) {
return actionConfirmationBottomSheet(
context: context,
title: LocaleKeys.deleteAdConfirmation.tr().toText(fontSize: 28, isBold: true, letterSpacing: -1.44),
subtitle: LocaleKeys.deleteAdConfirmationMessage.tr(),
actionButtonYes: Expanded(
child: ShowFillButton(
maxHeight: 55,
title: LocaleKeys.yes.tr(),
fontSize: 15,
onPressed: () {
Navigator.pop(context);
adVM.deleteMyAd(context, adId: widget.adDetails.id!);
},
),
),
actionButtonNo: Expanded(
child: ShowFillButton(
maxHeight: 55,
isFilled: false,
borderColor: MyColors.darkPrimaryColor,
title: LocaleKeys.no.tr(),
txtColor: MyColors.darkPrimaryColor,
fontSize: 15,
onPressed: () {
Navigator.pop(context);
},
),
),
);
}
Widget buildVehicleDetailsWidget() {
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ImagesCorouselWidget(imagesList: widget.adDetails.vehicle!.image!),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: "${widget.adDetails.vehicle!.vehicleTitle} | ${widget.adDetails.vehicle!.color!.label} | ${widget.adDetails.id}".toText(
fontSize: 18,
isBold: true,
maxLines: 2,
),
),
(widget.adDetails.vehicle!.cityName ?? "").toText(fontSize: 10, isBold: true, color: MyColors.lightTextColor),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
("${LocaleKeys.model.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
"${widget.adDetails.vehicle!.modelyear!.label}".toText(
fontSize: 14,
isBold: true,
),
],
),
"${widget.adDetails.vehicle!.countryID}".toText(fontSize: 10, isBold: true, color: MyColors.lightTextColor),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
("${LocaleKeys.mileage.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
"${widget.adDetails.vehicle!.mileage!.mileageEnd}Km".toText(
fontSize: 14,
isBold: true,
),
],
),
widget.adDetails.createdOn != null ? DateTime.parse(widget.adDetails.createdOn!).getTimeAgo().toText(fontSize: 10, isBold: true, color: MyColors.lightTextColor) : const SizedBox(),
],
),
Row(
children: [
("${LocaleKeys.transmission.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
"${widget.adDetails.vehicle!.transmission!.label}".toText(
fontSize: 14,
isBold: true,
),
],
),
8.height,
("${LocaleKeys.description.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
"${widget.adDetails.vehicle!.vehicleDescription}".toText(
fontSize: 14,
isBold: true,
),
if (widget.adDetails.isMyAd ?? false) ...[
8.height,
("${LocaleKeys.demand.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
widget.adDetails.vehicle!.demandAmount!.toInt().toString().toText(fontSize: 30, height: 1.2, isBold: true),
LocaleKeys.sar.tr().toText(fontSize: 15, isBold: true, color: MyColors.lightTextColor).paddingOnly(bottom: 5),
],
),
if (widget.adDetails.adPostStatus == AdPostStatus.expired) ...[
8.height,
const Divider(thickness: 1, height: 1),
8.height,
LocaleKeys.adDurationExpired.tr().toText(
color: MyColors.redColor,
fontSize: 12,
isItalic: true,
),
],
]
],
).toWhiteContainer(width: double.infinity, allPading: 12);
}
Widget buildBankDetailsIfAvailable() {
return Consumer(builder: (BuildContext context, AdVM adVM, Widget? child) {
if (adVM.adsBankDetailsModel != null) {
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.bankDetails.tr().toText(fontSize: 18, isBold: true),
// Row(
// children: [
// "Full Name: ".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
// "${widget.adDetails.vehicle!.vehicleDescription}".toText(
// fontSize: 14,
// isBold: true,
// ),
// ],
// ),
Row(
children: [
("${LocaleKeys.bankName.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
(adVM.adsBankDetailsModel!.bankName ?? "").toText(
fontSize: 14,
isBold: true,
),
],
),
Row(
children: [
("${LocaleKeys.iban.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
(adVM.adsBankDetailsModel!.iban ?? "").toText(
fontSize: 14,
isBold: true,
),
],
),
],
).toWhiteContainer(width: double.infinity, allPading: 12);
}
return const SizedBox.shrink();
});
}
Widget buildAdRejectionDetails() {
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
LocaleKeys.rejectionComments.tr().toText(fontSize: 13, isBold: true, color: MyColors.lightTextColor),
Row(
children: [
LocaleKeys.editAd.tr().toText(fontSize: 10, isBold: true),
2.width,
const Icon(Icons.edit, size: 15),
],
).onPress(() async {
Utils.showLoading(context);
await adVM.getVehicleTypes();
await adVM.getVehicleBrandsByVehicleTypeId(vehicleIdForEditAd: widget.adDetails.vehicle!.vehicleType ?? -1);
Utils.hideLoading(context);
adVM.onEditUpdateAdPressed(context: context, previousDetails: widget.adDetails, isFromExtendAd: false);
}),
],
).paddingOnly(bottom: 5),
Row(
children: [
Flexible(
child: (widget.adDetails.comment ?? "").toText(
color: MyColors.redColor,
fontSize: 12,
isItalic: true,
),
)
],
),
],
).toWhiteContainer(width: double.infinity, allPading: 12);
}
Widget buildDamagePartDetails() {
return Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
MyAssets.carHitIcon.buildSvg(color: MyColors.darkTextColor),
10.width,
LocaleKeys.damagePartPictures.tr().toText(fontSize: 16),
],
),
const Icon(Icons.arrow_forward_ios_rounded, size: 20)
],
).paddingOnly(top: 5, bottom: 5).onPress(() {
showMyBottomSheet(context, child: AdDamagePartPicturesSheet(adDamageReportList: widget.adDetails.vehicle!.damagereport ?? []));
}).toWhiteContainer(width: double.infinity, allPading: 12);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
title: LocaleKeys.vehicleDetails.tr(),
profileImageUrl: MyAssets.bnCar,
isRemoveBackButton: false,
isDrawerEnabled: false,
actions: [
((widget.adDetails.isMyAd ?? false) && (widget.adDetails.adPostStatus != AdPostStatus.reserved) && (widget.adDetails.adPostStatus != AdPostStatus.active)
? IconButton(
icon: const Icon(Icons.delete_outline, color: MyColors.redColor),
onPressed: () {
return deleteAdBottomSheet(context);
},
)
: IconButton(icon: const Icon(Icons.chat_outlined, color: Colors.black), onPressed: () => adVM.onMessagesButtonPressed(context: context, adDetailsModel: widget.adDetails)))
.toContainer(
margin: const EdgeInsets.fromLTRB(0, 8, 21, 8),
paddingAll: 0,
padding: const EdgeInsets.only(right: 21),
borderRadius: 100,
borderColor: MyColors.lightGreyEFColor,
isEnabledBorder: true,
height: 40,
width: 42,
)
],
onTap: () {},
),
body: Container(
padding: const EdgeInsets.only(bottom: 10, left: 21, right: 21),
child: Column(
children: [
Expanded(
child: ListView(
shrinkWrap: true,
children: [
buildVehicleDetailsWidget(),
12.height,
buildBankDetailsIfAvailable(),
if (widget.adDetails.vehicle!.damagereport != null && widget.adDetails.vehicle!.damagereport!.isNotEmpty) ...[
buildDamagePartDetails(),
],
12.height,
if (widget.adDetails.adPostStatus == AdPostStatus.rejected) ...[
buildAdRejectionDetails(),
],
],
),
),
SizedBox(
child: Column(
children: [
if (!(widget.adDetails.isMyAd ?? false)) ...[
const Divider(thickness: 1, height: 1),
18.height,
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
widget.adDetails.vehicle!.demandAmount!.toInt().toString().toText(fontSize: 30, isBold: true),
LocaleKeys.sar.tr().toText(fontSize: 15, isBold: true, color: MyColors.lightTextColor).paddingOnly(bottom: 5),
],
),
14.height,
],
widget.adDetails.isMyAd ?? false ? BuildAdDetailsActionButtonForMyAds(adDetailsModel: widget.adDetails) : BuildAdDetailsActionButtonForExploreAds(adDetailsModel: widget.adDetails),
],
),
)
],
),
),
);
}
}

@ -1,5 +1,4 @@
import 'dart:async'; import 'dart:async';
import 'dart:developer';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/config/routes.dart';
@ -15,15 +14,11 @@ import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/utils/utils.dart'; import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart'; import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/view_models/payment_view_model.dart';
import 'package:mc_common_app/views/advertisement/bottom_sheets/ad_duration_selection_sheet.dart'; import 'package:mc_common_app/views/advertisement/bottom_sheets/ad_duration_selection_sheet.dart';
import 'package:mc_common_app/views/advertisement/bottom_sheets/ads_damage_part_pictures_sheet.dart';
import 'package:mc_common_app/views/advertisement/components/ads_images_corousel_widget.dart';
import 'package:mc_common_app/views/advertisement/components/picked_images_container_widget.dart'; import 'package:mc_common_app/views/advertisement/components/picked_images_container_widget.dart';
import 'package:mc_common_app/views/appointments/widgets/custom_calender_widget.dart'; import 'package:mc_common_app/views/appointments/widgets/custom_calender_widget.dart';
import 'package:mc_common_app/widgets/bottom_sheet.dart'; import 'package:mc_common_app/widgets/bottom_sheet.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart'; import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/common_widgets/info_bottom_sheet.dart'; import 'package:mc_common_app/widgets/common_widgets/info_bottom_sheet.dart';
import 'package:mc_common_app/widgets/common_widgets/time_slots.dart'; import 'package:mc_common_app/widgets/common_widgets/time_slots.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart'; import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
@ -32,354 +27,6 @@ import 'package:mc_common_app/widgets/txt_field.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
class AdsDetailView extends StatefulWidget {
final AdDetailsModel adDetails;
const AdsDetailView({Key? key, required this.adDetails}) : super(key: key);
@override
State<AdsDetailView> createState() => _AdsDetailViewState();
}
class _AdsDetailViewState extends State<AdsDetailView> {
late AdVM adVM;
late List<VehicleDamageCard> damagePartsPictures;
@override
void initState() {
adVM = context.read<AdVM>();
damagePartsPictures = [];
scheduleMicrotask(() {
onAdDetailsLoaded();
populateDamagePartPictures();
});
super.initState();
}
Future<void> onAdDetailsLoaded() async {
context.read<PaymentVM>().updateCurrentAdId(id: widget.adDetails.id!);
if ((widget.adDetails.isMyAd ?? false) && (widget.adDetails.adPostStatus == AdPostStatus.reserved)) {
await adVM.getAdBankingAccountInfo(adId: widget.adDetails.id!);
}
}
void populateDamagePartPictures() {
if (widget.adDetails.vehicle!.damagereport != null && widget.adDetails.vehicle!.damagereport!.isNotEmpty) {
for (var element in widget.adDetails.vehicle!.damagereport!) {
int index = -1;
ImageModel imageModel = ImageModel(id: element.id!, filePath: element.imageUrl!, isFromNetwork: true);
VehicleDamageCard vehicleDamageCard = VehicleDamageCard(
partSelectedId: SelectionModel(
selectedId: element.vehicleDamagePartID!,
selectedOption: element.partName ?? "",
),
partImages: [imageModel],
);
damagePartsPictures.add(vehicleDamageCard);
}
}
}
void deleteAdBottomSheet(BuildContext context) {
return actionConfirmationBottomSheet(
context: context,
title: LocaleKeys.deleteAdConfirmation.tr().toText(fontSize: 28, isBold: true, letterSpacing: -1.44),
subtitle: LocaleKeys.deleteAdConfirmationMessage.tr(),
actionButtonYes: Expanded(
child: ShowFillButton(
maxHeight: 55,
title: LocaleKeys.yes.tr(),
fontSize: 15,
onPressed: () {
Navigator.pop(context);
adVM.deleteMyAd(context, adId: widget.adDetails.id!);
},
),
),
actionButtonNo: Expanded(
child: ShowFillButton(
maxHeight: 55,
isFilled: false,
borderColor: MyColors.darkPrimaryColor,
title: LocaleKeys.no.tr(),
txtColor: MyColors.darkPrimaryColor,
fontSize: 15,
onPressed: () {
Navigator.pop(context);
},
),
),
);
}
Widget buildVehicleDetailsWidget() {
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ImagesCorouselWidget(imagesList: widget.adDetails.vehicle!.image!),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: "${widget.adDetails.vehicle!.vehicleTitle} | ${widget.adDetails.vehicle!.color!.label} | ${widget.adDetails.id}".toText(
fontSize: 18,
isBold: true,
maxLines: 2,
),
),
(widget.adDetails.vehicle!.cityName ?? "").toText(fontSize: 10, isBold: true, color: MyColors.lightTextColor),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
("${LocaleKeys.model.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
"${widget.adDetails.vehicle!.modelyear!.label}".toText(
fontSize: 14,
isBold: true,
),
],
),
"${widget.adDetails.vehicle!.countryID}".toText(fontSize: 10, isBold: true, color: MyColors.lightTextColor),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
("${LocaleKeys.mileage.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
"${widget.adDetails.vehicle!.mileage!.mileageEnd}Km".toText(
fontSize: 14,
isBold: true,
),
],
),
widget.adDetails.createdOn != null ? DateTime.parse(widget.adDetails.createdOn!).getTimeAgo().toText(fontSize: 10, isBold: true, color: MyColors.lightTextColor) : const SizedBox(),
],
),
Row(
children: [
("${LocaleKeys.transmission.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
"${widget.adDetails.vehicle!.transmission!.label}".toText(
fontSize: 14,
isBold: true,
),
],
),
8.height,
("${LocaleKeys.description.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
"${widget.adDetails.vehicle!.vehicleDescription}".toText(
fontSize: 14,
isBold: true,
),
if (widget.adDetails.isMyAd ?? false) ...[
8.height,
("${LocaleKeys.demand.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
widget.adDetails.vehicle!.demandAmount!.toInt().toString().toText(fontSize: 30, height: 1.2, isBold: true),
LocaleKeys.sar.tr().toText(fontSize: 15, isBold: true, color: MyColors.lightTextColor).paddingOnly(bottom: 5),
],
),
if (widget.adDetails.adPostStatus == AdPostStatus.expired) ...[
8.height,
const Divider(thickness: 1, height: 1),
8.height,
LocaleKeys.adDurationExpired.tr().toText(
color: MyColors.redColor,
fontSize: 12,
isItalic: true,
),
],
]
],
).toWhiteContainer(width: double.infinity, allPading: 12);
}
Widget buildBankDetailsIfAvailable() {
return Consumer(builder: (BuildContext context, AdVM adVM, Widget? child) {
if (adVM.adsBankDetailsModel != null) {
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.bankDetails.tr().toText(fontSize: 18, isBold: true),
// Row(
// children: [
// "Full Name: ".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
// "${widget.adDetails.vehicle!.vehicleDescription}".toText(
// fontSize: 14,
// isBold: true,
// ),
// ],
// ),
Row(
children: [
("${LocaleKeys.bankName.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
(adVM.adsBankDetailsModel!.bankName ?? "").toText(
fontSize: 14,
isBold: true,
),
],
),
Row(
children: [
("${LocaleKeys.iban.tr()}: ").toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
(adVM.adsBankDetailsModel!.iban ?? "").toText(
fontSize: 14,
isBold: true,
),
],
),
],
).toWhiteContainer(width: double.infinity, allPading: 12);
}
return const SizedBox.shrink();
});
}
Widget buildAdRejectionDetails() {
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
LocaleKeys.rejectionComments.tr().toText(fontSize: 13, isBold: true, color: MyColors.lightTextColor),
Row(
children: [
LocaleKeys.editAd.tr().toText(fontSize: 10, isBold: true),
2.width,
const Icon(Icons.edit, size: 15),
],
).onPress(() async {
Utils.showLoading(context);
await adVM.getVehicleTypes();
await adVM.getVehicleBrandsByVehicleTypeId(vehicleIdForEditAd: widget.adDetails.vehicle!.vehicleType ?? -1);
Utils.hideLoading(context);
adVM.onEditUpdateAdPressed(context: context, previousDetails: widget.adDetails, isFromExtendAd: false);
}),
],
).paddingOnly(bottom: 5),
Row(
children: [
Flexible(
child: (widget.adDetails.comment ?? "").toText(
color: MyColors.redColor,
fontSize: 12,
isItalic: true,
),
)
],
),
],
).toWhiteContainer(width: double.infinity, allPading: 12);
}
Widget buildDamagePartDetails() {
return Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
MyAssets.carHitIcon.buildSvg(color: MyColors.darkTextColor),
10.width,
LocaleKeys.damagePartPictures.tr().toText(fontSize: 16),
],
),
const Icon(Icons.arrow_forward_ios_rounded, size: 20)
],
).paddingOnly(top: 5, bottom: 5).onPress(() {
showMyBottomSheet(context, child: AdDamagePartPicturesSheet(adDamageReportList: widget.adDetails.vehicle!.damagereport ?? []));
}).toWhiteContainer(width: double.infinity, allPading: 12);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
title: LocaleKeys.ads.tr(),
profileImageUrl: MyAssets.bnCar,
isRemoveBackButton: false,
isDrawerEnabled: false,
actions: [
((widget.adDetails.isMyAd ?? false) && (widget.adDetails.adPostStatus != AdPostStatus.reserved) && (widget.adDetails.adPostStatus != AdPostStatus.active)
? IconButton(
icon: const Icon(Icons.delete_outline, color: MyColors.redColor),
onPressed: () {
return deleteAdBottomSheet(context);
},
)
: IconButton(icon: const Icon(Icons.chat_outlined, color: Colors.black), onPressed: () => adVM.onMessagesButtonPressed(context: context, adDetailsModel: widget.adDetails)))
.toContainer(
margin: const EdgeInsets.fromLTRB(0, 8, 21, 8),
paddingAll: 0,
padding: const EdgeInsets.only(right: 21),
borderRadius: 100,
borderColor: MyColors.lightGreyEFColor,
isEnabledBorder: true,
height: 40,
width: 42,
)
],
onTap: () {},
),
body: Container(
padding: const EdgeInsets.only(bottom: 10, left: 21, right: 21),
child: Column(
children: [
Expanded(
child: ListView(
shrinkWrap: true,
children: [
buildVehicleDetailsWidget(),
12.height,
buildBankDetailsIfAvailable(),
if (widget.adDetails.vehicle!.damagereport != null && widget.adDetails.vehicle!.damagereport!.isNotEmpty) ...[
buildDamagePartDetails(),
],
12.height,
if (widget.adDetails.adPostStatus == AdPostStatus.rejected) ...[
buildAdRejectionDetails(),
],
],
),
),
SizedBox(
child: Column(
children: [
if (!(widget.adDetails.isMyAd ?? false)) ...[
const Divider(thickness: 1, height: 1),
18.height,
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
widget.adDetails.vehicle!.demandAmount!.toInt().toString().toText(fontSize: 30, isBold: true),
LocaleKeys.sar.tr().toText(fontSize: 15, isBold: true, color: MyColors.lightTextColor).paddingOnly(bottom: 5),
],
),
14.height,
],
widget.adDetails.isMyAd ?? false ? BuildAdDetailsActionButtonForMyAds(adDetailsModel: widget.adDetails) : BuildAdDetailsActionButtonForExploreAds(adDetailsModel: widget.adDetails),
],
),
)
],
),
),
);
}
}
class BuildAdDetailsActionButtonForExploreAds extends StatelessWidget { class BuildAdDetailsActionButtonForExploreAds extends StatelessWidget {
final AdDetailsModel adDetailsModel; final AdDetailsModel adDetailsModel;
@ -856,11 +503,9 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
children: [ children: [
Expanded( Expanded(
child: ShowFillButton( child: ShowFillButton(
backgroundColor: MyColors.grey98Color.withOpacity(0.3), isDisabled: true,
txtColor: MyColors.lightTextColor,
maxHeight: 55, maxHeight: 55,
title: pendingText, title: pendingText,
isBold: false,
onPressed: () {}, onPressed: () {},
), ),
), ),

@ -28,7 +28,7 @@ class CommonAppointmentSliderWidget extends StatelessWidget {
return CarouselSlider.builder( return CarouselSlider.builder(
options: CarouselOptions( options: CarouselOptions(
height: appType == AppType.provider ? 121 : 140, height: appType == AppType.provider ? 121 : 140,
viewportFraction: 0.99999, // Todo: Dont do anything viewportFraction: 1, // Todo: Dont do anything
enlargeCenterPage: false, enlargeCenterPage: false,
enableInfiniteScroll: false, enableInfiniteScroll: false,
), ),
@ -57,7 +57,7 @@ class CommonAppointmentSliderWidget extends StatelessWidget {
if (model.myUpComingAppointments.isEmpty) { if (model.myUpComingAppointments.isEmpty) {
return LocaleKeys.noUpcomingAppointments.tr().toText(fontSize: 16, color: MyColors.lightTextColor).paddingAll(21); return LocaleKeys.noUpcomingAppointments.tr().toText(fontSize: 16, color: MyColors.lightTextColor).paddingAll(21);
} else { } else {
return getCarouselSliderWidget(AppState().currentAppType, model); return getCarouselSliderWidget(AppState().currentAppType, model).toWhiteContainer(width: double.infinity, margin: EdgeInsets.symmetric(horizontal: 21));
} }
} else { } else {
if (model.myUpComingAppointments.isEmpty) { if (model.myUpComingAppointments.isEmpty) {
@ -74,7 +74,7 @@ class CommonAppointmentSliderWidget extends StatelessWidget {
), ),
).padding(const EdgeInsets.symmetric(vertical: 10, horizontal: 21)); ).padding(const EdgeInsets.symmetric(vertical: 10, horizontal: 21));
} else { } else {
return getCarouselSliderWidget(AppState().currentAppType, model); return getCarouselSliderWidget(AppState().currentAppType, model).toWhiteContainer(width: double.infinity, margin: EdgeInsets.symmetric(horizontal: 21));
} }
} }
} }
@ -215,10 +215,8 @@ class BuildAppointmentContainerForCustomer extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
(AppState().currentAppType == AppType.provider ? appointmentListModel!.branchName ?? "" : appointmentListModel!.branchName ?? "") (AppState().currentAppType == AppType.provider ? appointmentListModel!.branchName ?? "" : appointmentListModel!.branchName ?? "").toText(color: MyColors.greyColor, fontSize: 12, letterSpacing: 0, height: 19 / 12),
.toText(color: MyColors.greyColor, fontSize: 12, letterSpacing: 0, height: 19 / 12), (AppState().currentAppType == AppType.provider ? appointmentListModel!.customerName ?? "" : appointmentListModel!.branchName ?? "").toText(color: MyColors.black, fontSize: 16, letterSpacing: -0.64, height: 24 / 16),
(AppState().currentAppType == AppType.provider ? appointmentListModel!.customerName ?? "" : appointmentListModel!.branchName ?? "")
.toText(color: MyColors.black, fontSize: 16, letterSpacing: -0.64, height: 24 / 16),
Row( Row(
children: [ children: [
!isForProvider ? MyAssets.miniClock.buildSvg(height: 12) : SizedBox(), !isForProvider ? MyAssets.miniClock.buildSvg(height: 12) : SizedBox(),

@ -1,25 +1,17 @@
import 'dart:developer';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.dart'; 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/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/main.dart';
import 'package:mc_common_app/models/chat_models/chat_message_model.dart'; import 'package:mc_common_app/models/chat_models/chat_message_model.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/theme/colors.dart';
import 'package:mc_common_app/utils/dialogs_and_bottomsheets.dart';
import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/enums.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/chat_view_model.dart';
import 'package:mc_common_app/view_models/requests_view_model.dart'; import 'package:mc_common_app/view_models/requests_view_model.dart';
import 'package:mc_common_app/views/chat/widgets/chat_message_widget.dart';
import 'package:mc_common_app/views/requests/request_bottomsheets.dart'; import 'package:mc_common_app/views/requests/request_bottomsheets.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/checkbox_with_title_desc.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart'; import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/common_widgets/info_bottom_sheet.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:mc_common_app/widgets/txt_field.dart'; import 'package:mc_common_app/widgets/txt_field.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -65,70 +57,6 @@ class _ChatViewState extends State<ChatView> {
super.dispose(); super.dispose();
} }
// Future buildSendOfferBottomSheet(BuildContext context) {
// RequestModel requestDetail = chatViewArgumentsForRequest!.requestModel!;
// return showModalBottomSheet(
// context: context,
// isScrollControlled: true,
// enableDrag: true,
// builder: (BuildContext context) {
// return Consumer(builder: (BuildContext context, RequestsVM requestsVM, Widget? child) {
// return InfoBottomSheet(
// title: LocaleKeys.makeAnOffer.tr().toText(fontSize: 28, isBold: true, letterSpacing: -1.44),
// description: Padding(
// padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// 12.height,
// TxtField(
// value: requestsVM.offerPrice,
// errorValue: requestsVM.offerPriceError,
// keyboardType: TextInputType.number,
// hint: LocaleKeys.enterAmount.tr(),
// numbersOnly: true,
// onChanged: (v) => requestsVM.updateOfferPrice(v),
// ),
// 12.height,
// TxtField(
// maxLines: 5,
// value: requestsVM.offerDescription,
// errorValue: requestsVM.offerDescriptionError,
// keyboardType: TextInputType.text,
// hint: LocaleKeys.description.tr(),
// onChanged: (v) => requestsVM.updateOfferDescription(v),
// ),
// ],
// ),
// 25.height,
// ShowFillButton(
// title: LocaleKeys.submit.tr(),
// onPressed: () {
// requestsVM.onSendOfferPressed(
// context: context,
// receiverId: requestDetail.customerID,
// message: requestsVM.offerDescription,
// requestId: requestDetail.id,
// offerPrice: requestsVM.offerPrice,
// requestModel: requestDetail,
// requestIndex: chatViewArgumentsForRequest!.requestIndex,
// isFromChatScreen: true,
// );
// },
// maxWidth: double.infinity,
// ),
// 19.height,
// ],
// ),
// ));
// });
// },
// );
// }
Future<bool> onTextMessageSend() async { Future<bool> onTextMessageSend() async {
bool status = false; bool status = false;
if (chatTypeEnum == ChatTypeEnum.requestOffer) { if (chatTypeEnum == ChatTypeEnum.requestOffer) {
@ -205,7 +133,7 @@ class _ChatViewState extends State<ChatView> {
size: 30, size: 30,
).onPress( ).onPress(
() { () {
RequestDetailPageArguments requestDetailArguments = RequestDetailPageArguments(requestIndex: chatViewArgumentsForRequest!.requestIndex , requestModel: chatViewArgumentsForRequest!.requestModel!); RequestDetailPageArguments requestDetailArguments = RequestDetailPageArguments(requestIndex: chatViewArgumentsForRequest!.requestIndex, requestModel: chatViewArgumentsForRequest!.requestModel!);
buildSendOfferBottomSheet(context, requestDetailArguments); buildSendOfferBottomSheet(context, requestDetailArguments);
}, },
), ),
@ -247,336 +175,3 @@ class _ChatViewState extends State<ChatView> {
); );
} }
} }
class ChatMessageCustomWidget extends StatefulWidget {
final ChatMessageModel chatMessageModel;
const ChatMessageCustomWidget({super.key, required this.chatMessageModel});
@override
State<ChatMessageCustomWidget> createState() => _ChatMessageCustomWidgetState();
}
class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
Future buildRejectOfferBottomSheet({required ChatMessageModel chatMessageModel}) {
return showModalBottomSheet(
context: context,
isScrollControlled: true,
enableDrag: true,
builder: (BuildContext context) {
return Consumer(builder: (BuildContext context, ChatVM chatVM, Widget? child) {
return InfoBottomSheet(
title: LocaleKeys.makeAnOffer.tr().toText(fontSize: 28, isBold: true, letterSpacing: -1.44),
description: Padding(
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
12.height,
ListView.separated(
shrinkWrap: true,
itemCount: chatVM.offerRejectModelList.length,
separatorBuilder: (BuildContext context, int index) => const Divider(thickness: 0.5),
itemBuilder: (BuildContext context, int index) {
OfferRequestCommentModel offerRequestCommentModel = chatVM.offerRejectModelList[index];
return CircleCheckBoxWithTitle(
isChecked: offerRequestCommentModel.isSelected ?? false,
title: '${offerRequestCommentModel.title}',
onSelected: () {
chatVM.updateSelectionInOfferRejectModelList(index);
},
selectedColor: MyColors.darkPrimaryColor,
);
},
),
if (chatVM.selectedOfferRequestCommentModel.index == chatVM.offerRejectModelList.length - 1) ...[
// comparing if the "other" is selected
12.height,
TxtField(
maxLines: 5,
value: chatVM.rejectOfferDescription,
errorValue: chatVM.rejectOfferDescriptionError,
keyboardType: TextInputType.text,
hint: LocaleKeys.description.tr(),
onChanged: (v) => chatVM.updateRejectOfferDescription(v),
),
],
],
),
25.height,
ShowFillButton(
title: LocaleKeys.submit.tr(),
onPressed: () async {
String comments = "";
if (chatVM.selectedOfferRequestCommentModel.index == chatVM.offerRejectModelList.length - 1) //Other
{
comments = chatVM.rejectOfferDescription;
} else {
comments = chatVM.selectedOfferRequestCommentModel.title ?? "";
}
if (!chatVM.isRejectOfferButtonValidated()) {
return;
}
Navigator.pop(context);
bool status = await context.read<ChatVM>().onSendMessageForActionOnRequestOffer(
receiverId: chatMessageModel.receiverUserID ?? "",
chatMessageType: ChatMessageTypeEnum.offer,
comments: comments,
requestId: chatMessageModel.reqOffer!.requestID ?? -1,
serviceProviderID: chatMessageModel.serviceProviderID ?? 0,
requestOfferID: chatMessageModel.reqOffer!.id ?? -1,
offerPrice: chatMessageModel.reqOffer!.price.toString(),
requestOfferStatusEnum: RequestOfferStatusEnum.rejected,
context: context,
);
if (status) {
chatMessageModel.reqOffer!.requestOfferStatusEnum = RequestOfferStatusEnum.rejected;
setState(() {});
// Navigator.pop(context);
Utils.showToast("Offer Rejected");
// navigateReplaceWithName(context, AppRoutes.dashboard);
}
},
maxWidth: double.infinity,
),
19.height,
],
),
));
});
},
);
}
void offerAcceptConfirmationBottomSheet({required ChatMessageModel chatMessageModel}) {
return actionConfirmationBottomSheet(
context: context,
title: LocaleKeys.acceptOfferConfirmation.tr().toText(fontSize: 28, isBold: true, letterSpacing: -1.44),
subtitle: LocaleKeys.acceptOfferConfirmationMessage.tr(),
actionButtonYes: Expanded(
child: ShowFillButton(
maxHeight: 55,
title: LocaleKeys.yes.tr(),
fontSize: 15,
onPressed: () async {
log("ServiceProviderID: ${chatMessageModel.toString()}");
Navigator.pop(context);
// int status = await context.read<ChatVM>().onActionOfferTapped(
// context: context,
// requestOfferStatusEnum: RequestOfferStatusEnum.accepted,
// reqOfferId: chatMessageModel.reqOfferID ?? -1,
// comments: GlobalConsts.acceptingThisOffer,
// );
bool status = await context.read<ChatVM>().onSendMessageForActionOnRequestOffer(
receiverId: chatMessageModel.receiverUserID ?? "",
chatMessageType: ChatMessageTypeEnum.offer,
comments: GlobalConsts.acceptingThisOffer,
requestId: chatMessageModel.reqOffer!.requestID ?? -1,
serviceProviderID: chatMessageModel.serviceProviderID ?? 0,
requestOfferID: chatMessageModel.reqOffer!.id ?? -1,
offerPrice: chatMessageModel.reqOffer!.price.toString(),
requestOfferStatusEnum: RequestOfferStatusEnum.accepted,
context: context,
);
if (status) {
chatMessageModel.reqOffer!.requestOfferStatusEnum = RequestOfferStatusEnum.accepted;
setState(() {});
// Navigator.pop(context);
Utils.showToast("Offer Accepted");
// navigateReplaceWithName(context, AppRoutes.dashboard);
}
},
),
),
actionButtonNo: Expanded(
child: ShowFillButton(
maxHeight: 55,
isFilled: false,
borderColor: MyColors.darkPrimaryColor,
title: LocaleKeys.no.tr(),
txtColor: MyColors.darkPrimaryColor,
fontSize: 15,
onPressed: () {
Navigator.pop(context);
},
),
),
);
}
Widget buildOfferDetailsInChatMessage({required ChatMessageModel chatMessageModel, required BuildContext context}) {
final requestOfferStatusEnum = chatMessageModel.reqOffer!.requestOfferStatusEnum ?? RequestOfferStatusEnum.offer;
switch (requestOfferStatusEnum) {
case RequestOfferStatusEnum.offer:
return Column(
children: [
5.height,
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"${chatMessageModel.reqOffer!.price}".toText(fontSize: 19, isBold: true, color: AppState().currentAppType == AppType.provider ? MyColors.white : MyColors.darkTextColor),
5.width,
LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, height: 2.2, fontSize: 10, isBold: true),
],
),
if (widget.chatMessageModel.isMyMessage == false) ...[
10.height,
Row(
children: [
Expanded(
child: ShowFillButton(
maxHeight: 27,
title: LocaleKeys.accept.tr(),
fontSize: 9,
borderColor: MyColors.greenColor,
isFilled: false,
onPressed: () {
offerAcceptConfirmationBottomSheet(chatMessageModel: chatMessageModel);
},
backgroundColor: MyColors.white,
txtColor: MyColors.greenColor,
),
),
20.width,
Expanded(
child: ShowFillButton(
maxHeight: 27,
title: LocaleKeys.reject.tr(),
borderColor: MyColors.redColor,
isFilled: false,
backgroundColor: MyColors.white,
txtColor: MyColors.redColor,
fontSize: 9,
onPressed: () async {
buildRejectOfferBottomSheet(chatMessageModel: chatMessageModel);
},
),
)
],
),
],
],
);
case RequestOfferStatusEnum.negotiate:
return Column(
children: [
Center(
child: LocaleKeys.newOfferRequired.tr().toText(
color: MyColors.adPendingStatusColor,
fontSize: 12,
isItalic: true,
),
).toContainer(borderRadius: 40, width: double.infinity, backgroundColor: MyColors.adPendingStatusColor.withOpacity(0.16)),
],
);
case RequestOfferStatusEnum.accepted:
return Column(
children: [
Center(
child: LocaleKeys.offerHasBeenAccepted.tr().toText(
color: MyColors.adPendingStatusColor,
fontSize: 12,
isItalic: true,
),
).toContainer(borderRadius: 40, width: double.infinity, backgroundColor: MyColors.adPendingStatusColor.withOpacity(0.16)),
],
);
case RequestOfferStatusEnum.rejected:
return Column(
children: [
Center(
child: LocaleKeys.offerHasBeenRejected.tr().toText(
color: MyColors.adPendingStatusColor,
fontSize: 12,
isItalic: true,
),
).toContainer(borderRadius: 40, width: double.infinity, backgroundColor: MyColors.adPendingStatusColor.withOpacity(0.16)),
],
);
case RequestOfferStatusEnum.cancel:
return Column(
children: [
Center(
child: LocaleKeys.offerHasBeenCancelled.tr().toText(
color: MyColors.adPendingStatusColor,
fontSize: 12,
isItalic: true,
),
).toContainer(borderRadius: 40, width: double.infinity, backgroundColor: MyColors.adPendingStatusColor.withOpacity(0.16)),
],
);
}
}
@override
Widget build(BuildContext context) {
return Directionality(
textDirection: (widget.chatMessageModel.isMyMessage ?? false) ? TextDirection.rtl : TextDirection.ltr,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
flex: 1,
child: Image.asset(
MyAssets.bnCar,
width: 34,
height: 34,
fit: BoxFit.fill,
).toCircle(borderRadius: 100),
),
10.width,
Expanded(
flex: 10,
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
((widget.chatMessageModel.isMyMessage ?? false) ? "You" : widget.chatMessageModel.senderName ?? "").toText(fontSize: 16, isBold: true),
],
),
5.height,
Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Directionality(
textDirection: TextDirection.ltr,
child: (widget.chatMessageModel.chatText ?? "").toText(
color: (widget.chatMessageModel.isMyMessage ?? false) ? MyColors.white : MyColors.lightTextColor,
fontSize: 12,
// isBold: true,
),
),
),
],
),
if (widget.chatMessageModel.chatMessageTypeEnum == ChatMessageTypeEnum.offer) ...[
buildOfferDetailsInChatMessage(chatMessageModel: widget.chatMessageModel, context: context),
],
],
).toContainer(
isShadowEnabled: !(widget.chatMessageModel.isMyMessage ?? false),
backgroundColor: (widget.chatMessageModel.isMyMessage ?? false) ? MyColors.darkIconColor : MyColors.white,
borderRadius: 0,
margin: EdgeInsets.fromLTRB((widget.chatMessageModel.isMyMessage ?? false) ? 25 : 0, 0, !(widget.chatMessageModel.isMyMessage ?? false) ? 25 : 0, 0),
),
],
),
)
],
),
);
}
}

@ -0,0 +1,389 @@
import 'dart:developer';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.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/chat_models/chat_message_model.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/dialogs_and_bottomsheets.dart';
import 'package:mc_common_app/utils/enums.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/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/checkbox_with_title_desc.dart';
import 'package:mc_common_app/widgets/common_widgets/info_bottom_sheet.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:mc_common_app/widgets/txt_field.dart';
import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart' as lcl;
class ChatMessageCustomWidget extends StatefulWidget {
final ChatMessageModel chatMessageModel;
const ChatMessageCustomWidget({super.key, required this.chatMessageModel});
@override
State<ChatMessageCustomWidget> createState() => _ChatMessageCustomWidgetState();
}
class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
Future buildRejectOfferBottomSheet({required ChatMessageModel chatMessageModel}) {
return showModalBottomSheet(
context: context,
isScrollControlled: true,
enableDrag: true,
builder: (BuildContext context) {
return Consumer(builder: (BuildContext context, ChatVM chatVM, Widget? child) {
return InfoBottomSheet(
title: LocaleKeys.makeAnOffer.tr().toText(fontSize: 28, isBold: true, letterSpacing: -1.44),
description: Padding(
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
12.height,
ListView.separated(
shrinkWrap: true,
itemCount: chatVM.offerRejectModelList.length,
separatorBuilder: (BuildContext context, int index) => const Divider(thickness: 0.5),
itemBuilder: (BuildContext context, int index) {
OfferRequestCommentModel offerRequestCommentModel = chatVM.offerRejectModelList[index];
return CircleCheckBoxWithTitle(
isChecked: offerRequestCommentModel.isSelected ?? false,
title: '${offerRequestCommentModel.title}',
onSelected: () {
chatVM.updateSelectionInOfferRejectModelList(index);
},
selectedColor: MyColors.darkPrimaryColor,
);
},
),
if (chatVM.selectedOfferRequestCommentModel.index == chatVM.offerRejectModelList.length - 1) ...[
// comparing if the "other" is selected
12.height,
TxtField(
maxLines: 5,
value: chatVM.rejectOfferDescription,
errorValue: chatVM.rejectOfferDescriptionError,
keyboardType: TextInputType.text,
hint: LocaleKeys.description.tr(),
onChanged: (v) => chatVM.updateRejectOfferDescription(v),
),
],
],
),
25.height,
ShowFillButton(
title: LocaleKeys.submit.tr(),
onPressed: () async {
String comments = "";
if (chatVM.selectedOfferRequestCommentModel.index == chatVM.offerRejectModelList.length - 1) //Other
{
comments = chatVM.rejectOfferDescription;
} else {
comments = chatVM.selectedOfferRequestCommentModel.title ?? "";
}
if (!chatVM.isRejectOfferButtonValidated()) {
return;
}
Navigator.pop(context);
bool status = await context.read<ChatVM>().onSendMessageForActionOnRequestOffer(
receiverId: chatMessageModel.senderUserID ?? "",
chatMessageType: ChatMessageTypeEnum.offer,
comments: comments,
requestId: chatMessageModel.reqOffer!.requestID ?? -1,
serviceProviderID: chatMessageModel.serviceProviderID ?? 0,
requestOfferID: chatMessageModel.reqOffer!.id ?? -1,
offerPrice: chatMessageModel.reqOffer!.price.toString(),
serviceItemName: chatMessageModel.reqOffer!.serviceItemName ?? "",
manufacturedOn: chatMessageModel.reqOffer!.manufacturedOn ?? "",
manufacturedById: chatMessageModel.reqOffer!.manufacturedById ?? 0,
requestOfferStatusEnum: RequestOfferStatusEnum.rejected,
context: context,
);
if (status) {
chatMessageModel.reqOffer!.requestOfferStatusEnum = RequestOfferStatusEnum.rejected;
setState(() {});
// Navigator.pop(context);
Utils.showToast("Offer Rejected");
// navigateReplaceWithName(context, AppRoutes.dashboard);
}
},
maxWidth: double.infinity,
),
19.height,
],
),
));
});
},
);
}
void offerAcceptConfirmationBottomSheet({required ChatMessageModel chatMessageModel}) {
return actionConfirmationBottomSheet(
context: context,
title: LocaleKeys.acceptOfferConfirmation.tr().toText(fontSize: 28, isBold: true, letterSpacing: -1.44),
subtitle: LocaleKeys.acceptOfferConfirmationMessage.tr(),
actionButtonYes: Expanded(
child: ShowFillButton(
maxHeight: 55,
title: LocaleKeys.yes.tr(),
fontSize: 15,
onPressed: () async {
Navigator.pop(context);
bool status = await context.read<ChatVM>().onSendMessageForActionOnRequestOffer(
receiverId: chatMessageModel.senderUserID ?? "",
chatMessageType: ChatMessageTypeEnum.offer,
comments: GlobalConsts.acceptingThisOffer,
requestId: chatMessageModel.reqOffer!.requestID ?? -1,
serviceProviderID: chatMessageModel.serviceProviderID ?? 0,
requestOfferID: chatMessageModel.reqOffer!.id ?? -1,
offerPrice: chatMessageModel.reqOffer!.price.toString(),
serviceItemName: chatMessageModel.reqOffer!.serviceItemName ?? "",
manufacturedOn: chatMessageModel.reqOffer!.manufacturedOn ?? "",
manufacturedById: chatMessageModel.reqOffer!.manufacturedById ?? 0,
requestOfferStatusEnum: RequestOfferStatusEnum.accepted,
context: context,
);
if (status) {
chatMessageModel.reqOffer!.requestOfferStatusEnum = RequestOfferStatusEnum.accepted;
setState(() {});
// Navigator.pop(context);
Utils.showToast("Offer Accepted");
// navigateReplaceWithName(context, AppRoutes.dashboard);
}
},
),
),
actionButtonNo: Expanded(
child: ShowFillButton(
maxHeight: 55,
isFilled: false,
borderColor: MyColors.darkPrimaryColor,
title: LocaleKeys.no.tr(),
txtColor: MyColors.darkPrimaryColor,
fontSize: 15,
onPressed: () {
Navigator.pop(context);
},
),
),
);
}
Widget buildOfferDetailsInChatMessage({required ChatMessageModel chatMessageModel, required BuildContext context}) {
final requestOfferStatusEnum = chatMessageModel.reqOffer!.requestOfferStatusEnum ?? RequestOfferStatusEnum.offer;
switch (requestOfferStatusEnum) {
case RequestOfferStatusEnum.offer:
return Column(
children: [
5.height,
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"${(chatMessageModel.reqOffer!.price ?? 0.0).toInt()}".toText(fontSize: 19, isBold: true, color: AppState().currentAppType == AppType.provider ? MyColors.white : MyColors.darkTextColor),
5.width,
LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, height: 2.2, fontSize: 10, isBold: true),
],
),
if (widget.chatMessageModel.isMyMessage == false) ...[
10.height,
Row(
children: [
Expanded(
child: ShowFillButton(
maxHeight: 27,
title: LocaleKeys.accept.tr(),
fontSize: 9,
borderColor: MyColors.greenColor,
isFilled: false,
onPressed: () {
offerAcceptConfirmationBottomSheet(chatMessageModel: chatMessageModel);
},
backgroundColor: MyColors.white,
txtColor: MyColors.greenColor,
),
),
20.width,
Expanded(
child: ShowFillButton(
maxHeight: 27,
title: LocaleKeys.reject.tr(),
borderColor: MyColors.redColor,
isFilled: false,
backgroundColor: MyColors.white,
txtColor: MyColors.redColor,
fontSize: 9,
onPressed: () async {
buildRejectOfferBottomSheet(chatMessageModel: chatMessageModel);
},
),
)
],
),
],
],
);
case RequestOfferStatusEnum.negotiate:
return Column(
children: [
Center(
child: LocaleKeys.newOfferRequired.tr().toText(
color: MyColors.adPendingStatusColor,
fontSize: 12,
isItalic: true,
),
).toContainer(borderRadius: 40, width: double.infinity, backgroundColor: MyColors.adPendingStatusColor.withOpacity(0.16)),
],
);
case RequestOfferStatusEnum.accepted:
return Column(
children: [
Center(
child: LocaleKeys.offerHasBeenAccepted.tr().toText(
color: MyColors.adPendingStatusColor,
fontSize: 12,
isItalic: true,
),
).toContainer(borderRadius: 40, width: double.infinity, backgroundColor: MyColors.adPendingStatusColor.withOpacity(0.16)),
],
);
case RequestOfferStatusEnum.rejected:
return Column(
children: [
Center(
child: LocaleKeys.offerHasBeenRejected.tr().toText(
color: MyColors.adPendingStatusColor,
fontSize: 12,
isItalic: true,
),
).toContainer(borderRadius: 40, width: double.infinity, backgroundColor: MyColors.adPendingStatusColor.withOpacity(0.16)),
],
);
case RequestOfferStatusEnum.cancel:
return Column(
children: [
Center(
child: LocaleKeys.offerHasBeenCancelled.tr().toText(
color: MyColors.adPendingStatusColor,
fontSize: 12,
isItalic: true,
),
).toContainer(borderRadius: 40, width: double.infinity, backgroundColor: MyColors.adPendingStatusColor.withOpacity(0.16)),
],
);
}
}
Widget getProfilePicture({String profileImageUrl = ""}) {
Widget widget = const SizedBox();
if (profileImageUrl.isEmpty && AppState().getUser.data!.userInfo!.userLocalImage != null) {
widget = Image.file(
AppState().getUser.data!.userInfo!.userLocalImage!,
width: 34,
height: 34,
fit: BoxFit.fill,
);
} else if (profileImageUrl.isEmpty && AppState().getUser.data!.userInfo!.userImageUrl != null) {
widget = CachedNetworkImage(
imageUrl: AppState().getUser.data!.userInfo!.userImageUrl,
imageBuilder: (context, imageProvider) => Container(
decoration: BoxDecoration(
image: DecorationImage(
image: imageProvider,
fit: BoxFit.cover,
),
),
),
placeholder: (context, url) => const Center(child: CircularProgressIndicator()),
errorWidget: (context, url, error) => const Icon(Icons.supervised_user_circle_outlined),
fadeInCurve: Curves.easeIn,
width: 34,
height: 34,
fit: BoxFit.fill,
fadeInDuration: const Duration(milliseconds: 1000),
useOldImageOnUrlChange: false);
}
return widget.toCircle(borderRadius: 100);
}
@override
Widget build(BuildContext context) {
return Directionality(
textDirection: (widget.chatMessageModel.isMyMessage ?? false) ? TextDirection.rtl : TextDirection.ltr,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
flex: 1,
child: (widget.chatMessageModel.isMyMessage ?? false)
? getProfilePicture()
: Container(
width: 34,
height: 34,
alignment: Alignment.center,
color: MyColors.darkTextColor,
child: ((widget.chatMessageModel.senderName ?? "").getInitials()).toText(color: MyColors.white, isBold: true, fontSize: 12),
).toCircle(borderRadius: 100),
),
10.width,
Expanded(
flex: 10,
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
((widget.chatMessageModel.isMyMessage ?? false) ? "You" : widget.chatMessageModel.senderName ?? "").toText(fontSize: 16, isBold: true),
],
),
5.height,
Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Directionality(
textDirection: TextDirection.ltr,
child: (widget.chatMessageModel.chatText ?? "").toText(
color: (widget.chatMessageModel.isMyMessage ?? false) ? MyColors.white : MyColors.lightTextColor,
fontSize: 12,
// isBold: true,
),
),
),
],
),
if (widget.chatMessageModel.chatMessageTypeEnum == ChatMessageTypeEnum.offer) ...[
buildOfferDetailsInChatMessage(chatMessageModel: widget.chatMessageModel, context: context),
],
],
).toContainer(
isShadowEnabled: !(widget.chatMessageModel.isMyMessage ?? false),
backgroundColor: (widget.chatMessageModel.isMyMessage ?? false) ? MyColors.darkIconColor : MyColors.white,
borderRadius: 0,
margin: EdgeInsets.fromLTRB((widget.chatMessageModel.isMyMessage ?? false) ? 25 : 0, 0, !(widget.chatMessageModel.isMyMessage ?? false) ? 25 : 0, 0),
),
],
),
)
],
),
);
}
}

@ -88,15 +88,18 @@ Future buildSendOfferBottomSheet(BuildContext context, RequestDetailPageArgument
maxHeight: 55, maxHeight: 55,
onPressed: () { onPressed: () {
requestsVM.onSendOfferPressed( requestsVM.onSendOfferPressed(
context: context, context: context,
receiverId: requestDetail.customerID, receiverId: requestDetail.customerID,
message: requestsVM.offerDescription, message: requestsVM.offerDescription,
requestId: requestDetail.id, requestId: requestDetail.id,
offerPrice: requestsVM.offerPrice, offerPrice: requestsVM.offerPrice,
requestModel: requestDetail, requestModel: requestDetail,
requestIndex: requestDetailPageArguments.requestIndex, requestIndex: requestDetailPageArguments.requestIndex,
isFromChatScreen: false, isFromChatScreen: false,
); manufacturedById: 1,
// Todo: It should be the ID of the manufacturer
manufacturedOn: requestsVM.serviceItemCreatedOn,
serviceItemName: requestsVM.serviceItem);
}, },
maxWidth: double.infinity, maxWidth: double.infinity,
), ),

@ -0,0 +1,222 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.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/generated/locale_keys.g.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/views/advertisement/components/ads_images_corousel_widget.dart';
import 'package:mc_common_app/views/requests/request_bottomsheets.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart';
class RequestDetailPage extends StatelessWidget {
final RequestDetailPageArguments requestDetailPageArguments;
const RequestDetailPage({Key? key, required this.requestDetailPageArguments}) : super(key: key);
Widget buildBottomButton({required RequestStatus requestStatus, required String statusText, required BuildContext context, required Function() onViewChatTapped}) {
switch (requestStatus) {
case RequestStatus.submitted:
case RequestStatus.inProgress:
case RequestStatus.paid:
case RequestStatus.shipping:
return ShowFillButton(
maxWidth: double.infinity,
margin: const EdgeInsets.all(15),
maxHeight: 55,
title: LocaleKeys.viewChat.tr(),
isBold: false,
onPressed: onViewChatTapped,
);
case RequestStatus.completed:
case RequestStatus.cancelled:
case RequestStatus.expired:
case RequestStatus.pending:
return buildDisabledButton(statusText);
}
}
Widget buildDisabledButton(String text) {
return ShowFillButton(
backgroundColor: MyColors.grey98Color.withOpacity(0.3),
txtColor: MyColors.lightTextColor,
maxWidth: double.infinity,
margin: const EdgeInsets.all(15),
maxHeight: 55,
title: text,
isBold: false,
onPressed: () {},
);
}
Future<void> onViewChatTapped(BuildContext context) async {
ChatViewArgumentsForRequest chatViewArgumentsForRequest = ChatViewArgumentsForRequest(
chatTypeEnum: ChatTypeEnum.requestOffer,
receiverId: requestDetailPageArguments.requestModel.customerID,
senderId: AppState().getUser.data!.userInfo!.userId.toString(),
requestId: requestDetailPageArguments.requestModel.id,
providerIndex: -1,
// This will be only sent in case of customer
requestModel: requestDetailPageArguments.requestModel,
requestIndex: requestDetailPageArguments.requestIndex, // This will be only sent in case of provider
);
ChatViewArguments chatViewArguments = ChatViewArguments(
chatTypeEnum: ChatTypeEnum.requestOffer,
chatViewArgumentsForRequest: chatViewArgumentsForRequest,
);
final chatVM = context.read<ChatVM>();
await chatVM
.getUsersChatMessagesForProvider(
customerId: requestDetailPageArguments.requestModel.customerId,
context: context,
requestOfferId: 0,
requestId: requestDetailPageArguments.requestModel.id,
customerRequestIndex: requestDetailPageArguments.requestIndex,
)
.whenComplete(() => navigateWithName(context, AppRoutes.chatView, arguments: chatViewArguments));
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
title: LocaleKeys.requestDetail.tr(),
),
body: SizedBox(
width: double.infinity,
height: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
children: [
ImagesCorouselWidget(imagesList: requestDetailPageArguments.requestModel.requestImages ?? []),
24.height,
buildRequestContainer(context),
],
).toWhiteContainer(
width: double.infinity,
allPading: 12,
margin: const EdgeInsets.only(top: 21, right: 21, left: 21),
),
if (!requestDetailPageArguments.requestModel.isChatted) ...[
ShowFillButton(
maxWidth: double.infinity,
margin: const EdgeInsets.all(15),
maxHeight: 55,
title: LocaleKeys.sendOffer.tr(),
isBold: false,
fontSize: 18,
onPressed: () => buildSendOfferBottomSheet(context, requestDetailPageArguments),
),
] else ...[
buildBottomButton(
requestStatus: requestDetailPageArguments.requestModel.requestStatus,
statusText: "Offer ${requestDetailPageArguments.requestModel.requestStatusName}",
context: context,
onViewChatTapped: () async => onViewChatTapped(context),
),
],
],
),
),
);
}
Widget buildRequestContainer(BuildContext context) {
final requestDetail = requestDetailPageArguments.requestModel;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
requestDetail.vehicleTypeName.toText(fontSize: 16, isBold: true),
showItem("Manufacturer:", requestDetail.brand),
showItem("Model:", "${requestDetail.year}"),
],
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.start,
children: [
"${requestDetail.city ?? ""} ${requestDetail.countryName}".toText(
color: MyColors.lightTextColor,
),
if (requestDetail.createdOn != null) ...[
DateTime.parse(requestDetail.createdOn!).getTimeAgo().toText(color: MyColors.lightTextColor),
],
],
),
],
),
showItem("Customer Name: ", requestDetail.customerName),
showItem("Description: ", requestDetail.description),
showItem("Price Range:", ""),
Row(
children: [
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"${requestDetail.price.toInt()}".toText(fontSize: 25, isBold: true),
2.width,
LocaleKeys.sar.tr().toText(
color: MyColors.lightTextColor,
fontSize: 16,
height: 2.3,
),
],
),
Row(
children: [
Utils.statusContainerChip(
text: (requestDetail.requestStatusName),
chipColor: MyColors.grey98Color.withOpacity(0.3),
textColor: MyColors.lightTextColor,
),
],
),
],
),
),
// const Icon(Icons.arrow_forward)
],
),
],
);
}
Widget showItem(String title, String value) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (title.isNotEmpty)
title.toText(
color: MyColors.lightTextColor,
),
if (title.isNotEmpty) 2.width,
if (value.isNotEmpty) Expanded(child: value.toText(isBold: true)),
],
);
}
}

@ -4,6 +4,7 @@ import 'dart:developer';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/main.dart';
import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/view_models/chat_view_model.dart'; import 'package:mc_common_app/view_models/chat_view_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -126,7 +127,7 @@ class RequestItem extends StatelessWidget {
children: [ children: [
title.toText(color: MyColors.lightTextColor), title.toText(color: MyColors.lightTextColor),
3.width, 3.width,
Flexible(child: value.toText(isBold: true, overflow: TextOverflow.ellipsis )), Flexible(child: value.toText(isBold: true, overflow: TextOverflow.ellipsis)),
], ],
); );
} }

@ -4,18 +4,19 @@ import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
class ShowFillButton extends StatelessWidget { class ShowFillButton extends StatelessWidget {
String title; final String title;
Color? backgroundColor; final Color? backgroundColor;
VoidCallback onPressed; final VoidCallback onPressed;
Color txtColor; final Color txtColor;
double elevation, radius, maxWidth, maxHeight, fontSize, horizontalPadding, horizontalMargin, verticalMargin; final double elevation, radius, maxWidth, maxHeight, fontSize, horizontalPadding, horizontalMargin, verticalMargin;
bool isFlatButton, isBold; final bool isFlatButton, isBold;
EdgeInsets? margin; final EdgeInsets? margin;
bool isFilled; final bool isFilled;
Color borderColor; final bool isDisabled;
Widget? iconWidget; final Color borderColor;
final Widget? iconWidget;
ShowFillButton({ const ShowFillButton({
super.key, super.key,
required this.title, required this.title,
required this.onPressed, required this.onPressed,
@ -23,6 +24,7 @@ class ShowFillButton extends StatelessWidget {
this.backgroundColor = MyColors.darkPrimaryColor, this.backgroundColor = MyColors.darkPrimaryColor,
this.elevation = 0, this.elevation = 0,
this.isFilled = true, this.isFilled = true,
this.isDisabled = false,
this.radius = 0, this.radius = 0,
this.maxWidth = 88, this.maxWidth = 88,
this.maxHeight = 45, this.maxHeight = 45,
@ -65,11 +67,13 @@ class ShowFillButton extends StatelessWidget {
Widget showButton() { Widget showButton() {
return Container( return Container(
// decoration: isFlatButton ? null : MyColors.gradientButton, // decoration: isFlatButton ? null : MyColors.gradientButton,
color: isFlatButton color: isDisabled
? null ? MyColors.grey98Color.withOpacity(0.3)
: isFilled : (isFlatButton
? backgroundColor ? null
: null, : isFilled
? backgroundColor
: null),
margin: EdgeInsets.symmetric(horizontal: horizontalMargin, vertical: verticalMargin), margin: EdgeInsets.symmetric(horizontal: horizontalMargin, vertical: verticalMargin),
child: MaterialButton( child: MaterialButton(
onPressed: onPressed, onPressed: onPressed,
@ -85,7 +89,7 @@ class ShowFillButton extends StatelessWidget {
title.toText( title.toText(
fontSize: fontSize, fontSize: fontSize,
isBold: isBold, isBold: isBold,
color: txtColor, color: isDisabled ? MyColors.lightTextColor : txtColor,
maxLines: 1, maxLines: 1,
), ),
], ],
@ -93,7 +97,7 @@ class ShowFillButton extends StatelessWidget {
: title.toText( : title.toText(
fontSize: fontSize, fontSize: fontSize,
isBold: isBold, isBold: isBold,
color: txtColor, color: isDisabled ? MyColors.lightTextColor : txtColor,
maxLines: 1, maxLines: 1,
), ),
), ),

@ -30,8 +30,6 @@ class BranchDetailCard extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
print("Provider Image Title" + title);
print("Provider Image URL" + providerImageUrl);
return Padding( return Padding(
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
// padding: const EdgeInsets.only( // padding: const EdgeInsets.only(

@ -24,8 +24,7 @@ extension ExtendedText on Widget {
} }
extension ContainerExt on Widget { extension ContainerExt on Widget {
Widget toWhiteContainer( Widget toWhiteContainer({required double width, double? allPading, EdgeInsets? pading, EdgeInsets? margin, VoidCallback? onTap, Color? backgroundColor, bool isBorderRequired = false, double borderRadius = 0}) {
{required double width, double? allPading, EdgeInsets? pading, EdgeInsets? margin, VoidCallback? onTap, Color? backgroundColor, bool isBorderRequired = false, double borderRadius = 0}) {
return InkWell( return InkWell(
onTap: onTap, onTap: onTap,
child: Container( child: Container(
@ -84,12 +83,12 @@ extension ContainerExt on Widget {
boxShadow: !isShadowEnabled boxShadow: !isShadowEnabled
? null ? null
: [ : [
BoxShadow( BoxShadow(
color: const Color(0xff000000).withOpacity(.05), color: const Color(0xff000000).withOpacity(.05),
blurRadius: 26, blurRadius: 26,
offset: const Offset(0, -3), offset: const Offset(0, -3),
), ),
], ],
), ),
padding: padding ?? EdgeInsets.all(paddingAll), padding: padding ?? EdgeInsets.all(paddingAll),
margin: margin ?? EdgeInsets.all(marginAll), margin: margin ?? EdgeInsets.all(marginAll),
@ -234,8 +233,7 @@ extension WidgetExt on Widget {
); );
} }
Widget paddingOnly({double left = 0.0, double right = 0.0, double top = 0.0, double bottom = 0.0}) => Widget paddingOnly({double left = 0.0, double right = 0.0, double top = 0.0, double bottom = 0.0}) => Padding(padding: EdgeInsets.only(left: left, right: right, top: top, bottom: bottom), child: this);
Padding(padding: EdgeInsets.only(left: left, right: right, top: top, bottom: bottom), child: this);
// Widget onTap(VoidCallback onTap, {double corners = 0}) { // Widget onTap(VoidCallback onTap, {double corners = 0}) {
// return Clickable.widget(child: this, corners: corners, onTap: onTap); // return Clickable.widget(child: this, corners: corners, onTap: onTap);
@ -365,10 +363,14 @@ extension BuildSVG on String? {
if (imageChunk == null) { if (imageChunk == null) {
return child!; return child!;
} }
return const Center( return Center(
child: CircularProgressIndicator( child: SizedBox(
strokeWidth: 0.5, height: height,
color: MyColors.darkPrimaryColor, width: width,
child: const CircularProgressIndicator(
strokeWidth: 0.6,
color: MyColors.darkPrimaryColor,
),
), ),
); );
}, },
@ -382,12 +384,7 @@ extension BuildSVG on String? {
extension LocaleSetup on MultiProvider { extension LocaleSetup on MultiProvider {
Widget setupLocale() { Widget setupLocale() {
return EasyLocalization(supportedLocales: MyLocales.supportedLocales, return EasyLocalization(supportedLocales: MyLocales.supportedLocales, fallbackLocale: MyLocales.fallBackLocale, startLocale: MyLocales.startLocale, assetLoader: MyLocales.assetLoader, path: MyLocales.localesAssetPath, child: this);
fallbackLocale: MyLocales.fallBackLocale,
startLocale: MyLocales.startLocale,
assetLoader: MyLocales.assetLoader,
path: MyLocales.localesAssetPath,
child: this);
} }
} }

Loading…
Cancel
Save