import 'package:eatvio_app/core/data/selectionPopupModel/selection_popup_model.dart'; import 'package:eatvio_app/core/utils/date_time_utils.dart'; import 'package:eatvio_app/core/widgets/custom_drop_down.dart'; import 'package:eatvio_app/core/widgets/loader.dart'; import 'package:eatvio_app/features/create_diet/presentation/widgets/error_widget.dart'; import 'package:eatvio_app/features/settings/entities/settings_entity.dart'; import 'package:eatvio_app/features/settings/presentation/bloc/settings_cubit/settings_state.dart'; import 'package:eatvio_app/generated/l10n.dart'; import 'package:eatvio_app/core/theme/theme_helper.dart'; import 'package:eatvio_app/core/widgets/custom_text_form_field.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class GeneralInfoScreen extends StatefulWidget { final SettingsEntity settingsEntity; const GeneralInfoScreen({super.key, required this.settingsEntity}); @override State createState() => _GeneralInfoScreenState(); } class _GeneralInfoScreenState extends State { final firstNameController = TextEditingController(); final lastNameController = TextEditingController(); late DateTime selectedDate; late SelectionPopupModel gender; final countryController = TextEditingController(); final cityController = TextEditingController(); final languageController = TextEditingController(); late SelectionPopupModel isPublicProfile; bool isLoading = false; bool isNameMissing = false; bool isLastNameMissing = false; bool isLanguageMissing = false; final List genderSelectionPopupList = [ const SelectionPopupModel(id: 0, title: 'Женский', value: 'female'), const SelectionPopupModel(id: 1, title: 'Мужской', value: 'male'), ]; final List isPublicProfileSelectionPopupList = [ const SelectionPopupModel(id: 0, title: 'Только зарегистрированным', value: false), const SelectionPopupModel(id: 1, title: 'Всем', value: true), ]; @override void initState() { super.initState(); selectedDate = DateTime.now(); firstNameController.text = widget.settingsEntity.profileDetailsModel.firstName; lastNameController.text = widget.settingsEntity.profileDetailsModel.lastName; selectedDate = DateTime.parse(widget.settingsEntity.profileDetailsModel.birthdate); gender = widget.settingsEntity.profileDetailsModel.gender == 'male' ? genderSelectionPopupList[1] : genderSelectionPopupList[0]; countryController.text = widget.settingsEntity.profileDetailsModel.country; cityController.text = widget.settingsEntity.profileDetailsModel.city; languageController.text = widget.settingsEntity.profileDetailsModel.lang; isPublicProfile = widget.settingsEntity.profileSettingsModel.isPublicProfile == true ? isPublicProfileSelectionPopupList[1] : isPublicProfileSelectionPopupList[0]; } @override Widget build(BuildContext context) { final s = S.of(context); return Scaffold( appBar: AppBar(title: const Text('Общая информация')), bottomSheet: SafeArea( top: false, child: Padding( padding: const EdgeInsets.only(bottom: 56), // высота bottomNavigationBar child: _saveButton(), ), ), body: SingleChildScrollView( physics: const BouncingScrollPhysics(), padding: const EdgeInsets.all(16) + const EdgeInsets.only(bottom: 120), // 52 (кнопка) + 56 (навигация) + 12 (отступ) child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(s.first_name), const SizedBox(height: 4), Column( children: [ CustomTextFormField(hasError: isNameMissing, controller: firstNameController, hintText: 'Введите имя', onChanged: (newValue) {}), if (isNameMissing) ...[const SizedBox(height: 4), const ValidationErrorWidget(error: 'Имя не может быть пустым')], ], ), const SizedBox(height: 16), Text(s.last_name), const SizedBox(height: 4), Column( children: [ CustomTextFormField(hasError: isLastNameMissing, controller: lastNameController, hintText: 'Введите фамилию', onChanged: (newValue) {}), if (isLastNameMissing) ...[const SizedBox(height: 4), const ValidationErrorWidget(error: 'Фамилия не может быть пустой')], ], ), const SizedBox(height: 16), Text(s.date_of_birth), const SizedBox(height: 4), ListTile( onTap: onTapCalendar(context), trailing: Icon(Icons.keyboard_arrow_down_rounded, color: Colors.grey.shade700), contentPadding: const EdgeInsets.symmetric(horizontal: 12), title: Text(selectedDate.format('dd MMMM yyyy', 'ru')), tileColor: const Color(0xFFF6F6F6), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), ), const SizedBox(height: 16), const Text('Пол'), const SizedBox(height: 4), CustomDropDown( items: genderSelectionPopupList, value: gender, onChanged: (newValue) { setState(() { gender = newValue; }); }, ), const SizedBox(height: 16), const Text('Страна'), const SizedBox(height: 4), CustomTextFormField(controller: countryController), const SizedBox(height: 16), const Text('Город'), const SizedBox(height: 4), CustomTextFormField(controller: cityController), const SizedBox(height: 16), const Text('Предпочтительный язык общения'), const SizedBox(height: 4), Column( children: [ CustomTextFormField(hasError: isLanguageMissing, controller: languageController), if (isLanguageMissing) ...[const SizedBox(height: 4), const ValidationErrorWidget(error: 'Язык не может быть пустым')], ], ), const SizedBox(height: 16), const Text('Показывать анкету'), const SizedBox(height: 4), CustomDropDown( items: isPublicProfileSelectionPopupList, value: isPublicProfile, onChanged: (newValue) { setState(() { isPublicProfile = newValue; }); }, ), ], ), ), ); } Null Function() onTapCalendar(BuildContext context) { return () { _showDialog( CupertinoDatePicker( initialDateTime: selectedDate, maximumDate: DateTime.now(), minimumDate: DateTime(1900), mode: CupertinoDatePickerMode.date, onDateTimeChanged: (DateTime newDateTime) { setState(() { selectedDate = newDateTime; }); }, ), ); }; } void _showDialog(Widget child) { showCupertinoModalPopup( context: context, builder: (BuildContext context) => Container( height: 216, padding: const EdgeInsets.only(top: 6), margin: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), color: CupertinoColors.systemBackground.resolveFrom(context), child: SafeArea(top: false, child: child), ), ); } bool _checkFields() { bool hasError = false; if (firstNameController.text.isEmpty) { setState(() { isNameMissing = true; }); hasError = true; } else { setState(() { isNameMissing = false; }); } if (lastNameController.text.isEmpty) { setState(() { isLastNameMissing = true; }); hasError = true; } else { setState(() { isLastNameMissing = false; }); } if (languageController.text.isEmpty) { setState(() { isLanguageMissing = true; }); hasError = true; } else { setState(() { isLanguageMissing = false; }); } return hasError; } Widget _saveButton() { return isLoading ? const Center(child: Loader()) : InkWell( onTap: () async { final hasError = _checkFields(); if (hasError) { return; } setState(() { isLoading = true; }); await widget.settingsEntity.settingsCubit.updateProfileDetails( profileDetailsModel: (widget.settingsEntity.settingsCubit.state as SettingsStateLoaded).profileDetails.copyWith( firstName: firstNameController.text, lastName: lastNameController.text, birthdate: selectedDate.toString(), gender: gender.value, country: countryController.text, city: cityController.text, lang: languageController.text, ), ); await widget.settingsEntity.settingsCubit.updateProfileSettings( profileSettingsModel: (widget.settingsEntity.settingsCubit.state as SettingsStateLoaded).profileSettings.copyWith( isPublicProfile: isPublicProfile.value, ), ); setState(() { isLoading = false; }); }, borderRadius: BorderRadius.circular(20), child: Ink( height: 52, width: MediaQuery.of(context).size.width - 32, decoration: BoxDecoration(borderRadius: BorderRadius.circular(20), color: appTheme.blueA400), child: const Center( child: Text( 'Сохранить', style: TextStyle(color: Colors.white, height: 1, fontWeight: FontWeight.w600, fontSize: 18), ), ), ), ); } }