import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/H2O/user_detail_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/H2O_view_model.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/radio_selection_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/painting.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:manage_calendar_events/manage_calendar_events.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'Dialog/setting_page_radio_button_list_dialog.dart'; class H2oSetting extends StatefulWidget { final UserDetailModel userDetailModel; final H2OViewModel viewModel; H2oSetting({Key key, this.userDetailModel, this.viewModel}) : super(key: key); @override _H2oSettingState createState() { return _H2oSettingState(); } } class _H2oSettingState extends State { TextEditingController _nameController = TextEditingController(); TextEditingController _heightController = TextEditingController(); TextEditingController _weightController = TextEditingController(); List _weightPopupList = List(); List _heightPopupList = List(); bool _isUnitML = true; bool _isGenderMale = false; bool _isHeightCM = false; bool _isWeightKG = false; double _heightValue = 1; double _weightValue = 1; List _activityLevelListEng = []; List _remindedTimeListEng = []; int _selectedActiveLevel = 1; int _selectedRemindedTime = 0; DateTime _dobDate = DateTime.now(); DateTime _tempDate = DateTime.now(); UserDetailModel _userDetailModel; @override void initState() { super.initState(); _userDetailModel = widget.userDetailModel; _heightValue = _userDetailModel?.height ?? 100; _weightValue = _userDetailModel?.weight ?? 50; _heightController.text = _heightValue.toStringAsFixed(0); _weightController.text = _weightValue.toStringAsFixed(0); _nameController.text = _userDetailModel.firstName; _isWeightKG = _userDetailModel?.isWeightInKG ?? true; _isHeightCM = _userDetailModel?.isHeightInCM ?? true; _isGenderMale = (_userDetailModel?.gender ?? "M") == "M" ? true : false; _dobDate = DateUtil.convertStringToDate(_userDetailModel.dOB); _selectedActiveLevel = _userDetailModel.activityID ?? 1; readPrefs(); } SharedPreferences prefs; void readPrefs() async { prefs = await SharedPreferences.getInstance(); _isUnitML = (prefs.getString(H2O_UNIT) ?? "ml") == "ml" ? true : false; _selectedRemindedTime = prefs.getInt(H2O_REMINDER) ?? 0; setState(() {}); } @override void didChangeDependencies() { // TODO: implement didChangeDependencies super.didChangeDependencies(); _activityLevelListEng = [TranslationBase.of(context).notActive, TranslationBase.of(context).lightActive, TranslationBase.of(context).modActive, TranslationBase.of(context).active]; _remindedTimeListEng = ["1 ${TranslationBase.of(context).time}", "2 ${TranslationBase.of(context).times}", "3 ${TranslationBase.of(context).times}", "4 ${TranslationBase.of(context).times}"]; } @override void dispose() { super.dispose(); } @override Widget build(BuildContext context) { _weightPopupList = [PopupMenuItem(child: Text(TranslationBase.of(context).kg), value: true), PopupMenuItem(child: Text(TranslationBase.of(context).lb), value: false)]; _heightPopupList = [PopupMenuItem(child: Text(TranslationBase.of(context).cm), value: true), PopupMenuItem(child: Text(TranslationBase.of(context).ft), value: false)]; return AppScaffold( isShowAppBar: true, appBarTitle: TranslationBase.of(context).h2o, showNewAppBar: true, showNewAppBarTitle: true, backgroundColor: Color(0xffF7F7F7), showHomeAppBarIcon: false, body: Column( children: [ Expanded( child: SingleChildScrollView( physics: BouncingScrollPhysics(), padding: EdgeInsets.all(21), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( TranslationBase.of(context).enterDetailBelow, style: TextStyle( fontSize: 19, height: 23 / 19, fontWeight: FontWeight.w700, color: Color(0xff2E303A), letterSpacing: -1.14, ), ), SizedBox(height: 12), inputWidget(TranslationBase.of(context).enterNameHere, TranslationBase.of(context).name, _nameController).withBorderedContainer, SizedBox(height: 16), Text( TranslationBase.of(context).preferredunit, style: TextStyle( fontSize: 14, height: 21 / 14, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.44, ), ), SizedBox(height: 12), _commonRadioButtonsRow(TranslationBase.of(context).mililitre, TranslationBase.of(context).litre, _isUnitML, (value) { if (_isUnitML != value) { setState(() { _isUnitML = value; }); } }), SizedBox(height: 12), Text( TranslationBase.of(context).pleaseSelectGender, style: TextStyle( fontSize: 14, height: 21 / 14, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.44, ), ), SizedBox(height: 12), _commonRadioButtonsRow(TranslationBase.of(context).male, TranslationBase.of(context).female, _isGenderMale, (value) { if (_isGenderMale != value) { setState(() { _isGenderMale = value; }); } }), SizedBox(height: 18), _commonInputAndUnitRow( TranslationBase.of(context).height, _heightController, 1, 270, _heightValue, (text) { _heightController.text = text; }, (value) { _heightValue = value; }, _isHeightCM ? TranslationBase.of(context).cm : TranslationBase.of(context).ft, (value) { if (_isHeightCM != value) { setState(() { _isHeightCM = value; }); } }, _heightPopupList), SizedBox(height: 12), _commonInputAndUnitRow( TranslationBase.of(context).weight, _weightController, 1, 250, _weightValue, (text) { _heightController.text = text; }, (value) { _weightValue = value; }, _isWeightKG ? TranslationBase.of(context).kg : TranslationBase.of(context).lb, (value) { if (_isWeightKG != value) { setState(() { _isWeightKG = value; }); } }, _weightPopupList), SizedBox(height: 12), CommonDropDownView(TranslationBase.of(context).dateOfBirth, DateUtil.getFormattedDate(_dobDate, "dd MMMM, yyyy"), () { showModalBottomSheet( context: context, builder: (context) { return Container( height: 250, padding: EdgeInsets.all(8), child: Column(children: [ Container( height: 40, alignment: Alignment.centerRight, child: Row(mainAxisSize: MainAxisSize.min, children: [ InkWell( onTap: () => Navigator.pop(context), child: Container( alignment: Alignment.center, padding: EdgeInsets.fromLTRB(8, 4, 8, 4), child: Text(TranslationBase.of(context).cancel), ), ), SizedBox(width: 8), InkWell( onTap: () { Navigator.pop(context); setState(() { _dobDate = _tempDate; }); }, child: Container( alignment: Alignment.center, padding: EdgeInsets.fromLTRB(8, 4, 8, 4), child: Text(TranslationBase.of(context).ok), ), ) ]), ), Expanded( child: Container( width: MediaQuery.of(context).size.width, child: CupertinoDatePicker( initialDateTime: _dobDate, mode: CupertinoDatePickerMode.date, onDateTimeChanged: (_date) { _tempDate = _date; }, ), ), ) ]), ); }); }, iconData: Icons.calendar_today) .withBorderedContainer, SizedBox(height: 12), CommonDropDownView(TranslationBase.of(context).activityLevel, _activityLevelListEng[_selectedActiveLevel - 1], () { List list = [ for (int i = 0; i < _activityLevelListEng.length; i++) RadioSelectionDialogModel(_activityLevelListEng[i], i + 1), ]; showDialog( context: context, builder: (cxt) => RadioSelectionDialog( listData: list, selectedIndex: _selectedActiveLevel, onValueSelected: (index) { _selectedActiveLevel = index; setState(() {}); }, ), ); }).withBorderedContainer, SizedBox(height: 18), Text( TranslationBase.of(context).reminderLabel, style: TextStyle( fontSize: 14, height: 21 / 14, fontWeight: FontWeight.w600, color: Color(0xff2B353E), letterSpacing: -0.44, ), ), SizedBox(height: 12), CommonDropDownView(TranslationBase.of(context).reminderTimesLabel, _remindedTimeListEng[_selectedRemindedTime], () { List list = [ for (int i = 0; i < _remindedTimeListEng.length; i++) RadioSelectionDialogModel(_remindedTimeListEng[i], i), ]; showDialog( context: context, builder: (cxt) => RadioSelectionDialog( listData: list, selectedIndex: _selectedRemindedTime, onValueSelected: (index) { _selectedRemindedTime = index; setState(() {}); }, ), ); }).withBorderedContainer, ], ), ), ), Container( color: Colors.white, padding: EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), child: DefaultButton( TranslationBase.of(context).save, _updateUserDetails, color: Color(0xff349745), ), ), ], ), ); } Widget inputWidget(String _labelText, String _hintText, TextEditingController _controller, {String prefix, bool isEnable = true, bool hasSelection = false}) { return InkWell( onTap: hasSelection ? () {} : null, child: Row( children: [ Expanded( child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( _labelText, style: TextStyle( fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.44, ), ), TextField( enabled: isEnable, scrollPadding: EdgeInsets.zero, keyboardType: TextInputType.text, controller: _controller, onChanged: (value) => { // validateForm() }, style: TextStyle( fontSize: 14, height: 21 / 14, fontWeight: FontWeight.w400, color: Color(0xff575757), letterSpacing: -0.56, ), decoration: InputDecoration( isDense: true, hintText: _hintText, hintStyle: TextStyle( fontSize: 14, height: 21 / 14, fontWeight: FontWeight.w400, color: Color(0xff575757), letterSpacing: -0.56, ), prefixIconConstraints: BoxConstraints(minWidth: 50), prefixIcon: prefix == null ? null : Text( "+" + prefix, style: TextStyle( fontSize: 14, height: 21 / 14, fontWeight: FontWeight.w500, color: Color(0xff2E303A), letterSpacing: -0.56, ), ), contentPadding: EdgeInsets.zero, border: InputBorder.none, focusedBorder: InputBorder.none, enabledBorder: InputBorder.none, ), ), ], ), ), if (hasSelection) Icon(Icons.keyboard_arrow_down_outlined), ], ), ); } Widget _commonRadioButtonsRow(String rightText, String leftText, bool checkParam, Function(bool) callBack) { return Row( children: [ Row( mainAxisSize: MainAxisSize.min, children: [ SizedBox(width: 22, height: 22, child: Radio(value: true, groupValue: checkParam, onChanged: callBack)), SizedBox(width: 8), Text( rightText, style: TextStyle( fontSize: 14, height: 21 / 14, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.44, ), ), ], ), SizedBox(width: 12), Row( mainAxisSize: MainAxisSize.min, children: [ SizedBox(width: 22, height: 22, child: Radio(value: false, groupValue: checkParam, onChanged: callBack)), SizedBox(width: 8), Text( leftText, style: TextStyle( fontSize: 14, height: 21 / 14, fontWeight: FontWeight.w600, color: Color(0xff575757), letterSpacing: -0.44, ), ), ], ), ], ); } Widget _commonInputAndUnitRow(_title, _controller, double _minValue, double _maxValue, double _valueOrg, Function(String) onTextValueChange, Function(double) onValueChange, String unitTitle, Function(bool) onUnitTap, _list) { return Row( children: [ Expanded( flex: 3, child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( _title, style: TextStyle( fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.44, ), ), TextField( controller: _controller, keyboardType: TextInputType.number, onChanged: (value) { double _value = double.parse(value); if (_value > _maxValue) { onTextValueChange(_maxValue.toStringAsFixed(0)); onValueChange(_maxValue); return; } else if (_value < _minValue) { onTextValueChange(_minValue.toStringAsFixed(0)); onValueChange(_minValue); return; } else if (_value >= _minValue && _value <= _maxValue) { onValueChange(_value); return; } }, inputFormatters: [ FilteringTextInputFormatter.allow(RegExp(r'[0-9]')), ], style: TextStyle( color: Color(0xff575757), letterSpacing: -0.56, ), decoration: InputDecoration( isDense: true, hintText: "0", hintStyle: TextStyle( fontSize: 14, height: 21 / 14, fontWeight: FontWeight.w400, color: Color(0xff575757), letterSpacing: -0.56, ), contentPadding: EdgeInsets.zero, border: InputBorder.none, focusedBorder: InputBorder.none, enabledBorder: InputBorder.none, ), ), ], ), ), Container(height: 34, width: 1, color: Color(0xffE0E0E0), margin: EdgeInsets.only(left: 12, right: 12)), Expanded( flex: 1, child: PopupMenuButton( child: CommonDropDownView(TranslationBase.of(context).unit, unitTitle, null), onSelected: (value) { onUnitTap(value); }, itemBuilder: (context) => _list), ) ], ).withBorderedContainer; } void _updateUserDetails() async { _userDetailModel.height = _heightValue; _userDetailModel.weight = _weightValue; _userDetailModel.firstName = _nameController.text; _userDetailModel.isWeightInKG = _isWeightKG; _userDetailModel.isHeightInCM = _isHeightCM; _userDetailModel.gender = _isGenderMale ? "M" : "F"; var tempDate = DateUtil.convertDateToString(_dobDate); if (!tempDate.endsWith("/")) { tempDate = tempDate + "/"; } _userDetailModel.dOB = tempDate; _userDetailModel.activityID = _selectedActiveLevel; GifLoaderDialogUtils.showMyDialog(context); await widget.viewModel.updateUserDetail(_userDetailModel, (tag) async { if (tag) { AppToast.showSuccessToast(message: TranslationBase.of(context).success); await prefs.setString(H2O_UNIT, _isUnitML ? "ml" : "l"); int _tempRemindTime = prefs.getInt(H2O_REMINDER) ?? 0; if (_tempRemindTime != _selectedRemindedTime) { await prefs.setInt(H2O_REMINDER, _selectedRemindedTime); _addReminderToCalender(_selectedRemindedTime); } } GifLoaderDialogUtils.hideDialog(context); }); Navigator.pop(context); } final CalendarPlugin _myPlugin = CalendarPlugin(); void _addReminderToCalender(int _selectedRemindedTime) async { bool _calendarPermission = await _myPlugin.hasPermissions(); if (_calendarPermission) { } else { await _myPlugin.requestPermissions(); } _myPlugin.hasPermissions().then((value) { if (!value) { _myPlugin.requestPermissions(); } else { _myPlugin.getCalendars().then((value) => {}); } }); } } // todo 'sikander' move these to separate file once usability known class CommonDropDownView extends StatelessWidget { final String title; final String value; final VoidCallback callback; final IconData iconData; CommonDropDownView(this.title, this.value, this.callback, {Key key, this.iconData}) : super(key: key); @override Widget build(BuildContext context) { return InkWell( onTap: callback, child: Row( children: [ Expanded( child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: TextStyle( fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.44, ), ), Text( value, style: TextStyle( fontSize: 14, fontWeight: FontWeight.w400, color: Color(0xff575757), letterSpacing: -0.56, ), ), ]), ), Icon( iconData ?? Icons.keyboard_arrow_down_sharp, color: Color(0xff2E303A), ) ], ), ); } } extension BorderedContainer on Widget { Widget get withBorderedContainer => Container( padding: EdgeInsets.only(left: 16, right: 16, bottom: 15, top: 15), alignment: Alignment.center, decoration: BoxDecoration( borderRadius: BorderRadius.circular(15), color: Colors.white, border: Border.all( color: Color(0xffefefef), width: 1, ), ), child: this, ); }