diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 0e1df59..5324a6f 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -491,8 +491,7 @@ "submitAd": "إرسال الإعلان", "selectAdType": "اختر نوع الإعلان", "validUntilSubscriptionExpiration": "صالح حتى انتهاء الاشتراك", - "adsRemainingVar": "الإعلانات المتبقية", - "youLeftAdsGivenSubscription": "لقد بقي لديك 05 من 50 إعلانًا في الاشتراك.", + "youLeftAdsGivenSubscription": "لقد تركت مع إعلانات محدودة الواردة في الاشتراك.", "updateSubscription": "تحديث الاشتراك", "workInProgress": "العمل جارٍ", "visitCompleted": "تمت الزيارة", @@ -679,5 +678,7 @@ "inviteFriendsByWhatsApp": "دعوة الأصدقاء عبر واتساب", "inviteFriendsByEmail": "دعوة الأصدقاء عبر البريد الإلكتروني", "noFAQsToShow": "لا توجد أسئلة شائعة في الوقت الحالي. يرجى الاتصال بنا إذا كان لديك أي استفسار.", - "appInfo": "معلومات التطبيق" + "appInfo": "معلومات التطبيق", + "users": "المستخدمين", + "adsRemaining": "الإعلانات المتبقية" } \ No newline at end of file diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index a4cf2bd..0158029 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -492,8 +492,7 @@ "submitAd": "Submit Ad", "selectAdType": "Select Ad Type", "validUntilSubscriptionExpiration": "Valid Until Subscription Expiration", - "adsRemainingVar ": "Ads Remaining", - "youLeftAdsGivenSubscription": "You have left with 05 out of 50 ads given in the subscription.", + "youLeftAdsGivenSubscription": "You have left with limited ads given in the subscription.", "updateSubscription": "Update Subscription", "workInProgress": "Work In Progress", "visitCompleted": "Visit Completed", @@ -677,5 +676,7 @@ "inviteFriendsByWhatsApp": "Invite Friends By WhatsApp", "inviteFriendsByEmail": "Invite Friends By Email", "noFAQsToShow": "There are no Frequently asked Questions Right now. Please contact us if you have any query.", - "appInfo": "App Info" + "appInfo": "App Info", + "users": "Users", + "adsRemaining": "Ads Remaining" } \ No newline at end of file diff --git a/lib/classes/app_state.dart b/lib/classes/app_state.dart index 72ab7cf..4d528d9 100644 --- a/lib/classes/app_state.dart +++ b/lib/classes/app_state.dart @@ -41,7 +41,7 @@ class AppState { currentAppType = appType; } - User? _user = null; + User? _user; set setUser(v) => _user = v; diff --git a/lib/config/routes.dart b/lib/config/routes.dart index ea4978e..3521749 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -69,6 +69,43 @@ class AppRoutes { static const String changeEmailPage = "/changeEmailPage"; static const String editAccountPage = "/editAccoundPage"; + // Provider App Routes + + //settings + static const defineLicense = "/defineLicese"; + static const String dealershipSetting = "/dealershipSetting"; + static const String branchList = "/branchList"; + static const String branchDetail = "/branchDetail"; + static const String defineBranch = "/defineBranch"; + + //Appointments + static const String appointment = "/appointment"; + static const String appointmentDetailList = "/appointmentDetailList"; + static const String updateAppointmentPage = "/updateAppointmentPage"; + static const String addServiceInAppointment = "/addServiceInAppointment"; + static const String mergeAppointments = "/mergeAppointments"; + + //Services + static const String dealerUser = "/dealerUser"; + static const String servicesList = "/servicesList"; + static const String itemsList = "/itemsList"; + static const String createItem = "/createItem"; + static const String createServices = "/createServices"; + static const String createServices2 = "/createServices2"; + static const String createServices3 = "/createServices3"; + + //Schedules + static const String schedulesList = "/schedulesList"; + static const String addSchedule = "/addSchedule"; + + // Subscriptions + static const String mySubscriptionsPage = "/mySubscriptionsPage"; + static const String subscriptionsPage = "/subscriptionsPage"; + + //Bracnh Duplication + static const String matchServices = "/matchServices"; + static const String userSettings = "/userSettings"; + static const String dashboard = "/dashboard"; static const String bookProviderAppView = "/bookProviderAppView"; @@ -100,17 +137,13 @@ class AppRoutes { static const String providerProfileView = "/providerProfilePage"; static const String favoriteListView = "/favoriteListView"; - // Subscriptions - static const String mySubscriptionsPage = "/mySubscriptionsPage"; - static const String subscriptionsPage = "/subscriptionsPage"; - //Requests + static const String requestsDetailPage = "/requestsDetailPage"; + static const String sendOfferPage = "/sendOfferPage"; static const String myRequestsPage = "/myRequestsPage"; static const String requestsFilterView = "/requestsFilterView"; static const String createRequestPage = "/createRequestPage"; static const String offersListPage = "/offersListPage"; - static const String requestsDetailPage = "/requestsDetailPage"; - static const String sendOfferPage = "/sendOfferPage"; static const String reviewRequestOffer = "/reviewRequestOffer"; //Setting Options @@ -126,14 +159,8 @@ class AppRoutes { //Profile Screen static const String profileView = "/profileView"; - static const providerLicensePage = "/providerLicensePage"; - //Provider User Page - static const dealerUser = "/dealerUser"; - - // HomePage Provider - static const String generalChatsListForProvider = "/generalChatsListForProvider"; //Chat diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index 5e42c42..c1bc3ca 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -507,8 +507,7 @@ class CodegenLoader extends AssetLoader{ "submitAd": "إرسال الإعلان", "selectAdType": "اختر نوع الإعلان", "validUntilSubscriptionExpiration": "صالح حتى انتهاء الاشتراك", - "adsRemainingVar": "الإعلانات المتبقية", - "youLeftAdsGivenSubscription": "لقد بقي لديك 05 من 50 إعلانًا في الاشتراك.", + "youLeftAdsGivenSubscription": "لقد تركت مع إعلانات محدودة الواردة في الاشتراك.", "updateSubscription": "تحديث الاشتراك", "workInProgress": "العمل جارٍ", "visitCompleted": "تمت الزيارة", @@ -695,7 +694,9 @@ class CodegenLoader extends AssetLoader{ "inviteFriendsByWhatsApp": "دعوة الأصدقاء عبر واتساب", "inviteFriendsByEmail": "دعوة الأصدقاء عبر البريد الإلكتروني", "noFAQsToShow": "لا توجد أسئلة شائعة في الوقت الحالي. يرجى الاتصال بنا إذا كان لديك أي استفسار.", - "appInfo": "معلومات التطبيق" + "appInfo": "معلومات التطبيق", + "users": "المستخدمين", + "adsRemaining": "الإعلانات المتبقية" }; static const Map en_US = { "firstTimeLogIn": "First Time Log In", @@ -1191,8 +1192,7 @@ static const Map en_US = { "submitAd": "Submit Ad", "selectAdType": "Select Ad Type", "validUntilSubscriptionExpiration": "Valid Until Subscription Expiration", - "adsRemainingVar ": "Ads Remaining", - "youLeftAdsGivenSubscription": "You have left with 05 out of 50 ads given in the subscription.", + "youLeftAdsGivenSubscription": "You have left with limited ads given in the subscription.", "updateSubscription": "Update Subscription", "workInProgress": "Work In Progress", "visitCompleted": "Visit Completed", @@ -1376,7 +1376,9 @@ static const Map en_US = { "inviteFriendsByWhatsApp": "Invite Friends By WhatsApp", "inviteFriendsByEmail": "Invite Friends By Email", "noFAQsToShow": "There are no Frequently asked Questions Right now. Please contact us if you have any query.", - "appInfo": "App Info" + "appInfo": "App Info", + "users": "Users", + "adsRemaining": "Ads Remaining" }; static const Map> mapLocales = {"ar_SA": ar_SA, "en_US": en_US}; } diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 9734eae..77e667d 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -470,7 +470,6 @@ abstract class LocaleKeys { static const submitAd = 'submitAd'; static const selectAdType = 'selectAdType'; static const validUntilSubscriptionExpiration = 'validUntilSubscriptionExpiration'; - static const adsRemainingVar = 'adsRemainingVar'; static const youLeftAdsGivenSubscription = 'youLeftAdsGivenSubscription'; static const updateSubscription = 'updateSubscription'; static const workInProgress = 'workInProgress'; @@ -659,5 +658,7 @@ abstract class LocaleKeys { static const inviteFriendsByEmail = 'inviteFriendsByEmail'; static const noFAQsToShow = 'noFAQsToShow'; static const appInfo = 'appInfo'; + static const users = 'users'; + static const adsRemaining = 'adsRemaining'; } diff --git a/lib/repositories/shipping_repo.dart b/lib/repositories/shipping_repo.dart index e1b0312..da87b8d 100644 --- a/lib/repositories/shipping_repo.dart +++ b/lib/repositories/shipping_repo.dart @@ -1,3 +1,4 @@ +import 'dart:developer'; import 'package:easy_localization/easy_localization.dart'; import 'package:mc_common_app/api/api_client.dart'; @@ -25,17 +26,17 @@ class ShippingRepoImp extends ShippingRepo { @override Future> getShippingRequestListByStatus({ShippingRequestStatusEnum? shippingStatusEnum, int? requestId}) async { String token = appState.getUser.data!.accessToken ?? ""; - Map queryParameters = { + Map queryParameters = { "requestID": "${requestId ?? 0}", "shippingStatus": "${shippingStatusEnum != null ? shippingStatusEnum.getIdFromShippingStatusEnum() : 0}", }; - GenericRespModel genericRespModel = await injector.get().postJsonForObject( - (json) => GenericRespModel.fromJson(json), - ApiConsts.shippingRequestStatusGet, - queryParameters, - token: token, - ); + GenericRespModel genericRespModel = await apiClient.postJsonForObject( + (json) => GenericRespModel.fromJson(json), + ApiConsts.shippingRequestStatusGet, + queryParameters, + token: token, + ); if (genericRespModel.messageStatus != 1 || genericRespModel.data == null) { Utils.showToast(genericRespModel.message ?? LocaleKeys.somethingWrong.tr()); @@ -56,12 +57,12 @@ class ShippingRepoImp extends ShippingRepo { "comment": comment ?? "", }; - GenericRespModel genericRespModel = await injector.get().postJsonForObject( - (json) => GenericRespModel.fromJson(json), - ApiConsts.shippingRequestStatusUpdate, - queryParameters, - token: token, - ); + GenericRespModel genericRespModel = await apiClient.postJsonForObject( + (json) => GenericRespModel.fromJson(json), + ApiConsts.shippingRequestStatusUpdate, + queryParameters, + token: token, + ); if (genericRespModel.messageStatus != 1 || genericRespModel.data == null) { Utils.showToast(genericRespModel.message ?? LocaleKeys.somethingWrong.tr()); diff --git a/lib/repositories/subscription_repo.dart b/lib/repositories/subscription_repo.dart index 37b5524..3303fd5 100644 --- a/lib/repositories/subscription_repo.dart +++ b/lib/repositories/subscription_repo.dart @@ -5,16 +5,15 @@ import 'package:mc_common_app/config/dependency_injection.dart'; import 'package:mc_common_app/models/general_models/generic_resp_model.dart'; import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart'; import 'package:mc_common_app/models/subscriptions_models/branch_user_selection_model.dart'; -import 'package:mc_common_app/models/subscriptions_models/provider_subscription_model.dart'; import 'package:mc_common_app/models/subscriptions_models/subscription_model.dart'; import 'package:mc_common_app/models/user_models/branch_user.dart'; abstract class SubscriptionRepo { - Future getAllSubscriptions(String? serviceProviderID); + // Future getAllSubscriptions(String? serviceProviderID); - Future getMySubscriptions(String? serviceProviderID); + // Future> getProviderSubscription({String? serviceProviderID}); - Future> getProviderSubscription({String? serviceProviderID}); + Future getMySubscriptions(String? serviceProviderID); Future getSubscriptionBySP(String? serviceProviderID, bool isRenew); @@ -29,23 +28,10 @@ class SubscriptionRepoImp extends SubscriptionRepo { ApiClient apiClient = injector.get(); AppState appState = injector.get(); - @override - Future getAllSubscriptions(String? serviceProviderID) async { - String t = AppState().getUser.data!.accessToken ?? ""; - Map queryParameters = {}; - if (serviceProviderID != null) { - queryParameters = { - "ID": serviceProviderID, - }; - } - - return await injector.get().getJsonForObject((json) => SubscriptionModel.fromJson(json), ApiConsts.getAllSubscriptions, token: t, queryParameters: queryParameters); - } - @override Future getSubscriptionBySP(String? serviceProviderID, bool isRenew) async { String t = AppState().getUser.data!.accessToken ?? ""; - Map queryParameters = {}; + Map queryParameters = {}; if (serviceProviderID != null) { queryParameters = { "ProviderID": serviceProviderID, @@ -138,25 +124,38 @@ class SubscriptionRepoImp extends SubscriptionRepo { return await injector.get().getJsonForObject((json) => SubscriptionModel.fromJson(json), ApiConsts.getAllSubscriptions, token: t, queryParameters: queryParameters); } - @override - Future> getProviderSubscription({String? serviceProviderID}) async { - Map queryParameters = {}; - if (serviceProviderID != null) { - queryParameters = { - "ServiceProviderID": serviceProviderID, - "IsActiveSubscriptionForProvider": "true", - }; - } +// @override +// Future getAllSubscriptions(String? serviceProviderID) async { +// String t = AppState().getUser.data!.accessToken ?? ""; +// Map queryParameters = {}; +// if (serviceProviderID != null) { +// queryParameters = { +// "ID": serviceProviderID, +// }; +// } +// +// return await injector.get().getJsonForObject((json) => SubscriptionModel.fromJson(json), ApiConsts.getAllSubscriptions, token: t, queryParameters: queryParameters); +// } - GenericRespModel adsGenericModel = await apiClient.getJsonForObject( - token: appState.getUser.data!.accessToken, - (json) => GenericRespModel.fromJson(json), - ApiConsts.getMySubscriptions, - queryParameters: queryParameters, - ); - List providerSubList = List.generate(adsGenericModel.data.length, (index) => ProviderSubscriptionModel.fromJson(adsGenericModel.data[index])); - return providerSubList; - } +// @override +// Future> getProviderSubscription({String? serviceProviderID}) async { +// Map queryParameters = {}; +// if (serviceProviderID != null) { +// queryParameters = { +// "ServiceProviderID": serviceProviderID, +// "IsActiveSubscriptionForProvider": "true", +// }; +// } +// +// GenericRespModel adsGenericModel = await apiClient.getJsonForObject( +// token: appState.getUser.data!.accessToken, +// (json) => GenericRespModel.fromJson(json), +// ApiConsts.getMySubscriptions, +// queryParameters: queryParameters, +// ); +// List providerSubList = List.generate(adsGenericModel.data.length, (index) => ProviderSubscriptionModel.fromJson(adsGenericModel.data[index])); +// return providerSubList; +// } // @override // Future getProviderSubscription( diff --git a/lib/view_models/appointments_view_model.dart b/lib/view_models/appointments_view_model.dart index cf7ee78..2336b1b 100644 --- a/lib/view_models/appointments_view_model.dart +++ b/lib/view_models/appointments_view_model.dart @@ -28,6 +28,7 @@ import 'package:mc_common_app/repositories/branch_repo.dart'; import 'package:mc_common_app/repositories/common_repo.dart'; import 'package:mc_common_app/services/common_services.dart'; import 'package:mc_common_app/theme/colors.dart'; +import 'package:mc_common_app/utils/date_helper.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'; @@ -354,7 +355,9 @@ class AppointmentsVM extends BaseVM { myAppointments = await appointmentRepo.getMyAppointmentsForCustomersByFilters(); // myFilteredAppointments = myAppointments; - myUpComingAppointments = myAppointments.where((element) => element.appointmentStatusEnum == AppointmentStatusEnum.booked || element.appointmentStatusEnum == AppointmentStatusEnum.confirmed).toList(); + myUpComingAppointments = myAppointments + .where((element) => (element.appointmentStatusEnum == AppointmentStatusEnum.booked || element.appointmentStatusEnum == AppointmentStatusEnum.confirmed) && (DateHelper.parseStringToDate(element.appointmentDate!).isAfter(DateTime.now()))) + .toList(); setState(ViewState.idle); applyFilterOnAppointmentsVM(appointmentStatusEnum: AppointmentStatusEnum.allAppointments); notifyListeners(); @@ -380,7 +383,7 @@ class AppointmentsVM extends BaseVM { setState(ViewState.busy); myAppointments = await appointmentRepo.getMyAppointmentsForProvider(map); myFilteredAppointments = myAppointments; - myUpComingAppointments = myAppointments.where((element) => element.appointmentStatusEnum == AppointmentStatusEnum.confirmed).toList(); + myUpComingAppointments = myAppointments.where((element) => element.appointmentStatusEnum == AppointmentStatusEnum.confirmed && (DateHelper.parseStringToDate(element.appointmentDate!).isAfter(DateTime.now()))).toList(); applyFilterOnAppointmentsVM(appointmentStatusEnum: AppointmentStatusEnum.allAppointments, isNeedCustomerFilter: true); setState(ViewState.idle); } @@ -830,8 +833,14 @@ class AppointmentsVM extends BaseVM { if (isNeedToRebuild) setState(ViewState.busy); if (isFromRefresh) { - var selectedBranch = branchesFilterOptions.firstWhere((element) => element.isSelected); - nearbyBranches = await branchRepo.getBranchesByFilters(categoryIdsList: [selectedBranch.id]); + var selectedFilter = branchesFilterOptions.firstWhere((element) => element.isSelected); + log("selectedFilter: ${selectedFilter.id}"); + + if (selectedFilter.id == 0) { + nearbyBranches = await branchRepo.getAllNearBranchAndServices(); + } else { + nearbyBranches = await branchRepo.getBranchesByFilters(categoryIdsList: [selectedFilter.id]); + } setState(ViewState.idle); return; } @@ -1169,11 +1178,11 @@ class AppointmentsVM extends BaseVM { } Future getBranchesBasedOnCategoryFilters({required int categoryId}) async { + setState(ViewState.busy); if (categoryId == 0) { await getAllNearBranches(); return; } - setState(ViewState.busy); nearbyBranches.clear(); nearbyBranches = await branchRepo.getBranchesByFilters(categoryIdsList: [categoryId]); setState(ViewState.idle); @@ -1538,5 +1547,4 @@ class AppointmentsVM extends BaseVM { // .whenComplete(() => navigateWithName(context, AppRoutes.chatView, arguments: chatViewArguments)); // } } - } diff --git a/lib/view_models/dashboard_view_model_provider.dart b/lib/view_models/dashboard_view_model_provider.dart new file mode 100644 index 0000000..4f14fc6 --- /dev/null +++ b/lib/view_models/dashboard_view_model_provider.dart @@ -0,0 +1,150 @@ +import 'dart:io'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:mc_common_app/classes/app_state.dart'; +import 'package:mc_common_app/config/dependency_injection.dart'; +import 'package:mc_common_app/config/routes.dart'; +import 'package:mc_common_app/generated/locale_keys.g.dart'; +import 'package:mc_common_app/main.dart'; +import 'package:mc_common_app/models/user_models/image_response.dart'; +import 'package:mc_common_app/repositories/user_repo.dart'; +import 'package:mc_common_app/services/common_services.dart'; +import 'package:mc_common_app/utils/enums.dart'; +import 'package:mc_common_app/utils/navigator.dart'; +import 'package:mc_common_app/view_models/shipping_management_view_model.dart'; +import 'package:mc_common_app/widgets/common_widgets/add_phone_num_wiget.dart'; +import 'package:provider/provider.dart'; +import 'package:mc_common_app/utils/location/Location.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/appointments_view_model.dart'; +import 'package:mc_common_app/view_models/base_view_model.dart'; +import 'package:mc_common_app/widgets/bottom_sheet.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/service_view_model.dart'; +import 'package:mc_common_app/view_models/subscriptions_view_model.dart'; + +class DashboardVMProvider extends BaseVM { + final CommonAppServices commonServices; + final UserRepo userRepo; + + DashboardVMProvider({required this.commonServices, required this.userRepo}); + + String pickedImage = ""; + + int selectedNavbarBarIndex = 2; + + void onNavbarTapped(int index) async { + logger.i(AppState().getDeviceToken); + selectedNavbarBarIndex = index; + notifyListeners(); + } + + void pickImageFromPhone(BuildContext context, int sourceFlag) async { + final File? pickedImageFile = await commonServices.pickImageFromPhone(sourceFlag); + if (pickedImageFile == null) { + return; + } + int sizeInBytes = pickedImageFile.lengthSync(); + if (sizeInBytes > 1000000) { + Utils.showToast(LocaleKeys.fileLarger.tr()); + return; + } else { + String image64 = Utils.convertFileToBase64(pickedImageFile); + + Utils.showLoading(context); + ImageResponse response = await userRepo.updateUserImage(image64); + Utils.hideLoading(context); + Navigator.pop(context); + if (response.messageStatus == 1) { + Utils.showToast(LocaleKeys.imageUploaded.tr()); + AppState().getUser.data!.userInfo!.userImageUrl = response.data; + } else { + Utils.showToast(response.message ?? ""); + } + } + } + + Future updateUserImage(String image) async { + return await userRepo.updateUserImage(image); + } + + fetchUsernameAndLocation() async { + // String userName = await SharedPrefManager.getPhoneOrEmail(); + Location.getCurrentLocation( + (LatLng? latlng) { + AppState().currentLocation = latlng ?? const LatLng(0, 0); + }, + ); + notifyListeners(); + } + + Future onRefresh(BuildContext context) async { + final requestsVM = context.read(); + final chatVM = context.read(); + final appointmentVM = context.read(); + final shippingManagementVM = context.read(); + final serviceVM = context.read(); + final adVm = context.read(); + final subscriptionsVM = context.read(); + requestsVM.populateDataForRequestsFilter(); + appointmentVM.populateAppointmentsFilterList(); + shippingManagementVM.populateShippingRequestFilterList(); + await serviceVM.getBranchAndServices(); + await appointmentVM.getMyAppointmentsForProvider({"ServiceProviderID": injector.get().getUser.data?.userInfo?.providerId.toString() ?? "0"}); + adVm.populateAdsFilterList(); + await chatVM.buildHubConnection(context); + await adVm.getMyAds(); + await adVm.getExploreAds(); + await adVm.getVehicleTypes(); + await adVm.getVehicleAdsDuration(); + await requestsVM.getRequests(); + // await subscriptionsVM.getMySubscriptionsBySP(AppState().getUser.data?.userInfo?.providerId.toString() ?? ""); + await subscriptionsVM.getSubscriptionBySP(AppState().getUser.data?.userInfo?.providerId.toString() ?? "", true); + // await subscriptionsVM.getMySubscriptionsBySP(AppState().getUser.data?.userInfo?.providerId.toString() ?? ""); + } + + void checkUserSubscription(SubscriptionActionTypeEnum actionType, BuildContext context, {required Function() callback}) async { + switch (actionType) { + case SubscriptionActionTypeEnum.ads: + performCheckOnAds(context); + break; + case SubscriptionActionTypeEnum.users: + performCheckOnUsers(context, callback); + break; + case SubscriptionActionTypeEnum.branches: + performCheckOnBranches(context); + break; + } + } + + void performCheckOnBranches(BuildContext context) async { + if (AppState().getproviderSubscription.isNotEmpty && AppState().getproviderSubscription.first.branchesRemaining! > 0) { + logger.d(AppState().getproviderSubscription.first.toJson()); + await navigateWithName(context, AppRoutes.defineBranch); + } else { + Utils.showToast("Upgrade your subscription to add more Branches."); + } + } + + void performCheckOnAds(BuildContext context) async { + //adsRemaining + if (AppState().getproviderSubscription.isNotEmpty && AppState().getproviderSubscription.first.adsRemaining! > 0) { + logger.d(AppState().getproviderSubscription.first.toJson()); + await navigateWithName(context, AppRoutes.defineBranch); + } else { + Utils.showToast("Upgrade your subscription to add more Ads."); + } + } + + void performCheckOnUsers(BuildContext context, Function() callBack) async { + if (AppState().getproviderSubscription.isNotEmpty && AppState().getproviderSubscription.first.subUsersRemaining! > 0) { + logger.d(AppState().getproviderSubscription.first.toJson()); + showMyBottomSheet(context, isDismissible: false, child: const AddPhoneNumWidget(), callBackFunc: callBack); + } else { + Utils.showToast("Upgrade your subscription to add more Sub Users."); + } + } +} diff --git a/lib/view_models/payment_view_model.dart b/lib/view_models/payment_view_model.dart index 96a9af7..d7fee4e 100644 --- a/lib/view_models/payment_view_model.dart +++ b/lib/view_models/payment_view_model.dart @@ -12,6 +12,7 @@ import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/utils/utils.dart'; import 'package:mc_common_app/view_models/base_view_model.dart'; import 'package:mc_common_app/view_models/dashboard_view_model_customer.dart'; +import 'package:mc_common_app/view_models/dashboard_view_model_provider.dart'; import 'package:mc_common_app/view_models/subscriptions_view_model.dart'; import 'package:provider/provider.dart'; import 'package:easy_localization/easy_localization.dart'; @@ -181,12 +182,20 @@ class PaymentVM extends ChangeNotifier { } void onRequestPaymentSuccess(BuildContext context) { - context.read().onNavbarTapped(4); + if (AppState().currentAppType == AppType.provider) { + context.read().onNavbarTapped(4); + } else { + context.read().onNavbarTapped(4); + } navigateReplaceWithNameUntilRoute(context, AppRoutes.dashboard); } void onAdsPaymentSuccess(BuildContext context) { - context.read().onNavbarTapped(3); + if (AppState().currentAppType == AppType.provider) { + context.read().onNavbarTapped(3); + } else { + context.read().onNavbarTapped(3); + } navigateReplaceWithNameUntilRoute(context, AppRoutes.dashboard); } @@ -197,7 +206,11 @@ class PaymentVM extends ChangeNotifier { } void onAppointmentSuccess(BuildContext context) { - context.read().onNavbarTapped(1); + if (AppState().currentAppType == AppType.provider) { + context.read().onNavbarTapped(1); + } else { + context.read().onNavbarTapped(1); + } navigateReplaceWithNameUntilRoute(context, AppRoutes.dashboard); } diff --git a/lib/view_models/service_view_model.dart b/lib/view_models/service_view_model.dart index 90ad442..c1cc094 100644 --- a/lib/view_models/service_view_model.dart +++ b/lib/view_models/service_view_model.dart @@ -128,39 +128,47 @@ class ServiceVM extends BaseVM { notifyListeners(); } + int selectedBranchId = 0; + + updateSelectedBranchId(var value) { + selectedBranchId = value; + } + filterUserBranchCategories() { - categories = []; - List? localbranches; - if (branches!.data != null) { - if (selectedBranchStatus == 3) { - localbranches = branches!.data!.serviceProviderBranch!.where((element) => element.statusId == 3).toList(); - } else { - localbranches = branches!.data!.serviceProviderBranch!.where((element) => element.statusId != 3).toList(); - } + setState(ViewState.busy); + categories.clear(); + // List localBranches = []; + // if (branches!.data != null) { + // if (selectedBranchStatus == 3) { + // localBranches = branches!.data!.serviceProviderBranch!.where((element) => element.statusId == 3).toList(); + // } else { + // localBranches = branches!.data!.serviceProviderBranch!.where((element) => element.statusId != 3).toList(); + // } + // } + + final BranchDetailModel currentBranch = homePageBranches.firstWhere((element) => element.id == selectedBranchId); + for (var element in currentBranch.branchServices!) { + categories.add( + CategoryData( + id: element.categoryId, + categoryName: element.categoryName, + categoryNameN: element.categoryName, + ), + ); } - - for (var branch in localbranches!) { - for (var element in branch.branchServices!) { - categories.add( - CategoryData( - id: element.categoryId, - categoryName: element.categoryName, - categoryNameN: element.categoryName, - ), - ); - } - categories = categories.toSet().toList(); - for (var payment in categories) { - for (var element in branch.branchServices!) { - if (payment.id == element.categoryId) { - payment.services ??= []; - payment.services!.add(element); - } + categories = categories.toSet().toList(); + for (var payment in categories) { + for (var element in currentBranch.branchServices!) { + if (payment.id == element.categoryId) { + payment.services ??= []; + payment.services!.add(element); } } } - categories = categories; + setState(ViewState.idle); + + notifyListeners(); } // Future selectFile(BuildContext context, int index) async { diff --git a/lib/view_models/subscriptions_view_model.dart b/lib/view_models/subscriptions_view_model.dart index deefeef..a5c9e22 100644 --- a/lib/view_models/subscriptions_view_model.dart +++ b/lib/view_models/subscriptions_view_model.dart @@ -1,3 +1,5 @@ +import 'dart:developer'; + import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/models/general_models/generic_resp_model.dart'; import 'package:mc_common_app/models/subscriptions_models/branch_user_selection_model.dart'; @@ -23,27 +25,27 @@ class SubscriptionsVM extends BaseVM { //My Subscriptions //All Subscriptions - getAllAvailableSubscriptions(String? serviceProviderID) async { - selectedIndex = 0; - setState(ViewState.busy); - allSubscriptions = await subscriptionRepo.getAllSubscriptions(serviceProviderID); - if (allSubscriptions.messageStatus == 1) { - monthlyTabs.clear(); - var idSet = {}; - for (var d in allSubscriptions.data ?? []) { - if (idSet.add(d.durationDays ?? 0)) { - monthlyTabs.add(DropValue(d.durationDays, _convertDaysToMonths(d.durationDays ?? 0), "", isEnabled: false)); - } - } - monthlyTabs.sort((a, b) => a.value.compareTo(b.value)); - monthlyTabs.first.isEnabled = true; - selectedMonthlyTab = monthlyTabs.first; - filterSubscriptions(); - setState(ViewState.idle); - } else { - setState(ViewState.error); - } - } + // getAllAvailableSubscriptions(String? serviceProviderID) async { + // selectedIndex = 0; + // setState(ViewState.busy); + // allSubscriptions = await subscriptionRepo.getAllSubscriptions(serviceProviderID); + // if (allSubscriptions.messageStatus == 1) { + // monthlyTabs.clear(); + // var idSet = {}; + // for (var d in allSubscriptions.data ?? []) { + // if (idSet.add(d.durationDays ?? 0)) { + // monthlyTabs.add(DropValue(d.durationDays, _convertDaysToMonths(d.durationDays ?? 0), "", isEnabled: false)); + // } + // } + // monthlyTabs.sort((a, b) => a.value.compareTo(b.value)); + // monthlyTabs.first.isEnabled = true; + // selectedMonthlyTab = monthlyTabs.first; + // filterSubscriptions(); + // setState(ViewState.idle); + // } else { + // setState(ViewState.error); + // } + // } getSubscriptionBySP(String serviceProviderID, bool isRenew) async { selectedIndex = 0; @@ -184,17 +186,17 @@ class SubscriptionsVM extends BaseVM { // My Provider Subscription getMySubscriptionsBySP() async { + mySubscriptionsBySp.clear(); setState(ViewState.busy); - if (mySubscriptionsBySp.isEmpty) { - // allSubscriptions.data - for (var element in allSubscriptions.data!) { - if (element.subscriptionTypeEnum == SubscriptionTypeEnum.current) { - mySubscriptionsBySp.add(element); - } + // allSubscriptions.data + for (var element in allSubscriptions.data!) { + if (element.subscriptionTypeEnum == SubscriptionTypeEnum.current) { + mySubscriptionsBySp.add(element); } - // mySubscriptionsBySp = await subscriptionRepo.getProviderSubscription(serviceProviderID: serviceProviderID); - AppState().setproviderSubscription = mySubscriptionsBySp; } + // mySubscriptionsBySp = await subscriptionRepo.getProviderSubscription(serviceProviderID: serviceProviderID); + AppState().setproviderSubscription = mySubscriptionsBySp; + setState(ViewState.idle); } } diff --git a/lib/view_models/user_view_model.dart b/lib/view_models/user_view_model.dart index d550ad0..a422f6a 100644 --- a/lib/view_models/user_view_model.dart +++ b/lib/view_models/user_view_model.dart @@ -13,6 +13,7 @@ import 'package:mc_common_app/generated/locale_keys.g.dart'; import 'package:mc_common_app/main.dart'; import 'package:mc_common_app/models/general_models/generic_resp_model.dart'; import 'package:mc_common_app/models/general_models/generic_resp_model.dart'; +import 'package:mc_common_app/models/subscriptions_models/subscription_model.dart'; import 'package:mc_common_app/models/user_models/basic_otp.dart'; import 'package:mc_common_app/models/user_models/change_email.dart'; import 'package:mc_common_app/models/user_models/change_mobile.dart'; @@ -34,11 +35,14 @@ import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/utils/shared_prefrence.dart'; import 'package:mc_common_app/utils/utils.dart'; import 'package:mc_common_app/view_models/base_view_model.dart'; +import 'package:mc_common_app/view_models/service_view_model.dart'; +import 'package:mc_common_app/view_models/subscriptions_view_model.dart'; import 'package:mc_common_app/views/location_views/map_selection_widget.dart'; import 'package:mc_common_app/widgets/dialog/dialogs.dart'; import 'package:mc_common_app/widgets/dialog/message_dialog.dart'; import 'package:mc_common_app/widgets/dialog/otp_dialog.dart'; import 'package:mc_common_app/widgets/tab/login_email_tab.dart'; +import 'package:provider/provider.dart'; class UserVM extends BaseVM { final UserRepo userRepo; @@ -673,7 +677,10 @@ class UserVM extends BaseVM { AppState().getUser.data!.userInfo!.userLocalImage = null; AppState().getUser.data!.userInfo!.userImageUrl = null; } + AppState().setUser = null; AppState().setproviderSubscription = null; + context.read().mySubscriptionsBySp.clear(); + context.read().allSubscriptions = SubscriptionModel(); navigateReplaceWithNameUntilRoute(context, AppRoutes.registerSelection); } } diff --git a/lib/views/advertisement/select_ad_type_view.dart b/lib/views/advertisement/select_ad_type_view.dart index 9936850..ee4d0a2 100644 --- a/lib/views/advertisement/select_ad_type_view.dart +++ b/lib/views/advertisement/select_ad_type_view.dart @@ -1,8 +1,10 @@ import 'dart:developer'; +import 'package:flutter/gestures.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/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'; @@ -10,6 +12,7 @@ import 'package:mc_common_app/models/advertisment_models/vehicle_details_models. 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/enums.dart'; +import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/view_models/ad_view_model.dart'; import 'package:mc_common_app/views/advertisement/bottom_sheets/ad_duration_selection_sheet.dart'; import 'package:mc_common_app/widgets/bottom_sheet.dart'; @@ -76,7 +79,6 @@ class SelectAdTypeView extends StatelessWidget { if (adVM.isAdEditEnabled) { adVM.autoFillSelectedVehicleAdsDetails(); } - log("isUpdateAdSelected: ${adVM.isAdEditEnabled}}"); showMyBottomSheet(context, child: AdDurationSelectionSheet(isUpdateAdSelected: adVM.isAdEditEnabled, isFromExtendAd: isFromExtendAd, adsID: adsId)); }, child: SizedBox( @@ -147,27 +149,33 @@ class SelectAdTypeView extends StatelessWidget { children: [ Row( children: [ - "$remainingAds of $totalAds ".toText(fontSize: 29, isBold: true, letterSpacing: 0, height: 1), - LocaleKeys.adsRemainingVar.tr().toText(fontSize: 17, color: MyColors.lightTextColor, isBold: true), + "$remainingAds ".toText(fontSize: 29, isBold: true, letterSpacing: 0, height: 1), + LocaleKeys.adsRemaining.tr().toText(fontSize: 17, color: MyColors.lightTextColor, isBold: true), ], ), Text.rich( TextSpan( children: [ TextSpan( - text: LocaleKeys.youLeftAdsGivenSubscription.tr(), - style: const TextStyle( - fontSize: 14, - color: MyColors.lightTextColor, - )), + text: LocaleKeys.youLeftAdsGivenSubscription.tr(), + style: const TextStyle( + fontSize: 14, + color: MyColors.lightTextColor, + ), + ), TextSpan( - text: LocaleKeys.updateSubscription.tr(), - style: const TextStyle( - decoration: TextDecoration.underline, - fontSize: 14, - fontWeight: FontWeight.w600, - color: MyColors.darkPrimaryColor, - )) + text: " ${LocaleKeys.updateSubscription.tr()}", + recognizer: TapGestureRecognizer() + ..onTap = () { + navigateWithName(context, AppRoutes.mySubscriptionsPage); + }, + style: const TextStyle( + decoration: TextDecoration.underline, + fontSize: 14, + fontWeight: FontWeight.w600, + color: MyColors.darkPrimaryColor, + ), + ) ], ), ), diff --git a/lib/views/profile/profile_view.dart b/lib/views/profile/profile_view.dart index be4495c..fbf1e91 100644 --- a/lib/views/profile/profile_view.dart +++ b/lib/views/profile/profile_view.dart @@ -101,7 +101,7 @@ class _ProfileScreenState extends State { ), CustomProfileOptionsTile( titleText: LocaleKeys.phone.tr(), - subtitleText: "${AppState().getUser.data!.userInfo!.email}", + subtitleText: "${AppState().getUser.data!.userInfo!.mobileNo}", needBorderBelow: true, onTap: () { Navigator.pushNamed(context, AppRoutes.changeMobilePage); diff --git a/lib/views/user/register_provider_page.dart b/lib/views/user/register_provider_page.dart index e6805c0..aa9cb5a 100644 --- a/lib/views/user/register_provider_page.dart +++ b/lib/views/user/register_provider_page.dart @@ -62,6 +62,7 @@ class _RegisterPageState extends State { @override Widget build(BuildContext context) { + log("role: ${role}"); return Scaffold( appBar: const CustomAppBar(isRemoveBackButton: false, title: ""), body: Container( @@ -79,7 +80,6 @@ class _RegisterPageState extends State { letterSpacing: -1.44, ), 20.height, - LocaleKeys.enterPhoneNumber.tr().toText( color: MyColors.lightTextColor, textAlign: TextAlign.center, @@ -100,7 +100,7 @@ class _RegisterPageState extends State { role = snapshot.data?.data?.first.id ?? -1; } return RoleTypeTab( - 0, + role == 6 ? 1 : 0, dropList, onSelect: (DropValue value) { role = value.id; @@ -118,12 +118,8 @@ class _RegisterPageState extends State { if (snapshot.hasData) { List dropList = []; snapshot.data?.data?.forEach((element) { - dropList.add(DropValue( - element.id ?? 0, - EasyLocalization.of(context)?.currentLocale?.countryCode == "SA" - ? (element.countryNameN ?? "") + " " + (element.countryCode ?? "") - : (element.countryName ?? "") + " " + (element.countryCode ?? ""), - element.countryCode ?? "")); + dropList.add(DropValue(element.id ?? 0, + EasyLocalization.of(context)?.currentLocale?.countryCode == "SA" ? "${element.countryNameN ?? ""} ${element.countryCode ?? ""}" : "${element.countryName ?? ""} ${element.countryCode ?? ""}", element.countryCode ?? "")); }); return Column( children: [ @@ -143,12 +139,12 @@ class _RegisterPageState extends State { }, dropdownValue: selectedDrop, list: dropList, - hint: LocaleKeys.chooseCountry .tr(), + hint: LocaleKeys.chooseCountry.tr(), ), ], ); } else { - return CircularProgressIndicator(); + return const CircularProgressIndicator(); } }, ), @@ -169,7 +165,7 @@ class _RegisterPageState extends State { child: Row( children: [ Text( - (countryCode.isEmpty ? "+00" : "+" + countryCode), + (countryCode.isEmpty ? "+00" : "+$countryCode"), style: const TextStyle( fontSize: 20, color: MyColors.black, diff --git a/lib/widgets/common_widgets/add_phone_num_wiget.dart b/lib/widgets/common_widgets/add_phone_num_wiget.dart new file mode 100644 index 0000000..3b5b7a3 --- /dev/null +++ b/lib/widgets/common_widgets/add_phone_num_wiget.dart @@ -0,0 +1,139 @@ +import 'dart:async'; + +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.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/country.dart'; +import 'package:mc_common_app/theme/colors.dart'; +import 'package:mc_common_app/utils/navigator.dart'; +import 'package:mc_common_app/utils/utils.dart'; +import 'package:mc_common_app/view_models/user_view_model.dart'; +import 'package:mc_common_app/widgets/button/show_fill_button.dart'; +import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart'; +import 'package:mc_common_app/widgets/txt_field.dart'; +import 'package:provider/provider.dart'; + +class AddPhoneNumWidget extends StatefulWidget { + const AddPhoneNumWidget({Key? key}) : super(key: key); + + @override + State createState() => _AddPhoneNumWidgetState(); +} + +class _AddPhoneNumWidgetState extends State { + String phoneNum = "", countryCode = ""; + late UserVM userVM; + Country? _country; + + @override + void initState() { + super.initState(); + + scheduleMicrotask(() { + userVM = Provider.of(context, listen: false); + getCountryList(); + }); + } + + getCountryList() async { + _country = await userVM.getAllCountries(); + setState(() {}); + } + + @override + Widget build(BuildContext context) { + return Padding( + padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), + child: Container( + width: double.infinity, + padding: const EdgeInsets.only(left: 16, right: 16, bottom: 16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + "Enter Phone Number".toText(fontSize: 16, isBold: true), + 8.height, + getCountry(context), + 8.height, + TxtField( + keyboardType: TextInputType.phone, + hint: "546758594", + value: phoneNum, + isSidePaddingZero: true, + onChanged: (v) { + phoneNum = v; + }, + ), + 16.height, + Row( + children: [ + Expanded( + child: ShowFillButton( + title: "Cancel", + backgroundColor: MyColors.greyButtonColor, + txtColor: Colors.black, + onPressed: () { + pop(context); + }, + ), + ), + 12.width, + Expanded( + child: ShowFillButton( + title: LocaleKeys.sendOTP.tr(), + onPressed: () { + //User Role: Dealer|Manager for a branch + FocusScope.of(context).unfocus(); + if (validation()) { + userVM.performBasicOtpRegisterPage(context, countryCode: countryCode, phoneNum: phoneNum, role: 7, isNeedToPassToken: true, reloadPage: () { + pop(context); + }); + } + }, + ), + ), + ], + ) + ], + ), + ), + ); + } + + Widget getCountry(BuildContext context) { + if (_country != null) { + List dropList = []; + _country!.data?.forEach((element) { + dropList.add(DropValue(element.id ?? 0, "${element.countryName ?? ""} ${element.countryCode ?? ""}", element.countryCode ?? "")); + }); + return DropdownField( + (DropValue value) { + countryCode = value.subValue; + }, + list: dropList, + hint: countryCode.isNotEmpty ? countryCode.toString() : LocaleKeys.selectCountryCode.tr(), + ); + } else { + return const Center( + child: CircularProgressIndicator(), + ); + } + } + + bool validation() { + bool isValid = true; + if (countryCode.isEmpty) { + Utils.showToast(LocaleKeys.selectCountryCode.tr()); + //("Please select Country Code"); + isValid = false; + } else if (phoneNum.isEmpty) { + Utils.showToast(LocaleKeys.addPhoneNo.tr()); + //("Please add Phone No"); + isValid = false; + } + return isValid; + } +}