diff --git a/lib/core/locator_service.dart b/lib/core/locator_service.dart index 971ebb2c..e4a13866 100644 --- a/lib/core/locator_service.dart +++ b/lib/core/locator_service.dart @@ -137,7 +137,7 @@ Future init() async { sl.registerFactory(() => DietsCubit(feedRepository: sl(), dietsRepository: sl())); sl.registerFactory(() => CommentsCubit(feedRepository: sl(), commentsRepository: sl())); sl.registerFactory(() => PlansCubit(feedRepository: sl(), planRepository: sl())); - sl.registerFactory(() => SettingsCubit(profileRepository: sl(), settingsRepository: sl(), consultantRepository: sl())); + sl.registerFactory(() => SettingsCubit(profileRepository: sl(), settingsRepository: sl(), consultantRepository: sl(), consultationsRepository: sl())); sl.registerFactory(() => RegisterConsultantCubit(consultantRepository: sl())); sl.registerFactory( () => DiaryCubit( diff --git a/lib/features/finances_and_consultations_archive/presentation/user_purchases_screen.dart b/lib/features/finances_and_consultations_archive/presentation/user_purchases_screen.dart index 6f137211..67d4652f 100644 --- a/lib/features/finances_and_consultations_archive/presentation/user_purchases_screen.dart +++ b/lib/features/finances_and_consultations_archive/presentation/user_purchases_screen.dart @@ -33,21 +33,12 @@ class _UserPurchasesScreen extends State { return Scaffold( backgroundColor: const Color(0xFFF0F2F5), appBar: AppBar( - shape: const RoundedRectangleBorder( - borderRadius: BorderRadiusDirectional.vertical( - bottom: Radius.circular(12), - ), - ), - title: Text( - 'Финансы', - style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black), - ), + shape: const RoundedRectangleBorder(borderRadius: BorderRadiusDirectional.vertical(bottom: Radius.circular(12))), + title: Text('Финансы', style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black)), centerTitle: true, ), body: state.isLoading - ? const Center( - child: Loader(), - ) + ? const Center(child: Loader()) : SingleChildScrollView( padding: const EdgeInsets.symmetric(vertical: 8), child: Column( @@ -67,10 +58,7 @@ class _UserPurchasesScreen extends State { .map( (value) => DropdownMenuItem( value: value, - child: Text( - value.name, - style: TextStyles.textMMedium.copyWith(color: appTheme.black), - ), + child: Text(value.name, style: TextStyles.textMMedium.copyWith(color: appTheme.black)), ), ) .toList(), @@ -105,60 +93,41 @@ class _UserPurchasesScreen extends State { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Builder(builder: (context) { - final idLen = state.purchasesModels[index].bankId.length; - return Text( - '${state.purchasesModels[index].bankId.substring(0, 4)}...${state.purchasesModels[index].bankId.substring(idLen - 4, idLen)} ', - style: TextStyles.textSMedium.copyWith(color: appTheme.black), - ); - }), + Builder( + builder: (context) { + final idLen = state.purchasesModels[index].bankId.length; + return Text( + '${state.purchasesModels[index].bankId.substring(0, 4)}...${state.purchasesModels[index].bankId.substring(idLen - 4, idLen)} ', + style: TextStyles.textSMedium.copyWith(color: appTheme.black), + ); + }, + ), Text( - state.purchasesModels[index].startDate.format('yyyy.MM.dd'), - style: const TextStyle( - color: Color(0xFF6D6F71), - height: 1, - fontWeight: FontWeight.w500, - ), + state.purchasesModels[index].startDate.format('dd.MM.yyyy'), + style: const TextStyle(color: Color(0xFF6D6F71), height: 1, fontWeight: FontWeight.w500), ), ], ), const SizedBox(height: 8), Text( state.purchasesModels[index].title, - style: TextStyle( - color: appTheme.blueA400, - height: 1, - fontSize: 18, - fontWeight: FontWeight.w600, - ), + style: TextStyle(color: appTheme.blueA400, height: 1, fontSize: 18, fontWeight: FontWeight.w600), ), const SizedBox(height: 8), Text( 'Продавец: ${state.purchasesModels[index].consultantName}', - style: const TextStyle( - color: Color(0xFF323F4B), - height: 1, - fontSize: 14, - fontWeight: FontWeight.w500, - ), + style: const TextStyle(color: Color(0xFF323F4B), height: 1, fontSize: 14, fontWeight: FontWeight.w500), ), const SizedBox(height: 8), Text( '${state.purchasesModels[index].duration} ${getDayForm(state.purchasesModels[index].duration, s)}', - style: const TextStyle( - color: Color(0xFF323F4B), - height: 1, - fontSize: 14, - fontWeight: FontWeight.w500, - ), + style: const TextStyle(color: Color(0xFF323F4B), height: 1, fontSize: 14, fontWeight: FontWeight.w500), ), const SizedBox(height: 8), Container( height: 1, width: double.infinity, - decoration: const BoxDecoration( - color: Color(0xFFDEDEDF), - ), + decoration: const BoxDecoration(color: Color(0xFFDEDEDF)), ), const SizedBox(height: 8), Row( @@ -166,16 +135,9 @@ class _UserPurchasesScreen extends State { children: [ Text( '${state.purchasesModels[index].paymentPrice} ₽', - style: const TextStyle( - color: Color(0xFF323F4B), - height: 1, - fontSize: 18, - fontWeight: FontWeight.w600, - ), - ), - StatusWidget( - status: purchaseStatus, + style: const TextStyle(color: Color(0xFF323F4B), height: 1, fontSize: 18, fontWeight: FontWeight.w600), ), + StatusWidget(status: purchaseStatus), ], ), ], @@ -189,10 +151,7 @@ class _UserPurchasesScreen extends State { else const Padding( padding: EdgeInsets.symmetric(vertical: 40.0), - child: Text( - 'У вас нет таких консультаций', - style: TextStyles.textMMedium, - ), + child: Text('У вас нет таких консультаций', style: TextStyles.textMMedium), ), ], ), @@ -200,7 +159,8 @@ class _UserPurchasesScreen extends State { ), ), ], - )), + ), + ), ); }, ), diff --git a/lib/features/settings/presentation/bloc/settings_cubit/settings_cubit.dart b/lib/features/settings/presentation/bloc/settings_cubit/settings_cubit.dart index ae498824..2a64e2e9 100644 --- a/lib/features/settings/presentation/bloc/settings_cubit/settings_cubit.dart +++ b/lib/features/settings/presentation/bloc/settings_cubit/settings_cubit.dart @@ -1,5 +1,7 @@ import 'package:eatvio_app/features/consultant/become_consultant/models/consultation_request_model.dart'; import 'package:eatvio_app/features/consultant/become_consultant/repositories/consultant_repository.dart'; +import 'package:eatvio_app/features/consultations/repositories/consultations_repository.dart'; +import 'package:eatvio_app/features/plans/enums/chosen_plan_state_enum.dart'; import 'package:eatvio_app/features/profile/models/profile_model.dart'; import 'package:eatvio_app/features/profile/repositories/profile_repository.dart'; import 'package:eatvio_app/features/settings/models/profile_settings_model.dart'; @@ -11,16 +13,20 @@ class SettingsCubit extends Cubit { final ProfileRepository profileRepository; final SettingsRepository settingsRepository; final ConsultantRepository consultantRepository; + final ConsultationsRepository consultationsRepository; SettingsCubit({ - required this.profileRepository, - required this.settingsRepository, + required this.profileRepository, + required this.settingsRepository, required this.consultantRepository, + required this.consultationsRepository, }) : super(const SettingsState.loading()); Future init() async { final profile = await profileRepository.getMyProfile(); late final ConsultationRequestModel? consultantInfo; + late final bool hasActiveConsultation; + try { if (profile.phoneConfirmationState.contains('confirmed')) { consultantInfo = await consultantRepository.getMyRequestStatus(profile.slug); @@ -30,6 +36,13 @@ class SettingsCubit extends Cubit { } catch (e) { consultantInfo = null; } + + try { + hasActiveConsultation = await _checkActiveConsultation(); + } catch (e) { + hasActiveConsultation = false; + } + try { emit( SettingsState.loaded( @@ -37,6 +50,7 @@ class SettingsCubit extends Cubit { profileDetails: await profileRepository.getMyProfileDetails(), profile: profile, consultationRequestModel: consultantInfo, + hasActiveConsultation: hasActiveConsultation, ), ); } catch (e) { @@ -44,13 +58,9 @@ class SettingsCubit extends Cubit { } } - Future updateProfileDetails({ - required ProfileDetailsModel profileDetailsModel, - }) async { + Future updateProfileDetails({required ProfileDetailsModel profileDetailsModel}) async { try { - await settingsRepository.updateProfileDetails( - profileDetailsModel: profileDetailsModel, - ); + await settingsRepository.updateProfileDetails(profileDetailsModel: profileDetailsModel); } catch (e) { rethrow; } finally { @@ -58,13 +68,9 @@ class SettingsCubit extends Cubit { } } - Future updateProfileSettings({ - required ProfileSettingsModel profileSettingsModel, - }) async { + Future updateProfileSettings({required ProfileSettingsModel profileSettingsModel}) async { try { - await settingsRepository.updateProfileSettings( - profileSettingsModel: profileSettingsModel, - ); + await settingsRepository.updateProfileSettings(profileSettingsModel: profileSettingsModel); } catch (e) { rethrow; } finally { @@ -80,4 +86,17 @@ class SettingsCubit extends Cubit { return false; } } + + Future _checkActiveConsultation() async { + try { + final userPurchases = await consultationsRepository.getUserPurchases(null, null); + final activeStates = ChosenPlanStateEnum.getActiveStates(); + + return userPurchases.any((purchase) => + activeStates.contains(purchase.chosenPlanState) + ); + } catch (e) { + return false; + } + } } diff --git a/lib/features/settings/presentation/bloc/settings_cubit/settings_state.dart b/lib/features/settings/presentation/bloc/settings_cubit/settings_state.dart index f220fe5e..86471f31 100644 --- a/lib/features/settings/presentation/bloc/settings_cubit/settings_state.dart +++ b/lib/features/settings/presentation/bloc/settings_cubit/settings_state.dart @@ -16,6 +16,7 @@ abstract class SettingsState with _$SettingsState { required ProfileDetailsModel profileDetails, required ProfileModel profile, ConsultationRequestModel? consultationRequestModel, + required bool hasActiveConsultation, }) = SettingsStateLoaded; const factory SettingsState.error({ diff --git a/lib/features/settings/presentation/pages/settings_screen.dart b/lib/features/settings/presentation/pages/settings_screen.dart index 1c304f29..ad42a7b4 100644 --- a/lib/features/settings/presentation/pages/settings_screen.dart +++ b/lib/features/settings/presentation/pages/settings_screen.dart @@ -32,6 +32,24 @@ class _SettingsScreenState extends State { late bool bedTimeSwitchState; late bool moodSwitchState; + void _showConsultationWarning() { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: const Text('Предупреждение'), + content: const Text('Во время консультации этот параметр нельзя отключить'), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text('Понятно'), + ), + ], + ); + }, + ); + } + @override Widget build(BuildContext context) { return BlocProvider( @@ -58,8 +76,8 @@ class _SettingsScreenState extends State { children: [ _additionalInfo(state), const SizedBox(height: 12), - // _notifications(state), - // const SizedBox(height: 12), + _notifications(state), + const SizedBox(height: 12), _becomeConsultantButton(state), _deleteAccountButton(state, settingsCubit), ], @@ -147,76 +165,35 @@ class _SettingsScreenState extends State { ); } - // ignore: unused_element Column _notifications(SettingsStateLoaded state) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Padding( padding: EdgeInsets.symmetric(horizontal: 16), - child: Text('Уведомления', style: TextStyle(fontSize: 16, height: 1, color: Colors.grey)), + child: Text('При использовании дневника', style: TextStyle(fontSize: 16, height: 1, color: Colors.grey)), ), _tile( padding: const EdgeInsets.symmetric(horizontal: 16), onTap: () { - setState(() { - updatesNotificationsSwitchState = !updatesNotificationsSwitchState; - }); - settingsCubit.updateProfileSettings(profileSettingsModel: state.profileSettings.copyWith(newUpdatesNotifications: updatesNotificationsSwitchState)); - }, - title: 'Уведомление о новых обновлениях', - trailing: CupertinoSwitch( - value: updatesNotificationsSwitchState, - activeTrackColor: appTheme.blueA400, - onChanged: (newValue) { - setState(() { - updatesNotificationsSwitchState = newValue; - }); - settingsCubit.updateProfileSettings( - profileSettingsModel: state.profileSettings.copyWith(newUpdatesNotifications: updatesNotificationsSwitchState), - ); - }, - ), - ), - _divider(context), - _tile( - padding: const EdgeInsets.symmetric(horizontal: 16), - onTap: () { - setState(() { - fillDiaryNotificationsSwitchState = !fillDiaryNotificationsSwitchState; - }); - settingsCubit.updateProfileSettings( - profileSettingsModel: state.profileSettings.copyWith(diaryReminderNotifications: fillDiaryNotificationsSwitchState), - ); - }, - title: 'Напоминание о заполнении дневника', - trailing: CupertinoSwitch( - value: fillDiaryNotificationsSwitchState, - activeTrackColor: appTheme.blueA400, - onChanged: (newValue) { - setState(() { - fillDiaryNotificationsSwitchState = newValue; - }); - settingsCubit.updateProfileSettings( - profileSettingsModel: state.profileSettings.copyWith(diaryReminderNotifications: fillDiaryNotificationsSwitchState), - ); - }, - ), - ), - _divider(context), - _tile( - padding: const EdgeInsets.symmetric(horizontal: 16), - onTap: () { + if (state.hasActiveConsultation) { + _showConsultationWarning(); + return; + } setState(() { moodSwitchState = !moodSwitchState; }); settingsCubit.updateProfileSettings(profileSettingsModel: state.profileSettings.copyWith(isMoodFillable: moodSwitchState)); }, - title: 'Указывать “настроение” в заполнение дневника', + title: 'Указывать "настроение" в заполнение дневника', trailing: CupertinoSwitch( - value: moodSwitchState, + value: state.hasActiveConsultation ? true : moodSwitchState, activeTrackColor: appTheme.blueA400, onChanged: (newValue) { + if (state.hasActiveConsultation) { + _showConsultationWarning(); + return; + } setState(() { moodSwitchState = newValue; }); @@ -228,16 +205,24 @@ class _SettingsScreenState extends State { _tile( padding: const EdgeInsets.symmetric(horizontal: 16), onTap: () { + if (state.hasActiveConsultation) { + _showConsultationWarning(); + return; + } setState(() { bedTimeSwitchState = !bedTimeSwitchState; }); settingsCubit.updateProfileSettings(profileSettingsModel: state.profileSettings.copyWith(isBedtimeFillable: bedTimeSwitchState)); }, - title: 'Указывать “отход ко сну” в заполнение дневника', + title: 'Указывать "отход ко сну" в заполнение дневника', trailing: CupertinoSwitch( - value: bedTimeSwitchState, + value: state.hasActiveConsultation ? true : bedTimeSwitchState, activeTrackColor: appTheme.blueA400, onChanged: (newValue) { + if (state.hasActiveConsultation) { + _showConsultationWarning(); + return; + } setState(() { bedTimeSwitchState = newValue; });