forked from eatvio/eatvio_app
246 lines
9.3 KiB
Dart
246 lines
9.3 KiB
Dart
import 'package:eatvio_app/features/settings/entities/settings_entity.dart';
|
||
import 'package:eatvio_app/features/settings/presentation/bloc/settings_cubit/settings_cubit.dart';
|
||
import 'package:eatvio_app/features/settings/presentation/bloc/settings_cubit/settings_state.dart';
|
||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||
import 'package:flutter/material.dart';
|
||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||
import 'package:go_router/go_router.dart';
|
||
|
||
class PhysicalActivityScreen extends StatefulWidget {
|
||
final SettingsEntity settingsEntity;
|
||
|
||
const PhysicalActivityScreen({super.key, required this.settingsEntity});
|
||
|
||
@override
|
||
State<PhysicalActivityScreen> createState() => _PhysicalActivityScreenState();
|
||
}
|
||
|
||
enum PhysicalActivity { minimum, low, medium, high, extreme }
|
||
|
||
class _PhysicalActivityScreenState extends State<PhysicalActivityScreen> {
|
||
PhysicalActivity? _physicalActivity;
|
||
|
||
PhysicalActivity? _getPhysicalActivityFromCoefficient(double coefficient) {
|
||
switch (coefficient) {
|
||
case 1.2:
|
||
return PhysicalActivity.minimum;
|
||
case 1.375:
|
||
return PhysicalActivity.low;
|
||
case 1.55:
|
||
return PhysicalActivity.medium;
|
||
case 1.7:
|
||
return PhysicalActivity.high;
|
||
case 1.9:
|
||
return PhysicalActivity.extreme;
|
||
default:
|
||
return null;
|
||
}
|
||
}
|
||
|
||
void _updatePhysicalActivityFromState() {
|
||
final state = widget.settingsEntity.settingsCubit.state;
|
||
if (state is SettingsStateLoaded) {
|
||
final newActivity = _getPhysicalActivityFromCoefficient(state.profileDetails.activityCoefficient);
|
||
if (newActivity != _physicalActivity) {
|
||
setState(() {
|
||
_physicalActivity = newActivity;
|
||
});
|
||
}
|
||
}
|
||
}
|
||
|
||
@override
|
||
void initState() {
|
||
super.initState();
|
||
_updatePhysicalActivityFromState();
|
||
_physicalActivity ??= _getPhysicalActivityFromCoefficient(widget.settingsEntity.profileDetailsModel.activityCoefficient);
|
||
}
|
||
|
||
@override
|
||
void didChangeDependencies() {
|
||
super.didChangeDependencies();
|
||
// Update when returning to this screen
|
||
_updatePhysicalActivityFromState();
|
||
}
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
return BlocListener<SettingsCubit, SettingsState>(
|
||
bloc: widget.settingsEntity.settingsCubit,
|
||
listener: (context, state) {
|
||
_updatePhysicalActivityFromState();
|
||
},
|
||
child: BlocBuilder<SettingsCubit, SettingsState>(
|
||
bloc: widget.settingsEntity.settingsCubit,
|
||
builder: (context, state) {
|
||
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.only(top: 16, bottom: 120), // 52 (кнопка) + 56 (навигация) + 12 (отступ)
|
||
child: Column(
|
||
children: [
|
||
Row(
|
||
children: [
|
||
Radio<PhysicalActivity>(
|
||
value: PhysicalActivity.minimum,
|
||
// ignore: deprecated_member_use
|
||
groupValue: _physicalActivity,
|
||
// ignore: deprecated_member_use
|
||
onChanged: (PhysicalActivity? value) {
|
||
setState(() {
|
||
_physicalActivity = value;
|
||
});
|
||
},
|
||
),
|
||
const Expanded(
|
||
child: Padding(
|
||
padding: EdgeInsets.only(left: 8, right: 16),
|
||
child: Text('1,2 — минимальный (сидячая работа, отсутствие физических нагрузок);'),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
Row(
|
||
children: [
|
||
Radio<PhysicalActivity>(
|
||
value: PhysicalActivity.low,
|
||
// ignore: deprecated_member_use
|
||
groupValue: _physicalActivity,
|
||
// ignore: deprecated_member_use
|
||
onChanged: (PhysicalActivity? value) {
|
||
setState(() {
|
||
_physicalActivity = value;
|
||
});
|
||
},
|
||
),
|
||
const Expanded(
|
||
child: Padding(
|
||
padding: EdgeInsets.only(left: 8, right: 16),
|
||
child: Text('1,375 — низкий (тренировки не менее 20 мин 1–3 раза в неделю);'),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
Row(
|
||
children: [
|
||
Radio<PhysicalActivity>(
|
||
value: PhysicalActivity.medium,
|
||
// ignore: deprecated_member_use
|
||
groupValue: _physicalActivity,
|
||
// ignore: deprecated_member_use
|
||
onChanged: (PhysicalActivity? value) {
|
||
setState(() {
|
||
_physicalActivity = value;
|
||
});
|
||
},
|
||
),
|
||
const Expanded(
|
||
child: Padding(padding: EdgeInsets.only(left: 8, right: 16), child: Text('1,55 — умеренный (тренировки 30–60 мин 3–4 раза в неделю);')),
|
||
),
|
||
],
|
||
),
|
||
Row(
|
||
children: [
|
||
Radio<PhysicalActivity>(
|
||
value: PhysicalActivity.high,
|
||
// ignore: deprecated_member_use
|
||
groupValue: _physicalActivity,
|
||
// ignore: deprecated_member_use
|
||
onChanged: (PhysicalActivity? value) {
|
||
setState(() {
|
||
_physicalActivity = value;
|
||
});
|
||
},
|
||
),
|
||
const Expanded(
|
||
child: Padding(
|
||
padding: EdgeInsets.only(left: 8, right: 16),
|
||
child: Text('1,7 — высокий (тренировки 30–60 мин 5–7 раза в неделю; тяжёлая физическая работа);'),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
Row(
|
||
children: [
|
||
Radio<PhysicalActivity>(
|
||
value: PhysicalActivity.extreme,
|
||
// ignore: deprecated_member_use
|
||
groupValue: _physicalActivity,
|
||
// ignore: deprecated_member_use
|
||
onChanged: (PhysicalActivity? value) {
|
||
setState(() {
|
||
_physicalActivity = value;
|
||
});
|
||
},
|
||
),
|
||
const Expanded(
|
||
child: Padding(
|
||
padding: EdgeInsets.only(left: 8, right: 16),
|
||
child: Text('1,9 — экстремальный (несколько интенсивных тренировок в день'),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
],
|
||
),
|
||
),
|
||
);
|
||
},
|
||
),
|
||
);
|
||
}
|
||
|
||
InkWell _saveButton() {
|
||
return InkWell(
|
||
onTap: () {
|
||
late final double activityCoefficient;
|
||
switch (_physicalActivity) {
|
||
case PhysicalActivity.minimum:
|
||
activityCoefficient = 1.2;
|
||
break;
|
||
case PhysicalActivity.low:
|
||
activityCoefficient = 1.375;
|
||
break;
|
||
case PhysicalActivity.medium:
|
||
activityCoefficient = 1.55;
|
||
break;
|
||
case PhysicalActivity.high:
|
||
activityCoefficient = 1.7;
|
||
break;
|
||
case PhysicalActivity.extreme:
|
||
activityCoefficient = 1.9;
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
widget.settingsEntity.settingsCubit.updateProfileDetails(
|
||
profileDetailsModel: (widget.settingsEntity.settingsCubit.state as SettingsStateLoaded).profileDetails.copyWith(
|
||
activityCoefficient: activityCoefficient,
|
||
),
|
||
);
|
||
GoRouter.of(context).pop();
|
||
},
|
||
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),
|
||
),
|
||
),
|
||
),
|
||
);
|
||
}
|
||
}
|