Finished weight chart

This commit is contained in:
2024-01-15 15:44:23 +03:00
parent 3015e91dd7
commit d530b6b409
8 changed files with 226 additions and 75 deletions

View File

@@ -106,7 +106,8 @@ final Map<String, String> ru = {
"user_authorization": "Аутентификация",
// Личный кабинет Screen
"Dmitry_Koval": "Дмитрий Коваль", "done": "Готово", "exit": "Выйти",
"loading": "Загрузка...",
"exit": "Выйти",
"my_blog": "Мой блог", "lbl_01_04_21": "01.04.21", "lbl_01_05_21": "01.05.21",
// Настройки Screen

View File

@@ -83,7 +83,8 @@ class AuthScreen extends StatelessWidget {
'password': state.passwordController!.text,
};
final response = await http.post(
Uri.parse('http://10.55.5.126:1092/api/login'),
Uri.parse(
'https://emaibo4wahye-dev3.eatvio.ru/api/login'),
headers: {'Content-Type': 'application/json'},
body: json.encode(credentials),
encoding: utf8);

View File

@@ -1,3 +1,5 @@
import 'dart:ffi';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import '/core/app_export.dart';
@@ -14,6 +16,29 @@ class MyProfileBloc extends Bloc<MyProfileEvent, MyProfileState> {
MyProfileBloc(MyProfileState initialState) : super(initialState) {
on<MyProfileInitialEvent>(_onInitialize);
}
Stream<MyProfileState> mapEventToState(MyProfileEvent event) async* {
if (event is LogoutEvent) {
// Удаление токенов из баз данных Hive и Laravel Sanctum
var box = await Hive.openBox('myBox');
final token = box.get('token');
box.delete('token');
final response = await http.post(
Uri.parse('http://10.55.5.126:1092/api/profile/logout'),
headers: {
'Authorization': 'Bearer $token',
},
);
if (response.statusCode == 200) {
// Токен Laravel Sanctum успешно удален из базы данных
} else {
// Обработка ошибки
}
// Перенаправление пользователя на экран AuthScreen
}
}
_onInitialize(
MyProfileInitialEvent event,
@@ -22,12 +47,15 @@ class MyProfileBloc extends Bloc<MyProfileEvent, MyProfileState> {
final box = await Hive.openBox('token');
final token = box.get('token');
final response = await http.get(
Uri.parse('http://10.55.5.126:1092/api/profile/index'),
Uri.parse('https://emaibo4wahye-dev3.eatvio.ru/api/profile/index'),
headers: {
'Authorization': 'Bearer $token',
},
);
final data = jsonDecode(response.body);
emit(state.copyWith(user: data));
emit(state.copyWith(
user: data['user'],
chartPoints: data['chartPoints'],
userDetails: data['userDetails']));
}
}

View File

@@ -14,3 +14,8 @@ class MyProfileInitialEvent extends MyProfileEvent {
@override
List<Object?> get props => [];
}
class LogoutEvent extends Equatable {
@override
List<Object> get props => [];
}

View File

@@ -4,19 +4,25 @@ part of 'my_profile_bloc.dart';
/// Represents the state of MyProfile in the application.
class MyProfileState extends Equatable {
MyProfileState({this.myProfileModelObj, this.user});
MyProfileState(
{this.myProfileModelObj, this.user, this.userDetails, this.chartPoints});
MyProfileModel? myProfileModelObj;
Map<String, dynamic>? user;
Map<String, dynamic>? userDetails;
Map<String, dynamic>? chartPoints;
@override
List<Object?> get props => [
myProfileModelObj,
];
List<Object?> get props => [myProfileModelObj, user, chartPoints];
MyProfileState copyWith(
{MyProfileModel? myProfileModelObj, Map<String, dynamic>? user}) {
{MyProfileModel? myProfileModelObj,
Map<String, dynamic>? user,
Map<String, dynamic>? userDetails,
Map<String, dynamic>? chartPoints}) {
return MyProfileState(
myProfileModelObj: myProfileModelObj ?? this.myProfileModelObj,
user: user ?? this.user);
user: user ?? this.user,
userDetails: userDetails ?? this.userDetails,
chartPoints: chartPoints ?? this.chartPoints);
}
}

View File

@@ -1,7 +1,6 @@
import 'bloc/my_profile_bloc.dart';
import 'models/my_profile_model.dart';
import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/widgets/app_bar/appbar_leading_image.dart';
import 'package:eatvio_app/widgets/app_bar/appbar_subtitle.dart';
import 'package:eatvio_app/widgets/app_bar/appbar_title_circleimage.dart';
import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart';
@@ -9,6 +8,7 @@ import 'package:eatvio_app/widgets/custom_bottom_bar.dart';
import 'package:eatvio_app/widgets/app_bar/exit_button.dart';
import 'package:eatvio_app/widgets/next_step_button.dart';
import 'package:flutter/material.dart';
import 'dart:math';
import 'package:fl_chart/fl_chart.dart';
class MyProfileScreen extends StatelessWidget {
@@ -28,7 +28,8 @@ class MyProfileScreen extends StatelessWidget {
builder: (context, state) {
return SafeArea(
child: Scaffold(
appBar: _buildAppBar(context, state.user!['name']),
appBar:
_buildAppBar(context, state.user?['name'] ?? 'loading'.tr),
body: Container(
width: double.maxFinite,
padding:
@@ -38,15 +39,17 @@ class MyProfileScreen extends StatelessWidget {
SizedBox(height: 15.v),
_buildSettings(context),
SizedBox(height: 30.v),
/*_buildChart(
[70.0, 72.0, 71.0, 73.0],
[
DateTime(2021, 10, 1),
DateTime(2021, 10, 2),
DateTime(2021, 10, 3),
DateTime(2021, 10, 4),
],
),*/
_buildChart(
context,
state.chartPoints?.values
.map<int>((e) => e['weight'])
.toList()
.map((i) => i.toDouble())
.toList() ??
[0.0, 0.0, 0.0, 0.0],
state.chartPoints?.values
.map<String>((e) => e['created_at'])
.toList()),
SizedBox(height: 15.v),
_buildWidget(context),
SizedBox(height: 5.v),
@@ -60,12 +63,6 @@ class MyProfileScreen extends StatelessWidget {
return CustomAppBar(
height: 54.v,
leadingWidth: 28.h,
leading: AppbarLeadingImage(
imagePath: ImageConstant.imgArrowLeft,
margin: EdgeInsets.only(left: 15.h, top: 13.v, bottom: 14.v),
onTap: () {
onTapArrowLeft(context);
}),
title: Padding(
padding: EdgeInsets.only(left: 20.h),
child: Row(children: [
@@ -76,8 +73,10 @@ class MyProfileScreen extends StatelessWidget {
])),
actions: [
ExitButton(
text: "exit".tr,
margin: EdgeInsets.symmetric(horizontal: 16.h, vertical: 17.v))
text: "exit".tr,
margin: EdgeInsets.symmetric(horizontal: 16.h, vertical: 17.v),
onTap: () {},
)
]);
}
@@ -122,49 +121,163 @@ class MyProfileScreen extends StatelessWidget {
}
/// Section Widget
/* Widget _buildChart(List<double> values, List<DateTime> dates) {
// Создаем список точек для графика
final List<FlSpot> spots = [];
for (int i = 0; i < values.length; i++) {
spots.add(FlSpot(i.toDouble(), values[i]));
}
Widget _buildChart(BuildContext context, List<double> chartPoints, dates) {
// Определение данных для графика
/* List<FlSpot> chartData = chartPoints
.map((point) =>
FlSpot(point['created_at'] as double, point['weight'] as double))
.toList(); */
return LineChart(
LineChartData(
// Ось X - даты
minX: 0,
maxX: dates.length.toDouble() - 1,
// Ось Y - значения
minY: 0,
maxY: values.reduce((a, b) => a > b ? a : b) + 10,
// Список точек
lineBarsData: [
LineChartBarData(
spots: spots,
isCurved: false,
color: Colors.blue,
barWidth: 3,
),
],
// Оси и легенда
titlesData: FlTitlesData(
bottomTitles: AxisTitles(sideTitles:SideTitles(
showTitles: true,
getTitlesWidget: (value) {
final index = value.toInt();
return '${dates[index].day}.${dates[index].month}';
},
)),
leftTitles: AxisTitles(sideTitles: SideTitles(
showTitles: true,
getTitlesWidget: (value,TitleMeta ) {
return '${value.toInt()}';
// Определение осей графика
List<FlSpot> spots = [];
for (int i = 0; i < 4; i++) {
spots.add(
FlSpot((i * 10 / 10) + 1, chartPoints[i]),
);
}
print(spots);
Widget bottomTitleWidgets(double value, TitleMeta meta, double chartWidth) {
if (value % 1 != 0) {
return Container();
}
final style = TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: min(18, 18 * chartWidth / 300),
);
return SideTitleWidget(
axisSide: meta.axisSide,
space: 16,
child: Text(meta.formattedValue, style: style),
);
}
Widget leftTitleWidgets(double value, TitleMeta meta, double chartWidth) {
final style = TextStyle(
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),
);
}
return Padding(
padding: const EdgeInsets.only(
left: 12,
bottom: 12,
right: 20,
top: 18,
),
child: AspectRatio(
aspectRatio: 1,
child: LayoutBuilder(
builder: (context, constraints) {
return LineChart(
LineChartData(
lineTouchData: LineTouchData(
touchTooltipData: LineTouchTooltipData(
maxContentWidth: 100,
tooltipBgColor: Colors.black,
getTooltipItems: (touchedSpots) {
return touchedSpots.map((LineBarSpot touchedSpot) {
final textStyle = TextStyle(
color: touchedSpot.bar.gradient?.colors[0] ??
touchedSpot.bar.color,
fontWeight: FontWeight.bold,
fontSize: 14,
);
return LineTooltipItem(
'${touchedSpot.x}, ${touchedSpot.y.toStringAsFixed(2)}',
textStyle,
);
}).toList();
},
),
handleBuiltInTouches: true,
getTouchLineStart: (data, index) => 0,
),
lineBarsData: [
LineChartBarData(
color: Colors.pink,
spots: spots,
isCurved: true,
isStrokeCapRound: true,
barWidth: 3,
belowBarData: BarAreaData(
show: false,
),
dotData: const FlDotData(show: false),
),
],
minY: chartPoints.reduce(
(value, element) => value < element ? value : element),
maxY: chartPoints.reduce(
(value, element) => value > element ? value : element),
minX: 1,
maxX: 4,
titlesData: FlTitlesData(
leftTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
getTitlesWidget: (value, meta) =>
leftTitleWidgets(value, meta, constraints.maxWidth),
reservedSize: 56,
),
drawBelowEverything: true,
),
rightTitles: const AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
bottomTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
getTitlesWidget: (value, meta) =>
bottomTitleWidgets(value, meta, constraints.maxWidth),
reservedSize: 36,
interval: 1,
),
drawBelowEverything: true,
),
topTitles: const AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
),
gridData: FlGridData(
show: true,
drawHorizontalLine: true,
drawVerticalLine: true,
horizontalInterval: 1.5,
verticalInterval: 5,
checkToShowHorizontalLine: (value) {
return value.toInt() == 0;
},
getDrawingHorizontalLine: (_) => FlLine(
color: Colors.blue.withOpacity(1),
dashArray: [8, 2],
strokeWidth: 0.8,
),
getDrawingVerticalLine: (_) => FlLine(
color: Colors.blue.withOpacity(1),
dashArray: [8, 2],
strokeWidth: 0.8,
),
checkToShowVerticalLine: (value) {
return value.toInt() == 0;
},
),
borderData: FlBorderData(show: false),
),
);
},
),
)),
),
);
}*/
),
);
}
/// Section Widget
Widget _buildWidget(BuildContext context) {
@@ -341,9 +454,4 @@ class MyProfileScreen extends StatelessWidget {
]))
]));
}
/// Navigates to the previous screen.
onTapArrowLeft(BuildContext context) {
NavigatorService.goBack();
}
}

View File

@@ -72,7 +72,8 @@ class AdditionalInformationScreen extends StatelessWidget {
.userRegistrationSheet;
sheet.additionalInfo = state.editTextController!.text;
final response = await http.post(
Uri.parse('http://10.55.5.126:1092/api/register'),
Uri.parse(
'https://emaibo4wahye-dev3.eatvio.ru/api/register'),
headers: {'Content-Type': 'application/json'},
body: json.encode(sheet),
);

View File

@@ -20,6 +20,7 @@ dependencies:
isar_flutter_libs: ^4.0.0-dev.13
path_provider: ^2.1.0
fl_chart: ^0.66.0
flutter_spinkit: ^5.0.0
dev_dependencies:
flutter_test: