forked from eatvio/eatvio_app
feat(profile): add weight and imt charts, menu add dividers
This commit is contained in:
@@ -27,7 +27,7 @@ class InitializationCubit extends Cubit<InitializationState> {
|
||||
privateNotificationChannel.subscribe();
|
||||
|
||||
privateNotificationChannel.bindToAll().listen((event) {
|
||||
sl<NotificationsCubit>().incrementCounter();
|
||||
sl<NotificationsCubit>().incrementCounter(event.name);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -3,11 +3,18 @@ import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/noti
|
||||
|
||||
class NotificationsCubit extends Cubit<NotificationsState> {
|
||||
int _notificationsCount = 0;
|
||||
List<String> notifications = [];
|
||||
|
||||
NotificationsCubit() : super(const NotificationsState.empty());
|
||||
|
||||
incrementCounter() {
|
||||
incrementCounter(String data) {
|
||||
_notificationsCount++;
|
||||
emit(NotificationsState.loaded(notificationsCount: _notificationsCount));
|
||||
notifications.add(data);
|
||||
emit(
|
||||
NotificationsState.loaded(
|
||||
notifications: notifications,
|
||||
notificationsCount: _notificationsCount,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ abstract class NotificationsState with _$NotificationsState {
|
||||
const factory NotificationsState.empty() = NotificationsStateEmpty;
|
||||
|
||||
const factory NotificationsState.loaded({
|
||||
required List<String> notifications,
|
||||
required int notificationsCount,
|
||||
}) = NotificationsStateLoaded;
|
||||
|
||||
|
||||
@@ -20,7 +20,9 @@ mixin _$NotificationsState {
|
||||
TResult when<TResult extends Object?>(
|
||||
TResult Function() $default, {
|
||||
required TResult Function() empty,
|
||||
required TResult Function(int notificationsCount) loaded,
|
||||
required TResult Function(
|
||||
List<String> notifications, int notificationsCount)
|
||||
loaded,
|
||||
required TResult Function(String errorMessage) error,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@@ -28,7 +30,8 @@ mixin _$NotificationsState {
|
||||
TResult? whenOrNull<TResult extends Object?>(
|
||||
TResult? Function()? $default, {
|
||||
TResult? Function()? empty,
|
||||
TResult? Function(int notificationsCount)? loaded,
|
||||
TResult? Function(List<String> notifications, int notificationsCount)?
|
||||
loaded,
|
||||
TResult? Function(String errorMessage)? error,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@@ -36,7 +39,8 @@ mixin _$NotificationsState {
|
||||
TResult maybeWhen<TResult extends Object?>(
|
||||
TResult Function()? $default, {
|
||||
TResult Function()? empty,
|
||||
TResult Function(int notificationsCount)? loaded,
|
||||
TResult Function(List<String> notifications, int notificationsCount)?
|
||||
loaded,
|
||||
TResult Function(String errorMessage)? error,
|
||||
required TResult orElse(),
|
||||
}) =>
|
||||
@@ -126,7 +130,9 @@ class _$NotificationsStateImpl implements _NotificationsState {
|
||||
TResult when<TResult extends Object?>(
|
||||
TResult Function() $default, {
|
||||
required TResult Function() empty,
|
||||
required TResult Function(int notificationsCount) loaded,
|
||||
required TResult Function(
|
||||
List<String> notifications, int notificationsCount)
|
||||
loaded,
|
||||
required TResult Function(String errorMessage) error,
|
||||
}) {
|
||||
return $default();
|
||||
@@ -137,7 +143,8 @@ class _$NotificationsStateImpl implements _NotificationsState {
|
||||
TResult? whenOrNull<TResult extends Object?>(
|
||||
TResult? Function()? $default, {
|
||||
TResult? Function()? empty,
|
||||
TResult? Function(int notificationsCount)? loaded,
|
||||
TResult? Function(List<String> notifications, int notificationsCount)?
|
||||
loaded,
|
||||
TResult? Function(String errorMessage)? error,
|
||||
}) {
|
||||
return $default?.call();
|
||||
@@ -148,7 +155,8 @@ class _$NotificationsStateImpl implements _NotificationsState {
|
||||
TResult maybeWhen<TResult extends Object?>(
|
||||
TResult Function()? $default, {
|
||||
TResult Function()? empty,
|
||||
TResult Function(int notificationsCount)? loaded,
|
||||
TResult Function(List<String> notifications, int notificationsCount)?
|
||||
loaded,
|
||||
TResult Function(String errorMessage)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
@@ -244,7 +252,9 @@ class _$NotificationsStateEmptyImpl implements NotificationsStateEmpty {
|
||||
TResult when<TResult extends Object?>(
|
||||
TResult Function() $default, {
|
||||
required TResult Function() empty,
|
||||
required TResult Function(int notificationsCount) loaded,
|
||||
required TResult Function(
|
||||
List<String> notifications, int notificationsCount)
|
||||
loaded,
|
||||
required TResult Function(String errorMessage) error,
|
||||
}) {
|
||||
return empty();
|
||||
@@ -255,7 +265,8 @@ class _$NotificationsStateEmptyImpl implements NotificationsStateEmpty {
|
||||
TResult? whenOrNull<TResult extends Object?>(
|
||||
TResult? Function()? $default, {
|
||||
TResult? Function()? empty,
|
||||
TResult? Function(int notificationsCount)? loaded,
|
||||
TResult? Function(List<String> notifications, int notificationsCount)?
|
||||
loaded,
|
||||
TResult? Function(String errorMessage)? error,
|
||||
}) {
|
||||
return empty?.call();
|
||||
@@ -266,7 +277,8 @@ class _$NotificationsStateEmptyImpl implements NotificationsStateEmpty {
|
||||
TResult maybeWhen<TResult extends Object?>(
|
||||
TResult Function()? $default, {
|
||||
TResult Function()? empty,
|
||||
TResult Function(int notificationsCount)? loaded,
|
||||
TResult Function(List<String> notifications, int notificationsCount)?
|
||||
loaded,
|
||||
TResult Function(String errorMessage)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
@@ -325,7 +337,7 @@ abstract class _$$NotificationsStateLoadedImplCopyWith<$Res> {
|
||||
$Res Function(_$NotificationsStateLoadedImpl) then) =
|
||||
__$$NotificationsStateLoadedImplCopyWithImpl<$Res>;
|
||||
@useResult
|
||||
$Res call({int notificationsCount});
|
||||
$Res call({List<String> notifications, int notificationsCount});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@@ -341,9 +353,14 @@ class __$$NotificationsStateLoadedImplCopyWithImpl<$Res>
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? notifications = null,
|
||||
Object? notificationsCount = null,
|
||||
}) {
|
||||
return _then(_$NotificationsStateLoadedImpl(
|
||||
notifications: null == notifications
|
||||
? _value._notifications
|
||||
: notifications // ignore: cast_nullable_to_non_nullable
|
||||
as List<String>,
|
||||
notificationsCount: null == notificationsCount
|
||||
? _value.notificationsCount
|
||||
: notificationsCount // ignore: cast_nullable_to_non_nullable
|
||||
@@ -355,14 +372,25 @@ class __$$NotificationsStateLoadedImplCopyWithImpl<$Res>
|
||||
/// @nodoc
|
||||
|
||||
class _$NotificationsStateLoadedImpl implements NotificationsStateLoaded {
|
||||
const _$NotificationsStateLoadedImpl({required this.notificationsCount});
|
||||
const _$NotificationsStateLoadedImpl(
|
||||
{required final List<String> notifications,
|
||||
required this.notificationsCount})
|
||||
: _notifications = notifications;
|
||||
|
||||
final List<String> _notifications;
|
||||
@override
|
||||
List<String> get notifications {
|
||||
if (_notifications is EqualUnmodifiableListView) return _notifications;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_notifications);
|
||||
}
|
||||
|
||||
@override
|
||||
final int notificationsCount;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'NotificationsState.loaded(notificationsCount: $notificationsCount)';
|
||||
return 'NotificationsState.loaded(notifications: $notifications, notificationsCount: $notificationsCount)';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -370,12 +398,15 @@ class _$NotificationsStateLoadedImpl implements NotificationsStateLoaded {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$NotificationsStateLoadedImpl &&
|
||||
const DeepCollectionEquality()
|
||||
.equals(other._notifications, _notifications) &&
|
||||
(identical(other.notificationsCount, notificationsCount) ||
|
||||
other.notificationsCount == notificationsCount));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, notificationsCount);
|
||||
int get hashCode => Object.hash(runtimeType,
|
||||
const DeepCollectionEquality().hash(_notifications), notificationsCount);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
@@ -389,10 +420,12 @@ class _$NotificationsStateLoadedImpl implements NotificationsStateLoaded {
|
||||
TResult when<TResult extends Object?>(
|
||||
TResult Function() $default, {
|
||||
required TResult Function() empty,
|
||||
required TResult Function(int notificationsCount) loaded,
|
||||
required TResult Function(
|
||||
List<String> notifications, int notificationsCount)
|
||||
loaded,
|
||||
required TResult Function(String errorMessage) error,
|
||||
}) {
|
||||
return loaded(notificationsCount);
|
||||
return loaded(notifications, notificationsCount);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -400,10 +433,11 @@ class _$NotificationsStateLoadedImpl implements NotificationsStateLoaded {
|
||||
TResult? whenOrNull<TResult extends Object?>(
|
||||
TResult? Function()? $default, {
|
||||
TResult? Function()? empty,
|
||||
TResult? Function(int notificationsCount)? loaded,
|
||||
TResult? Function(List<String> notifications, int notificationsCount)?
|
||||
loaded,
|
||||
TResult? Function(String errorMessage)? error,
|
||||
}) {
|
||||
return loaded?.call(notificationsCount);
|
||||
return loaded?.call(notifications, notificationsCount);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -411,12 +445,13 @@ class _$NotificationsStateLoadedImpl implements NotificationsStateLoaded {
|
||||
TResult maybeWhen<TResult extends Object?>(
|
||||
TResult Function()? $default, {
|
||||
TResult Function()? empty,
|
||||
TResult Function(int notificationsCount)? loaded,
|
||||
TResult Function(List<String> notifications, int notificationsCount)?
|
||||
loaded,
|
||||
TResult Function(String errorMessage)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (loaded != null) {
|
||||
return loaded(notificationsCount);
|
||||
return loaded(notifications, notificationsCount);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
@@ -461,8 +496,10 @@ class _$NotificationsStateLoadedImpl implements NotificationsStateLoaded {
|
||||
|
||||
abstract class NotificationsStateLoaded implements NotificationsState {
|
||||
const factory NotificationsStateLoaded(
|
||||
{required final int notificationsCount}) = _$NotificationsStateLoadedImpl;
|
||||
{required final List<String> notifications,
|
||||
required final int notificationsCount}) = _$NotificationsStateLoadedImpl;
|
||||
|
||||
List<String> get notifications;
|
||||
int get notificationsCount;
|
||||
@JsonKey(ignore: true)
|
||||
_$$NotificationsStateLoadedImplCopyWith<_$NotificationsStateLoadedImpl>
|
||||
@@ -540,7 +577,9 @@ class _$NotificationsStateErrorImpl implements NotificationsStateError {
|
||||
TResult when<TResult extends Object?>(
|
||||
TResult Function() $default, {
|
||||
required TResult Function() empty,
|
||||
required TResult Function(int notificationsCount) loaded,
|
||||
required TResult Function(
|
||||
List<String> notifications, int notificationsCount)
|
||||
loaded,
|
||||
required TResult Function(String errorMessage) error,
|
||||
}) {
|
||||
return error(errorMessage);
|
||||
@@ -551,7 +590,8 @@ class _$NotificationsStateErrorImpl implements NotificationsStateError {
|
||||
TResult? whenOrNull<TResult extends Object?>(
|
||||
TResult? Function()? $default, {
|
||||
TResult? Function()? empty,
|
||||
TResult? Function(int notificationsCount)? loaded,
|
||||
TResult? Function(List<String> notifications, int notificationsCount)?
|
||||
loaded,
|
||||
TResult? Function(String errorMessage)? error,
|
||||
}) {
|
||||
return error?.call(errorMessage);
|
||||
@@ -562,7 +602,8 @@ class _$NotificationsStateErrorImpl implements NotificationsStateError {
|
||||
TResult maybeWhen<TResult extends Object?>(
|
||||
TResult Function()? $default, {
|
||||
TResult Function()? empty,
|
||||
TResult Function(int notificationsCount)? loaded,
|
||||
TResult Function(List<String> notifications, int notificationsCount)?
|
||||
loaded,
|
||||
TResult Function(String errorMessage)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
|
||||
@@ -24,36 +24,43 @@ class MenuScreen extends StatelessWidget {
|
||||
leading: ImageConstant.icnProfileSettings,
|
||||
onTap: () => GoRouter.of(context).push('/my-settings-screen'),
|
||||
),
|
||||
_divider(context),
|
||||
_tile(
|
||||
leading: ImageConstant.icnRecipes,
|
||||
title: 'Мои рецепты',
|
||||
onTap: () => GoRouter.of(context).push('/recipe-select-screen'),
|
||||
),
|
||||
_divider(context),
|
||||
_tile(
|
||||
leading: 'assets/icons/diets.svg',
|
||||
title: 'Мои диеты',
|
||||
onTap: () => GoRouter.of(context).push('/diet-select-screen'),
|
||||
),
|
||||
_divider(context),
|
||||
_tile(
|
||||
leading: ImageConstant.icnPlans,
|
||||
title: 'Мои планы',
|
||||
onTap: () => GoRouter.of(context).push('/plan-select-screen'),
|
||||
),
|
||||
_divider(context),
|
||||
_tile(
|
||||
leading: 'assets/icons/calendar.svg',
|
||||
title: 'Календарь',
|
||||
onTap: () => GoRouter.of(context).push('/calendar-screen'),
|
||||
),
|
||||
_divider(context),
|
||||
_tile(
|
||||
leading: ImageConstant.icnGlossary,
|
||||
title: 'Глоссарий',
|
||||
onTap: () => GoRouter.of(context).push('/glossary-screen'),
|
||||
),
|
||||
_divider(context),
|
||||
_tile(
|
||||
leading: ImageConstant.icnSupport,
|
||||
title: 'Поддержка',
|
||||
onTap: () {},
|
||||
),
|
||||
_divider(context),
|
||||
_tile(
|
||||
leading: ImageConstant.icnExit,
|
||||
title: 'Выход',
|
||||
@@ -78,6 +85,22 @@ class MenuScreen extends StatelessWidget {
|
||||
width: 24,
|
||||
),
|
||||
title: Text(title),
|
||||
trailing: Icon(
|
||||
Icons.arrow_forward_ios_rounded,
|
||||
size: 12,
|
||||
color: Colors.black38,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_divider(BuildContext context) {
|
||||
return Container(
|
||||
height: 0.4,
|
||||
width: MediaQuery.of(context).size.width - 32,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black26,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import 'package:eatvio_app/core/app_export.dart';
|
||||
import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/notifications_cubit/notifications_cubit.dart';
|
||||
import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/notifications_cubit/notifications_state.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class NotificationsScreen extends StatelessWidget {
|
||||
@@ -5,10 +8,20 @@ class NotificationsScreen extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text('Уведомления'),
|
||||
),
|
||||
return BlocBuilder<NotificationsCubit, NotificationsState>(
|
||||
builder: (BuildContext context, NotificationsState state) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text('Уведомления'),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
padding: EdgeInsets.all(16),
|
||||
child: Text(
|
||||
state is NotificationsStateLoaded ? state.notifications.toString() : 'Уведомлений нет',
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,6 +101,7 @@ class ChartPoint with _$ChartPoint {
|
||||
@JsonKey(name: "id") required int id,
|
||||
@JsonKey(name: "user_id") required int userId,
|
||||
@JsonKey(name: "weight") required int weight,
|
||||
@JsonKey(name: "bmi") required String bmi,
|
||||
@JsonKey(name: "created_at") required DateTime createdAt,
|
||||
@JsonKey(name: "updated_at") required DateTime updatedAt,
|
||||
}) = _ChartPoint;
|
||||
|
||||
@@ -2122,6 +2122,8 @@ mixin _$ChartPoint {
|
||||
int get userId => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: "weight")
|
||||
int get weight => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: "bmi")
|
||||
String get bmi => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: "created_at")
|
||||
DateTime get createdAt => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: "updated_at")
|
||||
@@ -2143,6 +2145,7 @@ abstract class $ChartPointCopyWith<$Res> {
|
||||
{@JsonKey(name: "id") int id,
|
||||
@JsonKey(name: "user_id") int userId,
|
||||
@JsonKey(name: "weight") int weight,
|
||||
@JsonKey(name: "bmi") String bmi,
|
||||
@JsonKey(name: "created_at") DateTime createdAt,
|
||||
@JsonKey(name: "updated_at") DateTime updatedAt});
|
||||
}
|
||||
@@ -2163,6 +2166,7 @@ class _$ChartPointCopyWithImpl<$Res, $Val extends ChartPoint>
|
||||
Object? id = null,
|
||||
Object? userId = null,
|
||||
Object? weight = null,
|
||||
Object? bmi = null,
|
||||
Object? createdAt = null,
|
||||
Object? updatedAt = null,
|
||||
}) {
|
||||
@@ -2179,6 +2183,10 @@ class _$ChartPointCopyWithImpl<$Res, $Val extends ChartPoint>
|
||||
? _value.weight
|
||||
: weight // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
bmi: null == bmi
|
||||
? _value.bmi
|
||||
: bmi // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
createdAt: null == createdAt
|
||||
? _value.createdAt
|
||||
: createdAt // ignore: cast_nullable_to_non_nullable
|
||||
@@ -2203,6 +2211,7 @@ abstract class _$$ChartPointImplCopyWith<$Res>
|
||||
{@JsonKey(name: "id") int id,
|
||||
@JsonKey(name: "user_id") int userId,
|
||||
@JsonKey(name: "weight") int weight,
|
||||
@JsonKey(name: "bmi") String bmi,
|
||||
@JsonKey(name: "created_at") DateTime createdAt,
|
||||
@JsonKey(name: "updated_at") DateTime updatedAt});
|
||||
}
|
||||
@@ -2221,6 +2230,7 @@ class __$$ChartPointImplCopyWithImpl<$Res>
|
||||
Object? id = null,
|
||||
Object? userId = null,
|
||||
Object? weight = null,
|
||||
Object? bmi = null,
|
||||
Object? createdAt = null,
|
||||
Object? updatedAt = null,
|
||||
}) {
|
||||
@@ -2237,6 +2247,10 @@ class __$$ChartPointImplCopyWithImpl<$Res>
|
||||
? _value.weight
|
||||
: weight // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
bmi: null == bmi
|
||||
? _value.bmi
|
||||
: bmi // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
createdAt: null == createdAt
|
||||
? _value.createdAt
|
||||
: createdAt // ignore: cast_nullable_to_non_nullable
|
||||
@@ -2256,6 +2270,7 @@ class _$ChartPointImpl implements _ChartPoint {
|
||||
{@JsonKey(name: "id") required this.id,
|
||||
@JsonKey(name: "user_id") required this.userId,
|
||||
@JsonKey(name: "weight") required this.weight,
|
||||
@JsonKey(name: "bmi") required this.bmi,
|
||||
@JsonKey(name: "created_at") required this.createdAt,
|
||||
@JsonKey(name: "updated_at") required this.updatedAt});
|
||||
|
||||
@@ -2272,6 +2287,9 @@ class _$ChartPointImpl implements _ChartPoint {
|
||||
@JsonKey(name: "weight")
|
||||
final int weight;
|
||||
@override
|
||||
@JsonKey(name: "bmi")
|
||||
final String bmi;
|
||||
@override
|
||||
@JsonKey(name: "created_at")
|
||||
final DateTime createdAt;
|
||||
@override
|
||||
@@ -2280,7 +2298,7 @@ class _$ChartPointImpl implements _ChartPoint {
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ChartPoint(id: $id, userId: $userId, weight: $weight, createdAt: $createdAt, updatedAt: $updatedAt)';
|
||||
return 'ChartPoint(id: $id, userId: $userId, weight: $weight, bmi: $bmi, createdAt: $createdAt, updatedAt: $updatedAt)';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -2291,6 +2309,7 @@ class _$ChartPointImpl implements _ChartPoint {
|
||||
(identical(other.id, id) || other.id == id) &&
|
||||
(identical(other.userId, userId) || other.userId == userId) &&
|
||||
(identical(other.weight, weight) || other.weight == weight) &&
|
||||
(identical(other.bmi, bmi) || other.bmi == bmi) &&
|
||||
(identical(other.createdAt, createdAt) ||
|
||||
other.createdAt == createdAt) &&
|
||||
(identical(other.updatedAt, updatedAt) ||
|
||||
@@ -2300,7 +2319,7 @@ class _$ChartPointImpl implements _ChartPoint {
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
int get hashCode =>
|
||||
Object.hash(runtimeType, id, userId, weight, createdAt, updatedAt);
|
||||
Object.hash(runtimeType, id, userId, weight, bmi, createdAt, updatedAt);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
@@ -2321,6 +2340,7 @@ abstract class _ChartPoint implements ChartPoint {
|
||||
{@JsonKey(name: "id") required final int id,
|
||||
@JsonKey(name: "user_id") required final int userId,
|
||||
@JsonKey(name: "weight") required final int weight,
|
||||
@JsonKey(name: "bmi") required final String bmi,
|
||||
@JsonKey(name: "created_at") required final DateTime createdAt,
|
||||
@JsonKey(name: "updated_at") required final DateTime updatedAt}) =
|
||||
_$ChartPointImpl;
|
||||
@@ -2338,6 +2358,9 @@ abstract class _ChartPoint implements ChartPoint {
|
||||
@JsonKey(name: "weight")
|
||||
int get weight;
|
||||
@override
|
||||
@JsonKey(name: "bmi")
|
||||
String get bmi;
|
||||
@override
|
||||
@JsonKey(name: "created_at")
|
||||
DateTime get createdAt;
|
||||
@override
|
||||
|
||||
@@ -169,6 +169,7 @@ _$ChartPointImpl _$$ChartPointImplFromJson(Map<String, dynamic> json) =>
|
||||
id: (json['id'] as num).toInt(),
|
||||
userId: (json['user_id'] as num).toInt(),
|
||||
weight: (json['weight'] as num).toInt(),
|
||||
bmi: json['bmi'] as String,
|
||||
createdAt: DateTime.parse(json['created_at'] as String),
|
||||
updatedAt: DateTime.parse(json['updated_at'] as String),
|
||||
);
|
||||
@@ -178,6 +179,7 @@ Map<String, dynamic> _$$ChartPointImplToJson(_$ChartPointImpl instance) =>
|
||||
'id': instance.id,
|
||||
'user_id': instance.userId,
|
||||
'weight': instance.weight,
|
||||
'bmi': instance.bmi,
|
||||
'created_at': instance.createdAt.toIso8601String(),
|
||||
'updated_at': instance.updatedAt.toIso8601String(),
|
||||
};
|
||||
|
||||
@@ -4,6 +4,8 @@ import 'package:eatvio_app/features/profile/models/profile_model.dart';
|
||||
import 'package:eatvio_app/features/profile/presentation/bloc/profile_cubit/profile_cubit.dart';
|
||||
import 'package:eatvio_app/features/profile/presentation/bloc/profile_cubit/profile_state.dart';
|
||||
import 'package:eatvio_app/features/profile/presentation/widgets/circumference_chart_widget.dart';
|
||||
import 'package:eatvio_app/features/profile/presentation/widgets/imt_chart_widget.dart';
|
||||
import 'package:eatvio_app/features/profile/presentation/widgets/weight_chart_widget.dart';
|
||||
import 'package:eatvio_app/locator_service.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
@@ -18,6 +20,7 @@ class ProfileScreen extends StatefulWidget {
|
||||
|
||||
class _ProfileScreenState extends State<ProfileScreen> {
|
||||
List<Circumference> chartData = [];
|
||||
List<ChartPoint> chartPoints = [];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -32,6 +35,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
builder: (BuildContext context, ProfileState state) {
|
||||
if (state is ProfileStateLoaded) {
|
||||
chartData = state.profile.circumferences;
|
||||
chartPoints = state.profile.chartPoints;
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
toolbarHeight: 0,
|
||||
@@ -48,6 +52,8 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
),
|
||||
),
|
||||
CircumferenceChartWidget(chartData: chartData),
|
||||
WeightChartWidget(chartPoints: chartPoints),
|
||||
ImtChartWidget(chartPoints: chartPoints),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
import 'package:eatvio_app/features/profile/models/profile_model.dart' as ProfileModel;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncfusion_flutter_charts/charts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class ImtChartWidget extends StatelessWidget {
|
||||
final List<ProfileModel.ChartPoint> chartPoints;
|
||||
|
||||
const ImtChartWidget({
|
||||
super.key,
|
||||
required this.chartPoints,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SfCartesianChart(
|
||||
margin: EdgeInsets.zero,
|
||||
enableAxisAnimation: true,
|
||||
enableSideBySideSeriesPlacement: true,
|
||||
legend: const Legend(
|
||||
isVisible: true,
|
||||
opacity: 0.7,
|
||||
position: LegendPosition.bottom,
|
||||
),
|
||||
plotAreaBorderWidth: 0,
|
||||
trackballBehavior: TrackballBehavior(
|
||||
enable: true,
|
||||
activationMode: ActivationMode.singleTap,
|
||||
),
|
||||
primaryXAxis: DateTimeAxis(
|
||||
dateFormat: DateFormat.MMMd('ru'),
|
||||
axisLine: AxisLine(
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
primaryYAxis: NumericAxis(
|
||||
labelFormat: '{value} кг',
|
||||
axisLine: AxisLine(
|
||||
width: 1,
|
||||
),
|
||||
majorTickLines: MajorTickLines(size: 0),
|
||||
),
|
||||
series: _getSplineSeries(),
|
||||
tooltipBehavior: TooltipBehavior(enable: true),
|
||||
);
|
||||
}
|
||||
|
||||
List<CartesianSeries<ProfileModel.ChartPoint, DateTime>> _getSplineSeries() {
|
||||
return <CartesianSeries<ProfileModel.ChartPoint, DateTime>>[
|
||||
SplineSeries<ProfileModel.ChartPoint, DateTime>(
|
||||
markerSettings: MarkerSettings(
|
||||
isVisible: true,
|
||||
color: Colors.blue,
|
||||
height: 12,
|
||||
width: 12,
|
||||
),
|
||||
dataLabelSettings: DataLabelSettings(
|
||||
labelAlignment: ChartDataLabelAlignment.top,
|
||||
isVisible: true,
|
||||
),
|
||||
dataSource: chartPoints,
|
||||
color: Colors.blue,
|
||||
name: 'ИМТ',
|
||||
xValueMapper: (ProfileModel.ChartPoint value, int index) => value.createdAt,
|
||||
yValueMapper: (ProfileModel.ChartPoint value, int index) => double.parse(value.bmi),
|
||||
),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
import 'package:eatvio_app/features/profile/models/profile_model.dart' as ProfileModel;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncfusion_flutter_charts/charts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class WeightChartWidget extends StatelessWidget {
|
||||
final List<ProfileModel.ChartPoint> chartPoints;
|
||||
|
||||
const WeightChartWidget({
|
||||
super.key,
|
||||
required this.chartPoints,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SfCartesianChart(
|
||||
margin: EdgeInsets.zero,
|
||||
enableAxisAnimation: true,
|
||||
enableSideBySideSeriesPlacement: true,
|
||||
legend: const Legend(
|
||||
isVisible: true,
|
||||
opacity: 0.7,
|
||||
position: LegendPosition.bottom,
|
||||
),
|
||||
plotAreaBorderWidth: 0,
|
||||
trackballBehavior: TrackballBehavior(
|
||||
enable: true,
|
||||
activationMode: ActivationMode.singleTap,
|
||||
),
|
||||
primaryXAxis: DateTimeAxis(
|
||||
dateFormat: DateFormat.MMMd('ru'),
|
||||
axisLine: AxisLine(
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
primaryYAxis: NumericAxis(
|
||||
labelFormat: '{value} кг',
|
||||
axisLine: AxisLine(
|
||||
width: 1,
|
||||
),
|
||||
majorTickLines: MajorTickLines(size: 0),
|
||||
),
|
||||
series: _getSplineSeries(),
|
||||
tooltipBehavior: TooltipBehavior(enable: true),
|
||||
);
|
||||
}
|
||||
|
||||
List<CartesianSeries<ProfileModel.ChartPoint, DateTime>> _getSplineSeries() {
|
||||
return <CartesianSeries<ProfileModel.ChartPoint, DateTime>>[
|
||||
SplineSeries<ProfileModel.ChartPoint, DateTime>(
|
||||
markerSettings: MarkerSettings(
|
||||
isVisible: true,
|
||||
color: Colors.blue,
|
||||
height: 12,
|
||||
width: 12,
|
||||
),
|
||||
dataLabelSettings: DataLabelSettings(
|
||||
labelAlignment: ChartDataLabelAlignment.top,
|
||||
isVisible: true,
|
||||
),
|
||||
dataSource: chartPoints,
|
||||
color: Colors.blue,
|
||||
name: 'Вес',
|
||||
xValueMapper: (ProfileModel.ChartPoint value, int index) => value.createdAt,
|
||||
yValueMapper: (ProfileModel.ChartPoint value, int index) => value.weight,
|
||||
),
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user