Merge branch 'aamir_dev' into faiz_development_common

# Conflicts:
#	assets/langs/ar-SA.json
#	assets/langs/en-US.json
#	lib/generated/codegen_loader.g.dart
#	lib/generated/locale_keys.g.dart
#	lib/views/advertisement/bottom_sheets/ads_damage_part_pictures_sheet.dart
aamir_dev
Faiz Hashmi 10 months ago
commit 054944e28a

@ -785,10 +785,13 @@
"tapToView": "انقر لعرض",
"noServicesAvailableToCopy": "لا توجد خدمات متاحة في هذا الفرع لنسخها.",
"copySelectedItems": "نسخ العناصر المحددة",
"companyNameMandatory": "اسم الشركة إلزامي",
"noOfInvites": "عدد الدعوات",
"noSpecialServicesAvailable": "لا توجد خدمات خاصة متاحة للمنطقة المحددة.",
"customService": "الخدمة المخصصة",
"selectServiceDetails": "اختر تفاصيل الخدمة",
"addServiceDetails": "أضف تفاصيل الخدمة"
"addServiceDetails": "أضف تفاصيل الخدمة",
"companyNameMandatory": "اسم الشركة إلزامي",
"connectionProblem": "مشكلة في الاتصال",
"pleaseCheckConnection": "يرجى التحقق من اتصالك بالإنترنت والمحاولة مرة أخرى",
"ok": "نعم"
}

@ -788,5 +788,8 @@
"noSpecialServicesAvailable": "There are no special services available for the selected region.",
"customService": "Custom Service",
"selectServiceDetails": "Select service details",
"addServiceDetails": "Add service details"
"addServiceDetails": "Add service details",
"connectionProblem": "Connection Problem",
"pleaseCheckConnection": "Please check your internet connection and try again.",
"ok": "Ok"
}

