Files
eatvio_app/lib/features/settings/presentation/pages/physical_activity_screen.dart
2025-11-05 23:55:48 +03:00

240 lines
9.0 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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: _saveButton(),
body: SingleChildScrollView(
physics: const BouncingScrollPhysics(),
padding: const EdgeInsets.only(top: 16, bottom: 80),
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),
),
),
),
);
}
}