feat(insights): first isights impemetation

This commit is contained in:
misha
2026-11-09 15:35:10 +03:00
parent 67920b2016
commit 45d072cff4
63 changed files with 6374 additions and 1465 deletions

View File

@@ -0,0 +1,132 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'insights_payload_model.freezed.dart';
part 'insights_payload_model.g.dart';
/// Структура повторяет веб-`UserInsightsService::chartPayload()`, чтобы во второй
/// итерации заменить только источник данных.
@freezed
abstract class InsightsPayloadModel with _$InsightsPayloadModel {
const factory InsightsPayloadModel({
required WeightChartModel weight,
required BmiChartModel bmi,
required MeasureChartModel measure,
DailyChartModel? daily,
IntraChartModel? intra,
}) = _InsightsPayloadModel;
factory InsightsPayloadModel.fromJson(Map<String, dynamic> json) =>
_$InsightsPayloadModelFromJson(json);
}
@freezed
abstract class WeightChartModel with _$WeightChartModel {
const factory WeightChartModel({
@Default([]) List<String> labels,
@Default([]) List<double> values,
double? last,
double? delta,
@Default('') String headline,
@Default('') String unit,
@Default('') String deltaText,
}) = _WeightChartModel;
factory WeightChartModel.fromJson(Map<String, dynamic> json) =>
_$WeightChartModelFromJson(json);
}
@freezed
abstract class BmiChartModel with _$BmiChartModel {
const factory BmiChartModel({
@Default([]) List<String> labels,
@Default([]) List<double> values,
double? last,
double? delta,
@Default('') String headline,
String? category,
@Default('') String deltaText,
@Default('') String hint,
}) = _BmiChartModel;
factory BmiChartModel.fromJson(Map<String, dynamic> json) =>
_$BmiChartModelFromJson(json);
}
@freezed
abstract class MeasureChartModel with _$MeasureChartModel {
const factory MeasureChartModel({
@Default([]) List<String> labels,
@Default([]) List<double> waist,
@Default([]) List<double> chest,
@Default([]) List<double> hips,
@Default('') String headline,
@Default('') String deltaText,
}) = _MeasureChartModel;
factory MeasureChartModel.fromJson(Map<String, dynamic> json) =>
_$MeasureChartModelFromJson(json);
}
@freezed
abstract class DailyChartModel with _$DailyChartModel {
const factory DailyChartModel({
@Default([]) List<String> labels,
@Default([]) List<double> kcal,
@Default([]) List<double> proteins,
@Default([]) List<double> fats,
@Default([]) List<double> carbs,
double? average,
double? percent,
@Default('') String headline,
@Default('') String deltaText,
}) = _DailyChartModel;
factory DailyChartModel.fromJson(Map<String, dynamic> json) =>
_$DailyChartModelFromJson(json);
}
@freezed
abstract class IntraChartModel with _$IntraChartModel {
const factory IntraChartModel({
@Default([]) List<IntraBarModel> bars,
@Default([]) List<ScalePointModel> satiety,
@Default([]) List<ScalePointModel> mood,
double? wake,
double? sleep,
String? wakeLabel,
String? sleepLabel,
String? wakeText,
String? sleepText,
@Default('') String date,
@Default('') String maxDate,
@Default('') String dateLabel,
@Default(false) bool isToday,
}) = _IntraChartModel;
factory IntraChartModel.fromJson(Map<String, dynamic> json) =>
_$IntraChartModelFromJson(json);
}
/// Приём пищи: время `x` (часы 0–24) и калории из белков/жиров/углеводов.
@freezed
abstract class IntraBarModel with _$IntraBarModel {
const factory IntraBarModel({
required double x,
@Default(0) double p,
@Default(0) double f,
@Default(0) double c,
}) = _IntraBarModel;
factory IntraBarModel.fromJson(Map<String, dynamic> json) =>
_$IntraBarModelFromJson(json);
}
/// Точка шкалы 0–5 (сытость/настроение) в момент времени `x`.
@freezed
abstract class ScalePointModel with _$ScalePointModel {
const factory ScalePointModel({required double x, required double y}) =
_ScalePointModel;
factory ScalePointModel.fromJson(Map<String, dynamic> json) =>
_$ScalePointModelFromJson(json);
}

View File

@@ -0,0 +1,26 @@
/// Период для вкладок «Вес», «ИМТ» и «Замеры». Значение совпадает с `{period}` в
/// `/api/profile/measure/weight/{period}`.
enum BodyPeriod {
month('1'),
threeMonths('3'),
sixMonths('6'),
year('12'),
all('all');
const BodyPeriod(this.apiValue);
final String apiValue;
}
/// Период для вкладки «КБЖУ по дням» (используется со второй итерации).
enum DailyPeriod {
week('7'),
twoWeeks('14'),
month('30'),
threeMonths('90'),
all('all');
const DailyPeriod(this.apiValue);
final String apiValue;
}