@ -4,15 +4,18 @@ import 'dart:developer';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:http/io_client.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/exceptions/api_exception.dart';
import 'package:mc_common_app/main.dart';
import 'package:mc_common_app/models/user_models/refresh_token.dart';
import 'package:mc_common_app/models/user_models/user.dart';
import 'package:mc_common_app/utils/shared_prefrence.dart';
import 'package:mc_common_app/utils/utils.dart';
typedef FactoryConstructor<U> = U Function(dynamic);
@ -56,7 +59,8 @@ class APIError {
}
abstract class ApiClient {
Future<U> postJsonForObject<T, U>(FactoryConstructor<U> factoryConstructor, String url, T jsonObject, {String? token, Map<String, dynamic>? queryParameters, Map<String, String>? headers, int retryTimes = 0});
Future<U> postJsonForObject<T, U>(FactoryConstructor<U> factoryConstructor, String url, T jsonObject,
{String? token, Map<String, dynamic>? queryParameters, Map<String, String>? headers, int retryTimes = 0});
Future<Response> postJsonForResponse<T>(String url, T jsonObject, {String? token, Map<String, dynamic>? queryParameters, Map<String, String>? headers, int retryTimes = 0});
@ -67,7 +71,8 @@ abstract class ApiClient {
class ApiClientImp implements ApiClient {
@override
Future<U> postJsonForObject<T, U>(FactoryConstructor<U> factoryConstructor, String url, T jsonObject, {String? token, Map<String, dynamic>? queryParameters, Map<String, String>? headers, int retryTimes = 0}) async {
Future<U> postJsonForObject<T, U>(FactoryConstructor<U> factoryConstructor, String url, T jsonObject,
{String? token, Map<String, dynamic>? queryParameters, Map<String, String>? headers, int retryTimes = 0}) async {
var headers0 = {'Accept': 'application/json'};
if (headers != null && headers.isNotEmpty) {
headers0.addAll(headers);
@ -163,6 +168,10 @@ class ApiClientImp implements ApiClient {
throw APIException(APIException.OTHER, arguments: e);
}
} on TimeoutException catch (e) {
BuildContext? context = navigatorKey.currentContext;
if (context != null) {
NoInternetDialog.show(context);
}
throw APIException(APIException.TIMEOUT, arguments: e);
} on ClientException catch (e) {
if (retryTimes > 0) {
@ -193,7 +202,8 @@ class ApiClientImp implements ApiClient {
Future<Response> _post(url, {Map<String, String>? headers, body, Encoding? encoding}) => _withClient((client) => client.post(url, headers: headers, body: body, encoding: encoding));
@override
Future<U> getJsonForObject<T, U>(FactoryConstructor<U> factoryConstructor, String url, {String? token, Map<String, dynamic>? queryParameters, Map<String, String>? headers, int retryTimes = 0}) async {
Future<U> getJsonForObject<T, U>(FactoryConstructor<U> factoryConstructor, String url,
{String? token, Map<String, dynamic>? queryParameters, Map<String, String>? headers, int retryTimes = 0}) async {
var headers0 = {'Accept': 'application/json'};
if (headers != null && headers.isNotEmpty) {
headers0.addAll(headers);
@ -272,6 +282,10 @@ class ApiClientImp implements ApiClient {
throw APIException(APIException.OTHER, arguments: e);
}
} on TimeoutException catch (e) {
final context = navigatorKey.currentContext;
if (context != null) {
NoInternetDialog.show(context);
}
throw APIException(APIException.TIMEOUT, arguments: e);
} on ClientException catch (e) {
if (retryTimes > 0) {

@ -72,12 +72,21 @@ class AppState {
_providerSubscription = value;
}
DropValue? _userRegisterCountrySelection ;
DropValue? _userRegisterCountrySelection;
DropValue get getUserRegisterCountrySelection => _userRegisterCountrySelection!;
set setUserRegisterCountrySelection(DropValue value) {
_userRegisterCountrySelection = value;
}
bool _isViewOnly = false;
bool get getIsViewOnly => _isViewOnly;
set setIsViewOnly(bool value) {
_isViewOnly = value;
}
}

@ -3,6 +3,7 @@ import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/generated/codegen_loader.g.dart';
import 'package:mc_common_app/models/user_models/user.dart';
import 'package:mc_common_app/utils/enums.dart';
class ApiConsts {
@ -413,3 +414,46 @@ class SignalrConsts {
static String sendMessageGeneral = "SendMessageGeneral";
static String receiveMessageGeneral = "ReceiveMessageGeneral";
}
class GuestConsts {
UserInfo userInfo = UserInfo.fromJson({
"id": -1,
"userID": null,
"firstName": "Guest",
"lastName": "User",
"companyName": null,
"accountStatus": "2",
"activityStatus": "Offline",
"accountStatusText": null,
"subscriptionDate": null,
"mobileNo": "966123456789",
"email": "mowatter@gmail.com",
"userImageUrl": "https://ms.hmg.com/api/ProfileImage?imageName=User_Default.png",
"roleID": 4,
"roleName": "Customer",
"isEmailVerified": false,
"serviceProviderBranch": [],
"isVerified": true,
"userRoles": [],
"isProviderDealership": false,
"isProviderIndividual": false,
"isProvider": false,
"providerID": null,
"isCustomer": true,
"customerID": 25,
"countryID": 1,
"countryName": "Saudi Arabia",
"cityID": 1,
"cityName": "Riyadh",
"dealershipUserID": null,
"serviceProviderBranchID": null,
"createdOn": "2024-12-24T09:20:47.6733333",
"genderID": 1,
"genderName": "Male",
"serviceProviderPayment": [],
"deviceType": "1",
"deviceToken": null,
});
}

@ -50,7 +50,11 @@ import 'package:mc_common_app/views/user/vertify_password_page.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/widgets/image_viewer/image_viewer_screen.dart';
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
class AppRoutes {
//User
static const String splash = "/splash";
static const String registerSelection = "/registerSelection";
@ -184,11 +188,27 @@ class AppRoutes {
forgetPassword: (context) => const ForgetPasswordPage(),
loginVerification: (context) => const LoginVerificationPage(),
loginWithPassword: (context) => const LoginWithPassword(),
loginMethodSelection: (context) => LoginMethodSelectionPage(ModalRoute.of(context)!.settings.arguments as String),
completeProfile: (context) => CompleteProfilePage(ModalRoute.of(context)!.settings.arguments as RegisterUserRespModel),
loginMethodSelection: (context) =>
LoginMethodSelectionPage(ModalRoute
.of(context)!
.settings
.arguments as String),
completeProfile: (context) =>
CompleteProfilePage(ModalRoute
.of(context)!
.settings
.arguments as RegisterUserRespModel),
verifyPassword: (context) => VerifyPasswordPage(),
confirmNewPasswordPage: (context) => ConfirmNewPasswordPage(ModalRoute.of(context)!.settings.arguments as String),
forgetPasswordMethodPage: (context) => ForgetPasswordMethodPage(ModalRoute.of(context)!.settings.arguments as String),
confirmNewPasswordPage: (context) =>
ConfirmNewPasswordPage(ModalRoute
.of(context)!
.settings
.arguments as String),
forgetPasswordMethodPage: (context) =>
ForgetPasswordMethodPage(ModalRoute
.of(context)!
.settings
.arguments as String),
changeMobilePage: (context) => ChangeMobilePage(),
changeEmailPage: (context) => const ChangeEmailPage(),
updateUserDetails: (context) => const UpdateUserDetails(),
@ -201,30 +221,66 @@ class AppRoutes {
providerLicensePage: (context) => const ProviderLicensePage(),
// common pages
AppRoutes.adsDetailView: (context) => AdsDetailView(adDetails: ModalRoute.of(context)!.settings.arguments as AdDetailsModel),
AppRoutes.adsDetailView: (context) =>
AdsDetailView(adDetails: ModalRoute
.of(context)!
.settings
.arguments as AdDetailsModel),
AppRoutes.createAdView: (context) => const CreateAdView(),
AppRoutes.adsFilterView: (context) => const AdsFilterView(),
AppRoutes.selectAdTypeView: (context) => SelectAdTypeView(arguments: ModalRoute.of(context)!.settings.arguments as List<dynamic>),
AppRoutes.chatView: (context) => ChatView(chatViewArguments: ModalRoute.of(context)!.settings.arguments as ChatViewArguments),
AppRoutes.adsBuyerChatsListView: (context) => AdsBuyerChatsView(buyersListViewArguments: ModalRoute.of(context)!.settings.arguments as List<BuyersChatForAdsModel>),
AppRoutes.selectAdTypeView: (context) =>
SelectAdTypeView(arguments: ModalRoute
.of(context)!
.settings
.arguments as List<dynamic>),
AppRoutes.chatView: (context) =>
ChatView(chatViewArguments: ModalRoute
.of(context)!
.settings
.arguments as ChatViewArguments),
AppRoutes.adsBuyerChatsListView: (context) =>
AdsBuyerChatsView(buyersListViewArguments: ModalRoute
.of(context)!
.settings
.arguments as List<BuyersChatForAdsModel>),
AppRoutes.settingOptionsFaqs: (context) => const SettingOptionsFAQs(),
AppRoutes.settingOptionsContactUs: (context) => const SettingOptionsContactUs(),
AppRoutes.settingOptionsAppInfo: (context) => const SettingOptionsAppInfo(),
AppRoutes.settingOptionsTermsAndConditions: (context) => const SettingOptionsTermsAndConditions(),
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.requestsDetailPage: (context) =>
RequestDetailPage(requestDetailPageArguments: ModalRoute
.of(context)!
.settings
.arguments as RequestDetailPageArguments),
AppRoutes.createRequestPage: (context) => const CreateRequestPage(),
AppRoutes.offersListPage: (context) => OfferListPage(requestId: ModalRoute.of(context)!.settings.arguments as int),
AppRoutes.offersListPage: (context) =>
OfferListPage(requestId: ModalRoute
.of(context)!
.settings
.arguments as int),
AppRoutes.reviewRequestOffer: (context) => const ReviewRequestOffer(),
AppRoutes.requestsFilterView: (context) => const RequestsFilterView(),
//MediaViewer
AppRoutes.mediaViewerScreen: (context) => MediaViewerScreen(images: ModalRoute.of(context)!.settings.arguments as List<MessageImageModel>),
AppRoutes.mediaViewerScreen: (context) =>
MediaViewerScreen(images: ModalRoute
.of(context)!
.settings
.arguments as List<MessageImageModel>),
// ChatsList Provider
AppRoutes.generalChatsListForProvider: (context) => OfferListPage(requestId: ModalRoute.of(context)!.settings.arguments as int),
AppRoutes.generalChatsListForProvider: (context) =>
OfferListPage(requestId: ModalRoute
.of(context)!
.settings
.arguments as int),
//Shipping
AppRoutes.shippingManagementView: (context) => const ShippingManagementView(),

@ -807,6 +807,10 @@ class CodegenLoader extends AssetLoader{
"customService": "الخدمة المخصصة",
"selectServiceDetails": "اختر تفاصيل الخدمة",
"addServiceDetails": "أضف تفاصيل الخدمة"
"companyNameMandatory": "اسم الشركة إلزامي",
"connectionProblem": "مشكلة في الاتصال",
"pleaseCheckConnection": "يرجى التحقق من اتصالك بالإنترنت والمحاولة مرة أخرى",
"ok": "نعم"
};
static const Map<String,dynamic> en_US = {
"firstTimeLogIn": "First Time Log In",
@ -1594,6 +1598,10 @@ static const Map<String,dynamic> en_US = {
"noServicesAvailableToCopy": "There are no services available in this branch to copy.",
"copySelectedItems": "Copy Selected Items",
"companyNameMandatory": "Company Name is mandatory",
"connectionProblem": "Connection Problem",
"pleaseCheckConnection": "Please check your internet connection and try again.",
"ok": "Ok"
"companyNameMandatory": "Company Name is mandatory",
"noOfInvites": "No of invites",
"noSpecialServicesAvailable": "There are no special services available for the selected region.",
"customService": "Custom Service",

@ -770,5 +770,8 @@ abstract class LocaleKeys {
static const customService = 'customService';
static const selectServiceDetails = 'selectServiceDetails';
static const addServiceDetails = 'addServiceDetails';
static const connectionProblem = 'connectionProblem';
static const pleaseCheckConnection = 'pleaseCheckConnection';
static const ok = 'ok';
}

@ -4,6 +4,8 @@ import 'dart:typed_data';
import 'package:easy_localization/easy_localization.dart';
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/generated/locale_keys.g.dart';
import 'package:mc_common_app/utils/date_helper.dart';
@ -724,3 +726,36 @@ class Utils {
);
}
}
class NoInternetDialog {
static void show(BuildContext context) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text(
LocaleKeys.connectionProblem,
textAlign: TextAlign.center,
),
content: const Text(
LocaleKeys.pleaseCheckConnection,
textAlign: TextAlign.center,
),
actions: [
ElevatedButton(
onPressed: () {
// // if (AppState().currentAppType == AppType.provider) {
// Navigator.of(context).pop();
Navigator.of(context).pushNamedAndRemoveUntil(AppRoutes.registerSelection, (Route<dynamic> route) => true);
},
child: const Text(
LocaleKeys.ok,
style: TextStyle(color: Colors.white),
),
),
],
);
},
);
}
}

@ -1503,8 +1503,12 @@ class AdVM extends BaseVM {
// }
// }
Future<void> onAdSSBookAppointmentPressed(BuildContext context, {required AdDetailsModel adDetailsModel, required int adsSpecialServiceID}) async {
Future<void> onAdSSBookAppointmentPressed(BuildContext context, {required AdDetailsModel adDetailsModel}) async {
bool isValidated = false;
int specialSServideId = 1;
if (adDetailsModel.specialservice != null && adDetailsModel.specialservice!.isNotEmpty) {
specialSServideId = adDetailsModel.specialservice!.first.specialServiceID ?? 1;
}
if (selectedPhotoSSSchedulesByOffice.photoOfficeID == null) {
isValidated = false;
@ -1530,7 +1534,7 @@ class AdVM extends BaseVM {
adId: adDetailsModel.id ?? 0,
photoOfficeID: photoOfficeSelectedId.selectedId,
photoOfficeSlotID: selectedPhotoOfficeSlotDateTime ?? 0,
adsSpecialServiceID: adsSpecialServiceID,
adsSpecialServiceID: specialSServideId,
);
Utils.hideLoading(context);

@ -63,6 +63,10 @@ class DashboardVmCustomer extends BaseVM {
AppointmentsVM appointmentsVM = Provider.of<AppointmentsVM>(context, listen: false);
RequestsVM requestsVM = Provider.of<RequestsVM>(context, listen: false);
ChatVM chatVM = Provider.of<ChatVM>(context, listen: false);
appointmentsVM.populateBranchesFilterList();
appointmentsVM.populateAppointmentsFilterList();
adVM.populateAdsFilterList();

@ -404,6 +404,7 @@ class UserVM extends BaseVM {
}
Future<void> performBasicOtpLoginSelectionPage(BuildContext context, {required String userToken, required AppType appType, String? loginType}) async {
AppState().setIsViewOnly = false;
log("loginType: $loginType");
if (loginType == "3" || loginType == "4") {
//Utils.showLoading(context);

@ -308,6 +308,8 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
var element = adVM.photoSSSchedulesByOffices[i];
vehicleCitiesDrop.add(DropValue(element.photoOfficeID?.toInt() ?? 0, element.photoOfficeName ?? "", i.toString()));
}
print(adVM.photoOfficeSelectedId.selectedId);
return DropdownField(
(DropValue value) => adVM.updatePhotoOfficeSelectedId(SelectionModel(selectedId: value.id, selectedOption: value.value, itemPrice: value.subValue)),
list: vehicleCitiesDrop,
@ -351,7 +353,7 @@ class BuildAdDetailsActionButtonForMyAds extends StatelessWidget {
title: LocaleKeys.bookAndPay.tr(),
fontSize: 15,
onPressed: () {
adVM.onAdSSBookAppointmentPressed(context, adDetailsModel: adDetailsModel, adsSpecialServiceID: 1); //1 for photography Service
adVM.onAdSSBookAppointmentPressed(context, adDetailsModel: adDetailsModel);
},
),
),

@ -35,27 +35,26 @@ class _AdDamagePartPicturesSheetState extends State<AdDamagePartPicturesSheet> {
}
void populateDamagePartPictures() {
for (var element in widget.adDamageReportList) {
ImageModel imageModel = ImageModel(id: element.id!, filePath: element.imageUrl!, isFromNetwork: true);
VehicleDamageCard vehicleDamageCard = VehicleDamageCard(
partSelectedId: SelectionModel(
selectedId: element.vehicleDamagePartID!,
selectedOption: element.partName ?? "",
),
damagePartDescription: element.comment ?? "",
partImages: [imageModel],
);
int index = vehicleDamageCards.indexWhere((card) => card.partSelectedId!.selectedId == element.vehicleDamagePartID!);
List<dynamic> adDamageReportList = widget.adDamageReportList; // Assuming this is your data source.
Map<String, VehicleDamageCard> groupedDamageCards = {};
if (index == -1) {
vehicleDamageCards.add(vehicleDamageCard);
for (var element in adDamageReportList) {
String partName = element.partName ?? "Unknown";
ImageModel imageModel = ImageModel(id: element.id!, filePath: element.imageUrl!, isFromNetwork: true);
if (groupedDamageCards.containsKey(partName)) {
groupedDamageCards[partName]!.partImages!.add(imageModel);
} else {
if (vehicleDamageCards[index].partImages != null) {
vehicleDamageCards[index].partImages!.add(imageModel);
}
groupedDamageCards[partName] = VehicleDamageCard(
partSelectedId: SelectionModel(
selectedId: element.vehicleDamagePartID!,
selectedOption: partName,
),
damagePartDescription: element.comment ?? "",
partImages: [imageModel]);
}
}
vehicleDamageCards = groupedDamageCards.values.toList();
setState(() {});
}

@ -64,7 +64,9 @@ class AdsListWidget extends StatelessWidget {
adDetails: adsList[index],
isAdsFragment: isAdsFragment,
shouldShowAdStatus: shouldShowAdStatus,
).onPress(() => navigateWithName(context, AppRoutes.adsDetailView, arguments: adsList[index]));
).onPress(() => navigateWithName(context, AppRoutes.adsDetailView, arguments: adsList[index])).toViewOnly(context, onTap: () {
navigateWithName(context, AppRoutes.loginWithPassword);
});
},
separatorBuilder: (BuildContext context, int index) {
return 12.height;

@ -58,7 +58,9 @@ class AdsFragment extends StatelessWidget {
navigateWithName(context, AppRoutes.adsFilterView);
})
],
),
).toViewOnly(context, onTap: () {
navigateWithName(context, AppRoutes.loginWithPassword);
}),
body: SizedBox(
width: double.infinity,
height: double.infinity,
@ -89,8 +91,8 @@ class AdsFragment extends StatelessWidget {
},
),
),
12.width,
Expanded(
if(!AppState().getIsViewOnly) 12.width,
if(!AppState().getIsViewOnly) Expanded(
child: ShowFillButton(
isFilled: !adVM.isExploreAdsTapped,
txtColor: !adVM.isExploreAdsTapped ? MyColors.white : MyColors.darkTextColor,
@ -116,16 +118,17 @@ class AdsFragment extends StatelessWidget {
needLeftPadding: false,
).paddingOnly(left: 21),
]
] else ...[
16.height,
FiltersList(
filterList: adVM.myAdsFilterOptions,
onFilterTapped: (index, selectedFilterId) {
adVM.applyFilterOnMyAds(adPostStatusEnum: selectedFilterId.toAdPostEnum());
},
needLeftPadding: false,
).paddingOnly(left: 21),
],
] else
...[
16.height,
FiltersList(
filterList: adVM.myAdsFilterOptions,
onFilterTapped: (index, selectedFilterId) {
adVM.applyFilterOnMyAds(adPostStatusEnum: selectedFilterId.toAdPostEnum());
},
needLeftPadding: false,
).paddingOnly(left: 21),
],
],
);
},
@ -135,38 +138,46 @@ class AdsFragment extends StatelessWidget {
child: RefreshIndicator(
onRefresh: () async {
if (adVM.isExploreAdsTapped) {
int vehicleBrandId = adVM.exploreAdsFilterOptions.firstWhere((element) => element.isSelected).id;
int vehicleBrandId = adVM.exploreAdsFilterOptions
.firstWhere((element) => element.isSelected)
.id;
adVM.applyFilterOnExploreAds(vehicleBrandId: vehicleBrandId);
} else {
AdPostStatus adPostStatusEnum = adVM.myAdsFilterOptions.firstWhere((element) => element.isSelected).id.toAdPostEnum();
AdPostStatus adPostStatusEnum = adVM.myAdsFilterOptions
.firstWhere((element) => element.isSelected)
.id
.toAdPostEnum();
adVM.applyFilterOnMyAds(adPostStatusEnum: adPostStatusEnum);
}
},
child: adVM.state == ViewState.busy
? const Center(child: CircularProgressIndicator())
: AdsListWidget(
isAdsFragment: true,
shouldShowAdStatus: !adVM.isExploreAdsTapped,
adsList: getAdsList(adVM),
hasMoreData: adVM.isExploreAdsTapped ? adVM.hasMoreDataForExploreAds : adVM.hasMoreDataForMyAds,
onFetchMoreAds: () async {
AdPostStatus adPostStatusEnum = adVM.myAdsFilterOptions.firstWhere((element) => element.isSelected).id.toAdPostEnum();
isAdsFragment: true,
shouldShowAdStatus: !adVM.isExploreAdsTapped,
adsList: getAdsList(adVM),
hasMoreData: adVM.isExploreAdsTapped ? adVM.hasMoreDataForExploreAds : adVM.hasMoreDataForMyAds,
onFetchMoreAds: () async {
AdPostStatus adPostStatusEnum = adVM.myAdsFilterOptions
.firstWhere((element) => element.isSelected)
.id
.toAdPostEnum();
if (adVM.isExploreAdsTapped) {
await adVM.fetchMoreExploreAds();
} else {
await adVM.fetchMoreMyAds(adsStatus: adPostStatusEnum);
}
},
),
if (adVM.isExploreAdsTapped) {
await adVM.fetchMoreExploreAds();
} else {
await adVM.fetchMoreMyAds(adsStatus: adPostStatusEnum);
}
},
),
),
),
if (adVM.isLoadingMore) ...[
const Center(
child: Padding(
padding: EdgeInsets.all(8.0),
child: CircularProgressIndicator(),
))
padding: EdgeInsets.all(8.0),
child: CircularProgressIndicator(),
))
]
],
),
@ -186,11 +197,15 @@ class AdsFragment extends StatelessWidget {
}
}
navigateWithName(context, AppRoutes.selectAdTypeView, arguments: [injector.get<AppState>().currentAppType == AppType.provider, false, -1]);
navigateWithName(context, AppRoutes.selectAdTypeView, arguments: [injector
.get<AppState>()
.currentAppType == AppType.provider, false, -1]);
},
backgroundColor: MyColors.darkPrimaryColor,
child: const Icon(Icons.add, color: MyColors.white),
),
).toViewOnly(context, onTap: () {
navigateWithName(context, AppRoutes.loginWithPassword);
}),
);
},
);

