Files
Dmitry 62d36aa3e8 feat(app): новый визуальный язык, верхняя навигация, портфели, создание счетов и ручные события
Тема и общие виджеты (AssetIcon, ServiceMark, HelpTip, глоссарий), верхняя панель TopNav и вкладки Аналитики вместо NavSidebar, иконки PWA. Экраны: портфели, создание брокерского счёта, ручное событие, правка инструмента, Обзор карточками по скоупам и таблица активов, пересчёт метрик с опросом /metrics/status. design-system.md обновлён.
2026-09-19 22:14:21 +03:00

137 lines
3.4 KiB
Dart

import 'package:flutter/material.dart';
/// The groups destinations belong to: the main tabs, the ledger screens behind «Операции», and
/// the system ones (Здоровье, Настройки) that sit as icons on the right of the top bar.
enum NavGroup { overview, ledger, system }
class NavDestination {
const NavDestination(
this.path,
this.icon,
this.selectedIcon,
this.label,
this.group, {
this.alsoMatches = const [],
this.primary = false,
});
final String path;
final IconData icon;
final IconData selectedIcon;
final String label;
final NavGroup group;
/// Extra route prefixes that belong to this destination but do not start with [path] —
/// `/instruments/pending` is reached from Импорт and must keep it highlighted, and the
/// four phase-4 screens are reached from Аналитика the same way.
final List<String> alsoMatches;
/// Shown directly in the bottom bar on a phone. Everything else moves behind «Ещё».
final bool primary;
/// The longest prefix of [location] this destination claims, or -1 for no match.
int matchLength(String location) {
var best = -1;
for (final p in [path, ...alsoMatches]) {
final hit = p == '/' ? location == '/' : location.startsWith(p);
if (hit && p.length > best) best = p.length;
}
return best;
}
}
const navDestinations = [
NavDestination(
'/',
Icons.dashboard_outlined,
Icons.dashboard,
'Обзор',
NavGroup.overview,
primary: true,
),
// One entry for the phase-4 screens. They keep their own top-level routes from the
// contract and stay deep-linkable; `/analytics` is what the bars point at, and
// `alsoMatches` keeps it highlighted while you are inside any of them.
NavDestination(
'/analytics',
Icons.insights_outlined,
Icons.insights,
'Аналитика',
NavGroup.overview,
alsoMatches: ['/income', '/rebalance', '/goals', '/tax', '/portfolios'],
primary: true,
),
NavDestination(
'/portfolio',
Icons.pie_chart_outline,
Icons.pie_chart,
'Портфель',
NavGroup.overview,
primary: true,
),
NavDestination(
'/accounts',
Icons.account_balance_outlined,
Icons.account_balance,
'Счета',
NavGroup.overview,
primary: true,
),
NavDestination(
'/events',
Icons.event_note_outlined,
Icons.event_note,
'События',
NavGroup.ledger,
),
NavDestination(
'/imports',
Icons.upload_file_outlined,
Icons.upload_file,
'Импорт',
NavGroup.ledger,
alsoMatches: ['/instruments/pending'],
),
NavDestination(
'/cashflow',
Icons.swap_horiz_outlined,
Icons.swap_horiz,
'Потоки',
NavGroup.ledger,
),
NavDestination(
'/categories',
Icons.category_outlined,
Icons.category,
'Категории',
NavGroup.ledger,
),
NavDestination(
'/transactions',
Icons.receipt_long_outlined,
Icons.receipt_long,
'Операции',
NavGroup.ledger,
),
NavDestination(
'/rules',
Icons.rule_folder_outlined,
Icons.rule_folder,
'Правила',
NavGroup.ledger,
),
NavDestination(
'/health',
Icons.monitor_heart_outlined,
Icons.monitor_heart,
'Здоровье',
NavGroup.system,
),
NavDestination(
'/settings',
Icons.settings_outlined,
Icons.settings,
'Настройки',
NavGroup.system,
),
];