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
+33 -12
View File
@@ -35,7 +35,9 @@ class _ImportsPageState extends ConsumerState<ImportsPage> {
if (!mounted) return;
ref.invalidate(importsListProvider);
if (preview.duplicateOfId != null) {
_snack('Этот файл уже загружали — открыт существующий импорт №${preview.id}');
_snack(
'Этот файл уже загружали — открыт существующий импорт №${preview.id}',
);
}
context.go('/imports/${preview.id}');
} catch (e) {
@@ -47,7 +49,8 @@ class _ImportsPageState extends ConsumerState<ImportsPage> {
}
void _snack(String message) =>
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(message)));
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text(message)));
@override
Widget build(BuildContext context) {
@@ -72,7 +75,10 @@ class _ImportsPageState extends ConsumerState<ImportsPage> {
onPressed: _uploading ? null : _upload,
icon: _uploading
? const SizedBox(
width: 18, height: 18, child: CircularProgressIndicator(strokeWidth: 2))
width: 18,
height: 18,
child: CircularProgressIndicator(strokeWidth: 2),
)
: const Icon(Icons.upload_file),
label: Text(_uploading ? 'Загрузка…' : 'Загрузить отчёт'),
),
@@ -91,7 +97,8 @@ class _ImportsPageState extends ConsumerState<ImportsPage> {
leading: const Icon(Icons.help_outline),
title: Text('Нераспознанных инструментов: $pendingCount'),
subtitle: const Text(
'События по ним ждут в статусе pending и не попадают в аналитику.'),
'События по ним ждут в статусе pending и не попадают в аналитику.',
),
trailing: const Icon(Icons.chevron_right),
onTap: () => context.go('/instruments/pending'),
),
@@ -106,11 +113,16 @@ class _ImportsPageState extends ConsumerState<ImportsPage> {
padding: EdgeInsets.only(top: 48),
child: EmptyState(
icon: Icons.upload_file_outlined,
message: 'Отчёты ещё не загружались.\n'
message:
'Отчёты ещё не загружались.\n'
'Поддерживаются выгрузки Сбера и ВТБ (HTML, XLSX) и CSV.',
),
)
: Column(children: [for (final row in rows) _ImportCard(item: row)]),
: Column(
children: [
for (final row in rows) _ImportCard(item: row),
],
),
),
],
),
@@ -164,8 +176,12 @@ class _ImportCard extends StatelessWidget {
: 'период не определён';
final subtitle = [
period,
item.accountName ?? (item.accountId != null ? 'счёт #${item.accountId}' : 'счёт не найден'),
if (item.uploadedAt != null) 'загружен ${ruDate(item.uploadedAt!.toLocal())}',
item.accountName ??
(item.accountId != null
? 'счёт #${item.accountId}'
: 'счёт не найден'),
if (item.uploadedAt != null)
'загружен ${ruDate(item.uploadedAt!.toLocal())}',
if (item.sizeBytes != null) formatBytes(item.sizeBytes),
].join(' · ');
@@ -174,7 +190,9 @@ class _ImportCard extends StatelessWidget {
onTap: () => context.go('/imports/${item.id}'),
title: Row(
children: [
Flexible(child: Text(item.filename, overflow: TextOverflow.ellipsis)),
Flexible(
child: Text(item.filename, overflow: TextOverflow.ellipsis),
),
const SizedBox(width: 8),
parseStatusChip(context, item.parseStatus),
],
@@ -198,9 +216,12 @@ class _ImportCard extends StatelessWidget {
if (item.isFailed && item.error != null)
Padding(
padding: const EdgeInsets.only(top: 4),
child: Text(item.error!,
style: theme.textTheme.bodySmall
?.copyWith(color: theme.colorScheme.error)),
child: Text(
item.error!,
style: theme.textTheme.bodySmall?.copyWith(
color: theme.colorScheme.error,
),
),
),
],
),