Files
fin-tracker/app/lib/features/shell/analytics_page.dart
T
Dmitry b69bb4a0c9 feat(app): экраны импорта отчётов, целей, доходов, ребалансировки, налогов и бенчмарков
Импорт (/imports, /instruments/pending) и фаза 4 (/goals, /income,
/rebalance, /tax, аналитика-хаб с benchmarks_card) — по
docs/ai/import-contract.md и docs/ai/phase4-contract.md. file_picker для
загрузки отчёта.
2026-09-19 10:44:38 +03:00

70 lines
2.6 KiB
Dart

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
/// Аналитика: a hub for the phase-4 screens.
///
/// Why a hub instead of four more destinations: the shell already carried eleven, which on
/// a phone leaves ~36 px per label in the bottom bar. Доходы, Ребалансировка, Цели and
/// Налоги are all "what do I do with the portfolio next" questions, so they live behind one
/// entry that highlights for all four (see `alsoMatches` in `app_shell.dart`), while each
/// keeps its own top-level route from the contract (`/income`, `/rebalance`, `/goals`,
/// `/tax`) and is deep-linkable.
class AnalyticsHubPage extends StatelessWidget {
const AnalyticsHubPage({super.key});
static const _entries = [
(
path: '/income',
icon: Icons.payments_outlined,
title: 'Доходы',
subtitle: 'Календарь дивидендов и купонов, история выплат, прогноз на 12 месяцев',
),
(
path: '/rebalance',
icon: Icons.balance,
title: 'Ребалансировка',
subtitle: 'Целевые веса портфеля и рекомендации, что докупить или продать',
),
(
path: '/goals',
icon: Icons.flag_outlined,
title: 'Цели',
subtitle: 'Накопительные цели и прогноз их достижения по текущему тренду',
),
(
path: '/tax',
icon: Icons.receipt_long_outlined,
title: 'Налоги',
subtitle: 'Оценка налога за год и лоты с датой ЛДВ — для сверки со справкой брокера',
),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Аналитика')),
body: ListView(
padding: const EdgeInsets.all(16),
children: [
for (final e in _entries)
Card(
child: ListTile(
leading: Icon(e.icon),
title: Text(e.title),
subtitle: Text(e.subtitle),
trailing: const Icon(Icons.chevron_right),
onTap: () => context.go(e.path),
),
),
const SizedBox(height: 12),
Text(
'Сравнение с бенчмарками живёт на экране «Портфель»: обгон индекса — '
'свойство портфеля, а не отдельная тема.',
style: Theme.of(context).textTheme.bodySmall,
),
],
),
);
}
}