style(app): остальные экраны под новый визуальный язык и форматирование

Доходы, ребалансировка, налоги, импорт, цели, здоровье данных, правила, транзакции, категории, cashflow, pending: новые виджеты и токены темы, dart format. Тесты подстроены под новые модели.
This commit is contained in:
Dmitry
2026-09-19 22:14:27 +03:00
parent 62d36aa3e8
commit 322c60a359
55 changed files with 2158 additions and 1080 deletions
+24 -10
View File
@@ -19,7 +19,8 @@ const goalBasisLabels = {
const goalBasisDescriptions = {
'xirr': 'Прогноз построен на фактической доходности портфеля (XIRR).',
'contribution': 'Прогноз построен на регулярных взносах, без учёта доходности.',
'contribution':
'Прогноз построен на регулярных взносах, без учёта доходности.',
'none': 'Данных для прогноза нет: ни доходности, ни истории взносов.',
};
@@ -58,12 +59,15 @@ class GoalCard extends ConsumerWidget {
Text(
[
'цель ${MoneyText.format(goal.targetAmount, goal.currency)}',
if (goal.targetDate != null) 'к ${ruDate(goal.targetDate!)}',
if (goal.targetDate != null)
'к ${ruDate(goal.targetDate!)}',
if (goal.monthlyContribution != null)
'взнос ${MoneyText.format(goal.monthlyContribution!, goal.currency)}/мес',
if (goal.archived) 'в архиве',
].join(' · '),
style: theme.textTheme.bodySmall?.copyWith(color: theme.hintColor),
style: theme.textTheme.bodySmall?.copyWith(
color: theme.hintColor,
),
),
],
),
@@ -86,7 +90,8 @@ class GoalCard extends ConsumerWidget {
AsyncValueView(
value: progress,
onRetry: () => ref.invalidate(goalProgressProvider(goal.id)),
data: (cached) => GoalProgressView(goal: goal, progress: cached.data),
data: (cached) =>
GoalProgressView(goal: goal, progress: cached.data),
),
],
),
@@ -98,7 +103,11 @@ class GoalCard extends ConsumerWidget {
/// The progress body, split out of [GoalCard] so it can be rendered (and tested) without a
/// provider container.
class GoalProgressView extends StatelessWidget {
const GoalProgressView({required this.goal, required this.progress, super.key});
const GoalProgressView({
required this.goal,
required this.progress,
super.key,
});
final Goal goal;
final GoalProgress progress;
@@ -150,15 +159,17 @@ class GoalProgressView extends StatelessWidget {
Icon(
unreachable ? Icons.trending_flat : Icons.flag_outlined,
size: 18,
color: unreachable ? theme.colorScheme.error : theme.colorScheme.primary,
color: unreachable
? theme.colorScheme.error
: theme.colorScheme.primary,
),
const SizedBox(width: 8),
Expanded(
child: Text(
unreachable
? (progress.basis == 'none'
? 'Прогноз недоступен: данных для оценки тренда пока нет'
: 'При текущем тренде цель не достигается')
? 'Прогноз недоступен: данных для оценки тренда пока нет'
: 'При текущем тренде цель не достигается')
: 'Прогнозная дата достижения: ${ruDate(progress.projectedDate!)}',
style: theme.textTheme.bodyMedium?.copyWith(
color: unreachable ? theme.colorScheme.error : null,
@@ -177,7 +188,7 @@ class GoalProgressView extends StatelessWidget {
progress.monthlyNeededRub == null
? 'Нужный ежемесячный взнос: — (нет целевой даты)'
: 'Нужно докладывать: '
'${MoneyText.format(progress.monthlyNeededRub!, 'RUB')}/мес',
'${MoneyText.format(progress.monthlyNeededRub!, 'RUB')}/мес',
style: theme.textTheme.bodySmall,
),
if (progress.assumedRate != null)
@@ -192,7 +203,10 @@ class GoalProgressView extends StatelessWidget {
),
),
if (progress.asOf != null)
Text('на ${ruDate(progress.asOf!)}', style: theme.textTheme.bodySmall),
Text(
'на ${ruDate(progress.asOf!)}',
style: theme.textTheme.bodySmall,
),
],
),
],