forked from eatvio/eatvio_app
Finished weight chart
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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']));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,3 +14,8 @@ class MyProfileInitialEvent extends MyProfileEvent {
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
class LogoutEvent extends Equatable {
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
);
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user