@ -94,7 +94,9 @@ class MyRequestsFragment extends StatelessWidget {
navigateWithName(context, AppRoutes.requestsFilterView);
})
],
),
).toViewOnly(context, onTap: () {
navigateWithName(context, AppRoutes.loginWithPassword);
}),
body: Container(
color: MyColors.backgroundColor,
width: double.infinity,
@ -175,7 +177,9 @@ class MyRequestsFragment extends StatelessWidget {
requestsVM.notifyListeners();
navigateWithName(context, AppRoutes.offersListPage, arguments: request.id);
}
}),
}).toViewOnly(context, onTap: () {
navigateWithName(context, AppRoutes.loginWithPassword);
}),
);
},
separatorBuilder: (context, index) {
@ -196,7 +200,9 @@ class MyRequestsFragment extends StatelessWidget {
Icons.add,
color: MyColors.white,
),
)
).toViewOnly(context, onTap: () {
navigateWithName(context, AppRoutes.loginWithPassword);
})
: null,
);
});

@ -7,6 +7,7 @@ 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/models/user_models/user.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';
@ -90,6 +91,18 @@ class _RegisterSelectionPageState extends State<RegisterSelectionPage> {
}
},
),
20.height,
ShowFillButton(
title: "Guest View",
maxWidth: double.infinity,
horizontalMargin: 20,
onPressed: () {
appState.setIsViewOnly = true;
AppState().setUser = User(data: UserData(userInfo: GuestConsts().userInfo, accessToken: null, expiryDate: DateTime.now()));
navigateReplaceWithName(context, AppRoutes.dashboard);
},
),
10.height,
Utils.mFlex(3),
// TextButton(

