feat(insights): added kbju fetching for analitics

This commit is contained in:
misha
2026-11-10 12:21:53 +03:00
parent 45d072cff4
commit 8c33f033ff
30 changed files with 1910 additions and 118 deletions

View File

@@ -22,6 +22,7 @@ import 'package:eatvio_app/features/diary/presentation/widgets/meal_widget.dart'
import 'package:eatvio_app/features/diary/presentation/widgets/wakeup_and_retire_widget.dart';
import 'package:eatvio_app/features/insights/presentation/widgets/insights_card.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -49,7 +50,12 @@ class UserDiaryScreen extends StatelessWidget {
}
class DiaryScreenContent extends StatefulWidget {
const DiaryScreenContent({super.key, this.diaryId, this.date, this.ownerSlug});
const DiaryScreenContent({
super.key,
this.diaryId,
this.date,
this.ownerSlug,
});
final int? diaryId;
final DateTime? date;
final String? ownerSlug;
@@ -60,9 +66,14 @@ class DiaryScreenContent extends StatefulWidget {
class _DiaryScreenContentState extends State<DiaryScreenContent> {
bool _isDiaryFinishing = false;
/// Slug владельца: из `user.slug` дневника, иначе из параметра экрана.
String? _ownerSlug(DiaryStateLoaded state) {
return state.diary.ownerSlug ?? widget.ownerSlug;
}
/// Консультант видит аналитику клиента только при известном slug владельца.
bool _canShowInsights(DiaryStateLoaded state) {
return !state.isConsultantView || widget.ownerSlug != null;
return !state.isConsultantView || _ownerSlug(state) != null;
}
@override
@@ -122,9 +133,9 @@ class _DiaryScreenContentState extends State<DiaryScreenContent> {
],
if (state is DiaryStateLoaded && _canShowInsights(state))
Padding(
padding: const EdgeInsets.fromLTRB(16, 12, 16, 0),
child: InsightsCard(
slug: state.isConsultantView ? widget.ownerSlug : null,
padding: const EdgeInsets.fromLTRB(4, 12, 4, 12),
child: _DiaryInsights(
slug: state.isConsultantView ? _ownerSlug(state) : null,
canAdd: !state.isConsultantView,
),
),
@@ -267,3 +278,45 @@ class _DiaryScreenContentState extends State<DiaryScreenContent> {
);
}
}
/// Блок «Аналитика» в дневнике. Для своего дневника перезапрашивает данные,
/// когда в том же дне меняются приёмы пищи или время подъёма/отбоя: от них
/// зависят КБЖУ-графики. Чужой дневник консультант не редактирует.
class _DiaryInsights extends StatefulWidget {
const _DiaryInsights({required this.slug, required this.canAdd});
final String? slug;
final bool canAdd;
@override
State<_DiaryInsights> createState() => _DiaryInsightsState();
}
class _DiaryInsightsState extends State<_DiaryInsights> {
int _refreshToken = 0;
bool _isOwnDiaryMutation(DiaryState previous, DiaryState current) {
if (!widget.canAdd ||
previous is! DiaryStateLoaded ||
current is! DiaryStateLoaded ||
previous.diary.id != current.diary.id) {
return false;
}
return !listEquals(previous.diary.meals, current.diary.meals) ||
previous.diary.wakeup != current.diary.wakeup ||
previous.diary.retire != current.diary.retire;
}
@override
Widget build(BuildContext context) {
return BlocListener<DiaryCubit, DiaryState>(
listenWhen: _isOwnDiaryMutation,
listener: (context, state) => setState(() => _refreshToken++),
child: InsightsCard(
slug: widget.slug,
canAdd: widget.canAdd,
refreshToken: _refreshToken,
),
);
}
}