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

@@ -37,6 +37,7 @@ class InsightsCard extends StatelessWidget {
this.canAdd = false,
this.repository,
this.kbjuEnabled = InsightsFeatureFlags.kbjuEnabled,
this.refreshToken = 0,
});
final String? slug;
@@ -44,6 +45,10 @@ class InsightsCard extends StatelessWidget {
final InsightsRepository? repository;
final bool kbjuEnabled;
/// При смене значения блок перезапрашивает данные (например, после правок
/// в дневнике), сохраняя вкладку, период и выбранный день.
final int refreshToken;
@override
Widget build(BuildContext context) {
return KeyedSubtree(
@@ -55,14 +60,29 @@ class InsightsCard extends StatelessWidget {
canAdd: canAdd,
kbjuEnabled: kbjuEnabled,
)..load(),
child: const _InsightsView(),
child: _InsightsView(refreshToken: refreshToken),
),
);
}
}
class _InsightsView extends StatelessWidget {
const _InsightsView();
class _InsightsView extends StatefulWidget {
const _InsightsView({required this.refreshToken});
final int refreshToken;
@override
State<_InsightsView> createState() => _InsightsViewState();
}
class _InsightsViewState extends State<_InsightsView> {
@override
void didUpdateWidget(covariant _InsightsView oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.refreshToken != widget.refreshToken) {
context.read<InsightsCubit>().refresh();
}
}
@override
Widget build(BuildContext context) {
@@ -113,7 +133,7 @@ class _ErrorContent extends StatelessWidget {
Widget build(BuildContext context) {
final s = S.of(context);
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12),
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
child: Row(
children: [
Expanded(
@@ -158,9 +178,9 @@ class _LoadedContent extends StatelessWidget {
child: state.isExpanded
? Padding(
padding: EdgeInsets.fromLTRB(
20,
16,
0,
20,
16,
showFab ? 24 + 44 : 24,
),
child: _Body(state: state),
@@ -241,7 +261,7 @@ class _Toggle extends StatelessWidget {
borderRadius: BorderRadius.circular(8),
onTap: onTap,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16),
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
child: Row(
children: [
Container(
@@ -443,8 +463,7 @@ class _PanelContent extends StatelessWidget {
}
}
/// «КБЖУ по дням». Период пока фиксирован: перезапрос появится вместе с
/// эндпоинтом `GET /api/profile/insights` (итерация 2).
/// «КБЖУ по дням». Смена периода перезапрашивает `GET /api/profile/insights`.
class _DailyPanel extends StatelessWidget {
const _DailyPanel({required this.state});
@@ -462,9 +481,10 @@ class _DailyPanel extends StatelessWidget {
children: [
PeriodPills<DailyPeriod>(
periods: DailyPeriod.values,
selected: DailyPeriod.twoWeeks,
selected: state.dailyPeriod,
labelOf: (period) => period.pillLabel(s),
keyOf: (period) => period.apiValue,
onSelected: cubit.setDailyPeriod,
),
const SizedBox(height: 16),
if (daily == null)
@@ -474,7 +494,7 @@ class _DailyPanel extends StatelessWidget {
headline: daily.headline,
unit: s.insights_unit_kcal_avg,
deltaText: daily.deltaText,
isDeltaHighlighted: daily.percent != null,
isDeltaHighlighted: (daily.percent ?? 0) != 0,
),
const SizedBox(height: 12),
SeriesChips(
@@ -510,7 +530,7 @@ class _DailyPanel extends StatelessWidget {
}
}
/// «В течение дня». Навигация по датам неактивна до итерации 2.
/// «В течение дня». Листание дней запрашивает только `/insights/intra`.
class _IntraPanel extends StatelessWidget {
const _IntraPanel({required this.state});
@@ -530,7 +550,12 @@ class _IntraPanel extends StatelessWidget {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
IntraDateNav(model: intra),
IntraDateNav(
model: intra,
onPreviousDay: cubit.showPreviousDay,
onNextDay: cubit.showNextDay,
onDatePicked: cubit.setIntraDate,
),
const SizedBox(height: 16),
SeriesChips(
chips: [