@ -1,6 +1,7 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/main.dart';
import 'package:mc_common_app/theme/colors.dart';
@ -25,7 +26,8 @@ extension ExtendedText on Widget {
}
extension ContainerExt on Widget {
Widget toWhiteContainer({required double width, double? allPading, EdgeInsets? pading, EdgeInsets? margin, VoidCallback? onTap, Color? backgroundColor, bool isBorderRequired = false, double borderRadius = 0}) {
Widget toWhiteContainer(
{required double width, double? allPading, EdgeInsets? pading, EdgeInsets? margin, VoidCallback? onTap, Color? backgroundColor, bool isBorderRequired = false, double borderRadius = 0}) {
return InkWell(
onTap: onTap,
child: Container(
@ -234,7 +236,8 @@ extension WidgetExt on Widget {
);
}
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);
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);
// Widget onTap(VoidCallback onTap, {double corners = 0}) {
// return Clickable.widget(child: this, corners: corners, onTap: onTap);
@ -407,10 +410,49 @@ extension BuildSVG on String? {
extension LocaleSetup on MultiProvider {
Widget setupLocale() {
return EasyLocalization(supportedLocales: MyLocales.supportedLocales, fallbackLocale: MyLocales.fallBackLocale, startLocale: MyLocales.startLocale, assetLoader: MyLocales.assetLoader, path: MyLocales.localesAssetPath, child: this);
return EasyLocalization(
supportedLocales: MyLocales.supportedLocales,
fallbackLocale: MyLocales.fallBackLocale,
startLocale: MyLocales.startLocale,
assetLoader: MyLocales.assetLoader,
path: MyLocales.localesAssetPath,
child: this);
}
}
extension WidgetExtensions on Widget {
Widget onPress(VoidCallback onTap) => InkWell(onTap: onTap, child: this);
}
extension ViewOnlyExtension on Widget {
Widget toViewOnly(BuildContext context, {required Function() onTap}) {
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
if (AppState().getIsViewOnly) {
onTap();
}
},
child: AbsorbPointer(absorbing: AppState().getIsViewOnly, child: this));
}
}
extension PreferredSizeWidgetViewOnlyExtension on PreferredSizeWidget {
PreferredSizeWidget toViewOnly(BuildContext context, {required Function() onTap}) {
return PreferredSize(
preferredSize: this.preferredSize,
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
if (AppState().getIsViewOnly) {
onTap();
}
},
child: AbsorbPointer(
absorbing: AppState().getIsViewOnly,
child: this,
),
),
);
}
}

Loading…
Cancel
Save