diff --git a/lib/presentation/profile/my_profile_screen/bloc/my_profile_bloc.dart b/lib/presentation/profile/my_profile_screen/bloc/my_profile_bloc.dart index 26d8d916..b8e7c983 100644 --- a/lib/presentation/profile/my_profile_screen/bloc/my_profile_bloc.dart +++ b/lib/presentation/profile/my_profile_screen/bloc/my_profile_bloc.dart @@ -17,70 +17,120 @@ class MyProfileBloc extends Bloc { } Future _onInitialize( - MyProfileInitialEvent event, - Emitter emit, -) async { - try { - final box = await Hive.openBox('token'); - final token = box.get('token'); - final response = await http.get( - Uri.parse(dotenv.env['SERVER_ROOT']! + '/profile/index'), - headers: { - 'Authorization': 'Bearer $token', - }, - ); + MyProfileInitialEvent event, + Emitter emit, + ) async { + try { + final box = await Hive.openBox('token'); + final token = box.get('token'); + final response = await http.get( + Uri.parse(dotenv.env['SERVER_ROOT']! + '/profile/index'), + headers: { + 'Authorization': 'Bearer $token', + }, + ); - if (response.statusCode == 200) { - final data = jsonDecode(response.body); + if (response.statusCode == 200) { + final data = jsonDecode(response.body); - // Проверка наличия ключевых полей в JSON - if (data is Map && - data.containsKey('user') && - data.containsKey('userDetails') && - data.containsKey('chartPoints') && - data.containsKey('plans') && - data.containsKey('circumferences')) { - // Все ключевые поля присутствуют, продолжаем обработку - if (state is MyProfileLoadedState) { - // Если текущее состояние уже загружено, обновляем его - emit((state as MyProfileLoadedState).copyWith( - chartPoints: data['chartPoints'], - circumferences: data['circumferences'], - user: data['user'], - userDetails: data['userDetails'], - plans: data['plans'], - token: token, - chestCircumferenceController: TextEditingController(), - waistCircumferenceController: TextEditingController(), - hipCircumferenceController: TextEditingController(), - weightController: TextEditingController(), - )); + // Проверка наличия ключевых полей в JSON + if (data is Map && + data.containsKey('user') && + data.containsKey('userDetails') && + data.containsKey('chartPoints') && + data.containsKey('plans') && + data.containsKey('circumferences')) { + // Все ключевые поля присутствуют, продолжаем обработку + if (state is MyProfileLoadedState) { + // Если текущее состояние уже загружено, обновляем его + var currentState = state as MyProfileLoadedState; + // Обновляем значения контроллеров только если они уже были созданы + if (currentState.firstNameFormController != null && + data['userDetails'] != null) { + currentState.firstNameFormController!.text = 'asdasdasd'; + // Повторите для других контроллеров и полей данных + } + emit((currentState).copyWith( + chartPoints: data['chartPoints'], + circumferences: data['circumferences'], + user: data['user'], + userDetails: data['userDetails'], + plans: data['plans'], + token: token, + chestCircumferenceController: TextEditingController(), + waistCircumferenceController: TextEditingController(), + hipCircumferenceController: TextEditingController(), + weightController: TextEditingController(), + chestCircumferenceFormController: + currentState.chestCircumferenceFormController, + waistCircumferenceFormController: + currentState.waistCircumferenceFormController, + hipCircumferenceFormController: + currentState.hipCircumferenceFormController, + firstNameFormController: currentState.firstNameFormController, + lastNameFormController: currentState.lastNameFormController, + countryFormController: currentState.countryFormController, + cityFormController: currentState.cityFormController, + heightFormController: currentState.heightFormController, + upPressureFormController: currentState.upPressureFormController, + downPressureFormController: + currentState.downPressureFormController, + allergiesFormController: currentState.allergiesFormController, + pillsFormController: currentState.pillsFormController, + sportsFormController: currentState.sportsFormController, + )); + } else { + print(data['userDetails']); + // Если текущее состояние - начальное, создаем новое загруженное состояние + emit(MyProfileLoadedState( + chartPoints: data['chartPoints'], + circumferences: data['circumferences'], + user: data['user'], + userDetails: data['userDetails'], + plans: data['plans'], + token: token, + chestCircumferenceFormController: TextEditingController( + text: data['userDetails']['chest_circumference']?.toString()), + waistCircumferenceFormController: TextEditingController( + text: data['userDetails']['waist_circumference']?.toString()), + hipCircumferenceFormController: TextEditingController( + text: data['userDetails']['hip_circumference']?.toString()), + weightController: TextEditingController( + text: data['userDetails']['weight']?.toString()), + firstNameFormController: TextEditingController( + text: data['userDetails']['first_name']), + lastNameFormController: + TextEditingController(text: data['userDetails']['last_name']), + countryFormController: + TextEditingController(text: data['userDetails']['country']), + cityFormController: + TextEditingController(text: data['userDetails']['city']), + heightFormController: TextEditingController( + text: data['userDetails']['height']?.toString()), + upPressureFormController: TextEditingController( + text: data['userDetails']['blood_pressure_up']?.toString()), + downPressureFormController: TextEditingController( + text: data['userDetails']['blood_pressure_down']?.toString()), + allergiesFormController: + TextEditingController(text: data['userDetails']['allergies']), + pillsFormController: + TextEditingController(text: data['userDetails']['pills']), + sportsFormController: + TextEditingController(text: data['userDetails']['sports']), + )); + } } else { - // Если текущее состояние - начальное, создаем новое загруженное состояние - emit(MyProfileLoadedState( - chartPoints: data['chartPoints'], - circumferences: data['circumferences'], - user: data['user'], - userDetails: data['userDetails'], - plans: data['plans'], - token: token, - chestCircumferenceController: TextEditingController(), - waistCircumferenceController: TextEditingController(), - hipCircumferenceController: TextEditingController(), - weightController: TextEditingController(), - )); + // Один или несколько ключевых полей отсутствуют, обрабатываем ошибку + emit( + MyProfileErrorState('Некоторые необходимые данные отсутствуют.')); } } else { - // Один или несколько ключевых полей отсутствуют, обрабатываем ошибку - emit(MyProfileErrorState('Некоторые необходимые данные отсутствуют.')); + // Статус ответа не равен 200, обрабатываем ошибку + emit(MyProfileErrorState('Ошибка сервера: ${response.statusCode}')); } - } else { - // Статус ответа не равен 200, обрабатываем ошибку - emit(MyProfileErrorState('Ошибка сервера: ${response.statusCode}')); + } catch (e) { + // Ошибка при декодировании JSON или другая ошибка выполнения + emit(MyProfileErrorState('Ошибка при получении данных профиля: $e')); } - } catch (e) { - // Ошибка при декодировании JSON или другая ошибка выполнения - emit(MyProfileErrorState('Ошибка при получении данных профиля: $e')); } } -} \ No newline at end of file diff --git a/lib/presentation/profile/my_profile_screen/bloc/my_profile_state.dart b/lib/presentation/profile/my_profile_screen/bloc/my_profile_state.dart index 080deb63..55ed737e 100644 --- a/lib/presentation/profile/my_profile_screen/bloc/my_profile_state.dart +++ b/lib/presentation/profile/my_profile_screen/bloc/my_profile_state.dart @@ -1,6 +1,7 @@ // ignore_for_file: must_be_immutable part of 'my_profile_bloc.dart'; + class MyProfileState extends Equatable { const MyProfileState({this.myProfileModelObj}); @@ -11,8 +12,10 @@ class MyProfileState extends Equatable { } class MyProfileInitialState extends MyProfileState { - MyProfileInitialState({required MyProfileModel myProfileModelObj}) : super(myProfileModelObj: myProfileModelObj); + MyProfileInitialState({required MyProfileModel myProfileModelObj}) + : super(myProfileModelObj: myProfileModelObj); } + /// Represents the state of MyProfile in the application. class MyProfileLoadedState extends MyProfileState { MyProfileLoadedState( @@ -26,7 +29,22 @@ class MyProfileLoadedState extends MyProfileState { this.chartPoints, this.plans, this.token, - this.circumferences}) : super(myProfileModelObj: null); + this.chestCircumferenceFormController, + this.waistCircumferenceFormController, + this.hipCircumferenceFormController, + this.firstNameFormController, + this.lastNameFormController, + this.countryFormController, + this.cityFormController, + this.heightFormController, + this.weightFormController, + this.upPressureFormController, + this.downPressureFormController, + this.allergiesFormController, + this.pillsFormController, + this.sportsFormController, + this.circumferences}) + : super(myProfileModelObj: null); MyProfileModel? myProfileModelObj; Map? user; @@ -38,6 +56,20 @@ class MyProfileLoadedState extends MyProfileState { TextEditingController? chestCircumferenceController; TextEditingController? waistCircumferenceController; TextEditingController? hipCircumferenceController; + TextEditingController? weightFormController; + TextEditingController? chestCircumferenceFormController; + TextEditingController? waistCircumferenceFormController; + TextEditingController? hipCircumferenceFormController; + TextEditingController? firstNameFormController; + TextEditingController? lastNameFormController; + TextEditingController? countryFormController; + TextEditingController? cityFormController; + TextEditingController? heightFormController; + TextEditingController? upPressureFormController; + TextEditingController? downPressureFormController; + TextEditingController? allergiesFormController; + TextEditingController? pillsFormController; + TextEditingController? sportsFormController; String? token; @override @@ -51,7 +83,21 @@ class MyProfileLoadedState extends MyProfileState { chestCircumferenceController, waistCircumferenceController, hipCircumferenceController, - token + token, + chestCircumferenceFormController, + waistCircumferenceFormController, + hipCircumferenceFormController, + firstNameFormController, + lastNameFormController, + countryFormController, + cityFormController, + heightFormController, + weightFormController, + upPressureFormController, + downPressureFormController, + allergiesFormController, + pillsFormController, + sportsFormController, ]; MyProfileLoadedState copyWith({ MyProfileModel? myProfileModelObj, @@ -64,6 +110,18 @@ class MyProfileLoadedState extends MyProfileState { TextEditingController? chestCircumferenceController, TextEditingController? waistCircumferenceController, TextEditingController? hipCircumferenceController, + TextEditingController? chestCircumferenceFormController, + TextEditingController? waistCircumferenceFormController, + TextEditingController? hipCircumferenceFormController, + TextEditingController? firstNameFormController, + TextEditingController? lastNameFormController, + TextEditingController? countryFormController, + TextEditingController? cityFormController, + TextEditingController? heightFormController, + TextEditingController? weightFormeFormController, + TextEditingController? allergiesFormController, + TextEditingController? pillsFormController, + TextEditingController? sportsFormController, String? token, }) { return MyProfileLoadedState( @@ -80,6 +138,29 @@ class MyProfileLoadedState extends MyProfileState { waistCircumferenceController ?? this.waistCircumferenceController, hipCircumferenceController: hipCircumferenceController ?? this.hipCircumferenceController, + chestCircumferenceFormController: chestCircumferenceFormController ?? + this.chestCircumferenceFormController, + waistCircumferenceFormController: waistCircumferenceFormController ?? + this.waistCircumferenceFormController, + hipCircumferenceFormController: + hipCircumferenceFormController ?? this.hipCircumferenceFormController, + firstNameFormController: + firstNameFormController ?? this.firstNameFormController, + lastNameFormController: + lastNameFormController ?? this.lastNameFormController, + countryFormController: + countryFormController ?? this.countryFormController, + cityFormController: cityFormController ?? this.cityFormController, + heightFormController: heightFormController ?? this.heightFormController, + weightFormController: weightFormController ?? this.weightFormController, + upPressureFormController: + upPressureFormController ?? this.upPressureFormController, + downPressureFormController: + downPressureFormController ?? this.downPressureFormController, + allergiesFormController: + allergiesFormController ?? this.allergiesFormController, + pillsFormController: pillsFormController ?? this.pillsFormController, + sportsFormController: sportsFormController ?? this.sportsFormController, token: token ?? this.token, ); } @@ -92,4 +173,4 @@ class MyProfileErrorState extends MyProfileState { @override List get props => [errorMessage]; -} \ No newline at end of file +} diff --git a/lib/presentation/profile/my_profile_screen/my_settings_screen.dart b/lib/presentation/profile/my_profile_screen/my_settings_screen.dart index 51d5b078..f87a3d19 100644 --- a/lib/presentation/profile/my_profile_screen/my_settings_screen.dart +++ b/lib/presentation/profile/my_profile_screen/my_settings_screen.dart @@ -65,8 +65,8 @@ class MySettingsScreen extends StatelessWidget { NotificationSwitch('Уведомление о новых обновлениях'), NotificationSwitch('Напоминания о заполнении дневника'), SectionTitle('Дополнительная информация'), - ExpandableList('Персональные данные', userDetails), - ExpandableList('О нас', ['Контакты', 'Адрес']), + ExpandableList('Персональные данные'), + ExpandableList('О нас'), ], ), ), @@ -241,9 +241,8 @@ class _HypoHyperState extends State { class ExpandableList extends StatefulWidget { final String title; - final List items; - ExpandableList(this.title, this.items); + ExpandableList(this.title); @override _ExpandableListState createState() => _ExpandableListState(); @@ -280,86 +279,117 @@ class _ExpandableListState extends State { if (isExpanded) Padding( padding: const EdgeInsets.only(left: 16.0), - child: Column(children: [ - TextField( - decoration: InputDecoration(labelText: 'first_name'.tr), - ), - TextField( - decoration: InputDecoration(labelText: 'last_name'.tr), - ), - TextField( - decoration: InputDecoration(labelText: 'date_of_birth'.tr), - onTap: () {}, - ), - TextField( - decoration: InputDecoration(labelText: 'country'.tr), - ), - TextField( - decoration: InputDecoration(labelText: 'place_of_living'.tr), - ), - TextField( - decoration: - InputDecoration(labelText: 'weight_measurements'.tr), - keyboardType: TextInputType.number, - ), - TextField( - decoration: - InputDecoration(labelText: 'height_measurements'.tr), - keyboardType: TextInputType.number, - ), - TextField( - decoration: - InputDecoration(labelText: 'chest_circumference'.tr), - keyboardType: TextInputType.number, - ), - TextField( - decoration: - InputDecoration(labelText: 'waist_circumference'.tr), - keyboardType: TextInputType.number, - ), - TextField( - decoration: InputDecoration(labelText: 'hip_circumference'.tr), - keyboardType: TextInputType.number, - ), - TextField( - decoration: InputDecoration(labelText: 'up_pressure'.tr), - keyboardType: TextInputType.number, - ), - TextField( - decoration: InputDecoration(labelText: 'down_pressure'.tr), - keyboardType: TextInputType.number, - ), - TextField( - decoration: InputDecoration(labelText: 'allergies_presence'.tr), - maxLines: null, - ), - TextField( - decoration: InputDecoration(labelText: 'do_you_take_pills'.tr), - maxLines: null, - ), - TextField( - decoration: - InputDecoration(labelText: 'your_favorite_sports'.tr), - maxLines: null, - ), - Row( - children: [ - HypoHyperSwitch('do_you_have_hypotension_tendency'.tr), - ], - ), - Row( - children: [ - HypoHyperSwitch('do_you_have_hypertension_tendency'.tr), - ], - ), - NextStepButton( - buttonStyle: CustomButtonStyles.outlinePrimaryTL15, - text: "save".tr.toUpperCase(), - margin: EdgeInsets.only(top: 20.h, bottom: 20.h)), - ]), + child: BlocBuilder( + builder: (context, state) { + if (state is MyProfileInitialState) { + // Это начальное состояние, данные ещё не загружены. + return CircularProgressIndicator( + color: Colors.white, + backgroundColor: Colors.white, + ); + } else if (state is MyProfileLoadedState) { + // Данные загружены, можно строить форму. + return _buildForm(context, state); + } else if (state is MyProfileErrorState) { + // Произошла ошибка при загрузке данных. + return Center(child: Text(state.errorMessage)); + } else { + // Другие состояния, если они есть. + return Container(); // Пустой контейнер для необработанных состояний. + } + }), ), Divider(), ], ); } + + Widget _buildForm(BuildContext context, MyProfileLoadedState state) { + return Column(children: [ + TextField( + controller: state.firstNameFormController, + decoration: InputDecoration(labelText: 'first_name'.tr), + ), + TextField( + controller: state.lastNameFormController, + decoration: InputDecoration(labelText: 'last_name'.tr), + ), + TextField( + decoration: InputDecoration(labelText: 'date_of_birth'.tr), + onTap: () {}, + ), + TextField( + controller: state.countryFormController, + decoration: InputDecoration(labelText: 'country'.tr), + ), + TextField( + controller: state.cityFormController, + decoration: InputDecoration(labelText: 'place_of_living'.tr), + ), + TextField( + controller: state.weightFormController, + decoration: InputDecoration(labelText: 'weight_measurements'.tr), + keyboardType: TextInputType.number, + ), + TextField( + controller: state.heightFormController, + decoration: InputDecoration(labelText: 'height_measurements'.tr), + keyboardType: TextInputType.number, + ), + TextField( + controller: state.chestCircumferenceFormController, + decoration: InputDecoration(labelText: 'chest_circumference'.tr), + keyboardType: TextInputType.number, + ), + TextField( + controller: state.waistCircumferenceFormController, + decoration: InputDecoration(labelText: 'waist_circumference'.tr), + keyboardType: TextInputType.number, + ), + TextField( + controller: state.hipCircumferenceFormController, + decoration: InputDecoration(labelText: 'hip_circumference'.tr), + keyboardType: TextInputType.number, + ), + TextField( + controller: state.upPressureFormController, + decoration: InputDecoration(labelText: 'up_pressure'.tr), + keyboardType: TextInputType.number, + ), + TextField( + controller: state.downPressureFormController, + decoration: InputDecoration(labelText: 'down_pressure'.tr), + keyboardType: TextInputType.number, + ), + TextField( + controller: state.allergiesFormController, + decoration: InputDecoration(labelText: 'allergies_presence'.tr), + maxLines: null, + ), + TextField( + controller: state.pillsFormController, + decoration: InputDecoration(labelText: 'do_you_take_pills'.tr), + maxLines: null, + ), + TextField( + controller: state.sportsFormController, + decoration: InputDecoration(labelText: 'your_favorite_sports'.tr), + maxLines: null, + ), + Row( + children: [ + HypoHyperSwitch('do_you_have_hypotension_tendency'.tr), + ], + ), + Row( + children: [ + HypoHyperSwitch('do_you_have_hypertension_tendency'.tr), + ], + ), + NextStepButton( + buttonStyle: CustomButtonStyles.outlinePrimaryTL15, + text: "save".tr.toUpperCase(), + margin: EdgeInsets.only(top: 20.h, bottom: 20.h)), + ]); + } }