Files
eatvio_app/lib/features/settings/presentation/pages/general_info_screen.dart

270 lines
10 KiB
Dart

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<GeneralInfoScreen> createState() => _GeneralInfoScreenState();
}
class _GeneralInfoScreenState extends State<GeneralInfoScreen> {
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<SelectionPopupModel> genderSelectionPopupList = [
const SelectionPopupModel(id: 0, title: 'Женский', value: 'female'),
const SelectionPopupModel(id: 1, title: 'Мужской', value: 'male'),
];
final List<SelectionPopupModel> 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<void>(
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),
),
),
),
);
}
}