import 'package:eatvio_app/core/const.dart'; import 'package:eatvio_app/core/widgets/data_error_widget.dart'; import 'package:eatvio_app/core/widgets/loader.dart'; import 'package:eatvio_app/features/settings/entities/settings_entity.dart'; import 'package:eatvio_app/features/settings/presentation/bloc/settings_cubit/settings_cubit.dart'; import 'package:eatvio_app/features/settings/presentation/bloc/settings_cubit/settings_state.dart'; import 'package:eatvio_app/core/locator_service.dart'; import 'package:eatvio_app/core/theme/theme_helper.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; import 'package:url_launcher/url_launcher.dart'; class SettingsScreen extends StatefulWidget { const SettingsScreen({super.key}); @override State createState() => _SettingsScreenState(); } class _SettingsScreenState extends State { final SettingsCubit settingsCubit = sl()..init(); late bool updatesNotificationsSwitchState; late bool fillDiaryNotificationsSwitchState; late bool bedTimeSwitchState; late bool moodSwitchState; @override Widget build(BuildContext context) { return BlocProvider( create: (BuildContext context) => settingsCubit, child: BlocConsumer( bloc: settingsCubit, listener: (BuildContext context, SettingsState state) { if (state is SettingsStateLoaded) { updatesNotificationsSwitchState = state.profileSettings.newUpdatesNotifications == 1 ? true : false; fillDiaryNotificationsSwitchState = state.profileSettings.diaryReminderNotifications == 1 ? true : false; bedTimeSwitchState = state.profileSettings.isBedtimeFillable; moodSwitchState = state.profileSettings.isMoodFillable; } }, builder: (BuildContext context, SettingsState state) { if (state is SettingsStateLoaded) { return Scaffold( appBar: AppBar( title: Text('Настройки'), ), body: SingleChildScrollView( padding: EdgeInsets.symmetric(vertical: 16), physics: const BouncingScrollPhysics(), child: Column( children: [ _additionalInfo(state), const SizedBox(height: 12), _notifications(state), const SizedBox(height: 12), _aboutEatvio(state), const SizedBox(height: 12), if (!state.profile.roles.contains('consultant')) Padding( padding: const EdgeInsets.only(bottom: 8), child: _becomeConsultantButton(state), ), _deleteAccountButton(state), ], ), ), ); } if (state is SettingsStateError) { return Scaffold( appBar: AppBar( title: Text('Настройки'), ), body: DataErrorWidget(onReload: () => settingsCubit.init()), ); } return Scaffold( appBar: AppBar( title: Text('Настройки'), ), body: Loader(), ); }, ), ); } _additionalInfo(SettingsStateLoaded state) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Text( 'Дополнительаная информация', style: TextStyle( fontSize: 16, height: 1, color: Colors.grey, fontFamily: 'Mulish', ), ), ), _tile( onTap: () => GoRouter.of(context).pushNamed( 'generalInfoScreen', extra: SettingsEntity( profileSettingsModel: state.profileSettings, profileDetailsModel: state.profileDetails, settingsCubit: settingsCubit, ), ), title: 'Общая информация', ), _divider(context), _tile( onTap: () => GoRouter.of(context).pushNamed( 'physicalFormScreen', extra: SettingsEntity( profileSettingsModel: state.profileSettings, profileDetailsModel: state.profileDetails, settingsCubit: settingsCubit, ), ), title: 'Физическая форма', ), _divider(context), _tile( onTap: () => GoRouter.of(context).pushNamed( 'pressureScreen', extra: SettingsEntity( profileSettingsModel: state.profileSettings, profileDetailsModel: state.profileDetails, settingsCubit: settingsCubit, ), ), title: 'Давление', ), _divider(context), _tile( onTap: () => GoRouter.of(context).pushNamed( 'otherInfoScreen', extra: SettingsEntity( profileSettingsModel: state.profileSettings, profileDetailsModel: state.profileDetails, settingsCubit: settingsCubit, ), ), title: 'Прочая информация', ), _divider(context), _tile( onTap: () => GoRouter.of(context).pushNamed( 'physicalActivityScreen', extra: SettingsEntity( profileSettingsModel: state.profileSettings, profileDetailsModel: state.profileDetails, settingsCubit: settingsCubit, ), ), title: 'Физическая нагрузка', ), _divider(context), _tile( onTap: () => GoRouter.of(context).pushNamed( 'changePasswordScreen', extra: SettingsEntity( profileSettingsModel: state.profileSettings, profileDetailsModel: state.profileDetails, settingsCubit: settingsCubit, ), ), title: 'Сменить пароль', ), _divider(context), _tile( onTap: () => GoRouter.of(context).pushNamed( 'changeEmailScreen', extra: SettingsEntity( profileSettingsModel: state.profileSettings, profileDetailsModel: state.profileDetails, settingsCubit: settingsCubit, ), ), title: 'Сменить Email', ), ], ); } _notifications(SettingsStateLoaded state) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Text( 'Уведомления', style: TextStyle( fontSize: 16, height: 1, color: Colors.grey, ), ), ), _tile( padding: 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: 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: EdgeInsets.symmetric(horizontal: 16), onTap: () { setState(() { moodSwitchState = !moodSwitchState; }); settingsCubit.updateProfileSettings( profileSettingsModel: state.profileSettings.copyWith( isMoodFillable: moodSwitchState, ), ); }, title: 'Указывать “настроение” в заполнение дневника', trailing: CupertinoSwitch( value: moodSwitchState, activeTrackColor: appTheme.blueA400, onChanged: (newValue) { setState(() { moodSwitchState = newValue; }); settingsCubit.updateProfileSettings( profileSettingsModel: state.profileSettings.copyWith( isMoodFillable: moodSwitchState, ), ); }, ), ), _divider(context), _tile( padding: EdgeInsets.symmetric(horizontal: 16), onTap: () { setState(() { bedTimeSwitchState = !bedTimeSwitchState; }); settingsCubit.updateProfileSettings( profileSettingsModel: state.profileSettings.copyWith( isBedtimeFillable: bedTimeSwitchState, ), ); }, title: 'Указывать “отход ко сну” в заполнение дневника', trailing: CupertinoSwitch( value: bedTimeSwitchState, activeTrackColor: appTheme.blueA400, onChanged: (newValue) { setState(() { bedTimeSwitchState = newValue; }); settingsCubit.updateProfileSettings( profileSettingsModel: state.profileSettings.copyWith( isBedtimeFillable: bedTimeSwitchState, ), ); }, ), ), ], ); } _aboutEatvio(SettingsStateLoaded state) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Text( 'О Eatvio', style: TextStyle( fontSize: 16, height: 1, color: Colors.grey, ), ), ), _tile( title: 'О компании', onTap: () async => await launchUrl(Uri.parse(baseUrl + '/ru/company-details')), ), _divider(context), _tile( title: 'Пользовательское соглашение', onTap: () async => await launchUrl(Uri.parse(baseUrl + '/oferta_bs.pdf')), ), ], ); } _becomeConsultantButton(SettingsStateLoaded state) { return Padding( padding: EdgeInsets.symmetric(horizontal: 16), child: InkWell( onTap: () => GoRouter.of(context).pushNamed('becomeConsultantScreen'), borderRadius: BorderRadius.circular(20), child: Ink( height: 52, width: MediaQuery.of(context).size.width - 16, decoration: BoxDecoration( borderRadius: BorderRadius.circular(20), color: appTheme.blueA400, ), child: Center( child: Text( 'Стать консультантом', style: TextStyle( color: Colors.white, height: 1, fontSize: 18, ), ), ), ), ), ); } _deleteAccountButton(SettingsStateLoaded state) { return Padding( padding: EdgeInsets.symmetric(horizontal: 16), child: InkWell( onTap: () {}, borderRadius: BorderRadius.circular(20), child: Ink( height: 52, width: MediaQuery.of(context).size.width - 16, decoration: BoxDecoration( borderRadius: BorderRadius.circular(20), color: Color(0xFFEAEAEA), ), child: Center( child: Text( 'Удалить аккаунт', style: TextStyle( color: Colors.black, height: 1, fontSize: 18, ), ), ), ), ), ); } _tile({ required String title, required Function() onTap, Widget? trailing, EdgeInsets? padding, }) { return ListTile( contentPadding: padding, onTap: onTap, title: Text( title, style: TextStyle( fontSize: 14, fontWeight: FontWeight.w500, height: 1, ), ), trailing: trailing ?? Icon( Icons.arrow_forward_ios_rounded, size: 12, color: Colors.black38, ), ); } _divider(BuildContext context) { return Center( child: Container( height: 0.4, width: MediaQuery.of(context).size.width - 32, decoration: BoxDecoration( color: Colors.black26, borderRadius: BorderRadius.circular(16), ), ), ); } }