Added logic for profile screen edit inputs

This commit is contained in:
2024-01-30 13:56:56 +03:00
parent 901e23fa44
commit 041ecbdd7e
3 changed files with 304 additions and 143 deletions

View File

@@ -17,70 +17,120 @@ class MyProfileBloc extends Bloc<MyProfileEvent, MyProfileState> {
}
Future<void> _onInitialize(
MyProfileInitialEvent event,
Emitter<MyProfileState> 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<MyProfileState> 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<String, dynamic> &&
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<String, dynamic> &&
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'));
}
}
}

View File

@@ -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<String, dynamic>? 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<Object> get props => [errorMessage];
}
}

View File

@@ -65,8 +65,8 @@ class MySettingsScreen extends StatelessWidget {
NotificationSwitch('Уведомление о новых обновлениях'),
NotificationSwitch('Напоминания о заполнении дневника'),
SectionTitle('Дополнительная информация'),
ExpandableList('Персональные данные', userDetails),
ExpandableList('О нас', ['Контакты', 'Адрес']),
ExpandableList('Персональные данные'),
ExpandableList('О нас'),
],
),
),
@@ -241,9 +241,8 @@ class _HypoHyperState extends State<HypoHyperSwitch> {
class ExpandableList extends StatefulWidget {
final String title;
final List<String> items;
ExpandableList(this.title, this.items);
ExpandableList(this.title);
@override
_ExpandableListState createState() => _ExpandableListState();
@@ -280,86 +279,117 @@ class _ExpandableListState extends State<ExpandableList> {
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<MyProfileBloc, MyProfileState>(
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)),
]);
}
}