diff --git a/lib/localization/ru/ru_translations.dart b/lib/localization/ru/ru_translations.dart index 2cb0f732..017f958a 100644 --- a/lib/localization/ru/ru_translations.dart +++ b/lib/localization/ru/ru_translations.dart @@ -111,6 +111,9 @@ final Map ru = { "weight_chart": "График веса", "circumferences_chart": "График обхватов", "bodymass_chart": "График ИМТ", + "chest": "Грудь", + "waist": "Талия", + "hips": "Бедра", "exit": "Выйти", "active": "Активен", "archived": "В архиве", diff --git a/lib/presentation/profile/my_profile_screen/my_profile_screen.dart b/lib/presentation/profile/my_profile_screen/my_profile_screen.dart index df7353a9..803734f8 100644 --- a/lib/presentation/profile/my_profile_screen/my_profile_screen.dart +++ b/lib/presentation/profile/my_profile_screen/my_profile_screen.dart @@ -12,6 +12,7 @@ import 'package:carousel_slider/carousel_slider.dart'; import 'package:flutter/material.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'dart:math'; +import 'package:intl/intl.dart'; import 'package:fl_chart/fl_chart.dart'; class MyProfileScreen extends StatelessWidget { @@ -103,7 +104,94 @@ class MyProfileScreen extends StatelessWidget { case 3: //График обхватов return GestureDetector( onTap: () { - _showAddMeasurementDialog(context); + showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: Text("Добавить замер"), + content: Column( + children: [ + BlocSelector< + MyProfileBloc, + MyProfileState, + TextEditingController?>( + selector: (state) => state + .chestCircumferenceController, + builder: (context, + chestCircumferenceController) { + return TextField( + controller: + chestCircumferenceController, + keyboardType: + TextInputType + .number, + decoration: InputDecoration( + labelText: + "chest_circumference" + .tr), + ); + }), + BlocSelector< + MyProfileBloc, + MyProfileState, + TextEditingController?>( + selector: (state) => state + .waistCircumferenceController, + builder: (context, + waistCircumferenceController) { + return TextField( + controller: + waistCircumferenceController, + keyboardType: + TextInputType + .number, + decoration: InputDecoration( + labelText: + "waist_circumference" + .tr), + ); + }), + BlocSelector< + MyProfileBloc, + MyProfileState, + TextEditingController?>( + selector: (state) => state + .hipCircumferenceController, + builder: (context, + hipCircumferenceController) { + return TextField( + controller: + hipCircumferenceController, + keyboardType: + TextInputType + .number, + decoration: InputDecoration( + labelText: + "hip_circumference" + .tr), + ); + }), + ], + ), + actions: [ + TextButton( + onPressed: () { + Navigator.pop(context); + }, + child: Text("Отмена"), + ), + TextButton( + onPressed: () { + // Отправка данных на API + // Закрытие диалогового окна + Navigator.pop(context); + }, + child: Text("Изменить"), + ), + ], + ); + }, + ); }, child: Column(children: [ Text( @@ -113,11 +201,15 @@ class MyProfileScreen extends StatelessWidget { color: appTheme.black900, ), ), - SizedBox(height: 50.v), + SizedBox(height: 30.v), _buildCircumferenceChart( - context, - state.circumferences, - ) + context, + state.circumferences, + state.chartPoints?.values + .map( + (e) => e['created_at']) + .toList()), + _buildChartLegend() ])); case 4: return NextStepButton( @@ -211,8 +303,41 @@ class MyProfileScreen extends StatelessWidget { return CustomBottomBar(onChanged: (BottomBarEnum type) {}); } + Widget _buildChartLegend() { + final colors = [Colors.pink, Colors.green, Colors.purple]; + final titles = ["chest".tr, "waist".tr, "hips".tr]; + final style = TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold, + ); + return Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + for (var i = 0; i < colors.length; i++) + Container( + child: Row( + children: [ + Container( + width: 16, + height: 16, + color: colors[i], + ), + SizedBox(width: 8), + Text(titles[i], style: style), + ], + ), + ), + ], + ), + ], + ); + } + /// Section Widget - Widget _buildChart(BuildContext context, List chartPoints, dates) { + Widget _buildChart( + BuildContext context, List chartPoints, List? dates) { // Определение осей графика List spots = []; for (int i = 0; i < 4; i++) { @@ -221,20 +346,29 @@ class MyProfileScreen extends StatelessWidget { ); } - Widget bottomTitleWidgets(double value, TitleMeta meta, double chartWidth) { + Widget bottomTitleWidgets( + double value, TitleMeta meta, double chartWidth, List? dates) { if (value % 1 != 0) { return Container(); } final style = TextStyle( - color: Colors.white, + color: Colors.blue, fontWeight: FontWeight.bold, - fontSize: min(18, 18 * chartWidth / 300), - ); - return SideTitleWidget( - axisSide: meta.axisSide, - space: 16, - child: Text(meta.formattedValue, style: style), + fontSize: min(13, 13 * chartWidth / 300), ); + int index = value.toInt(); + if (index >= 0 && index < dates!.length) { + // Проверка на допустимый индекс в массиве dates + String formattedDate = + DateFormat('dd.MM').format(DateTime.parse(dates[index])); + return SideTitleWidget( + axisSide: meta.axisSide, + space: 16, + child: Text(formattedDate, style: style), + ); + } else { + return Container(); + } } Widget leftTitleWidgets(double value, TitleMeta meta, double chartWidth) { @@ -320,8 +454,8 @@ class MyProfileScreen extends StatelessWidget { bottomTitles: AxisTitles( sideTitles: SideTitles( showTitles: true, - getTitlesWidget: (value, meta) => - bottomTitleWidgets(value, meta, constraints.maxWidth), + getTitlesWidget: (value, meta) => bottomTitleWidgets( + value, meta, constraints.maxWidth, dates), reservedSize: 36, interval: 1, ), @@ -363,7 +497,8 @@ class MyProfileScreen extends StatelessWidget { ); } - Widget _buildCircumferenceChart(BuildContext context, chartPoints) { + Widget _buildCircumferenceChart( + BuildContext context, chartPoints, List? dates) { // Определение осей графика final chestCircumferences = chartPoints.values.map((e) => e['chest_circumference']).toList(); @@ -399,20 +534,29 @@ class MyProfileScreen extends StatelessWidget { ...waistCircumferences ]; - Widget bottomTitleWidgets(double value, TitleMeta meta, double chartWidth) { + Widget bottomTitleWidgets( + double value, TitleMeta meta, double chartWidth, List? dates) { if (value % 1 != 0) { return Container(); } final style = TextStyle( - color: Colors.white, + color: Colors.blue, fontWeight: FontWeight.bold, - fontSize: min(18, 18 * chartWidth / 300), - ); - return SideTitleWidget( - axisSide: meta.axisSide, - space: 16, - child: Text(meta.formattedValue, style: style), + fontSize: min(13, 13 * chartWidth / 300), ); + int index = value.toInt(); + if (index >= 0 && index < dates!.length) { + // Проверка на допустимый индекс в массиве dates + String formattedDate = + DateFormat('dd.MM').format(DateTime.parse(dates[index])); + return SideTitleWidget( + axisSide: meta.axisSide, + space: 16, + child: Text(formattedDate, style: style), + ); + } else { + return Container(); + } } Widget leftTitleWidgets(double value, TitleMeta meta, double chartWidth) { @@ -520,8 +664,8 @@ class MyProfileScreen extends StatelessWidget { bottomTitles: AxisTitles( sideTitles: SideTitles( showTitles: true, - getTitlesWidget: (value, meta) => - bottomTitleWidgets(value, meta, constraints.maxWidth), + getTitlesWidget: (value, meta) => bottomTitleWidgets( + value, meta, constraints.maxWidth, dates), reservedSize: 36, interval: 1, ), @@ -684,66 +828,5 @@ class MyProfileScreen extends StatelessWidget { } } -_showAddMeasurementDialog(BuildContext context) async { - return showDialog( - context: context, - builder: (context) { - return AlertDialog( - title: Text("Добавить замер"), - content: Column( - children: [ - BlocSelector( - selector: (state) => state.chestCircumferenceController, - builder: (context, chestCircumferenceController) { - return TextField( - controller: chestCircumferenceController, - keyboardType: TextInputType.number, - decoration: - InputDecoration(labelText: "chest_circumference".tr), - ); - }), - BlocSelector( - selector: (state) => state.waistCircumferenceController, - builder: (context, waistCircumferenceController) { - return TextField( - controller: waistCircumferenceController, - keyboardType: TextInputType.number, - decoration: - InputDecoration(labelText: "waist_circumference".tr), - ); - }), - BlocSelector( - selector: (state) => state.hipCircumferenceController, - builder: (context, hipCircumferenceController) { - return TextField( - controller: hipCircumferenceController, - keyboardType: TextInputType.number, - decoration: - InputDecoration(labelText: "hip_circumference".tr), - ); - }), - ], - ), - actions: [ - TextButton( - onPressed: () { - Navigator.pop(context); - }, - child: Text("Отмена"), - ), - TextButton( - onPressed: () { - // Отправка данных на API - // Закрытие диалогового окна - Navigator.pop(context); - }, - child: Text("Изменить"), - ), - ], - ); - }, - ); -} - _sendDataToApi(String chestCircumference, String waistCircumference, String hipCircumference) {}