forked from eatvio/eatvio_app
270 lines
10 KiB
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),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|